Skip to content

Commit

Permalink
feat(tree): make it possible to collapse a tree on a first load. Closes
Browse files Browse the repository at this point in the history
  • Loading branch information
geo committed Nov 19, 2017
1 parent 9f4dc18 commit fd807c7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 25 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ Here is an example of its usage:
```

* `static` - Boolean - This option makes it impossible to drag a tree or modify it in a some way, though you still can select nodes in the static tree and appropriate events will be generated.
* `isCollapsedOnInit` - Boolean - This option makes a tree to be collapsed on first load (this option cascades to its children).
* `rightMenu` - Boolean - This option allows you to activate (true, by default) or deactivate (false) right menu when clicking with right button of a mouse.
* `leftMenu` - Boolean - This option allows you to activate (true) or deactivate (false, by default) left menu.
* `cssClasses` - Object:
Expand Down
5 changes: 4 additions & 1 deletion src/demo/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,10 @@ export class AppComponent implements OnInit {
{value: 'chmod', id: 10},
{value: 'chown', id: 11},
{value: 'nano', id: 12}
]
],
settings: {
isCollapsedOnInit: true
}
},
{
value: 'boot',
Expand Down
28 changes: 22 additions & 6 deletions src/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,14 @@ export class Tree {
* @returns {Tree} A newly inserted child.
*/
public addChild(child: Tree, position?: number): Tree {
return this._addChild(Tree.cloneTreeShallow(child), position);
const newborn = this._addChild(Tree.cloneTreeShallow(child), position);

this._setFoldingType();
if (this.isNodeCollapsed()) {
this.switchFoldingType();
}

return newborn;
}

private _addChild(child: Tree, position: number = size(this._children) || 0): Tree {
Expand All @@ -268,10 +275,6 @@ export class Tree {
this._children = [child];
}

this._setFoldingType();
if (this.isNodeCollapsed()) {
this.switchFoldingType();
}
return child;
}

Expand Down Expand Up @@ -414,6 +417,9 @@ export class Tree {
if (this.isLeaf() || !this.hasChildren()) {
return;
}

this.disableCollapseOnInit();

this.node._foldingType = this.isNodeExpanded() ? FoldingType.Collapsed : FoldingType.Expanded;
}

Expand All @@ -440,7 +446,7 @@ export class Tree {
if (this.childrenShouldBeLoaded()) {
this.node._foldingType = FoldingType.Collapsed;
} else if (this._children && !isEmpty(this._children)) {
this.node._foldingType = FoldingType.Expanded;
this.node._foldingType = this.isCollapsedOnInit() ? FoldingType.Collapsed : FoldingType.Expanded;
} else if (Array.isArray(this._children)) {
this.node._foldingType = FoldingType.Empty;
} else {
Expand Down Expand Up @@ -510,6 +516,16 @@ export class Tree {
return '';
}

private disableCollapseOnInit() {
if (this.node.settings) {
this.node.settings.isCollapsedOnInit = false;
}
}

public isCollapsedOnInit() {
return !!get(this.node.settings, 'isCollapsedOnInit');
}

/**
* Check that current tree is newly created (added by user via menu for example). Tree that was built from the TreeModel is not marked as new.
* @returns {boolean} A flag whether the tree is new.
Expand Down
9 changes: 8 additions & 1 deletion src/tree.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,15 @@ export class TreeModelSettings {
*/
public static?: boolean;

public isCollapsedOnInit?: boolean;

public static merge(sourceA: TreeModel, sourceB: TreeModel): TreeModelSettings {
return defaultsDeep({}, get(sourceA, 'settings'), get(sourceB, 'settings'), {static: false, leftMenu: false, rightMenu: true});
return defaultsDeep(
{},
get(sourceA, 'settings'),
get(sourceB, 'settings'),
{static: false, leftMenu: false, rightMenu: true, isCollapsedOnInit: false}
);
}
}

Expand Down
34 changes: 17 additions & 17 deletions test/data-provider/tree.data-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,72 @@ export class TreeDataProvider {
'default values': {
treeModelA: { value: '42' },
treeModelB: { value: '12' },
result: { static: false, leftMenu: false, rightMenu: true }
result: { static: false, leftMenu: false, rightMenu: true, isCollapsedOnInit: false }
},
'first settings source has higher priority': {
treeModelA: { value: '42', settings: { static: true, leftMenu: true, rightMenu: true } },
treeModelB: { value: '12', settings: { static: false, leftMenu: false, rightMenu: false } },
result: { static: true, leftMenu: true, rightMenu: true }
treeModelA: { value: '42', settings: { static: true, leftMenu: true, rightMenu: true, isCollapsedOnInit: true } },
treeModelB: { value: '12', settings: { static: false, leftMenu: false, rightMenu: false, isCollapsedOnInit: false } },
result: { static: true, leftMenu: true, rightMenu: true, isCollapsedOnInit: true }
},
'second settings source has priority if first settings source doesn\'t have the option': {
treeModelA: { value: '42' },
treeModelB: { value: '12', settings: { static: true, leftMenu: true, rightMenu: false } },
result: { static: true, leftMenu: true, rightMenu: false }
treeModelB: { value: '12', settings: { static: true, leftMenu: true, rightMenu: false, isCollapsedOnInit: true } },
result: { static: true, leftMenu: true, rightMenu: false, isCollapsedOnInit: true }
},
'first expanded property of cssClasses has higher priority': {
treeModelA: { value: '12', settings: { cssClasses: { expanded: 'arrow-down-o' } } },
treeModelB: { value: '42', settings: { cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } } },
result: { static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } }
},
'first collapsed property of cssClasses has higher priority': {
treeModelA: { value: '12', settings: { cssClasses: { collapsed: 'arrow-right-o' } } },
treeModelB: { value: '42', settings: { cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } } },
result: { static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right-o', empty: 'arrow-gray', leaf: 'dot' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right-o', empty: 'arrow-gray', leaf: 'dot' } }
},
'first empty property of cssClasses has higher priority': {
treeModelA: { value: '12', settings: { cssClasses: { empty: 'arrow-gray-o' } } },
treeModelB: { value: '42', settings: { cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } } },
result: { static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray-o', leaf: 'dot' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray-o', leaf: 'dot' } }
},
'first leaf property of cssClasses has higher priority': {
treeModelA: { value: '12', settings: { cssClasses: { leaf: 'dot-o' } } },
treeModelB: { value: '42', settings: { cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } } },
result: { static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot-o' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot-o' } }
},
'first properties of cssClasses has higher priority': {
treeModelA: { value: '12', settings: { cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } } },
treeModelB: { value: '42', settings: { cssClasses: { expanded: 'arrow-down', collapsed: 'arrow-right', empty: 'arrow-gray', leaf: 'dot' } } },
result: { static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } }
},
'second properties of cssClasses in settings has priority, if first source doesn\'t have them': {
treeModelA: { value: '42', settings: { static: true, leftMenu: true, rightMenu: false } },
treeModelB: { value: '12', settings: { cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } } },
result: { static: true, leftMenu: true, rightMenu: false, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } }
result: { isCollapsedOnInit: false, static: true, leftMenu: true, rightMenu: false, cssClasses: { expanded: 'arrow-down-o', collapsed: 'arrow-right-o', empty: 'arrow-gray-o', leaf: 'dot-o' } }
},
'first node property of templates has higher priority': {
treeModelA: { value: '12', settings: { templates: { node: '<i class="folder-o"></i>' } } },
treeModelB: { value: '42', settings: { templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } } },
result: { static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } }
},
'first leaf property in templates has higher priority': {
treeModelA: { value: '12', settings: { templates: { leaf: '<i class="file-o"></i>' } } },
treeModelB: { value: '42', settings: { templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } } },
result: { static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation"></i>' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation"></i>' } }
},
'first leftMenu property in templates has higher priority': {
treeModelA: { value: '12', settings: { templates: { leftMenu: '<i class="navigation-o"></i>' } } },
treeModelB: { value: '42', settings: { templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } } },
result: { static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation-o"></i>' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation-o"></i>' } }
},
'first properties of templates has higher priority': {
treeModelA: { value: '12', settings: { templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } } },
treeModelB: { value: '42', settings: { templates: { node: '<i class="folder"></i>', leaf: '<i class="file"></i>', leftMenu: '<i class="navigation"></i>' } } },
result: { static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } }
result: { isCollapsedOnInit: false, static: false, leftMenu: false, rightMenu: true, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } }
},
'second properties of templates in settings has priority, if first source doesn\'t have them': {
treeModelA: { value: '42', settings: { static: true, leftMenu: true, rightMenu: false } },
treeModelB: { value: '12', settings: { templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } } },
result: { static: true, leftMenu: true, rightMenu: false, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } }
result: { isCollapsedOnInit: false, static: true, leftMenu: true, rightMenu: false, templates: { node: '<i class="folder-o"></i>', leaf: '<i class="file-o"></i>', leftMenu: '<i class="navigation-o"></i>' } }
}
};
}

0 comments on commit fd807c7

Please sign in to comment.