treeItemSelectableComponent.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { TreeItemSpecializedComponent } from "./treeItemSpecializedComponent";
  2. import { Observable, Nullable, IExplorerExtensibilityGroup } from "babylonjs";
  3. import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  4. import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
  5. import { Tools } from "../../tools";
  6. import * as ReactDOM from "react-dom";
  7. import * as React from "react";
  8. export interface ITreeItemSelectableComponentProps {
  9. entity: any,
  10. selectedEntity?: any,
  11. offset: number,
  12. extensibilityGroups?: IExplorerExtensibilityGroup[],
  13. onSelectionChangedObservable?: Observable<any>,
  14. filter: Nullable<string>
  15. }
  16. export class TreeItemSelectableComponent extends React.Component<ITreeItemSelectableComponentProps, { isExpanded: boolean, isSelected: boolean }> {
  17. private _wasSelected = false;
  18. constructor(props: ITreeItemSelectableComponentProps) {
  19. super(props);
  20. this.state = { isSelected: this.props.entity === this.props.selectedEntity, isExpanded: Tools.LookForItem(this.props.entity, this.props.selectedEntity) };
  21. }
  22. switchExpandedState(): void {
  23. this.setState({ isExpanded: !this.state.isExpanded });
  24. }
  25. shouldComponentUpdate(nextProps: ITreeItemSelectableComponentProps, nextState: { isExpanded: boolean, isSelected: boolean }) {
  26. if (!nextState.isExpanded && this.state.isExpanded) {
  27. return true;
  28. }
  29. if (nextProps.selectedEntity) {
  30. if (nextProps.entity === nextProps.selectedEntity) {
  31. nextState.isSelected = true;
  32. return true;
  33. } else {
  34. nextState.isSelected = false;
  35. }
  36. if (Tools.LookForItem(nextProps.entity, nextProps.selectedEntity)) {
  37. nextState.isExpanded = true;
  38. return true;
  39. }
  40. }
  41. return true;
  42. }
  43. scrollIntoView() {
  44. const element = ReactDOM.findDOMNode(this) as Element;
  45. if (element) {
  46. element.scrollIntoView();
  47. }
  48. }
  49. componentDidMount() {
  50. if (this.state.isSelected) {
  51. this.scrollIntoView();
  52. }
  53. }
  54. componentDidUpdate() {
  55. if (this.state.isSelected && !this._wasSelected) {
  56. this.scrollIntoView();
  57. }
  58. this._wasSelected = false;
  59. }
  60. onSelect() {
  61. if (!this.props.onSelectionChangedObservable) {
  62. return;
  63. }
  64. this._wasSelected = true;
  65. const entity = this.props.entity;
  66. this.props.onSelectionChangedObservable.notifyObservers(entity);
  67. }
  68. renderChildren() {
  69. const entity = this.props.entity;
  70. if (!entity.getChildren && !entity.children || !this.state.isExpanded) {
  71. return null;
  72. }
  73. const children = Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
  74. return (
  75. children.map(item => {
  76. return (
  77. <TreeItemSelectableComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.props.selectedEntity} key={item.uniqueId} offset={this.props.offset + 2} entity={item} onSelectionChangedObservable={this.props.onSelectionChangedObservable} filter={this.props.filter} />
  78. );
  79. })
  80. )
  81. }
  82. render() {
  83. const marginStyle = {
  84. paddingLeft: (10 * (this.props.offset + 0.5)) + "px"
  85. };
  86. const entity = this.props.entity;
  87. const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
  88. const children = Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
  89. const hasChildren = children.length > 0;
  90. if (!entity.metadata) {
  91. entity.metadata = {};
  92. }
  93. entity.metadata.setExpandedState = (value: boolean) => {
  94. this.setState({ isExpanded: value });
  95. }
  96. entity.metadata.isExpanded = this.state.isExpanded;
  97. if (this.props.filter) {
  98. const lowerCaseFilter = this.props.filter.toLowerCase();
  99. if (!entity.name || entity.name.toLowerCase().indexOf(lowerCaseFilter) === -1) {
  100. if (!hasChildren) {
  101. return null;
  102. }
  103. if (entity.getDescendants) {
  104. if (entity.getDescendants(false, (n: any) => {
  105. console.log(n.name);
  106. return n.name && n.name.toLowerCase().indexOf(lowerCaseFilter) !== -1
  107. }).length === 0) {
  108. return null;
  109. }
  110. }
  111. }
  112. }
  113. return (
  114. <div>
  115. <div className={this.state.isSelected ? "itemContainer selected" : "itemContainer"} style={marginStyle} >
  116. {
  117. hasChildren &&
  118. <div className="arrow icon" onClick={() => this.switchExpandedState()}>
  119. {chevron}
  120. </div>
  121. }
  122. <TreeItemSpecializedComponent extensibilityGroups={this.props.extensibilityGroups} label={entity.name} entity={entity} onClick={() => this.onSelect()} onSelectionChangedObservable={this.props.onSelectionChangedObservable} />
  123. </div>
  124. {
  125. this.renderChildren()
  126. }
  127. </div >
  128. );
  129. }
  130. }