diff --git a/src/app/examples/grid-editor.component.ts b/src/app/examples/grid-editor.component.ts index 22b51349b..7acf03393 100644 --- a/src/app/examples/grid-editor.component.ts +++ b/src/app/examples/grid-editor.component.ts @@ -632,7 +632,7 @@ export class GridEditorComponent implements OnInit { required: true, validator: myCustomTitleValidator, // use a custom validator }, - sortable: true, minWidth: 100, filterable: true, params: { useFormatterOuputToFilter: true } + sortable: true, minWidth: 100, filterable: true, }; // you can dynamically add your column to your column definitions diff --git a/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts index 23f39ca44..93d8036c1 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts @@ -63,6 +63,10 @@ const extensionContextMenuStub = { ...extensionStub, translateContextMenu: jest.fn() }; +const extensionHeaderButtonStub = { + ...extensionStub, + translateHeaderMenu: jest.fn() +}; const extensionHeaderMenuStub = { ...extensionStub, translateHeaderMenu: jest.fn() @@ -92,7 +96,7 @@ describe('ExtensionService', () => { { provide: DraggableGroupingExtension, useValue: extensionStub }, { provide: GridMenuExtension, useValue: extensionGridMenuStub }, { provide: GroupItemMetaProviderExtension, useValue: extensionGroupItemMetaStub }, - { provide: HeaderButtonExtension, useValue: extensionStub }, + { provide: HeaderButtonExtension, useValue: extensionHeaderButtonStub }, { provide: HeaderMenuExtension, useValue: extensionHeaderMenuStub }, { provide: RowDetailViewExtension, useValue: extensionStub }, { provide: RowMoveManagerExtension, useValue: extensionStub }, @@ -378,7 +382,7 @@ describe('ExtensionService', () => { expect(gridSpy).toHaveBeenCalled(); expect(extSpy).toHaveBeenCalled(); - expect(output).toEqual({ name: ExtensionName.headerButton, addon: instanceMock, instance: instanceMock, class: extensionStub } as ExtensionModel); + expect(output).toEqual({ name: ExtensionName.headerButton, addon: instanceMock, instance: instanceMock, class: extensionHeaderButtonStub } as ExtensionModel); }); it('should register the HeaderMenu addon when "enableHeaderMenu" is set in the grid options', () => { @@ -632,18 +636,18 @@ describe('ExtensionService', () => { it(`should call "setColumns" with the collection provided as argument but NOT override "allColumns" on the Shared Service when collection provided is smaller than "allColumns" that already exists`, () => { - const columnsMock = [ - { id: 'field1', field: 'field1', nameKey: 'HELLO' } - ] as Column[]; - jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); - const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); - const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); + const columnsMock = [ + { id: 'field1', field: 'field1', nameKey: 'HELLO' } + ] as Column[]; + jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); + const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); + const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); - service.renderColumnHeaders(columnsMock); + service.renderColumnHeaders(columnsMock); - expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); - expect(spyAllCols).not.toHaveBeenCalled(); - }); + expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); + expect(spyAllCols).not.toHaveBeenCalled(); + }); it('should re-register the Column Picker when enable and method is called with new column definition collection provided as argument', () => { const instanceMock = { onColumnsChanged: jest.fn() }; @@ -698,6 +702,66 @@ describe('ExtensionService', () => { expect(spyAllCols).toHaveBeenCalledWith(columnsMock); expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); }); + + it('should re-register the Header Button when enable and method is called with new column definition collection provided as argument', () => { + const instanceMock = { onColumnsChanged: jest.fn() }; + const extensionMock = { name: ExtensionName.headerButton, addon: null, instance: null, class: null } as ExtensionModel; + const expectedExtension = { name: ExtensionName.headerButton, instance: instanceMock as unknown, class: null } as ExtensionModel; + const gridOptionsMock = { enableHeaderButton: true } as GridOption; + const columnsMock = [ + { id: 'field1', field: 'field1', nameKey: 'HELLO' }, + { id: 'field2', field: 'field2', nameKey: 'WORLD' } + ] as Column[]; + + jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); + jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); + const spyGetExt = jest.spyOn(service, 'getExtensionByName').mockReturnValue(extensionMock); + const spyGmDispose = jest.spyOn(extensionHeaderButtonStub, 'dispose'); + const spyGmRegister = jest.spyOn(extensionHeaderButtonStub, 'register').mockReturnValue(instanceMock); + const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); + const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); + + service.renderColumnHeaders(columnsMock); + + expect(expectedExtension).toEqual(expectedExtension); + expect(spyGetExt).toHaveBeenCalled(); + expect(expectedExtension).toEqual(expectedExtension); + expect(spyGetExt).toHaveBeenCalled(); + expect(spyGmDispose).toHaveBeenCalled(); + expect(spyGmRegister).toHaveBeenCalled(); + expect(spyAllCols).toHaveBeenCalledWith(columnsMock); + expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); + }); + + it('should re-register the Header Menu when enable and method is called with new column definition collection provided as argument', () => { + const instanceMock = { onColumnsChanged: jest.fn() }; + const extensionMock = { name: ExtensionName.headerMenu, addon: null, instance: null, class: null } as ExtensionModel; + const expectedExtension = { name: ExtensionName.headerMenu, instance: instanceMock as unknown, class: null } as ExtensionModel; + const gridOptionsMock = { enableHeaderMenu: true } as GridOption; + const columnsMock = [ + { id: 'field1', field: 'field1', nameKey: 'HELLO' }, + { id: 'field2', field: 'field2', nameKey: 'WORLD' } + ] as Column[]; + + jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); + jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); + const spyGetExt = jest.spyOn(service, 'getExtensionByName').mockReturnValue(extensionMock); + const spyGmDispose = jest.spyOn(extensionHeaderMenuStub, 'dispose'); + const spyGmRegister = jest.spyOn(extensionHeaderMenuStub, 'register').mockReturnValue(instanceMock); + const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); + const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); + + service.renderColumnHeaders(columnsMock); + + expect(expectedExtension).toEqual(expectedExtension); + expect(spyGetExt).toHaveBeenCalled(); + expect(expectedExtension).toEqual(expectedExtension); + expect(spyGetExt).toHaveBeenCalled(); + expect(spyGmDispose).toHaveBeenCalled(); + expect(spyGmRegister).toHaveBeenCalled(); + expect(spyAllCols).toHaveBeenCalledWith(columnsMock); + expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); + }); }); }); @@ -715,7 +779,7 @@ describe('ExtensionService', () => { extensionStub as unknown as DraggableGroupingExtension, extensionGridMenuStub as unknown as GridMenuExtension, extensionGroupItemMetaStub as unknown as GroupItemMetaProviderExtension, - extensionStub as unknown as HeaderButtonExtension, + extensionHeaderButtonStub as unknown as HeaderButtonExtension, extensionHeaderMenuStub as unknown as HeaderMenuExtension, extensionStub as unknown as RowDetailViewExtension, extensionStub as unknown as RowMoveManagerExtension, diff --git a/src/app/modules/angular-slickgrid/services/extension.service.ts b/src/app/modules/angular-slickgrid/services/extension.service.ts index a1ac4cee6..3d5a53d59 100644 --- a/src/app/modules/angular-slickgrid/services/extension.service.ts +++ b/src/app/modules/angular-slickgrid/services/extension.service.ts @@ -7,6 +7,7 @@ import { Injectable, Optional } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Column, + Extension, ExtensionList, ExtensionModel, ExtensionName, @@ -418,26 +419,24 @@ export class ExtensionService { this.sharedService.grid.setColumns(collection); } - // dispose of previous Column Picker instance, then re-register it and don't forget to overwrite previous instance ref + // recreate the Column Picker when enabled if (this.sharedService.gridOptions.enableColumnPicker) { - this.columnPickerExtension.dispose(); - const instance = this.columnPickerExtension.register(); - const extension = this.getExtensionByName(ExtensionName.columnPicker); - if (extension) { - extension.addon = instance; - extension.instance = instance; - } + this.recreateExternalAddon(this.columnPickerExtension, ExtensionName.columnPicker); } - // dispose of previous Grid Menu instance, then re-register it and don't forget to overwrite previous instance ref + // recreate the Grid Menu when enabled if (this.sharedService.gridOptions.enableGridMenu) { - this.gridMenuExtension.dispose(); - const instance = this.gridMenuExtension.register(); - const extension = this.getExtensionByName(ExtensionName.gridMenu); - if (extension) { - extension.addon = instance; - extension.instance = instance; - } + this.recreateExternalAddon(this.gridMenuExtension, ExtensionName.gridMenu); + } + + // recreate the Header Button when enabled + if (this.sharedService.gridOptions.enableHeaderButton) { + this.recreateExternalAddon(this.headerButtonExtension, ExtensionName.headerButton); + } + + // recreate the Header Menu when enabled + if (this.sharedService.gridOptions.enableHeaderMenu) { + this.recreateExternalAddon(this.headerMenuExtension, ExtensionName.headerMenu); } } @@ -456,6 +455,20 @@ export class ExtensionService { return undefined; } + /** + * Dispose of previous extension/addon instance, then re-register it and don't forget to overwrite previous instance ref + * @param extensionName + */ + private recreateExternalAddon(externalExtension: Extension, extensionName: ExtensionName) { + externalExtension.dispose(); + const instance = externalExtension.register(); + const extension = this.getExtensionByName(extensionName); + if (extension) { + extension.addon = instance; + extension.instance = instance; + } + } + /** Translate an array of items from an input key and assign translated value to the output key */ private translateItems(items: any[], inputKey: string, outputKey: string) { if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableTranslate && (!this.translate || !this.translate.instant)) { diff --git a/test/cypress/integration/example03.spec.js b/test/cypress/integration/example03.spec.js index 0827fe583..acd573060 100644 --- a/test/cypress/integration/example03.spec.js +++ b/test/cypress/integration/example03.spec.js @@ -144,6 +144,33 @@ describe('Example 3 - Grid with Editors', () => { .scrollTo('top'); }); + it('should be able to filter and search "Task 2222" in the new column and expect only 1 row showing in the grid', () => { + cy.get('input.search-filter.filter-title1') + .type('Task 2222', { force: true }) + .should('have.value', 'Task 2222'); + + cy.get('.slick-row').should('have.length', 1); + cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(2)`).should('contain', 'Task 2222'); + }); + + it('should hover over the last "Title" column and click on "Clear Filter" and expect grid to have all rows shown', () => { + cy.get('.slick-header-column:nth-child(14)') + .first() + .trigger('mouseover') + .children('.slick-header-menubutton') + .invoke('show') + .click(); + + cy.get('.slick-header-menu') + .should('be.visible') + .children('.slick-header-menuitem:nth-child(4)') + .children('.slick-header-menucontent') + .should('contain', 'Remove Filter') + .click(); + + cy.get('.slick-row').should('have.length.greaterThan', 1); + }); + it('should be able to dynamically remove last 2 added Title columns', () => { cy.get('[data-test=remove-title-column]') .click() diff --git a/test/cypress/package.json b/test/cypress/package.json index 30146739f..6b843ba52 100644 --- a/test/cypress/package.json +++ b/test/cypress/package.json @@ -10,7 +10,7 @@ "author": "Ghislain B.", "license": "MIT", "devDependencies": { - "cypress": "^6.3.0", + "cypress": "^6.4.0", "mocha": "^8.2.1", "mochawesome": "^6.2.1" }