Skip to content

Commit

Permalink
fix(tree): use previous state when refreshing dataset afterward
Browse files Browse the repository at this point in the history
- use case: if we load our initial dataset with all collapsed, but then we click on "Expand All", we would expect that the next time we overwrite/refresh the dataset it would use last state (which was all expanded NOT the original `initiallyCollapsed` since we aren't on 1st load anymore, we should always use last state).
- also replace `exclude` Type to `extract` to make it less confusing on what remains (basically `exclude` is the inverse, so it's kinda confusing since we don't know what remains, while `extract` is exacly the provided type that remains)
  • Loading branch information
ghiscoding committed Oct 4, 2021
1 parent 5b27e22 commit 0982474
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
Expand Up @@ -15,5 +15,5 @@ export interface TreeToggleStateChange {
* What was the previous/last full toggle type?
* This will help us identify if the tree was fully collapsed or expanded when toggling items in the grid.
*/
previousFullToggleType: Exclude<ToggleStateChangeType, 'toggle'> | Exclude<ToggleStateChangeTypeString, 'toggle'>;
previousFullToggleType: Extract<ToggleStateChangeType, 'full-collapse' | 'full-expand'> | Extract<ToggleStateChangeTypeString, 'full-collapse' | 'full-expand'>;
}
26 changes: 23 additions & 3 deletions packages/common/src/services/__tests__/treeData.service.spec.ts
Expand Up @@ -6,6 +6,10 @@ import { PubSubService } from '../pubSub.service';
import { SharedService } from '../shared.service';
import { SortService } from '../sort.service';
import { TreeDataService } from '../treeData.service';
import * as utilities from '../utilities';

const mockUnflattenParentChildArrayToTree = jest.fn();
(utilities.unflattenParentChildArrayToTree as any) = mockUnflattenParentChildArrayToTree;

declare const Slick: SlickNamespace;

Expand Down Expand Up @@ -490,12 +494,12 @@ describe('TreeData Service', () => {

beforeEach(() => {
mockColumns = [{ id: 'file', field: 'file', }, { id: 'size', field: 'size', }] as Column[];
mockFlatDataset = [{ id: 0, file: 'documents' }, { id: 1, file: 'vacation.txt', size: 1.2, parentId: 0 }, { id: 2, file: 'todo.txt', size: 2.3, parentId: 0 }];
gridOptionsMock.treeDataOptions = { columnId: 'file', parentPropName: 'parentId' };
mockFlatDataset = [{ id: 0, file: 'documents' }, { id: 1, file: 'vacation.txt', size: 1.2, parentId: 0, __collapsed: false }, { id: 2, file: 'todo.txt', size: 2.3, parentId: 0, __collapsed: false }];
gridOptionsMock.treeDataOptions = { columnId: 'file', parentPropName: 'parentId', initiallyCollapsed: false };
jest.clearAllMocks();
});

it('should sort by the Tree column when there is no initial sort provided', () => {
it('should sort by the Tree column when there is no initial sort provided', async () => {
const mockHierarchical = [{
id: 0,
file: 'documents',
Expand All @@ -514,6 +518,22 @@ describe('TreeData Service', () => {
sortCol: mockColumns[0]
}]);
expect(result).toEqual({ flat: mockFlatDataset as any[], hierarchical: mockHierarchical as any[] });
expect(mockUnflattenParentChildArrayToTree).toHaveBeenNthCalledWith(1, mockFlatDataset, {
columnId: 'file',
identifierPropName: 'id',
initiallyCollapsed: false,
parentPropName: 'parentId',
});

// 2nd test, if we toggled all items to be collapsed, we should expect the unflatten to be called with updated `initiallyCollapsed` flag
await service.toggleTreeDataCollapse(true);
const result2 = service.convertFlatParentChildToTreeDatasetAndSort(mockFlatDataset, mockColumns, gridOptionsMock);
expect(mockUnflattenParentChildArrayToTree).toHaveBeenNthCalledWith(2, mockFlatDataset, {
columnId: 'file',
identifierPropName: 'id',
initiallyCollapsed: true, // changed to True
parentPropName: 'parentId',
});
});

it('should sort by the Tree column by the "initialSort" provided', () => {
Expand Down
8 changes: 6 additions & 2 deletions packages/common/src/services/treeData.service.ts
Expand Up @@ -114,7 +114,7 @@ export class TreeDataService {
* @param {Boolean} shouldPreProcessFullToggle - should we pre-process a full toggle on all items? defaults to True
* @param {Boolean} shouldTriggerEvent - should we trigger a toggled item event? defaults to False
*/
applyToggledItemStateChanges(treeToggledItems: TreeToggledItem[], previousFullToggleType?: Exclude<ToggleStateChangeType, 'toggle-collapse' | 'toggle-expand'> | Exclude<ToggleStateChangeTypeString, 'toggle-collapse' | 'toggle-expand'>, shouldPreProcessFullToggle = true, shouldTriggerEvent = false) {
applyToggledItemStateChanges(treeToggledItems: TreeToggledItem[], previousFullToggleType?: Extract<ToggleStateChangeType, 'full-collapse' | 'full-expand'> | Extract<ToggleStateChangeTypeString, 'full-collapse' | 'full-expand'>, shouldPreProcessFullToggle = true, shouldTriggerEvent = false) {
if (Array.isArray(treeToggledItems)) {
const collapsedPropName = this.getTreeDataOptionPropName('collapsedPropName');
const hasChildrenPropName = this.getTreeDataOptionPropName('hasChildrenPropName');
Expand Down Expand Up @@ -288,7 +288,11 @@ export class TreeDataService {
convertFlatParentChildToTreeDataset<P, T extends P & { [childrenPropName: string]: P[] }>(flatDataset: P[], gridOptions: GridOption): T[] {
const dataViewIdIdentifier = gridOptions?.datasetIdPropertyName ?? 'id';
const treeDataOpt: TreeDataOption = gridOptions?.treeDataOptions ?? { columnId: 'id' };
const treeDataOptions = { ...treeDataOpt, identifierPropName: treeDataOpt.identifierPropName ?? dataViewIdIdentifier };
const treeDataOptions = {
...treeDataOpt,
identifierPropName: treeDataOpt.identifierPropName ?? dataViewIdIdentifier,
initiallyCollapsed: this._isLastFullToggleCollapsed, // use the last full toggled flag so that if we replace the entire dataset we will still use the last toggled flag (this flag is also initialized with `initiallyCollapsed` when provided)
};
return unflattenParentChildArrayToTree(flatDataset, treeDataOptions);
}

Expand Down

0 comments on commit 0982474

Please sign in to comment.