All files / app/components DirectoryTree.tsx

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143                                    2x       2x       2x       2x         2x                             4x                     16x 16x 16x 12x   12x       12x                   12x 12x         16x               4x           8x                       12x 12x 12x 12x                                               24x      
import React from 'react';
import { style } from 'app/styles';
 
import { CaretDownIcon } from 'app/components/CaretDownIcon';
import { CaretRightIcon } from 'app/components/CaretRightIcon';
import { FileIcon } from 'app/components/FileIcon';
import { CommaNumber } from 'app/components/CommaNumber';
 
export interface DirectoryTreeProps {
  fileTree: object;
  expandedNodes: string[];
  onExpandNode: (fullPath: string) => void;
  onFileClick: (fullPath: string) => void;
  // only show commits that DON't have .status of this value
  filterCommitStatus?: 'added' | 'deleted' | 'modified';
  style?: object | string;
}
 
const outerStyle = {
  transition: 'all 1s ease',
  flexGrow: 1,
};
const directoryNodeStyle = {
  display: 'block',
  marginLeft: 20,
};
const treeNodeStyle = {
  _extends: 'normalText',
  marginLeft: 10,
};
const fileNameStyle = {
  _extends: 'normalText',
  textDecoration: 'underline',
  cursor: 'pointer',
};
const deltaStyle = {
  _extends: 'smallerText',
  float: 'right',
};
// const iconSize = 12;
 
// const iconStyle = {
//   display: 'inline-block',
//   height: iconSize,
//   width: iconSize,
//   textAlign: 'center'
// }
 
export class DirectoryTree extends React.Component<DirectoryTreeProps> {
  render() {
    return (
      <div
        style={style(outerStyle, this.props.style)}
        data-testid="directoryTree"
      >
        {this.renderTree(this.props.fileTree)}
      </div>
    );
  }
 
  renderTree(treeNode, key = 0) {
    let renderedTreeNodes = [];
    const index = 0;
    for (const nodeName in treeNode) {
      const childNode = treeNode[nodeName];
      const isExpanded =
        this.props.expandedNodes.includes(childNode.fullPath) ||
        Object.keys(childNode.nodes).length <= 1 ||
        Object.keys(treeNode).length <= 1;
 
      renderedTreeNodes.push(
        this.isFile(childNode)
          ? this.renderFileTreeNode(childNode, nodeName, key + index)
          : this.renderDirectoryTreeNode(
              childNode,
              nodeName,
              isExpanded,
              key + index
            )
      );
      Eif (isExpanded) {
        renderedTreeNodes = renderedTreeNodes.concat(
          this.renderTree(childNode.nodes, key + index)
        );
      }
    }
    return (
      <div style={directoryNodeStyle} key={key + index + 1}>
        {renderedTreeNodes}
      </div>
    );
  }
 
  renderFileTreeNode(childNode, nodeName, key) {
    return this.renderTreeNode(childNode, nodeName, FileIcon, key, () => {
      this.props.onFileClick(childNode.fullPath);
    });
  }
 
  renderDirectoryTreeNode(childNode, nodeName, isExpanded, key) {
    return this.renderTreeNode(
      childNode,
      nodeName,
      isExpanded ? CaretDownIcon : CaretRightIcon,
      key,
      () => {
        this.props.onExpandNode(childNode.fullPath);
      }
    );
  }
 
  renderTreeNode(childNode, nodeName, Icon, key, onClick) {
    const nodeStyle = Object.assign({}, treeNodeStyle) as any;
    nodeStyle.color = `@colors.${childNode.status}`;
    const nameStyle = this.isFile(childNode) ? fileNameStyle : {};
    return (
      <div
        key={key}
        style={style(nodeStyle)}
        onClick={onClick}
        data-testid="directoryTreeNode"
      >
        <Icon height={14} width={14} />
        {'    '}
        <span
          style={style(nameStyle, { color: nodeStyle.color })}
          title="click to filter"
        >
          {nodeName}
        </span>
        {'    '}
        <div style={style(deltaStyle)}>
          <CommaNumber value={childNode.delta || 0} />
          𝚫
        </div>
      </div>
    );
  }
  isFile(childNode) {
    return !childNode.nodes || Object.keys(childNode.nodes).length === 0;
  }
}