diff --git a/demos/aurelia/src/examples/slickgrid/example03.ts b/demos/aurelia/src/examples/slickgrid/example03.ts index 9e16160c2..01d5ff456 100644 --- a/demos/aurelia/src/examples/slickgrid/example03.ts +++ b/demos/aurelia/src/examples/slickgrid/example03.ts @@ -598,15 +598,6 @@ export class Example03 { // you can dynamically add your column to your column definitions // and then use the spread operator [...cols] OR slice to force Aurelia to review the changes this.columns.push(newCol); - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = this.aureliaGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Aurelia to do dirty checking - */ } dynamicallyRemoveLastColumn() { diff --git a/demos/aurelia/src/examples/slickgrid/example12.ts b/demos/aurelia/src/examples/slickgrid/example12.ts index 3564a55c8..d65117455 100644 --- a/demos/aurelia/src/examples/slickgrid/example12.ts +++ b/demos/aurelia/src/examples/slickgrid/example12.ts @@ -270,16 +270,9 @@ export class Example12 { params: { useFormatterOuputToFilter: true }, }; this.columns.push(newCol); - this.columns = this.columns.slice(); // or use spread operator [...cols] - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = this.aureliaGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Aurelia to do dirty checking - */ + // use slice spread operator [...cols] to trigger dirty checking + this.columns = this.columns.slice(); } exportToExcel() { diff --git a/demos/aurelia/src/examples/slickgrid/example16.ts b/demos/aurelia/src/examples/slickgrid/example16.ts index ceec9eab3..9bc579eae 100644 --- a/demos/aurelia/src/examples/slickgrid/example16.ts +++ b/demos/aurelia/src/examples/slickgrid/example16.ts @@ -204,12 +204,9 @@ export class Example16 { }, ]; - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below + // use slice or spread reassign to column definitions to trigger dirty checking const allColumns = this.aureliaGrid.gridService.getAllColumnDefinitions(); - allColumns.unshift(newCols[0], newCols[1]); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Aurelia to do dirty checking + this.columns = [...newCols, ...allColumns]; } } diff --git a/demos/react-fluent/src/examples/slickgrid/Example02.tsx b/demos/react-fluent/src/examples/slickgrid/Example02.tsx index 0ae2113f4..79e4e100a 100644 --- a/demos/react-fluent/src/examples/slickgrid/Example02.tsx +++ b/demos/react-fluent/src/examples/slickgrid/Example02.tsx @@ -208,12 +208,8 @@ const Example02: React.FC = () => { }, ]; - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - const allColumns = reactGridRef.current?.gridService.getAllColumnDefinitions() || []; - allColumns.unshift(newCols[0], newCols[1]); - setColumns([...allColumns]); // (or use slice) reassign to column definitions for React to do dirty checking + // use slice or spread reassign to column definitions to trigger dirty checking + setColumns([...newCols]); } } diff --git a/demos/react/src/examples/slickgrid/Example03.tsx b/demos/react/src/examples/slickgrid/Example03.tsx index a0002d2f9..ed5a7ac88 100644 --- a/demos/react/src/examples/slickgrid/Example03.tsx +++ b/demos/react/src/examples/slickgrid/Example03.tsx @@ -592,17 +592,8 @@ const Example3: React.FC = () => { }; // you can dynamically add your column to your column definitions - // and then use the spread operator [...cols] OR slice to force React to review the changes + // and then use the spread operator [...cols] OR slice to force dirty checking setColumns([...columns!, newCol]); - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use 'getAllColumnDefinitions()' from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = reactGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - columns = [...allColumns]; // (or use slice) reassign to column definitions for React to do dirty checking - */ } function dynamicallyRemoveLastColumn() { diff --git a/demos/react/src/examples/slickgrid/Example12.tsx b/demos/react/src/examples/slickgrid/Example12.tsx index fb3e1d0b3..d27182b69 100644 --- a/demos/react/src/examples/slickgrid/Example12.tsx +++ b/demos/react/src/examples/slickgrid/Example12.tsx @@ -218,7 +218,7 @@ const Example12: React.FC = () => { function dynamicallyAddTitleHeader() { // you can dynamically add your column to your column definitions - // and then use the spread operator [...cols] OR slice to force React to review the changes + // and then use the spread operator [...cols] OR slice to force dirty checking const newCol = { id: `title${duplicateTitleHeaderCount++}`, field: 'id', @@ -231,16 +231,8 @@ const Example12: React.FC = () => { }; columns.push(newCol); - setColumns(columns.slice()); // or use spread operator [...cols] - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = reactGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - columns = [...allColumns]; // (or use slice) reassign to column definitions for React to do dirty checking - */ + // use slice spread operator [...cols] to trigger dirty checking + setColumns(columns.slice()); } function exportToExcel() { diff --git a/demos/react/src/examples/slickgrid/Example16.tsx b/demos/react/src/examples/slickgrid/Example16.tsx index c7bfde9db..32ab14cfd 100644 --- a/demos/react/src/examples/slickgrid/Example16.tsx +++ b/demos/react/src/examples/slickgrid/Example16.tsx @@ -203,12 +203,9 @@ const Example16: React.FC = () => { }, ]; - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below + // use slice or spread reassign to column definitions to trigger dirty checking const allColumns = reactGridRef.current?.gridService.getAllColumnDefinitions() || []; - allColumns.unshift(newCols[0], newCols[1]); - setColumns([...allColumns]); // (or use slice) reassign to column definitions for React to do dirty checking + setColumns([...newCols, ...allColumns]); } } diff --git a/demos/vanilla/src/examples/example07.ts b/demos/vanilla/src/examples/example07.ts index b5466caab..96204b56d 100644 --- a/demos/vanilla/src/examples/example07.ts +++ b/demos/vanilla/src/examples/example07.ts @@ -612,27 +612,10 @@ export default class Example07 { // you can dynamically add your column to your column definitions // and then use the spread operator [...cols] OR slice to force the framework to review the changes this.sgb.columnDefinitions.push(newCol); - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allOriginalColumns = this.sgb.gridService.getAllColumnDefinitions(); - allOriginalColumns.push(newCol); - this.sgb.columnDefinitions = [...allOriginalColumns]; // (or use slice) reassign to column definitions for framework to do dirty checking - */ } dynamicallyRemoveLastColumn() { this.sgb.columnDefinitions.pop(); - - /* - const allColumns = this.slickerGridInstance.gridService.getAllColumnDefinitions(); - // remove your column from the full set of columns - // and use slice or spread [...] to trigger a dirty change - allOriginalColumns.pop(); - this.sgb.columnDefinitions = allOriginalColumns.slice(); - */ } hideFinishColumnDynamically() { diff --git a/demos/vue/src/components/Example03.vue b/demos/vue/src/components/Example03.vue index ca7aae59e..351ad58c8 100644 --- a/demos/vue/src/components/Example03.vue +++ b/demos/vue/src/components/Example03.vue @@ -586,14 +586,6 @@ function dynamicallyAddTitleHeader() { // you can dynamically add your column to your column definitions columns.value.push(newCol); - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = vueGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - */ } function dynamicallyRemoveLastColumn() { diff --git a/demos/vue/src/components/Example12.vue b/demos/vue/src/components/Example12.vue index 4911fcb21..07cf0beb6 100644 --- a/demos/vue/src/components/Example12.vue +++ b/demos/vue/src/components/Example12.vue @@ -259,15 +259,6 @@ function dynamicallyAddTitleHeader() { }; columns.value.push(newCol); columns.value = columns.value.slice(); // or use spread operator [...cols] - - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = vueGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - columns.value = [...allColumns]; // (or use slice) reassign to column definitions for Vue to do dirty checking - */ } function exportToExcel() { diff --git a/demos/vue/src/components/Example16.vue b/demos/vue/src/components/Example16.vue index 9bd59c87d..2f98a34b4 100644 --- a/demos/vue/src/components/Example16.vue +++ b/demos/vue/src/components/Example16.vue @@ -195,12 +195,9 @@ function addEditDeleteColumns() { }, ]; - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below + // use slice or spread reassign to column definitions to trigger dirty checking const allColumns = vueGrid.gridService.getAllColumnDefinitions(); - allColumns.unshift(newCols[0], newCols[1]); - columns.value = [...allColumns]; // (or use slice) reassign to column definitions for Vue to do dirty checking + columns.value = [...newCols, ...allColumns]; } } diff --git a/docs/grid-functionalities/row-selection.md b/docs/grid-functionalities/row-selection.md index 52fd49711..ddd4e635a 100644 --- a/docs/grid-functionalities/row-selection.md +++ b/docs/grid-functionalities/row-selection.md @@ -379,4 +379,7 @@ this.columns = allColumns.slice(); // or use spread operator [...cols] // you could also use SlickGrid setColumns() method // this.sgb.slickGrid.setColumns(cols); -``` \ No newline at end of file +``` + +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. \ No newline at end of file diff --git a/frameworks/angular-slickgrid/docs/grid-functionalities/row-detail.md b/frameworks/angular-slickgrid/docs/grid-functionalities/row-detail.md index c6c1f60a9..04d8cbfc7 100644 --- a/frameworks/angular-slickgrid/docs/grid-functionalities/row-detail.md +++ b/frameworks/angular-slickgrid/docs/grid-functionalities/row-detail.md @@ -391,6 +391,9 @@ addNewColumn() { } ``` +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. + ## Row Detail with Inner Grid You can also add an inner grid inside a Row Detail, however there are a few things to know off and remember. Any time a Row Detail is falling outside the main grid viewport, it will be unmounted and until it comes back into the viewport which is then remounted. The process of unmounting and remounting means that Row Detail previous states aren't preserved, however you could use Grid State & Presets to overcome this problem. diff --git a/frameworks/angular-slickgrid/docs/grid-functionalities/row-selection.md b/frameworks/angular-slickgrid/docs/grid-functionalities/row-selection.md index a53a8c369..86b3bb54c 100644 --- a/frameworks/angular-slickgrid/docs/grid-functionalities/row-selection.md +++ b/frameworks/angular-slickgrid/docs/grid-functionalities/row-selection.md @@ -347,3 +347,6 @@ addNewColumn() { // this.angularGrid.slickGrid.setColumns(cols); } ``` + +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. \ No newline at end of file diff --git a/frameworks/angular-slickgrid/src/demos/examples/example03.component.ts b/frameworks/angular-slickgrid/src/demos/examples/example03.component.ts index 713bdccc3..d4012eeb8 100644 --- a/frameworks/angular-slickgrid/src/demos/examples/example03.component.ts +++ b/frameworks/angular-slickgrid/src/demos/examples/example03.component.ts @@ -653,16 +653,9 @@ export class Example3Component implements OnInit { // you can dynamically add your column to your column definitions // and then use the spread operator [...cols] OR slice to force Angular to review the changes this.columns.push(newCol); - this.columns = this.columns.slice(); // or use spread operator [...cols] - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking - */ + // use slice spread operator [...cols] to trigger dirty checking + this.columns = this.columns.slice(); } dynamicallyRemoveLastColumn() { diff --git a/frameworks/angular-slickgrid/src/demos/examples/example12.component.ts b/frameworks/angular-slickgrid/src/demos/examples/example12.component.ts index b1a9fb9f1..64db2dbd1 100644 --- a/frameworks/angular-slickgrid/src/demos/examples/example12.component.ts +++ b/frameworks/angular-slickgrid/src/demos/examples/example12.component.ts @@ -275,16 +275,9 @@ export class Example12Component implements OnInit, OnDestroy { params: { useFormatterOuputToFilter: true }, }; this.columns.push(newCol); - this.columns = this.columns.slice(); // or use spread operator [...cols] - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below - /* - const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); - allColumns.push(newCol); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking - */ + // use slice spread operator [...cols] to trigger dirty checking + this.columns = this.columns.slice(); } exportToExcel() { diff --git a/frameworks/angular-slickgrid/src/demos/examples/example16.component.ts b/frameworks/angular-slickgrid/src/demos/examples/example16.component.ts index ef9a9092b..eb1da3528 100644 --- a/frameworks/angular-slickgrid/src/demos/examples/example16.component.ts +++ b/frameworks/angular-slickgrid/src/demos/examples/example16.component.ts @@ -201,12 +201,9 @@ export class Example16Component implements OnInit { }, ]; - // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you MUST use the code below + // use slice or spread reassign to column definitions to trigger dirty checking const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); - allColumns.unshift(newCols[0], newCols[1]); - this.columns = [...allColumns]; // (or use slice) reassign to column definitions for Aurelia to do dirty checking + this.columns = [...newCols, ...allColumns]; } } diff --git a/frameworks/angular-slickgrid/src/library/components/__tests__/angular-slickgrid.component.spec.ts b/frameworks/angular-slickgrid/src/library/components/__tests__/angular-slickgrid.component.spec.ts index 302776f4d..15c4b312b 100644 --- a/frameworks/angular-slickgrid/src/library/components/__tests__/angular-slickgrid.component.spec.ts +++ b/frameworks/angular-slickgrid/src/library/components/__tests__/angular-slickgrid.component.spec.ts @@ -19,7 +19,6 @@ import { type CurrentPagination, type CurrentPinning, type CurrentSorter, - type Editor, type ExtensionList, type ExtensionService, type ExtensionUtility, @@ -188,6 +187,9 @@ const gridStateServiceStub = { mockGrid.setColumns(gridColumns); } }), + addRxJsResource: vi.fn(), + loadSlickGridEditors: vi.fn(), + syncPluginColumns: vi.fn(), getAssociatedGridColumns: vi.fn(), getCurrentGridState: vi.fn(), needToPreserveRowSelection: vi.fn(), @@ -670,10 +672,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = component.ngAfterViewInit(); expect(component).toBeTruthy(); - expect(autoAddEditorFormatterToColumnsWithEditor).toHaveBeenCalledWith( - [{ id: 'name', field: 'name', editor: undefined }], - customEditableInputFormatter - ); + expect(autoAddEditorFormatterToColumnsWithEditor).toHaveBeenCalledWith(undefined, customEditableInputFormatter); }); }); @@ -683,6 +682,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = const autosizeSpy = vi.spyOn(mockGrid, 'autosizeColumns'); const updateSpy = vi.spyOn(component, 'updateColumnDefinitionsList'); const mockColDefs = [{ id: 'name', field: 'name', editor: undefined }]; + vi.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValueOnce(mockColDefs); component.options = { enableTranslate: true, darkMode: true }; component.ngAfterViewInit(); @@ -701,6 +701,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = const updateSpy = vi.spyOn(component, 'updateColumnDefinitionsList'); const renderSpy = vi.spyOn(extensionServiceStub, 'renderColumnHeaders'); const mockColDefs = [{ id: 'name', field: 'name', editor: undefined }]; + vi.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValueOnce(mockColDefs); component.ngAfterViewInit(); component.columns = mockColDefs; @@ -710,11 +711,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = expect(translateSpy).not.toHaveBeenCalled(); expect(autosizeSpy).toHaveBeenCalled(); expect(updateSpy).toHaveBeenCalledWith(mockColDefs); - expect(renderSpy).toHaveBeenCalledWith(mockColDefs, true); - expect(autoAddEditorFormatterToColumnsWithEditor).toHaveBeenCalledWith( - [{ id: 'name', field: 'name', editor: undefined }], - customEditableInputFormatter - ); + expect(autoAddEditorFormatterToColumnsWithEditor).toHaveBeenCalledWith(undefined, customEditableInputFormatter); }); }); @@ -783,6 +780,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = { firstName: 'Jane', lastName: 'Smith' }, ]; const mockColDefs = [{ id: 'gender', field: 'gender', editor: { model: Editors.text, collection: ['male', 'female'] } }] as Column[]; + vi.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValueOnce(mockColDefs); vi.spyOn(mockDataView, 'getLength').mockReturnValueOnce(0).mockReturnValueOnce(0).mockReturnValueOnce(mockData.length); component.columns = mockColDefs; @@ -880,69 +878,6 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = }); }); - describe('with editors', () => { - beforeEach(() => { - component.options = gridOptions; - }); - - it('should display a console warning when any of the column definition ids include a dot notation', () => { - const consoleSpy = vi.spyOn(console, 'warn').mockReturnValue(); - const mockColDefs = [{ id: 'user.gender', field: 'user.gender', editor: { model: Editors.text, collection: ['male', 'female'] } }] as Column[]; - - component.columns = mockColDefs; - component.initialization(slickEventHandler); - - expect(consoleSpy).toHaveBeenCalledWith( - '[Angular-Slickgrid] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".' - ); - }); - - it('should be able to load async editors with an Observable', () => - new Promise((done: any) => { - const mockCollection = ['male', 'female']; - const mockColDefs = [{ id: 'gender', field: 'gender', editor: { model: Editors.text, collectionAsync: of(mockCollection) } }] as Column[]; - - component.ngAfterViewInit(); - component.columns = mockColDefs; - - setTimeout(() => { - expect(component.columns[0].editor).toBeTruthy(); - expect(component.columns[0].editor!.collection).toEqual(mockCollection); - expect(component.columns[0].editor!.model).toEqual(Editors.text); - done(); - }); - })); - - it('should be able to load collectionAsync and expect Editor to be destroyed and re-render when receiving new collection from await', () => - new Promise((done: any) => { - const mockCollection = ['male', 'female']; - const promise = new Promise((resolve) => resolve(mockCollection)); - const mockEditor = { - disable: vi.fn(), - destroy: vi.fn(), - renderDomElement: vi.fn(), - } as unknown as Editor; - const mockColDefs = [{ id: 'gender', field: 'gender', editor: { model: Editors.text, collectionAsync: promise } }] as Column[]; - vi.spyOn(mockGrid, 'getCellEditor').mockReturnValue(mockEditor); - const disableSpy = vi.spyOn(mockEditor, 'disable'); - const destroySpy = vi.spyOn(mockEditor, 'destroy'); - const renderSpy = vi.spyOn(mockEditor, 'renderDomElement'); - - component.ngAfterViewInit(); - component.columns = mockColDefs; - - setTimeout(() => { - expect(component.columns[0].editor).toBeTruthy(); - expect(component.columns[0].editor!.collection).toEqual(mockCollection); - expect(component.columns[0].editor!.model).toEqual(Editors.text); - expect(disableSpy).toHaveBeenCalledWith(false); - expect(destroySpy).toHaveBeenCalled(); - expect(renderSpy).toHaveBeenCalledWith(mockCollection); - done(); - }); - })); - }); - describe('use grouping', () => { it('should load groupItemMetaProvider to the DataView when using "draggableGrouping" feature', () => { vi.spyOn(extensionServiceStub, 'extensionList', 'get').mockReturnValue({ @@ -1149,6 +1084,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = const rxjsMock = new RxJsResourceStub(); const backendUtilitySpy = vi.spyOn(backendUtilityServiceStub, 'addRxJsResource'); const filterServiceSpy = vi.spyOn(filterServiceStub, 'addRxJsResource'); + const stateServiceSpy = vi.spyOn(gridStateServiceStub, 'addRxJsResource'); const sortServiceSpy = vi.spyOn(sortServiceStub, 'addRxJsResource'); const paginationServiceSpy = vi.spyOn(paginationServiceStub, 'addRxJsResource'); @@ -1158,6 +1094,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = expect(backendUtilitySpy).toHaveBeenCalled(); expect(filterServiceSpy).toHaveBeenCalled(); + expect(stateServiceSpy).toHaveBeenCalled(); expect(sortServiceSpy).toHaveBeenCalled(); expect(paginationServiceSpy).toHaveBeenCalled(); expect(component.registeredResources.length).toBe(4); // RxJsResourceStub, GridService, GridStateService, SlickEmptyCompositeEditorComponent @@ -2262,10 +2199,8 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = }; component.columns = mockColDefs; component.initialization(slickEventHandler); - // component.columnsChanged(); setTimeout(() => { - expect(component.columns).toEqual(mockColDefs); expect(component.options.showCustomFooter).toBe(true); expect(component.options.customFooterOptions).toEqual({ dateFormat: 'YYYY-MM-DD, hh:mm a', @@ -2293,6 +2228,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = it('should NOT have a Custom Footer when "showCustomFooter" is enabled WITH Pagination in use', () => new Promise((done: any) => { const mockColDefs = [{ id: 'name', field: 'name', editor: undefined }]; + vi.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValueOnce(mockColDefs); component.options = { enablePagination: true, showCustomFooter: true }; component.columns = mockColDefs; @@ -2300,7 +2236,6 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = // component.columnsChanged(); setTimeout(() => { - expect(component.columns).toEqual(mockColDefs); expect(component.slickFooter).toBeFalsy(); done(); }); @@ -2606,7 +2541,6 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = component.datasetHierarchical = mockHierarchical; expect(hierarchicalSpy).toHaveBeenCalledWith(mockHierarchical); - expect(clearFilterSpy).toHaveBeenCalled(); expect(processSpy).toHaveBeenCalled(); expect(setItemsSpy).toHaveBeenCalledWith([], 'id'); setTimeout(() => { diff --git a/frameworks/angular-slickgrid/src/library/components/angular-slickgrid.component.ts b/frameworks/angular-slickgrid/src/library/components/angular-slickgrid.component.ts index 0b4b0256a..60472c708 100644 --- a/frameworks/angular-slickgrid/src/library/components/angular-slickgrid.component.ts +++ b/frameworks/angular-slickgrid/src/library/components/angular-slickgrid.component.ts @@ -42,7 +42,6 @@ import { SortService, TreeDataService, unsubscribeAll, - type AutocompleterEditor, type BackendService, type BackendServiceApi, type BackendServiceOption, @@ -57,7 +56,6 @@ import { type Pagination, type PaginationMetadata, type RxJsFacade, - type SelectEditor, } from '@slickgrid-universal/common'; import { SlickFooterComponent } from '@slickgrid-universal/custom-footer-component'; import { SlickEmptyWarningComponent } from '@slickgrid-universal/empty-warning-component'; @@ -710,7 +708,7 @@ export class AngularSlickgridComponent implements AfterViewInit, On this.preRegisterResources(); // prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it. - this._columns = this.loadSlickGridEditors(this._columns || []); + this._columns = this.gridStateService.loadSlickGridEditors(this._columns || []); // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again if (this.options.autoAddCustomEditorFormatter) { @@ -1013,12 +1011,12 @@ export class AngularSlickgridComponent implements AfterViewInit, On */ updateColumnDefinitionsList(newColumns: Column[]) { // map the Editor model to editorClass and load editor collectionAsync - newColumns = this.loadSlickGridEditors(newColumns); + const updatedColumns = this.gridStateService.syncPluginColumns(newColumns, [...(this.sharedService.allColumns || []), ...newColumns]); if (this.options.enableTranslate) { - this.extensionService.translateColumnHeaders(undefined, newColumns); + this.extensionService.translateColumnHeaders(undefined, updatedColumns); } - this.extensionService.renderColumnHeaders(newColumns, true); + this.extensionService.renderColumnHeaders(updatedColumns, true); if (this.options?.enableAutoSizeColumns) { this.slickGrid.autosizeColumns(); @@ -1392,26 +1390,6 @@ export class AngularSlickgridComponent implements AfterViewInit, On } } - /** Load the Editor Collection asynchronously and replace the "collection" property when Observable resolves */ - protected loadEditorCollectionAsync(column: Column) { - if (column?.editor) { - const collectionAsync = column.editor.collectionAsync; - column.editor.disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()" - - if (collectionAsync instanceof Observable) { - this.subscriptions.push(collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection))); - } else if (collectionAsync instanceof Promise) { - // wait for the "collectionAsync", once resolved we will save it into the "collection" - // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise - collectionAsync.then((response: any | any[]) => { - if (Array.isArray(response)) { - this.updateEditorCollection(column, response); // from Promise - } - }); - } - } - } - /** Load any possible Columns Grid Presets */ protected loadColumnPresetsWhenDatasetInitialized() { // if user entered some Columns "presets", we need to reflect them all in the grid @@ -1661,6 +1639,7 @@ export class AngularSlickgridComponent implements AfterViewInit, On this.backendUtilityService.addRxJsResource(this.rxjs); this.filterFactory.addRxJsResource(this.rxjs); this.filterService.addRxJsResource(this.rxjs); + this.gridStateService.addRxJsResource(this.rxjs); this.sortService.addRxJsResource(this.rxjs); this.paginationService.addRxJsResource(this.rxjs); this.containerService.registerInstance('RxJsResource', this.rxjs); @@ -1723,23 +1702,6 @@ export class AngularSlickgridComponent implements AfterViewInit, On return flatDatasetOutput; } - /** Prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it. */ - protected loadSlickGridEditors(columns: Column[]): Column[] { - if (columns.some((col) => `${col.id}`.includes('.'))) { - console.warn( - '[Angular-Slickgrid] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".' - ); - } - - return columns.map((column: Column | any) => { - // on every Editor that have a "collectionAsync", resolve the data and assign it to the "collection" property - if (column?.editor?.collectionAsync) { - this.loadEditorCollectionAsync(column); - } - return { ...column, editorClass: column.editor?.model }; - }); - } - protected suggestDateParsingWhenHelpful() { if ( this.dataView?.getItemCount() > WARN_NO_PREPARSE_DATE_SIZE && @@ -1753,23 +1715,4 @@ export class AngularSlickgridComponent implements AfterViewInit, On ); } } - - /** - * When the Editor(s) has a "editor.collection" property, we'll load the async collection. - * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed. - */ - protected updateEditorCollection(column: Column, newCollection: T[]) { - if (this.slickGrid && column.editor) { - column.editor.collection = newCollection; - column.editor.disabled = false; - - // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection. - const currentEditor = this.slickGrid.getCellEditor() as AutocompleterEditor | SelectEditor; - if (currentEditor?.disable && currentEditor?.renderDomElement) { - currentEditor.destroy(); - currentEditor.disable(false); - currentEditor.renderDomElement(newCollection); - } - } - } } diff --git a/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-detail.md b/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-detail.md index 367d70506..b7430bd3a 100644 --- a/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-detail.md +++ b/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-detail.md @@ -377,6 +377,9 @@ addNewColumn() { } ``` +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. + ## Row Detail with Inner Grid You can also add an inner grid inside a Row Detail, however there are a few things to know off and remember. Any time a Row Detail is falling outside the main grid viewport, it will be unmounted and until it comes back into the viewport which is then remounted. The process of unmounting and remounting means that Row Detail previous states aren't preserved, however you could use Grid State & Presets to overcome this problem. diff --git a/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-selection.md b/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-selection.md index 5acc05a0c..c65577db8 100644 --- a/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-selection.md +++ b/frameworks/aurelia-slickgrid/docs/grid-functionalities/row-selection.md @@ -364,3 +364,6 @@ addNewColumn() { // this.aureliaGrid.slickGrid.setColumns(cols); } ``` + +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. \ No newline at end of file diff --git a/frameworks/aurelia-slickgrid/src/custom-elements/aurelia-slickgrid.ts b/frameworks/aurelia-slickgrid/src/custom-elements/aurelia-slickgrid.ts index 093f4df28..dbd7d663d 100644 --- a/frameworks/aurelia-slickgrid/src/custom-elements/aurelia-slickgrid.ts +++ b/frameworks/aurelia-slickgrid/src/custom-elements/aurelia-slickgrid.ts @@ -1,6 +1,5 @@ import type { ICollectionObserver, ICollectionSubscriber } from '@aurelia/runtime'; import type { - AutocompleterEditor, BackendService, BackendServiceApi, BackendServiceOption, @@ -15,7 +14,6 @@ import type { Metrics, Pagination, PaginationMetadata, - SelectEditor, } from '@slickgrid-universal/common'; import { autoAddEditorFormatterToColumnsWithEditor, @@ -360,7 +358,7 @@ export class AureliaSlickgridCustomElement { // and allow slickgrid to pass its arguments to the editors constructor last // when slickgrid creates the editor // https://github.com/aurelia/dependency-injection/blob/master/src/resolvers.js - this._columns = this.loadSlickGridEditors(this._columns); + this._columns = this.gridStateService.loadSlickGridEditors(this._columns); // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again if (this.options.autoAddCustomEditorFormatter) { @@ -1157,25 +1155,18 @@ export class AureliaSlickgridCustomElement { * If using i18n, we also need to trigger a re-translate of the column headers */ updateColumnDefinitionsList(newColumns: Column[]) { - if (newColumns) { - // map the Editor model to editorClass and load editor collectionAsync - newColumns = this.loadSlickGridEditors(newColumns); + // map the Editor model to editorClass and load editor collectionAsync + const updatedColumns = this.gridStateService.syncPluginColumns(newColumns, [...(this.sharedService.allColumns || []), ...newColumns]); - // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again - if (this.options.autoAddCustomEditorFormatter) { - autoAddEditorFormatterToColumnsWithEditor(newColumns, this.options.autoAddCustomEditorFormatter); - } - - if (this.options.enableTranslate) { - this.extensionService.translateColumnHeaders(undefined, newColumns); - } - this.extensionService.renderColumnHeaders(newColumns, true); + if (this.options.enableTranslate) { + this.extensionService.translateColumnHeaders(undefined, updatedColumns); + } + this.extensionService.renderColumnHeaders(updatedColumns, true); - if (this.options?.enableAutoSizeColumns) { - this.grid.autosizeColumns(); - } else if (this.options?.enableAutoResizeColumnsByCellContent && this.resizerService?.resizeColumnsByCellContent) { - this.resizerService.resizeColumnsByCellContent(); - } + if (this.options?.enableAutoSizeColumns) { + this.grid.autosizeColumns(); + } else if (this.options?.enableAutoResizeColumnsByCellContent && this.resizerService?.resizeColumnsByCellContent) { + this.resizerService.resizeColumnsByCellContent(); } } @@ -1270,43 +1261,6 @@ export class AureliaSlickgridCustomElement { } } - /** Load the Editor Collection asynchronously and replace the "collection" property when Promise resolves */ - protected loadEditorCollectionAsync(column: Column) { - if (column?.editor) { - const collectionAsync = column.editor.collectionAsync; - column.editor.disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()" - - if (collectionAsync instanceof Promise) { - // wait for the "collectionAsync", once resolved we will save it into the "collection" - // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise - collectionAsync.then((response: any | any[]) => { - if (Array.isArray(response)) { - this.updateEditorCollection(column, response); // from Promise - } else if (response instanceof Response && typeof response.json === 'function') { - if (response.bodyUsed) { - console.warn( - `[Aurelia-SlickGrid] The response body passed to collectionAsync was already read. ` + - `Either pass the dataset from the Response or clone the response first using response.clone()` - ); - } else { - // from Fetch - (response as Response).json().then((data) => this.updateEditorCollection(column, data)); - } - } else if (response?.content) { - this.updateEditorCollection(column, response.content); // from http-client - } - }); - } else if (this.rxjs?.isObservable(collectionAsync)) { - // wrap this inside a microtask at the end of the task to avoid timing issue since updateEditorCollection requires to call SlickGrid getColumns() method after columns are available - queueMicrotask(() => { - this.subscriptions.push( - (collectionAsync as Observable).subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection)) - ); - }); - } - } - } - /** Load any possible Columns Grid Presets */ protected loadColumnPresetsWhenDatasetInitialized() { // if user entered some Columns "presets", we need to reflect them all in the grid @@ -1570,6 +1524,7 @@ export class AureliaSlickgridCustomElement { this.backendUtilityService.addRxJsResource(this.rxjs); this.filterFactory.addRxJsResource(this.rxjs); this.filterService.addRxJsResource(this.rxjs); + this.gridStateService.addRxJsResource(this.rxjs); this.sortService.addRxJsResource(this.rxjs); this.paginationService.addRxJsResource(this.rxjs); this.containerService.registerInstance('RxJsResource', this.rxjs); @@ -1642,27 +1597,6 @@ export class AureliaSlickgridCustomElement { return flatDatasetOutput; } - /** Prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it. */ - protected loadSlickGridEditors(columns: Column[]): Column[] { - if (columns.some((col) => `${col.id}`.includes('.'))) { - console.warn( - '[Aurelia-Slickgrid] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".' - ); - } - - return columns.map((column: Column | any) => { - // on every Editor which have a "collection" or a "collectionAsync" - if (column.editor?.collectionAsync) { - this.loadEditorCollectionAsync(column); - } - - return { - ...column, - editorClass: column.editor && this.container.getFactory(column.editor.model).Type, - }; - }); - } - protected suggestDateParsingWhenHelpful() { if ( this.dataview?.getItemCount() > WARN_NO_PREPARSE_DATE_SIZE && @@ -1676,23 +1610,4 @@ export class AureliaSlickgridCustomElement { ); } } - - /** - * When the Editor(s) has a "editor.collection" property, we'll load the async collection. - * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed. - */ - protected updateEditorCollection(column: Column, newCollection: T[]) { - if (this.grid && column.editor) { - column.editor.collection = newCollection; - column.editor.disabled = false; - - // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection. - const currentEditor = this.grid.getCellEditor() as AutocompleterEditor | SelectEditor; - if (currentEditor?.disable && currentEditor?.renderDomElement) { - currentEditor.destroy(); - currentEditor.disable(false); - currentEditor.renderDomElement(newCollection); - } - } - } } diff --git a/frameworks/slickgrid-react/docs/grid-functionalities/row-detail.md b/frameworks/slickgrid-react/docs/grid-functionalities/row-detail.md index c2592ce63..2bddb1fc5 100644 --- a/frameworks/slickgrid-react/docs/grid-functionalities/row-detail.md +++ b/frameworks/slickgrid-react/docs/grid-functionalities/row-detail.md @@ -478,6 +478,9 @@ const Example: React.FC = () => { } ``` +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. + ## Row Detail with Inner Grid You can also add an inner grid inside a Row Detail, however there are a few things to know off and remember. Any time a Row Detail is falling outside the main grid viewport, it will be unmounted and until it comes back into the viewport which is then remounted. The process of unmounting and remounting means that Row Detail previous states aren't preserved, however you could use Grid State & Presets to overcome this problem. diff --git a/frameworks/slickgrid-react/docs/grid-functionalities/row-selection.md b/frameworks/slickgrid-react/docs/grid-functionalities/row-selection.md index 90767a09f..f332f0ad1 100644 --- a/frameworks/slickgrid-react/docs/grid-functionalities/row-selection.md +++ b/frameworks/slickgrid-react/docs/grid-functionalities/row-selection.md @@ -444,3 +444,6 @@ addNewColumn() { // reactGridRef.current?.slickGrid.setColumns(cols); } ``` + +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. \ No newline at end of file diff --git a/frameworks/slickgrid-react/src/components/slickgrid-react.tsx b/frameworks/slickgrid-react/src/components/slickgrid-react.tsx index 19f43ad7b..1792f0ad5 100644 --- a/frameworks/slickgrid-react/src/components/slickgrid-react.tsx +++ b/frameworks/slickgrid-react/src/components/slickgrid-react.tsx @@ -24,7 +24,6 @@ import { SlickGroupItemMetadataProvider, SortService, TreeDataService, - type AutocompleterEditor, type BackendService, type BackendServiceApi, type BackendServiceOption, @@ -40,7 +39,6 @@ import { type Pagination, type PaginationMetadata, type RxJsFacade, - type SelectEditor, } from '@slickgrid-universal/common'; import { SlickFooterComponent } from '@slickgrid-universal/custom-footer-component'; import { SlickEmptyWarningComponent } from '@slickgrid-universal/empty-warning-component'; @@ -501,7 +499,7 @@ export class SlickgridReact extends React.Component extends React.Component[]) { - if (this.grid && this._options && Array.isArray(newColumns)) { - // map the Editor model to editorClass and load editor collectionAsync - newColumns = this.loadSlickGridEditors(newColumns); + // map the Editor model to editorClass and load editor collectionAsync + const updatedColumns = this.gridStateService.syncPluginColumns(newColumns, [...(this.sharedService.allColumns || []), ...newColumns]); - // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again - if (this._options.autoAddCustomEditorFormatter) { - autoAddEditorFormatterToColumnsWithEditor(newColumns, this._options.autoAddCustomEditorFormatter); - } - - if (this._options.enableTranslate) { - this.extensionService.translateColumnHeaders(undefined, newColumns); - } - this.extensionService.renderColumnHeaders(newColumns, true); + if (this._options.enableTranslate) { + this.extensionService.translateColumnHeaders(undefined, updatedColumns); + } + this.extensionService.renderColumnHeaders(updatedColumns, true); - if (this._options?.enableAutoSizeColumns) { - this.grid.autosizeColumns(); - } else if (this._options?.enableAutoResizeColumnsByCellContent && this.resizerService?.resizeColumnsByCellContent) { - this.resizerService.resizeColumnsByCellContent(); - } + if (this._options?.enableAutoSizeColumns) { + this.grid.autosizeColumns(); + } else if (this._options?.enableAutoResizeColumnsByCellContent && this.resizerService?.resizeColumnsByCellContent) { + this.resizerService.resizeColumnsByCellContent(); } } @@ -1375,43 +1366,6 @@ export class SlickgridReact extends React.Component { - if (Array.isArray(response)) { - this.updateEditorCollection(column, response); // from Promise - } else if (response instanceof Response && typeof response.json === 'function') { - if (response.bodyUsed) { - console.warn( - `[SlickGrid-React] The response body passed to collectionAsync was already read.` + - `Either pass the dataset from the Response or clone the response first using response.clone()` - ); - } else { - // from Fetch - (response as Response).json().then((data) => this.updateEditorCollection(column, data)); - } - } else if (response?.content) { - this.updateEditorCollection(column, response.content); // from http-client - } - }); - } else if (this.rxjs?.isObservable(collectionAsync)) { - // wrap this inside a microtask at the end of the task to avoid timing issue since updateEditorCollection requires to call SlickGrid getColumns() method after columns are available - queueMicrotask(() => { - this.subscriptions.push( - (collectionAsync as Observable).subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection)) - ); - }); - } - } - } - /** Load any possible Columns Grid Presets */ protected loadColumnPresetsWhenDatasetInitialized() { // if user entered some Columns "presets", we need to reflect them all in the grid @@ -1624,6 +1578,7 @@ export class SlickgridReact extends React.Component extends React.Component[]): Column[] { - if (columns.some((col) => `${col?.id}`.includes('.'))) { - console.warn( - '[Slickgrid-React] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".' - ); - } - - return columns.map((column: Column | any) => { - if (column) { - // on every Editor which have a "collection" or a "collectionAsync" - if (column.editor?.collectionAsync) { - this.loadEditorCollectionAsync(column); - } - return { ...column, editorClass: column.editor?.model }; - } - }); - } - protected suggestDateParsingWhenHelpful() { if ( this.dataView?.getItemCount() > WARN_NO_PREPARSE_DATE_SIZE && @@ -1693,25 +1629,6 @@ export class SlickgridReact extends React.Component(column: Column, newCollection: U[]) { - if (this.grid && column.editor) { - column.editor.collection = newCollection; - column.editor.disabled = false; - - // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection. - const currentEditor = this.grid.getCellEditor() as AutocompleterEditor | SelectEditor; - if (currentEditor?.disable && currentEditor?.renderDomElement) { - currentEditor.destroy(); - currentEditor.disable(false); - currentEditor.renderDomElement(newCollection); - } - } - } - render() { return (
**Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. + ## Row Detail with Inner Grid You can also add an inner grid inside a Row Detail, however there are a few things to know off and remember. Any time a Row Detail is falling outside the main grid viewport, it will be unmounted and until it comes back into the viewport which is then remounted. The process of unmounting and remounting means that Row Detail previous states aren't preserved, however you could use Grid State & Presets to overcome this problem. diff --git a/frameworks/slickgrid-vue/docs/grid-functionalities/row-selection.md b/frameworks/slickgrid-vue/docs/grid-functionalities/row-selection.md index 2c66d222d..a6c645fa9 100644 --- a/frameworks/slickgrid-vue/docs/grid-functionalities/row-selection.md +++ b/frameworks/slickgrid-vue/docs/grid-functionalities/row-selection.md @@ -512,3 +512,6 @@ function addNewColumn() { } ``` + +> **Note** +> The code above is no longer necessary with v10.8.0 and above, the lib will now take care of that for you. \ No newline at end of file diff --git a/frameworks/slickgrid-vue/src/components/SlickgridVue.vue b/frameworks/slickgrid-vue/src/components/SlickgridVue.vue index 970f2674d..1d1bb4da2 100644 --- a/frameworks/slickgrid-vue/src/components/SlickgridVue.vue +++ b/frameworks/slickgrid-vue/src/components/SlickgridVue.vue @@ -25,7 +25,6 @@ import { SlickGroupItemMetadataProvider, SortService, TreeDataService, - type AutocompleterEditor, type BackendServiceApi, type BackendServiceOption, type BasePaginationComponent, @@ -42,7 +41,6 @@ import { type Pagination, type PaginationMetadata, type RxJsFacade, - type SelectEditor, } from '@slickgrid-universal/common'; import { SlickFooterComponent } from '@slickgrid-universal/custom-footer-component'; import { SlickEmptyWarningComponent } from '@slickgrid-universal/empty-warning-component'; @@ -438,7 +436,7 @@ function initialization() { // Wrap each editor class in the Factory resolver so consumers of this library. // Vue will allow slickgrid to pass its arguments to the editors constructor last // when slickgrid creates the editor - _columns.value = loadSlickGridEditors(columnsModel.value || []); + _columns.value = gridStateService.loadSlickGridEditors(columnsModel.value || []); // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again if (_gridOptions.value.autoAddCustomEditorFormatter) { @@ -1156,25 +1154,18 @@ function setDarkMode(dark = false) { * If using i18n, we also need to trigger a re-translate of the column headers */ function updateColumnsList(newColumns: Column[]) { - if (newColumns) { - // map the Editor model to editorClass and load editor collectionAsync - newColumns = loadSlickGridEditors(newColumns); + // map the Editor model to editorClass and load editor collectionAsync + const updatedColumns = gridStateService.syncPluginColumns(newColumns, [...(sharedService.allColumns || []), ...newColumns]); - // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again - if (_gridOptions.value.autoAddCustomEditorFormatter) { - autoAddEditorFormatterToColumnsWithEditor(newColumns, _gridOptions.value.autoAddCustomEditorFormatter); - } - - if (_gridOptions.value.enableTranslate) { - extensionService.translateColumnHeaders(undefined, newColumns); - } - extensionService.renderColumnHeaders(newColumns, true); + if (_gridOptions.value.enableTranslate) { + extensionService.translateColumnHeaders(undefined, updatedColumns); + } + extensionService.renderColumnHeaders(updatedColumns, true); - if (_gridOptions.value?.enableAutoSizeColumns) { - grid?.autosizeColumns(); - } else if (_gridOptions.value?.enableAutoResizeColumnsByCellContent && resizerService?.resizeColumnsByCellContent) { - resizerService.resizeColumnsByCellContent(); - } + if (_gridOptions.value?.enableAutoSizeColumns) { + grid?.autosizeColumns(); + } else if (_gridOptions.value?.enableAutoResizeColumnsByCellContent && resizerService?.resizeColumnsByCellContent) { + resizerService.resizeColumnsByCellContent(); } } @@ -1245,43 +1236,6 @@ function initializePaginationService(paginationOptions: Pagination) { } } -/** Load the Editor Collection asynchronously and replace the "collection" property when Promise resolves */ -function loadEditorCollectionAsync(column: Column) { - if (column?.editor) { - const collectionAsync = column.editor.collectionAsync; - column.editor.disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()" - - if (collectionAsync instanceof Promise) { - // wait for the "collectionAsync", once resolved we will save it into the "collection" - // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise - collectionAsync.then((response: any | any[]) => { - if (Array.isArray(response)) { - updateEditorCollection(column, response); // from Promise - } else if (response instanceof Response && typeof response.json === 'function') { - if (response.bodyUsed) { - console.warn( - `[SlickGrid-Vue] The response body passed to collectionAsync was already read. ` + - `Either pass the dataset from the Response or clone the response first using response.clone()` - ); - } else { - // from Fetch - (response as Response).json().then((data) => updateEditorCollection(column, data)); - } - } else if (response?.content) { - updateEditorCollection(column, response.content); // from http-client - } - }); - } else if (rxjs?.isObservable(collectionAsync)) { - // wrap this inside a microtask at the end of the task to avoid timing issue since updateEditorCollection requires to call SlickGrid getColumns() method after columns are available - queueMicrotask(() => { - subscriptions.push( - (collectionAsync as Observable).subscribe((resolvedCollection) => updateEditorCollection(column, resolvedCollection)) - ); - }); - } - } -} - /** Load any possible Columns Grid Presets */ function loadColumnPresetsWhenDatasetInitialized() { // if user entered some Columns "presets", we need to reflect them all in the grid @@ -1528,6 +1482,7 @@ function registerRxJsResource(resource: RxJsFacade) { backendUtilityService.addRxJsResource(rxjs); filterFactory.addRxJsResource(rxjs); filterService.addRxJsResource(rxjs); + gridStateService.addRxJsResource(rxjs); sortService.addRxJsResource(rxjs); paginationService.addRxJsResource(rxjs); containerService.registerInstance('RxJsResource', rxjs); @@ -1601,24 +1556,6 @@ function sortTreeDataset(flatDatasetInput: T[], forceGridRefresh = false): T[ return flatDatasetOutput; } -/** Prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it. */ -function loadSlickGridEditors(columns: Column[]): Column[] { - if (columns.some((col) => `${col.id}`.includes('.'))) { - console.warn( - '[Slickgrid-Vue] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".' - ); - } - - return columns.map((column: Column | any) => { - // on every Editor which have a "collection" or a "collectionAsync" - if (column.editor?.collectionAsync) { - loadEditorCollectionAsync(column); - } - - return { ...column, editorClass: column.editor?.model }; - }); -} - function suggestDateParsingWhenHelpful() { if ( dataview!.getItemCount() > WARN_NO_PREPARSE_DATE_SIZE && @@ -1632,25 +1569,6 @@ function suggestDateParsingWhenHelpful() { ); } } - -/** - * When the Editor(s) has a "editor.collection" property, we'll load the async collection. - * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed. - */ -function updateEditorCollection(column: Column, newCollection: T[]) { - if (grid && column.editor) { - column.editor.collection = newCollection; - column.editor.disabled = false; - - // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection. - const currentEditor = grid.getCellEditor() as AutocompleterEditor | SelectEditor; - if (currentEditor?.disable && currentEditor?.renderDomElement) { - currentEditor.destroy(); - currentEditor.disable(false); - currentEditor.renderDomElement(newCollection); - } - } -}