Skip to content

Commit

Permalink
feat(tree): get a functional Tree View example working with add item
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding-SE committed Mar 26, 2020
1 parent 27d3261 commit c07cdb5
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 148 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ npm run test:watch
- [ ] GraphQL (**separate package**)
- [ ] OData (**separate package**)
- [ ] Grid Event
- [x] Grid Service (helper)
- [ ] Grid State
- [x] Grouping & Col Span
- [ ] Pagination
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ export * from './grouping-formatters/index';
export * from './sorters/index';

import * as Enums from './enums/index';
import * as ServiceUtilities from './services/utilities';
import * as SorterUtilities from './sorters/sorterUtilities';

const Utilities = { ...ServiceUtilities, ...SorterUtilities };
export { Enums };
export { Utilities };
export { SlickgridConfig } from './slickgrid-config';
18 changes: 15 additions & 3 deletions packages/common/src/services/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function convertArrayFlatToHierarchical(flatArray: any[], options?: { par
// connect childrens to its parent, and split roots apart
Object.keys(all).forEach((id) => {
const item = all[id];
if (item[parentPropName] === null) {
if (item[parentPropName] === null || !item.hasOwnProperty(parentPropName)) {
roots.push(item);
} else if (item[parentPropName] in all) {
const p = all[item[parentPropName]];
Expand All @@ -76,14 +76,26 @@ export function convertArrayFlatToHierarchical(flatArray: any[], options?: { par
* @param outputArray
* @param options you can provide "childPropName" (defaults to "children")
*/
export function convertArrayHierarchicalToFlat(hierarchicalArray: any[], outputArray: any[], options: { childPropName?: string; }) {
export function convertArrayHierarchicalToFlat(hierarchicalArray: any[], options?: { childPropName?: string; }): any[] {
const outputArray: any[] = [];
const inputArray = $.extend(true, [], hierarchicalArray); // make a deep copy of the input array to avoid modifying that array

convertArrayHierarchicalToFlatByReference(inputArray, outputArray, options);

// the output array is the one passed as reference
return outputArray;
}

export function convertArrayHierarchicalToFlatByReference(hierarchicalArray: any[], outputArray: any[], options?: { childPropName?: string; hasChildrenFlagPropName?: string; }) {
const childPropName = options?.childPropName || 'children';
const hasChildrenFlagPropName = options?.hasChildrenFlagPropName || '__hasChildren';

for (const item of hierarchicalArray) {
if (item) {
outputArray.push(item);
if (Array.isArray(item[childPropName])) {
convertArrayHierarchicalToFlat(item[childPropName], outputArray, options);
convertArrayHierarchicalToFlatByReference(item[childPropName], outputArray, options);
item[hasChildrenFlagPropName] = true;
delete item[childPropName]; // remove the children property
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/sorters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { stringSorter } from './stringSorter';
import { getAssociatedDateSorter } from './dateUtilities';
import { FieldType } from '../enums/fieldType.enum';

// export the sorter utilities so they could be used by others
export * from './sorterUtilities';

export const Sorters = {
/** Sorter method to sort values by Date object type (uses Moment.js ISO_8601 standard format, optionally include time) */
date: getAssociatedDateSorter(FieldType.date),
Expand Down
50 changes: 49 additions & 1 deletion packages/common/src/sorters/sorterUtilities.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { FieldType, SortDirectionNumber } from '../enums/index';
import { FieldType, SortDirectionNumber, SortDirection, SortDirectionString } from '../enums/index';
import { Column } from '../interfaces/index';
import { Sorters } from './index';
import { getAssociatedDateSorter } from './dateUtilities';
import { convertArrayHierarchicalToFlat, convertArrayFlatToHierarchical } from '../services/utilities';

export function sortByFieldType(fieldType: FieldType, value1: any, value2: any, sortDirection: number | SortDirectionNumber, sortColumn?: Column) {
let sortResult = 0;
Expand Down Expand Up @@ -51,3 +52,50 @@ export function sortByFieldType(fieldType: FieldType, value1: any, value2: any,

return sortResult;
}

/**
* Take a flat array (that has hierarchical data but flatten) and sort it by given parent/child properties
* It will sort by a given "parentPropName" and "childPropName"
* @param flatArray
* @param options
*/
export function sortFlatArrayByHierarchy(flatArray: any[], options?: { sortPropFieldType?: FieldType; parentPropName?: string; childPropName?: string; identifierPropName?: string; direction?: SortDirection | SortDirectionString; sortByPropName?: string; }): any[] {
const inputArray: any[] = $.extend(true, [], flatArray); // make a deep copy of the input array to avoid modifying that array

// step 1: convert array to a hierarchical structure so that we can sort it
const resultFlatArray = convertArrayFlatToHierarchical(inputArray, options);

// step 2: sort the hierarchical array
sortHierarchicalArray(resultFlatArray, options);
const inputHierarchicalArray: any[] = $.extend(true, [], resultFlatArray); // make a deep copy of the input array to avoid modifying that array

// step 3: re-convert the array back to a flat structure and return it
const resultSortedFlatDataset = convertArrayHierarchicalToFlat(inputHierarchicalArray, options);

return resultSortedFlatDataset;
}

/**
* Sort a hierarchical array (an array that has children property, that could also have children, ...)
* It will sort by a given "parentPropName" and "childPropName"
* @param hierarchicalArray
* @param options
*/
export function sortHierarchicalArray(hierarchicalArray: any[], options?: { sortPropFieldType?: FieldType; parentPropName?: string; childPropName?: string; identifierPropName?: string; direction?: SortDirection | SortDirectionString; sortByPropName?: string; }): any[] {
const childPropName = options?.childPropName || 'children';
const sortByPropName = options?.sortByPropName || 'id';
const fieldType = options?.sortPropFieldType || FieldType.string;

const sortAscending = ((options?.direction || 'ASC').toUpperCase() === SortDirection.ASC);
const sortingDirectionNumber = sortAscending ? 1 : -1;

hierarchicalArray.sort((a: any, b: any) => sortByFieldType(fieldType, (a && a[sortByPropName]), (b && b[sortByPropName]), sortingDirectionNumber));

for (const item of hierarchicalArray) {
if (item && Array.isArray(item[childPropName])) {
sortHierarchicalArray(item[childPropName], options);
}
}

return hierarchicalArray;
}
1 change: 1 addition & 0 deletions packages/common/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"target": "es2015",
"module": "esnext",
"sourceMap": true,
"noImplicitReturns": true,
"lib": [
"es2020",
"dom"
Expand Down
9 changes: 8 additions & 1 deletion packages/vanilla-bundle-examples/src/examples/example03.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ <h3 class="title is-4">Example 03 - Tree View</h3>
<div class="column is-narrow">
<button onclick.delegate="addNewRow()" class="button is-small is-info">
<span class="icon mdi mdi-plus"></span>
<span>Add New Item</span>
<span>Add New Item (in 1st group)</span>
</button>
<button onclick.delegate="recreateDataset()" class="button is-small">
<span class="icon mdi mdi-refresh-circle"></span>
<span>New Dataset</span>
</button>
<button onclick.delegate="collapseAll()" class="button is-small">
<span class="icon mdi mdi-arrow-collapse"></span>
Expand All @@ -13,6 +17,9 @@ <h3 class="title is-4">Example 03 - Tree View</h3>
<span class="icon mdi mdi-arrow-expand"></span>
<span>Expand All</span>
</button>
<button onclick.delegate="logExpandedStructure()" class="button is-small">
<span>Log Expanded Structure</span>
</button>
</div>
<div class="column is-6">
<div class="field is-horizontal">
Expand Down
Loading

0 comments on commit c07cdb5

Please sign in to comment.