From b5d9ab7da02ae622dab26eb6797471701d83e90d Mon Sep 17 00:00:00 2001 From: Jeeyun Lim Date: Mon, 6 Aug 2018 15:28:26 -0700 Subject: [PATCH] [ng] allow pre-selection of currentSingle when `all` hasn't been set (#2500) Signed-off-by: Jeeyun Lim --- .../data/datagrid/providers/selection.spec.ts | 62 +++++++++++++++++++ .../data/datagrid/providers/selection.ts | 27 ++++++-- .../selection-single/selection-single.html | 4 +- 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/clr-angular/data/datagrid/providers/selection.spec.ts b/src/clr-angular/data/datagrid/providers/selection.spec.ts index fa8efb5b48..4256226226 100644 --- a/src/clr-angular/data/datagrid/providers/selection.spec.ts +++ b/src/clr-angular/data/datagrid/providers/selection.spec.ts @@ -141,6 +141,23 @@ export default function(): void { expect(selectionInstance.isSelected(4)).toBe(true); }); + it( + 'accepts pre-selected items in multi selection type when `all` has not been defined', + fakeAsync(function() { + itemsInstance.all = null; + tick(); + selectionInstance.selectionType = SelectionType.Multi; + selectionInstance.current = [4, 2]; + tick(); + itemsInstance.all = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + tick(); + expect(selectionInstance.isSelected(1)).toBe(false); + expect(selectionInstance.isSelected(2)).toBe(true); + expect(selectionInstance.isSelected(3)).toBe(false); + expect(selectionInstance.isSelected(4)).toBe(true); + }) + ); + it('accepts pre-selected item in single selection type', function() { selectionInstance.selectionType = SelectionType.Single; selectionInstance.currentSingle = 2; @@ -150,6 +167,23 @@ export default function(): void { expect(selectionInstance.isSelected(4)).toBe(false); }); + it( + 'accepts pre-selected item in single selection type when `all` has not been defined', + fakeAsync(function() { + itemsInstance.all = null; + tick(); + selectionInstance.selectionType = SelectionType.Single; + selectionInstance.currentSingle = 2; + tick(); + itemsInstance.all = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + tick(); + expect(selectionInstance.isSelected(1)).toBe(false); + expect(selectionInstance.isSelected(2)).toBe(true); + expect(selectionInstance.isSelected(3)).toBe(false); + expect(selectionInstance.isSelected(4)).toBe(false); + }) + ); + it('exposes an Observable to follow selection changes in multi selection type', function() { let nbChanges = 0; let currentSelection: any[]; @@ -440,6 +474,20 @@ export default function(): void { }) ); + it( + 'accepts pre-selected items with trackBy when `all` has not been defined', + fakeAsync(() => { + itemsInstance.trackBy = (index, item) => item.id; + selectionInstance.current = [{ id: 1 }, { id: 2 }, { id: 3 }]; + tick(); + itemsInstance.all = itemsA; + tick(); + itemsA.forEach(item => { + expect(selectionInstance.isSelected(item)).toBe(true); + }); + }) + ); + it( 'should support toggleAll selection on page change', fakeAsync(() => { @@ -486,6 +534,20 @@ export default function(): void { // expect(selectionInstance.currentSingle.modified).toEqual(true); }) ); + + it( + 'accepts pre-selected items with trackBy when `all` has not been defined', + fakeAsync(() => { + itemsInstance.trackBy = (index, item) => item.id; + selectionInstance.currentSingle = { id: 1 }; + tick(); + itemsInstance.all = itemsA; + tick(); + expect(selectionInstance.isSelected(itemsA[0])).toBe(true); + expect(selectionInstance.isSelected(itemsA[1])).toBe(false); + expect(selectionInstance.isSelected(itemsA[2])).toBe(false); + }) + ); }); }); }); diff --git a/src/clr-angular/data/datagrid/providers/selection.ts b/src/clr-angular/data/datagrid/providers/selection.ts index 536f65fc37..ef2723683c 100644 --- a/src/clr-angular/data/datagrid/providers/selection.ts +++ b/src/clr-angular/data/datagrid/providers/selection.ts @@ -49,6 +49,14 @@ export class Selection { const trackBy: TrackByFunction = this._items.trackBy; let selectionUpdated: boolean = false; + // if the currentSingle has been set before data was loaded, we look up and save the ref from current data set + if (this.currentSingle && !this.prevSingleSelectionRef) { + if (this._items.all && this._items.trackBy) { + const lookup = this._items.all.findIndex(maybe => maybe === this.currentSingle); + this.prevSingleSelectionRef = this._items.trackBy(lookup, this.currentSingle); + } + } + updatedItems.forEach((item, index) => { const ref = trackBy(index, item); // If one of the updated items is the previously selectedSingle, set it as the new one @@ -58,10 +66,10 @@ export class Selection { } }); - // Delete the currentSingle if it doesn't exist anymore if we're using smart datagrids - // where we expect all items to be present. - // No explicit "delete" is required, since it would still be undefined at this point. - // Marking it as selectionUpdated will emit the change when the currentSingle is updated below. + // If we're using smart datagrids, we expect all items to be present in the updatedItems array. + // Therefore, we should delete the currentSingle if it used to be defined but doesn't exist anymore. + // No explicit "delete" is required, since newSingle would be undefined at this point. + // Marking it as selectionUpdated here will set currentSingle to undefined below in the setTimeout. if (this._items.smart && !newSingle) { selectionUpdated = true; } @@ -83,6 +91,17 @@ export class Selection { const trackBy: TrackByFunction = this._items.trackBy; let selectionUpdated: boolean = false; + // if the current has been set before data was loaded, we look up and save the ref from current data set + if (this.current.length > 0 && this.prevSelectionRefs.length !== this.current.length) { + if (this._items.all && this._items.trackBy) { + this.prevSelectionRefs = []; + this.current.forEach(item => { + const lookup = this._items.all.findIndex(maybe => maybe === item); + this.prevSelectionRefs.push(this._items.trackBy(lookup, item)); + }); + } + } + // TODO: revisit this when we work on https://github.com/vmware/clarity/issues/2342 // currently, the selection is cleared when filter is applied, so the logic inside // the if statement below results in broken behavior. diff --git a/src/dev/src/app/datagrid/selection-single/selection-single.html b/src/dev/src/app/datagrid/selection-single/selection-single.html index 6bc73a7475..cd2317e152 100644 --- a/src/dev/src/app/datagrid/selection-single/selection-single.html +++ b/src/dev/src/app/datagrid/selection-single/selection-single.html @@ -125,8 +125,8 @@

Server-driven, trackBy item

Selected user: - No user selected. - {{trackByIdSingleSelected.name}} + No user selected. + {{trackByIdServerSingleSelected.name}}