Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tree): allow specifying key where tree status is saved #130

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions projects/ngx-datatable/src/lib/components/body/body.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { DataTableSummaryRowComponent } from './summary/summary-row.component';
import { DataTableSelectionComponent } from './selection.component';
import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component';
import { ProgressBarComponent } from './progress-bar.component';
import { getByNestedIndex } from '../../utils/tree';

@Component({
selector: 'datatable-body',
Expand Down Expand Up @@ -138,7 +139,7 @@ import { ProgressBarComponent } from './progress-bar.component';
[expanded]="getRowExpanded(group)"
[rowClass]="rowClass"
[displayCheck]="displayCheck"
[treeStatus]="group?.treeStatus"
[treeStatus]="getTreeStatus(group)"
[ghostLoadingIndicator]="ghostLoadingIndicator"
[draggable]="rowDraggable"
[verticalScrollVisible]="verticalScrollVisible"
Expand Down Expand Up @@ -172,7 +173,7 @@ import { ProgressBarComponent } from './progress-bar.component';
[expanded]="getRowExpanded(group)"
[rowClass]="rowClass"
[displayCheck]="displayCheck"
[treeStatus]="group?.treeStatus"
[treeStatus]="getTreeStatus(group)"
[ghostLoadingIndicator]="ghostLoadingIndicator"
[draggable]="rowDraggable"
[verticalScrollVisible]="verticalScrollVisible"
Expand Down Expand Up @@ -394,6 +395,8 @@ export class DataTableBodyComponent<TRow extends { treeStatus?: TreeStatus } = a

@Input() verticalScrollVisible = false;

@Input() treeStatusKey = 'treeStatus';

@Output() scroll: EventEmitter<ScrollEvent> = new EventEmitter();
@Output() page: EventEmitter<number> = new EventEmitter();
@Output() activate: EventEmitter<ActivateEvent<TRow>> = new EventEmitter();
Expand Down Expand Up @@ -958,6 +961,13 @@ export class DataTableBodyComponent<TRow extends { treeStatus?: TreeStatus } = a
return this.rowIndexes.get(row) || 0;
}

/**
* Returns the tree status of the row
*/
getTreeStatus(row: RowOrGroup<TRow>): TreeStatus {
return getByNestedIndex(row, this.treeStatusKey);
}

onTreeAction(row: TRow) {
this.treeAction.emit({ row });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
[rowDraggable]="rowDraggable"
[rowDragEvents]="rowDragEvents"
[rowDefTemplate]="rowDefTemplate"
[treeStatusKey]="treeStatusKey"
>
<ng-content select="[loading-indicator]" ngProjectAs="[loading-indicator]">
<datatable-progress></datatable-progress>
Expand Down
14 changes: 11 additions & 3 deletions projects/ngx-datatable/src/lib/components/datatable.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ export class DatatableComponent<TRow = any>
*/
@Input() treeToRelation: string;

/**
* The key of the row used to store the tree status, can be nested by separating keys with "."
*/
@Input() treeStatusKey = 'treeStatus';

/**
* A flag for switching summary row on / off
*/
Expand Down Expand Up @@ -862,7 +867,8 @@ export class DatatableComponent<TRow = any>
this._internalRows = groupRowsByParents(
this._internalRows,
optionalGetterForProp(this.treeFromRelation),
optionalGetterForProp(this.treeToRelation)
optionalGetterForProp(this.treeToRelation),
this.treeStatusKey
);

if (this._rows && this._groupRowsBy) {
Expand Down Expand Up @@ -1205,7 +1211,8 @@ export class DatatableComponent<TRow = any>
this._internalRows = groupRowsByParents(
this._internalRows,
optionalGetterForProp(this.treeFromRelation),
optionalGetterForProp(this.treeToRelation)
optionalGetterForProp(this.treeToRelation),
this.treeStatusKey
);

// Always go to first page when sorting to see the newly sorted data
Expand Down Expand Up @@ -1306,7 +1313,8 @@ export class DatatableComponent<TRow = any>
this._internalRows = groupRowsByParents(
this._internalRows,
optionalGetterForProp(this.treeFromRelation),
optionalGetterForProp(this.treeToRelation)
optionalGetterForProp(this.treeToRelation),
this.treeStatusKey
);
}
}
Expand Down
49 changes: 43 additions & 6 deletions projects/ngx-datatable/src/lib/utils/tree.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getterForProp } from './column-prop-getters';
import { TableColumnProp } from '../types/table-column.type';
import { TreeStatus } from '../types/public.types';

export type OptionalValueGetter = (row: any) => any | undefined;
export function optionalGetterForProp(prop: TableColumnProp): OptionalValueGetter {
Expand Down Expand Up @@ -45,14 +46,15 @@ export function optionalGetterForProp(prop: TableColumnProp): OptionalValueGette
export function groupRowsByParents<TRow>(
rows: TRow[],
from?: OptionalValueGetter,
to?: OptionalValueGetter
to?: OptionalValueGetter,
statusIndex = 'treeStatus'
): TRow[] {
if (from && to) {
const nodeById = {};
const l = rows.length;
let node: TreeNode | null = null;

nodeById[0] = new TreeNode(); // that's the root node
nodeById[0] = new TreeNode(null, statusIndex); // that's the root node

const uniqIDs = rows.reduce((arr, item) => {
const toValue = to(item);
Expand All @@ -64,7 +66,7 @@ export function groupRowsByParents<TRow>(

for (let i = 0; i < l; i++) {
// make TreeNode objects for each item
nodeById[to(rows[i])] = new TreeNode(rows[i]);
nodeById[to(rows[i])] = new TreeNode(rows[i], statusIndex);
}

for (let i = 0; i < l; i++) {
Expand All @@ -91,25 +93,60 @@ export function groupRowsByParents<TRow>(
}
}

export const getByNestedIndex = (obj: any, index: string) => {
console.log(obj);
let prop: any = obj;
index.split('.').forEach(indexPart => {
if (prop !== undefined) {
prop = prop[indexPart];
}
});
console.log(prop);
return prop;
};

export const createWithNestedIndex = (index: string, val: any) => {
const rootProp: any = {};
let prop: any = rootProp;
const splitIndex = index.split('.');
splitIndex.forEach((indexPart, i) => {
if (i === splitIndex.length - 1) {
prop[indexPart] = val;
return;
}
if (prop[indexPart] === undefined) {
prop[indexPart] = {};
}
prop = prop[indexPart];
});
return rootProp;
};

class TreeNode {
public row: any;
public parent: any;
public children: any[];
private statusIndex: string;

constructor(row: any | null = null) {
constructor(row: any | null = null, statusIndex = 'treeStatus') {
if (!row) {
row = {
level: -1,
treeStatus: 'expanded'
...createWithNestedIndex(statusIndex, 'expanded')
};
}
this.row = row;
this.parent = null;
this.children = [];
this.statusIndex = statusIndex;
}

get treeStatus(): TreeStatus {
return getByNestedIndex(this.row, this.statusIndex);
}

flatten(f: any, recursive: boolean) {
if (this.row.treeStatus === 'expanded') {
if (this.treeStatus === 'expanded') {
for (let i = 0, l = this.children.length; i < l; i++) {
const child = this.children[i];
f.apply(child, Array.prototype.slice.call(arguments, 2));
Expand Down
12 changes: 8 additions & 4 deletions src/app/tree/client-tree.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Employee } from '../data.model';
rowHeight="auto"
[treeFromRelation]="'manager'"
[treeToRelation]="'name'"
[treeStatusKey]="'options.treeStatus'"
[rows]="rows"
(treeAction)="onTreeAction($event)"
>
Expand All @@ -49,7 +50,7 @@ import { Employee } from '../data.model';
styles: ['.icon {height: 10px; width: 10px; }', '.disabled {opacity: 0.5; }']
})
export class ClientTreeComponent {
rows: (Employee & { treeStatus: TreeStatus })[] = [];
rows: (Employee & { options: { treeStatus: TreeStatus } })[] = [];

ColumnMode = ColumnMode;

Expand All @@ -72,10 +73,13 @@ export class ClientTreeComponent {

onTreeAction(event: any) {
const row = event.row;
if (row.treeStatus === 'collapsed') {
row.treeStatus = 'expanded';
if (!row.options) {
row.options = {};
}
if (row.options.treeStatus === 'collapsed') {
row.options.treeStatus = 'expanded';
} else {
row.treeStatus = 'collapsed';
row.options.treeStatus = 'collapsed';
}
this.rows = [...this.rows];
}
Expand Down
18 changes: 9 additions & 9 deletions src/assets/data/company_tree.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,58 @@
"gender": "female",
"company": "Johnson, Johnson and Partners, LLC CMP DDC",
"age": 22,
"treeStatus": "collapsed"
"options": { "treeStatus": "collapsed" }
},
{
"name": "Claudine Neal",
"gender": "female",
"company": "Sealoud",
"age": 55,
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Beryl Rice",
"gender": "female",
"company": "Velity",
"age": 67,
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Wilder Gonzales",
"gender": "male",
"company": "Geekko",
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Georgina Schultz",
"gender": "female",
"company": "Suretech",
"treeStatus": "collapsed"
"options": { "treeStatus": "collapsed" }
},
{
"name": "Carroll Buchanan",
"gender": "male",
"company": "Ecosys",
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Valarie Atkinson",
"gender": "female",
"company": "Hopeli",
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Schroeder Mathews",
"gender": "male",
"company": "Polarium",
"manager": "Ethel Price",
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
},
{
"name": "Lynda Mendoza",
"gender": "female",
"company": "Dogspa",
"manager": "Georgina Schultz",
"treeStatus": "disabled"
"options": { "treeStatus": "disabled" }
}
]
Loading