From 131ada51cb6d52522990e6974ce0d779467bbae9 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Mon, 26 Apr 2021 18:56:33 -0400 Subject: [PATCH] fix(selection): full row selection should be selected w/show hidden row - fixes #739 --- .../__tests__/columnPickerExtension.spec.ts | 33 +++++++++++++++---- .../__tests__/gridMenuExtension.spec.ts | 21 ++++++++++++ .../extensions/columnPickerExtension.ts | 13 ++++++++ .../extensions/gridMenuExtension.ts | 12 +++++++ 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts b/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts index 6523c93e5..b88c50235 100644 --- a/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts +++ b/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts @@ -10,9 +10,11 @@ declare const Slick: any; const gridStub = { getOptions: jest.fn(), + getSelectedRows: jest.fn(), registerPlugin: jest.fn(), setColumns: jest.fn(), setOptions: jest.fn(), + setSelectedRows: jest.fn(), }; const mockAddon = jest.fn().mockImplementation(() => ({ @@ -71,7 +73,7 @@ describe('columnPickerExtension', () => { }); it('should register the addon', () => { - const onRegisteredSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onExtensionRegistered'); + const onRegisteredSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker!, 'onExtensionRegistered'); const instance = extension.register(); const addonInstance = extension.getAddonInstance(); @@ -84,7 +86,7 @@ describe('columnPickerExtension', () => { it('should call internal event handler subscribe and expect the "onColumnsChanged" grid option to be called when addon notify is called', () => { const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); - const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onColumnsChanged'); + const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker!, 'onColumnsChanged'); const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); const readjustSpy = jest.spyOn(extensionUtility, 'readjustFrozenColumnIndexWhenNeeded'); @@ -104,7 +106,7 @@ describe('columnPickerExtension', () => { it(`should call internal event handler subscribe and expect the "onColumnsChanged" grid option to be called when addon notify is called and it should override "visibleColumns" when array passed as arguments is bigger than previous visible columns`, () => { const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); - const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onColumnsChanged'); + const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker!, 'onColumnsChanged'); const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); const instance = extension.register(); @@ -119,6 +121,25 @@ describe('columnPickerExtension', () => { expect(visibleColsSpy).toHaveBeenCalledWith(columnsMock); }); + it('should call internal "onColumnsChanged" event and expect "setSelectedRows" method to be called using Row Selection is enabled', () => { + const mockRowSelection = [0, 3, 5]; + + const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); + jest.spyOn(gridStub, 'getSelectedRows').mockReturnValue(mockRowSelection); + const setSelectionSpy = jest.spyOn(gridStub, 'setSelectedRows'); + + gridOptionsMock.enableRowSelection = true; + const instance = extension.register(); + instance.onColumnsChanged.notify({ columnId: 'field1', showing: true, allColumns: columnsMock, columns: columnsMock.slice(0, 1), grid: gridStub }, new Slick.EventData(), gridStub); + + expect(handlerSpy).toHaveBeenCalledTimes(1); + expect(handlerSpy).toHaveBeenCalledWith( + { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, + expect.anything() + ); + expect(setSelectionSpy).toHaveBeenCalledWith(mockRowSelection); + }); + it('should call internal "onColumnsChanged" event and expect "readjustFrozenColumnIndexWhenNeeded" method to be called when the grid is detected to be a frozen grid', () => { gridOptionsMock.frozenColumn = 0; const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); @@ -157,9 +178,9 @@ describe('columnPickerExtension', () => { expect(utilitySpy).toHaveBeenCalled(); expect(translateSpy).toHaveBeenCalled(); expect(updateColsSpy).toHaveBeenCalledWith(SharedService.prototype.gridOptions.columnPicker); - expect(SharedService.prototype.gridOptions.columnPicker.columnTitle).toBe('Colonnes'); - expect(SharedService.prototype.gridOptions.columnPicker.forceFitTitle).toBe('Ajustement forcé des colonnes'); - expect(SharedService.prototype.gridOptions.columnPicker.syncResizeTitle).toBe('Redimension synchrone'); + expect(SharedService.prototype.gridOptions.columnPicker!.columnTitle).toBe('Colonnes'); + expect(SharedService.prototype.gridOptions.columnPicker!.forceFitTitle).toBe('Ajustement forcé des colonnes'); + expect(SharedService.prototype.gridOptions.columnPicker!.syncResizeTitle).toBe('Redimension synchrone'); expect(columnsMock).toEqual([ { id: 'field1', field: 'field1', width: 100, name: 'Titre', nameKey: 'TITLE' }, { id: 'field2', field: 'field2', width: 75 } diff --git a/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts b/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts index 2ae2e1b2c..99864085e 100644 --- a/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts +++ b/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts @@ -39,11 +39,13 @@ const gridStub = { getColumnIndex: jest.fn(), getColumns: jest.fn(), getOptions: jest.fn(), + getSelectedRows: jest.fn(), getUID: () => gridUid, registerPlugin: jest.fn(), setColumns: jest.fn(), setOptions: jest.fn(), setHeaderRowVisibility: jest.fn(), + setSelectedRows: jest.fn(), setTopPanelVisibility: jest.fn(), setPreHeaderPanelVisibility: jest.fn(), }; @@ -240,6 +242,25 @@ describe('gridMenuExtension', () => { expect(visibleColsSpy).toHaveBeenCalledWith(columnsMock); }); + it('should call internal "onColumnsChanged" event and expect "setSelectedRows" method to be called using Row Selection is enabled', () => { + const mockRowSelection = [0, 3, 5]; + + const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); + jest.spyOn(gridStub, 'getSelectedRows').mockReturnValue(mockRowSelection); + const setSelectionSpy = jest.spyOn(gridStub, 'setSelectedRows'); + + gridOptionsMock.enableRowSelection = true; + const instance = extension.register(); + instance.onColumnsChanged.notify({ columnId: 'field1', showing: true, allColumns: columnsMock, columns: columnsMock.slice(0, 1), grid: gridStub }, new Slick.EventData(), gridStub); + + expect(handlerSpy).toHaveBeenCalledTimes(5); + expect(handlerSpy).toHaveBeenCalledWith( + { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, + expect.anything() + ); + expect(setSelectionSpy).toHaveBeenCalledWith(mockRowSelection); + }); + it('should call internal "onColumnsChanged" event and expect "readjustFrozenColumnIndexWhenNeeded" method to be called when the grid is detected to be a frozen grid', () => { gridOptionsMock.frozenColumn = 0; const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); diff --git a/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts b/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts index 1f584c633..0256f2974 100644 --- a/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts +++ b/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts @@ -59,9 +59,22 @@ export class ColumnPickerExtension implements Extension { if (this._columnPicker && typeof this._columnPicker.onColumnsChanged === 'function') { this._columnPicker.onColumnsChanged(e, args); } + + // keep reference to the updated visible columns list if (args && Array.isArray(args.columns) && args.columns.length !== this.sharedService.visibleColumns.length) { this.sharedService.visibleColumns = args.columns; } + + // when using row selection, SlickGrid will only apply the "selected" CSS class on the visible columns only + // and if the row selection was done prior to the column being shown then that column that was previously hidden (at the time of the row selection) + // will not have the "selected" CSS class because it wasn't visible at the time. + // To bypass this problem we can simply recall the row selection with the same selection and that will trigger a re-apply of the CSS class + // on all columns including the column we just made visible + if (this.sharedService.gridOptions.enableRowSelection && args.showing) { + const rowSelection = args.grid.getSelectedRows(); + args.grid.setSelectedRows(rowSelection); + } + // if we're using frozen columns, we need to readjust pinning when the new hidden column becomes visible again on the left pinning container // we need to readjust frozenColumn index because SlickGrid freezes by index and has no knowledge of the columns themselves const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn !== undefined ? this.sharedService.gridOptions.frozenColumn : -1; diff --git a/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts b/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts index fb15909b4..8e42eacff 100644 --- a/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts +++ b/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts @@ -121,9 +121,21 @@ export class GridMenuExtension implements Extension { if (this._gridMenuOptions && typeof this._gridMenuOptions.onColumnsChanged === 'function') { this._gridMenuOptions.onColumnsChanged(e, args); } + + // keep reference to the updated visible columns list if (args && Array.isArray(args.columns) && args.columns.length > this.sharedService.visibleColumns.length) { this.sharedService.visibleColumns = args.columns; } + + // when using row selection, SlickGrid will only apply the "selected" CSS class on the visible columns only + // and if the row selection was done prior to the column being shown then that column that was previously hidden (at the time of the row selection) + // will not have the "selected" CSS class because it wasn't visible at the time. + // To bypass this problem we can simply recall the row selection with the same selection and that will trigger a re-apply of the CSS class + // on all columns including the column we just made visible + if (this.sharedService.gridOptions.enableRowSelection && args.showing) { + args.grid.setSelectedRows(args.grid.getSelectedRows()); + } + // if we're using frozen columns, we need to readjust pinning when the new hidden column becomes visible again on the left pinning container // we need to readjust frozenColumn index because SlickGrid freezes by index and has no knowledge of the columns themselves const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn !== undefined ? this.sharedService.gridOptions.frozenColumn : -1;