From e6335be01875e2e1223039f2daa11cea23643843 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Sat, 4 Feb 2023 14:54:26 -0500 Subject: [PATCH] feat(dataView): add option to apply row selection to all pages --- package.json | 26 +-- src/app/examples/grid-headermenu.component.ts | 5 +- .../grid-resize-by-content.component.html | 10 +- .../grid-resize-by-content.component.ts | 23 ++- .../examples/grid-rowselection.component.ts | 12 +- src/app/examples/grid-state.component.ts | 2 +- .../angular-slickgrid.component.spec.ts | 26 +-- .../components/angular-slickgrid.component.ts | 28 ++- .../angular-slickgrid/global-grid-options.ts | 6 +- test/cypress/e2e/example01.cy.ts | 4 +- test/cypress/e2e/example06.cy.ts | 2 +- test/cypress/e2e/example10.cy.ts | 126 +++++++++++-- test/cypress/e2e/example16.cy.ts | 4 +- test/cypress/e2e/example31.cy.ts | 106 ++++++++++- yarn.lock | 170 +++++++++--------- 15 files changed, 398 insertions(+), 152 deletions(-) diff --git a/package.json b/package.json index 0cf4db598..1cc9df9eb 100644 --- a/package.json +++ b/package.json @@ -50,13 +50,13 @@ }, "dependencies": { "@ngx-translate/core": ">=14.0.0", - "@slickgrid-universal/common": "~2.3.0", - "@slickgrid-universal/custom-footer-component": "~2.3.0", - "@slickgrid-universal/empty-warning-component": "~2.3.0", - "@slickgrid-universal/event-pub-sub": "~2.3.0", - "@slickgrid-universal/pagination-component": "~2.3.0", - "@slickgrid-universal/row-detail-view-plugin": "~2.3.0", - "@slickgrid-universal/rxjs-observable": "~2.3.0", + "@slickgrid-universal/common": "~2.4.0", + "@slickgrid-universal/custom-footer-component": "~2.4.0", + "@slickgrid-universal/empty-warning-component": "~2.4.0", + "@slickgrid-universal/event-pub-sub": "~2.4.0", + "@slickgrid-universal/pagination-component": "~2.4.0", + "@slickgrid-universal/row-detail-view-plugin": "~2.4.0", + "@slickgrid-universal/rxjs-observable": "~2.4.0", "@types/jquery": "^3.5.16", "dequal": "^2.0.3", "dompurify": "^2.4.3", @@ -88,12 +88,12 @@ "@ngx-translate/core": "^14.0.0", "@ngx-translate/http-loader": "^7.0.0", "@release-it/conventional-changelog": "^5.1.1", - "@slickgrid-universal/composite-editor-component": "~2.3.0", - "@slickgrid-universal/custom-tooltip-plugin": "~2.3.0", - "@slickgrid-universal/excel-export": "~2.3.0", - "@slickgrid-universal/graphql": "~2.3.0", - "@slickgrid-universal/odata": "~2.3.0", - "@slickgrid-universal/text-export": "~2.3.0", + "@slickgrid-universal/composite-editor-component": "~2.4.0", + "@slickgrid-universal/custom-tooltip-plugin": "~2.4.0", + "@slickgrid-universal/excel-export": "~2.4.0", + "@slickgrid-universal/graphql": "~2.4.0", + "@slickgrid-universal/odata": "~2.4.0", + "@slickgrid-universal/text-export": "~2.4.0", "@types/dompurify": "^2.4.0", "@types/flatpickr": "^3.1.2", "@types/fnando__sparkline": "^0.3.4", diff --git a/src/app/examples/grid-headermenu.component.ts b/src/app/examples/grid-headermenu.component.ts index 12a95913d..a3fff7feb 100644 --- a/src/app/examples/grid-headermenu.component.ts +++ b/src/app/examples/grid-headermenu.component.ts @@ -38,7 +38,10 @@ export class GridHeaderMenuComponent implements OnInit, OnDestroy { selectedLanguage: string; constructor(private translate: TranslateService) { - this.selectedLanguage = this.translate.getDefaultLang(); + // always start with English for Cypress E2E tests to be consistent + const defaultLang = 'en'; + this.translate.use(defaultLang); + this.selectedLanguage = defaultLang; } ngOnDestroy() { diff --git a/src/app/examples/grid-resize-by-content.component.html b/src/app/examples/grid-resize-by-content.component.html index 5b36f398e..d5ba56a62 100644 --- a/src/app/examples/grid-resize-by-content.component.html +++ b/src/app/examples/grid-resize-by-content.component.html @@ -35,9 +35,14 @@

Container Width (950px)

+
\ No newline at end of file diff --git a/src/app/examples/grid-resize-by-content.component.ts b/src/app/examples/grid-resize-by-content.component.ts index abf6ff23b..c5211bc3e 100644 --- a/src/app/examples/grid-resize-by-content.component.ts +++ b/src/app/examples/grid-resize-by-content.component.ts @@ -83,7 +83,7 @@ export class GridResizeByContentComponent implements OnInit { ngOnInit(): void { this.defineGrid(); - this.dataset = this.loadData(5000); + this.dataset = this.loadData(400); } // Grid2 definition @@ -303,6 +303,11 @@ export class GridResizeByContentComponent implements OnInit { rightPadding: 10 }, enableAutoResize: true, + enablePagination: true, + pagination: { + pageSize: 10, + pageSizes: [10, 200, 500, 5000] + }, // resizing by cell content is opt-in // we first need to disable the 2 default flags to autoFit/autosize @@ -463,6 +468,10 @@ export class GridResizeByContentComponent implements OnInit { this.isUsingDefaultResize = false; } + handleOnSelectedRowIdsChanged(args: any) { + console.log('Selected Ids:', args.selectedRowIds); + } + toggleGridEditReadonly() { // first need undo all edits this.undoAllEdits(); @@ -517,6 +526,18 @@ export class GridResizeByContentComponent implements OnInit { } } + // change row selection dynamically and apply it to the DataView and the Grid UI + setSelectedRowIds() { + // change row selection even across multiple pages via DataView + this.angularGrid.dataView?.setSelectedIds([3, 4, 11]); + + // you can also provide optional options (all defaults to true) + // this.sgb.dataView?.setSelectedIds([4, 5, 8, 10], { + // isRowBeingAdded: true, + // shouldTriggerEvent: true, + // applyGridRowSelection: true + // }); + } saveAll() { // Edit Queue (array increases every time a cell is changed, regardless of item object) diff --git a/src/app/examples/grid-rowselection.component.ts b/src/app/examples/grid-rowselection.component.ts index 4d3e61636..29ff4dede 100644 --- a/src/app/examples/grid-rowselection.component.ts +++ b/src/app/examples/grid-rowselection.component.ts @@ -37,8 +37,8 @@ export class GridRowSelectionComponent implements OnInit { gridObj1!: any; gridObj2!: any; isGrid2WithPagination = true; - selectedTitles!: any[]; - selectedTitle!: any; + selectedTitles = ''; + selectedTitle = ''; selectedGrid2IDs!: number[]; constructor(private cd: ChangeDetectorRef) { } @@ -158,7 +158,8 @@ export class GridRowSelectionComponent implements OnInit { checkboxSelector: { // you can toggle these 2 properties to show the "select all" checkbox in different location hideInFilterHeaderRow: false, - hideInColumnTitleRow: true + hideInColumnTitleRow: true, + applySelectOnAllPages: true, // when clicking "Select All", should we apply it to all pages (defaults to true) }, rowSelectionOptions: { // True (Single Selection), False (Multiple Selections) @@ -243,7 +244,10 @@ export class GridRowSelectionComponent implements OnInit { if (gridStateChanges!.gridState!.rowSelection) { this.selectedGrid2IDs = (gridStateChanges!.gridState!.rowSelection.filteredDataContextIds || []) as number[]; this.selectedGrid2IDs = this.selectedGrid2IDs.sort((a, b) => a - b); // sort by ID - this.selectedTitles = this.selectedGrid2IDs.map(dataContextId => `Task ${dataContextId}`); + this.selectedTitles = this.selectedGrid2IDs.map(dataContextId => `Task ${dataContextId}`).join(','); + if (this.selectedTitles.length > 293) { + this.selectedTitles = this.selectedTitles.substring(0, 293) + '...'; + } this.cd.detectChanges(); } } diff --git a/src/app/examples/grid-state.component.ts b/src/app/examples/grid-state.component.ts index aa6f6cf82..1f7ade3c5 100644 --- a/src/app/examples/grid-state.component.ts +++ b/src/app/examples/grid-state.component.ts @@ -72,9 +72,9 @@ export class GridStateComponent implements OnInit, OnDestroy { /** Clear the Grid State from Local Storage and reset the grid to it's original state */ clearGridStateFromLocalStorage() { - localStorage.removeItem(LOCAL_STORAGE_KEY); this.angularGrid.gridService.resetGrid(this.columnDefinitions); this.angularGrid.paginationService!.changeItemPerPage(DEFAULT_PAGE_SIZE); + setTimeout(() => localStorage[LOCAL_STORAGE_KEY] = null); } /* Define grid Options and Columns */ diff --git a/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts b/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts index 47d66592b..36d650313 100644 --- a/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts +++ b/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts @@ -230,6 +230,7 @@ const mockDataView = { onSetItemsCalled: new MockSlickEvent(), reSort: jest.fn(), setItems: jest.fn(), + setSelectedIds: jest.fn(), syncGridSelection: jest.fn(), }; @@ -1667,13 +1668,16 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = }); }); - it('should call trigger a gridStage change and reset selected rows when pagination change is triggered and "enableRowSelection" is set', () => { + it('should trigger a gridStage change and reset selected rows when pagination change is triggered and "enableRowSelection" is set', () => { const mockPagination = { pageNumber: 2, pageSize: 20 } as Pagination; const pluginEaSpy = jest.spyOn(eventPubSubService, 'publish'); const setRowSpy = jest.spyOn(mockGrid, 'setSelectedRows'); jest.spyOn(gridStateServiceStub, 'getCurrentGridState').mockReturnValue({ columns: [], pagination: mockPagination } as GridState); - component.gridOptions = { enableRowSelection: true } as unknown as GridOption; + component.gridOptions = { + enableRowSelection: true, + backendServiceApi: { service: mockGraphqlService as any } + } as unknown as GridOption; component.initialization(slickEventHandler); component.paginationChanged(mockPagination); @@ -1690,7 +1694,10 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = const setRowSpy = jest.spyOn(mockGrid, 'setSelectedRows'); jest.spyOn(gridStateServiceStub, 'getCurrentGridState').mockReturnValue({ columns: [], pagination: mockPagination } as GridState); - component.gridOptions = { enableCheckboxSelector: true } as unknown as GridOption; + component.gridOptions = { + enableCheckboxSelector: true, + backendServiceApi: { service: mockGraphqlService as any } + } as unknown as GridOption; component.initialization(slickEventHandler); component.paginationChanged(mockPagination); @@ -1945,10 +1952,11 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = }); }); - it('should NOT call the "setSelectedRows" when the Grid has Local Pagination and there are row selection presets with "dataContextIds" array set', (done) => { + it('should call the "setSelectedRows" and "setSelectedIds" when the Grid has Local Pagination and there are row selection presets with "dataContextIds" array set', () => { const selectedGridRows = [22]; const mockData = [{ firstName: 'John', lastName: 'Doe' }, { firstName: 'Jane', lastName: 'Smith' }]; - const selectRowSpy = jest.spyOn(mockGrid, 'setSelectedRows'); + const gridSelectedRowSpy = jest.spyOn(mockGrid, 'setSelectedRows'); + const dvSetSelectedIdSpy = jest.spyOn(mockDataView, 'setSelectedIds'); jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true); jest.spyOn(mockDataView, 'getLength').mockReturnValue(mockData.length); @@ -1962,11 +1970,9 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = component.isDatasetInitialized = false; // it won't call the preset unless we reset this flag component.initialization(slickEventHandler); - setTimeout(() => { - expect(component.isDatasetInitialized).toBe(true); - expect(selectRowSpy).not.toHaveBeenCalled(); - done(); - }, 2); + expect(component.isDatasetInitialized).toBe(true); + expect(gridSelectedRowSpy).toHaveBeenCalledWith([2]); + expect(dvSetSelectedIdSpy).toHaveBeenCalledWith([22], { applyRowSelectionToGrid: true, isRowBeingAdded: true, shouldTriggerEvent: false }); }); }); diff --git a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts index 2a33f0e5b..8291b8dd4 100644 --- a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts +++ b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts @@ -1,8 +1,8 @@ // import 3rd party vendor libs -import 'slickgrid/dist/slick.core.min'; -import 'slickgrid/dist/slick.interactions.min'; -import 'slickgrid/dist/slick.grid.min'; -import 'slickgrid/dist/slick.dataview.min'; +import 'slickgrid/slick.core'; +import 'slickgrid/slick.interactions'; +import 'slickgrid/slick.grid'; +import 'slickgrid/slick.dataview'; // ...then everything else... import { AfterViewInit, ApplicationRef, ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, Optional, Output, } from '@angular/core'; @@ -662,11 +662,11 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy { /** * On a Pagination changed, we will trigger a Grid State changed with the new pagination info - * Also if we use Row Selection or the Checkbox Selector, we need to reset any selection + * Also if we use Row Selection or the Checkbox Selector with a Backend Service (Odata, GraphQL), we need to reset any selection */ paginationChanged(pagination: ServicePagination) { const isSyncGridSelectionEnabled = this.gridStateService?.needToPreserveRowSelection() ?? false; - if (!isSyncGridSelectionEnabled && (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector)) { + if (this.slickGrid && !isSyncGridSelectionEnabled && this.gridOptions?.backendServiceApi && (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector)) { this.slickGrid.setSelectedRows([]); } const { pageNumber, pageSize } = pagination; @@ -1179,16 +1179,14 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy { } else if (Array.isArray(gridRowIndexes) && gridRowIndexes.length > 0) { dataContextIds = this.dataView.mapRowsToIds(gridRowIndexes) || []; } - this.gridStateService.selectedRowDataContextIds = dataContextIds; - // change the selected rows except UNLESS it's a Local Grid with Pagination - // local Pagination uses the DataView and that also trigger a change/refresh - // and we don't want to trigger 2 Grid State changes just 1 - if ((this._isLocalGrid && !this.gridOptions.enablePagination) || !this._isLocalGrid) { - setTimeout(() => { - if (this.slickGrid && Array.isArray(gridRowIndexes)) { - this.slickGrid.setSelectedRows(gridRowIndexes); - } + // apply row selection when defined as grid presets + if (this.slickGrid && Array.isArray(gridRowIndexes)) { + this.slickGrid.setSelectedRows(gridRowIndexes); + this.dataView!.setSelectedIds(dataContextIds || [], { + isRowBeingAdded: true, + shouldTriggerEvent: false, // do not trigger when presetting the grid + applyRowSelectionToGrid: true }); } } diff --git a/src/app/modules/angular-slickgrid/global-grid-options.ts b/src/app/modules/angular-slickgrid/global-grid-options.ts index 01428f06f..50d52bfdd 100644 --- a/src/app/modules/angular-slickgrid/global-grid-options.ts +++ b/src/app/modules/angular-slickgrid/global-grid-options.ts @@ -70,7 +70,11 @@ export const GlobalGridOptions: Partial = { } }, dataView: { - syncGridSelection: true, // when enabled, this will preserve the row selection even after filtering/sorting/grouping + // when enabled, this will preserve the row selection even after filtering/sorting/grouping + syncGridSelection: { + preserveHidden: false, + preserveHiddenOnSelectionChange: true + }, syncGridSelectionWithBackendService: false, // but disable it when using backend services }, datasetIdPropertyName: 'id', diff --git a/test/cypress/e2e/example01.cy.ts b/test/cypress/e2e/example01.cy.ts index 345902a81..eb9980f7d 100644 --- a/test/cypress/e2e/example01.cy.ts +++ b/test/cypress/e2e/example01.cy.ts @@ -11,13 +11,13 @@ describe('Example 1 - Basic Grids', { retries: 1 }, () => { .should('have.css', 'width', '800px'); cy.get('#slickGridContainer-grid1 > .slickgrid-container') - .should('have.css', 'height', '225px'); + .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(225)); cy.get('#slickGridContainer-grid2') .should('have.css', 'width', '800px'); cy.get('#slickGridContainer-grid2 > .slickgrid-container') - .should('have.css', 'height', '225px'); + .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(225)); }); it('should have exact column titles on 1st grid', () => { diff --git a/test/cypress/e2e/example06.cy.ts b/test/cypress/e2e/example06.cy.ts index c1a927599..94eca73ef 100644 --- a/test/cypress/e2e/example06.cy.ts +++ b/test/cypress/e2e/example06.cy.ts @@ -15,7 +15,7 @@ describe('Example 6 - GraphQL Grid', { retries: 1 }, () => { .should('have.css', 'width', '900px'); cy.get('#slickGridContainer-grid6 > .slickgrid-container') - .should('have.css', 'height', '200px'); + .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(200)); }); it('should have English Text inside some of the Filters', () => { diff --git a/test/cypress/e2e/example10.cy.ts b/test/cypress/e2e/example10.cy.ts index 1fe87ec8b..122c5c495 100644 --- a/test/cypress/e2e/example10.cy.ts +++ b/test/cypress/e2e/example10.cy.ts @@ -19,14 +19,14 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.get('@grid1') .find('.slickgrid-container') - .should('have.css', 'height', '225px'); + .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(225)); cy.get('#slickGridContainer-grid2').as('grid2'); cy.get('@grid2').should('have.css', 'width', '800px'); cy.get('@grid2') .find('.slickgrid-container') - .should('have.css', 'height', '255px'); + .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(255)); }); it('should have exact Titles on 1st grid', () => { @@ -450,7 +450,10 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(6); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [1, 3], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 12, 13, 522, 1] }, type: 'rowSelection' }); + // going to 1st page + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [3], dataContextIds: [12, 13, 3, 522], filteredDataContextIds: [3, 12, 13, 522] }, type: 'rowSelection' }); + // after selecting 1st row + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 3], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [1, 3, 12, 13, 522] }, type: 'rowSelection' }); }); }); @@ -506,7 +509,7 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(2); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [2], dataContextIds: [300], filteredDataContextIds: [300] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [2], dataContextIds: [300], filteredDataContextIds: [300] }, type: 'rowSelection' }); }); }); @@ -592,8 +595,8 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => .should('have.length', 2); cy.window().then((win) => { - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 0], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); }); }); @@ -616,7 +619,7 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(2); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [1, 12, 13, 3, 522], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 12, 13, 522, 1] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 12, 13, 3, 522], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [1, 3, 12, 13, 522] }, type: 'rowSelection' }); }); }); @@ -675,8 +678,8 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(4); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 0], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); }); }); @@ -726,8 +729,8 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(4); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [1, 3], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 12, 13, 522, 1] }, type: 'rowSelection' }); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { pageNumber: 1, pageSize: 5 }, type: 'pagination' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 3], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [1, 3, 12, 13, 522] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { pageNumber: 1, pageSize: 5 }, type: 'pagination' }); }); }); @@ -752,8 +755,8 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => cy.window().then((win) => { expect(win.console.log).to.have.callCount(4); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); - expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: { gridRowIndexes: [1, 0], dataContextIds: [1, 12, 13, 3, 522], filteredDataContextIds: [3, 13] }, type: 'rowSelection' }); + expect(win.console.log).to.be.calledWith('Grid State changed:: ', { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'], targetSelector: 'input.form-control.filter-title.search-filter.filled' }], type: 'filter' }); }); cy.get('@grid2') @@ -777,5 +780,102 @@ describe('Example 10 - Multiple Grids with Row Selection', { retries: 1 }, () => .find('[data-test=total-items]') .contains('179'); }); + + it('should Select All and expect all pages to no longer have any row selected', () => { + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .click({ force: true }); + }); + + it('should go to the next 2 pages and expect all rows selected in each page', () => { + cy.get('#slickGridContainer-grid2').as('grid2'); + + cy.get('@grid2') + .find('.icon-seek-next') + .click(); + + cy.get('@grid2') + .find('.slick-cell-checkboxsel input:checked') + .should('have.length', 5); + + cy.get('@grid2') + .find('.icon-seek-next') + .click(); + + cy.get('@grid2') + .find('.slick-cell-checkboxsel input:checked') + .should('have.length', 5); + }); + + it('should uncheck 1 row and expect current and next page to have "Select All" uncheck', () => { + cy.get('#slickGridContainer-grid2').as('grid2'); + + cy.get('@grid2') + .find('.slick-row:nth(0) .slick-cell:nth(0) input[type=checkbox]') + .click({ force: true }); + + cy.get('@grid2') + .find('#filter-checkbox-selectall-container input[type=checkbox]') + .should('not.be.checked', true); + + cy.get('@grid2') + .find('.icon-seek-next') + .click(); + + cy.get('@grid2') + .find('#filter-checkbox-selectall-container input[type=checkbox]') + .should('not.be.checked', true); + }); + + it('should go back to previous page, select the row that was unchecked and expect "Select All" to be selected again', () => { + cy.get('#slickGridContainer-grid2').as('grid2'); + + cy.get('@grid2') + .find('.icon-seek-prev') + .click(); + + cy.get('@grid2') + .find('.slick-row:nth(0) .slick-cell:nth(0) input[type=checkbox]') + .click({ force: true }); + + cy.get('@grid2') + .find('#filter-checkbox-selectall-container input[type=checkbox]') + .should('be.checked', true); + + cy.get('@grid2') + .find('.icon-seek-next') + .click(); + + cy.get('@grid2') + .find('#filter-checkbox-selectall-container input[type=checkbox]') + .should('be.checked', true); + }); + + it('should Unselect All and expect all pages to no longer have any row selected', () => { + cy.get('#slickGridContainer-grid2').as('grid2'); + + cy.get('@grid2') + .find('#filter-checkbox-selectall-container input[type=checkbox]') + .click({ force: true }); + + cy.get('@grid2') + .find('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + + cy.get('@grid2') + .find('.icon-seek-prev') + .click(); + + cy.get('@grid2') + .find('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + + cy.get('@grid2') + .find('.icon-seek-prev') + .click(); + + cy.get('@grid2') + .find('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + }); }); }); diff --git a/test/cypress/e2e/example16.cy.ts b/test/cypress/e2e/example16.cy.ts index 20de923d6..f819850ba 100644 --- a/test/cypress/e2e/example16.cy.ts +++ b/test/cypress/e2e/example16.cy.ts @@ -1,4 +1,4 @@ -describe('Example 16: Grid State & Presets using Local Storage', { retries: 1 }, () => { +describe('Example 16: Grid State & Presets using Local Storage', { retries: 0 }, () => { const fullEnglishTitles = ['', 'Title', 'Description', 'Duration', '% Complete', 'Start', 'Completed']; const fullFrenchTitles = ['', 'Titre', 'Description', 'Durée', '% Achevée', 'Début', 'Terminé']; @@ -73,7 +73,7 @@ describe('Example 16: Grid State & Presets using Local Storage', { retries: 1 }, // -- // Cypress does not yet implement the .hover() method and this test won't work until then - // xit('should resize "Title" column and make it wider', () => { + // it('should resize "Title" column and make it wider', () => { // cy.get('.slick-header-columns') // .children('.slick-header-column:nth(3)') // .should('contain', 'Title'); diff --git a/test/cypress/e2e/example31.cy.ts b/test/cypress/e2e/example31.cy.ts index b7f829afd..2b2946689 100644 --- a/test/cypress/e2e/example31.cy.ts +++ b/test/cypress/e2e/example31.cy.ts @@ -1,5 +1,12 @@ describe('Example 31 - Columns Resize by Content', { retries: 1 }, () => { - const titles = ['', 'Title', 'Duration', 'Cost', '% Complete', 'Complexity', 'Start', 'Completed', 'Finish', 'Product', 'Country of Origin', 'Action']; + const GRID_ROW_HEIGHT = 33; + + beforeEach(() => { + // create a console.log spy for later use + cy.window().then((win) => { + cy.spy(win.console, 'log'); + }); + }); it('should display Example title', () => { cy.visit(`${Cypress.config('baseUrl')}/resize-by-content`); @@ -80,4 +87,101 @@ describe('Example 31 - Columns Resize by Content', { retries: 1 }, () => { cy.get('.slick-row').find('.slick-cell:nth(9)').invoke('width').should('be.gt', 120); }); + + it('should change row selection across multiple pages, first page should have 2 selected', () => { + cy.get('[data-test="set-dynamic-rows-btn"]').click(); + + // Row index 3, 4 and 11 (last one will be on 2nd page) + cy.get('input[type="checkbox"]:checked').should('have.length', 2); // 2x in current page and 1x in next page + cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0) input[type="checkbox"]`).should('be.checked'); + cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0) input[type="checkbox"]`).should('be.checked'); + }); + + it('should go to next page and expect 1 row selected in that second page', () => { + cy.get('.icon-seek-next').click(); + + cy.get('input[type="checkbox"]:checked').should('have.length', 1); // only 1x row in page 2 + cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) input[type="checkbox"]`).should('be.checked'); + }); + + it('should click on "Select All" checkbox and expect all rows selected in current page', () => { + const expectedRowIds = [11, 3, 4]; + + // go back to 1st page + cy.get('.icon-seek-prev') + .click(); + + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .click({ force: true }); + + cy.window().then((win) => { + expect(win.console.log).to.have.callCount(3); + expect(win.console.log).to.be.calledWith('Selected Ids:', expectedRowIds); + }); + }); + + it('should go to the next 2 pages and expect all rows selected in each page', () => { + cy.get('.icon-seek-next') + .click(); + + cy.get('.slick-cell-checkboxsel input:checked') + .should('have.length', 10); + + cy.get('.icon-seek-next') + .click(); + + cy.get('.slick-cell-checkboxsel input:checked') + .should('have.length', 10); + }); + + it('should uncheck 1 row and expect current and next page to have "Select All" uncheck', () => { + cy.get('.slick-row:nth(0) .slick-cell:nth(0) input[type=checkbox]') + .click({ force: true }); + + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .should('not.be.checked', true); + + cy.get('.icon-seek-next') + .click(); + + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .should('not.be.checked', true); + }); + + it('should go back to previous page, select the row that was unchecked and expect "Select All" to be selected again', () => { + cy.get('.icon-seek-prev') + .click(); + + cy.get('.slick-row:nth(0) .slick-cell:nth(0) input[type=checkbox]') + .click({ force: true }); + + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .should('be.checked', true); + + cy.get('.icon-seek-next') + .click(); + + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .should('be.checked', true); + }); + + it('should Unselect All and expect all pages to no longer have any row selected', () => { + cy.get('#filter-checkbox-selectall-container input[type=checkbox]') + .click({ force: true }); + + cy.get('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + + cy.get('.icon-seek-prev') + .click(); + + cy.get('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + + cy.get('.icon-seek-prev') + .click(); + + cy.get('.slick-cell-checkboxsel input:checked') + .should('have.length', 0); + }); }); diff --git a/yarn.lock b/yarn.lock index ada9bade5..07d40bc63 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2206,20 +2206,20 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@slickgrid-universal/binding@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/binding/-/binding-2.3.0.tgz#0ffa21ff8cab73ad684958d58bbc19f4f03f62ad" - integrity sha512-FZQRrgiEGwJRM+5cn+7AWIMYMj5LHCv7jhSW3fwkKnL8kUDpslR/CDot1jKelK2PFyRcNl693hs2uGTXEKGadA== +"@slickgrid-universal/binding@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/binding/-/binding-2.4.0.tgz#c21f62a4322ef41b251c77e00789e677709285d2" + integrity sha512-EaGFfNtNzXBBA+iqdUHX3hQcN/tz3GSXDnEPfeWOdxc5JGRlrY+x4B8/9OiLa+oroZe+Kz5PnTz8AerDbkt+kA== dependencies: dompurify "^2.4.3" -"@slickgrid-universal/common@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/common/-/common-2.3.0.tgz#f4e9c2ff0a184fd9c7b3fc64e3ccb61887cf3c5a" - integrity sha512-qEsoEIwAKCc2i7zJ/CIhuPjyej1io1Md4Bo5FoPRPaRd0sLQOgekjr2EhGFPmwWhYvm/sDnWrouSU6mrbGj1Wg== +"@slickgrid-universal/common@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/common/-/common-2.4.0.tgz#49df40b7497b3b38b48ca67ab359f48db5f1d605" + integrity sha512-W4eXfuXbP3NbMSBy1ftk+J7lDMjMPRp7fRHqPRMntuvxJDjT2GYmaixHJYh9llwLmGonsh8GSZQmLEStqi7dcg== dependencies: - "@slickgrid-universal/event-pub-sub" "~2.3.0" - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/event-pub-sub" "~2.4.0" + "@slickgrid-universal/utils" "~2.4.0" autocompleter "^7.1.0" dequal "^2.0.3" dompurify "^2.4.3" @@ -2227,110 +2227,110 @@ jquery "^3.6.3" moment-mini "^2.29.4" multiple-select-modified "^1.3.17" - slickgrid "^3.0.2" + slickgrid "^3.0.3" sortablejs "^1.15.0" un-flatten-tree "^2.0.12" -"@slickgrid-universal/composite-editor-component@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/composite-editor-component/-/composite-editor-component-2.3.0.tgz#79e82b882fae3172d7c56abb9ac87c642d28cba9" - integrity sha512-D2D+wXKc8GXbnNzKHfxQ8XFKaVhStVTZRP48ASmB6ubSIIgtzkO/1ZLzGGcqQex4fR3HHvt5LsBp3rxg1epwOQ== +"@slickgrid-universal/composite-editor-component@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/composite-editor-component/-/composite-editor-component-2.4.0.tgz#04575b73fd77f779de0fe3c803dd8cc9a3f98bf1" + integrity sha512-reCX0GrdC4uRRUvbwfJXpke4PK1Aq0D55SqFUHUbglOxLiK2EUWHB3bL+1kdRpf1MBRjGk9AVfDJ7BhE3pSACw== dependencies: - "@slickgrid-universal/common" "~2.3.0" - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" + "@slickgrid-universal/utils" "~2.4.0" -"@slickgrid-universal/custom-footer-component@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/custom-footer-component/-/custom-footer-component-2.3.0.tgz#84cb2c8da746495214696a6da498b01c44aa5663" - integrity sha512-JuRnKO+UkW7fkHODp1Qjst2bHchsXhvEvp+ClDy/4Zhh0+TlHfpgk1lEim0YrtDLLyjm2LAo7Cf5RmgXzdhycA== +"@slickgrid-universal/custom-footer-component@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/custom-footer-component/-/custom-footer-component-2.4.0.tgz#411bda2b284fb015096601718ad6a9a5ce17a59f" + integrity sha512-eXWa40NT7Od+vTo9mSGGeRf+am0ClettrdLyOvfxqg1BntU1mtwWA+KYucyhtpVQJQn2LBHcp9yJcun+e2vQLA== dependencies: - "@slickgrid-universal/binding" "~2.3.0" - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/binding" "~2.4.0" + "@slickgrid-universal/common" "~2.4.0" moment-mini "^2.29.4" -"@slickgrid-universal/custom-tooltip-plugin@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/custom-tooltip-plugin/-/custom-tooltip-plugin-2.3.0.tgz#b78839c96f779f05a30f1cbd89fcfd9dd6b37d5d" - integrity sha512-i7cyDTi1h2pTREpeIM+3UugDlsxJRzwcYgGLL5kq+C7wIy30/ydOXp0TT8qkjtU45EQNulJA1Smwmyl8lI9iOg== +"@slickgrid-universal/custom-tooltip-plugin@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/custom-tooltip-plugin/-/custom-tooltip-plugin-2.4.0.tgz#976ba27a5fd7ab034d1f237c419c2212ad7ca3f2" + integrity sha512-Wy/k08G3uZ6X9LZSkIfhHocNbiQAe2zRn/M2VBTBNzcG5DWc4k2UABFf8ynjt1c/AoWUvt4QzSstWGQxDULGRw== dependencies: - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" dompurify "^2.4.3" -"@slickgrid-universal/empty-warning-component@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/empty-warning-component/-/empty-warning-component-2.3.0.tgz#4a6fd58e5efd14b471fb44ff2f25613504363603" - integrity sha512-c8YQu0qpf71IKvUWGdMt6Snb1tgce1QwRtxr1Wh6wge0iFEhkMrnerbXAqYdmKVGh2jQvmg9qyTR65qvkc9fcg== +"@slickgrid-universal/empty-warning-component@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/empty-warning-component/-/empty-warning-component-2.4.0.tgz#8dafac1cdfba958dc53536b6ae92ea308c25f0fd" + integrity sha512-ArXEnGVKaD0fnI4yAWYphj6jCJdvFxUfS6nET6aGaP2Z9INwaPCAXT/xBfsVV20HBz7yBAIKOmDHQqC6MPoiTg== dependencies: - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" -"@slickgrid-universal/event-pub-sub@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/event-pub-sub/-/event-pub-sub-2.3.0.tgz#724c435701932e444c5cf4b2a42598ac4fa137a3" - integrity sha512-GHY986Fn2GHVNC7uv+GX/dIeP+L2SzrbhYgO7cy7og9CbQvQ5WnvZkQpwLYsPjV4ZaR0LuseCAWq+lR0Qka9NQ== +"@slickgrid-universal/event-pub-sub@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/event-pub-sub/-/event-pub-sub-2.4.0.tgz#12a9d0a49ef28be4d08f2f1184cb6d07b75f4c24" + integrity sha512-YUnWByjPDvXznr73TfomimZfwwoBt16e3hcsrlWJA+7wl74y191i5J0DYgB49pvPn6jyTerQ/W7fCzTwojjCtA== dependencies: - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/utils" "~2.4.0" -"@slickgrid-universal/excel-export@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/excel-export/-/excel-export-2.3.0.tgz#eb7bd8e21ef7d2774d974e1b2d0d3109d5c7688a" - integrity sha512-LYTM0kL/NX8U4JtB3ys40IjuLX2cipCQgJ2tG4P7ZeY5FftSjY5Sq4zYhsO7j40qhgwJ40ABA1rbRtLpHZv8+g== +"@slickgrid-universal/excel-export@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/excel-export/-/excel-export-2.4.0.tgz#ecb4a015ce8a8f1e14c46fb0912ebe7728733d30" + integrity sha512-V0W+Ze3SVEgMiVgHi39zXYTWAfQ8YVqojG1icoO7dwbchNrNuV3uTQct5P32BKUdY7BYLW6GVkEjh/7AO33Jxg== dependencies: - "@slickgrid-universal/common" "~2.3.0" - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" + "@slickgrid-universal/utils" "~2.4.0" excel-builder-webpacker "^2.1.8" moment-mini "^2.29.4" -"@slickgrid-universal/graphql@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/graphql/-/graphql-2.3.0.tgz#3a61d2fecddac75bbb3e0e00206a65147b0932af" - integrity sha512-m7Dt7XQcMGoknzI1RVtvBCSD0cFJ6sXGzaWFT06W5jkzWnjtWcKK1X+CKHo3HhhUGUxy6HcTtZZfxlQqs/OEfg== +"@slickgrid-universal/graphql@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/graphql/-/graphql-2.4.0.tgz#ade14cfeda407cad58bc257b180b44e472094a30" + integrity sha512-ZaT4D93p24I2GI9IdOEDqBKJIYTQ4W6waiXMAr+W3CE3zjnWCS1piOU+jKta2PeX8rIpgKR+z044oZ+wMfTkqA== dependencies: - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" -"@slickgrid-universal/odata@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/odata/-/odata-2.3.0.tgz#8836d25ff346ef694706b64d8ddad1e3684ed45c" - integrity sha512-QpbQUJsLhuvzkj1UKmBR4gnaOSmRALLtamXIov2zRcNypG43sAptVywMnTVkdXS/Q7hoxkJiSTg8OeesKJ4w5A== +"@slickgrid-universal/odata@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/odata/-/odata-2.4.0.tgz#98a770d4c92f016530733a91f6f39be2fb2d1f8a" + integrity sha512-WlorgIJJP8n7CtkcCwh6xzbx59RtbTM2yz8WScxQilLgIlfG4KudgvdLv9tMOXZMiqcXsauDuYF+5EQ/doxsvw== dependencies: - "@slickgrid-universal/common" "~2.3.0" - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" + "@slickgrid-universal/utils" "~2.4.0" -"@slickgrid-universal/pagination-component@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/pagination-component/-/pagination-component-2.3.0.tgz#2f4d8435c7169bf285f2a711848ac7b7b40d09df" - integrity sha512-s88t/Br9hP6a0mxoUsV0CB2dKXpRgMC1n2p9+pei54CzY7NqJQgqilyBw/At6Ua1PcOm7tcMuluXwzf+XUuw4g== +"@slickgrid-universal/pagination-component@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/pagination-component/-/pagination-component-2.4.0.tgz#88ec08fb39dc304fb25330cb80c71903b93172ca" + integrity sha512-jEj5OLLJhrQPnoGvQMaBcqvcYqMIgytnm1bw9Q5zBPPHUaWNy5hVnKngdbObD81Z3pLfYuD5NSMS5JjKefsUvg== dependencies: - "@slickgrid-universal/binding" "~2.3.0" - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/binding" "~2.4.0" + "@slickgrid-universal/common" "~2.4.0" -"@slickgrid-universal/row-detail-view-plugin@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/row-detail-view-plugin/-/row-detail-view-plugin-2.3.0.tgz#cab43723421d26c980253ac53960b62eaa8182ce" - integrity sha512-dZvBkRs5Euwu4A6vgN9+Hl3ID2oGkPH7siWyUFYX9+XlBJN3FNojNsp8IVXPrEzpWlnZ3JLz0mdtVTSHF+/WLA== +"@slickgrid-universal/row-detail-view-plugin@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/row-detail-view-plugin/-/row-detail-view-plugin-2.4.0.tgz#70cf9c7fed82ded9944a6d25e156bb148f41d0c8" + integrity sha512-b1T6Sw+ob+We61Qh5UxguRXqQHPUhGw+rOSXSyp8/spqbqE+Kbio7YqiBItGKgufKG1ASIIkdE4jPL2nBX4hvg== dependencies: - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" -"@slickgrid-universal/rxjs-observable@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/rxjs-observable/-/rxjs-observable-2.3.0.tgz#60088c8ae38b9aa76d4249437256227087b31595" - integrity sha512-/BdZIHBB+Zwhi7iiw5Z4/7XlIcK8nrbcFL4rxddggLR8QlhV+/0/rfu3o03ELlU3ZchY+t5841x/yIK4SzzdAA== +"@slickgrid-universal/rxjs-observable@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/rxjs-observable/-/rxjs-observable-2.4.0.tgz#7ae75c48ba2a092d4ee5f1ef2a372cfc29b9d3f5" + integrity sha512-kRlU5I+rwlqjvld9z4B9H1wrofEOVG7AwaearRiglFwVv9nd+n7O/wFiUrbmnqxXSpDu1Hg3ehae1xGcGGnsKQ== dependencies: - "@slickgrid-universal/common" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" rxjs ">=7.5.0" -"@slickgrid-universal/text-export@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/text-export/-/text-export-2.3.0.tgz#b470868952bd11357a29134fb4345e6dbdd43b9f" - integrity sha512-ejd+8Ja78Sltmn9NO3eE+YDWpadhyjo1FnxZhnG8fvSyVaeMogE9CgZJ6J5c3a0LGKsEa3QDZwMIZicpDWSD8g== +"@slickgrid-universal/text-export@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/text-export/-/text-export-2.4.0.tgz#5da6a6ed56eb33a8b66f861dfc3606c2ed005c3f" + integrity sha512-YsSSFbsyW+aOvi0R9j3LH+8L14yjCEEf01el/HpS8ksFtubkOuYcWvJchfDHtksx6MVNesg+vGWCe+AhnGqyEA== dependencies: - "@slickgrid-universal/common" "~2.3.0" - "@slickgrid-universal/utils" "~2.3.0" + "@slickgrid-universal/common" "~2.4.0" + "@slickgrid-universal/utils" "~2.4.0" text-encoding-utf-8 "^1.0.2" -"@slickgrid-universal/utils@~2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@slickgrid-universal/utils/-/utils-2.3.0.tgz#c29de44d8fd28c9bc226d0693f17810cac7e9eaa" - integrity sha512-3+U2OgS2S016T4syGsrof5hXwbnN5Xky/fcAN2Fg1fxjvO1zbCfljyQPfrgzTyLicsBr0WUd+VraV1hIr7kuVg== +"@slickgrid-universal/utils@~2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@slickgrid-universal/utils/-/utils-2.4.0.tgz#d6b17a8149e34a9166533f26bdf96917a247dfb3" + integrity sha512-S9SCAxiFTUJN32kG+PZSyW61J7QaBdXns1r4plWOuvssnVBpX6gz3zXcccezP5Ny8cxp5fBdpa7Bqq5KfYc2Yw== "@szmarczak/http-timer@^5.0.1": version "5.0.1" @@ -10407,10 +10407,10 @@ slash@^5.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-5.0.0.tgz#8c18a871096b71ee0e002976a4fe3374991c3074" integrity sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ== -slickgrid@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/slickgrid/-/slickgrid-3.0.2.tgz#2aa83d0394b8e76f01d3140721ec03a85c8b7a6c" - integrity sha512-aLgguzFbw0HSKcSVcSEw+IbZ5qO3NKTvLJtOgF621E2oW/B0Ru+qzWvBjXtlN7bENbp1Lt/lsF5Les4rJHO89w== +slickgrid@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/slickgrid/-/slickgrid-3.0.3.tgz#9b5637eb682dbd2380a6f444100b9656f59e4fb0" + integrity sha512-9NlWDTHftNs3+Ta62cF6rV9Vo4PBHCYuBVxb5yHxZ62CiuqtMvKusktEOt1O1RLC1J+lg5v4Qs7LccJ6T3CAJQ== dependencies: jquery ">=3.0.0" sortablejs "^1.15.0"