Skip to content

Commit

Permalink
feat(tree): allow specifying key where tree status is saved
Browse files Browse the repository at this point in the history
  • Loading branch information
Killusions committed Dec 9, 2024
1 parent e818477 commit 23fde2b
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 24 deletions.
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, index) => {

Check failure on line 112 in projects/ngx-datatable/src/lib/utils/tree.ts

View workflow job for this annotation

GitHub Actions / build

'index' is already declared in the upper scope on line 108 column 39
if (index === 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" }
}
]

0 comments on commit 23fde2b

Please sign in to comment.