Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit 2e83d98

Browse files
authored
Merge pull request #1116 from ghiscoding/bugfix/dynamic-columns-with-presets
fix(presets): dynamic columns should be auto-inserted with Grid Presets
2 parents d417e75 + 0285916 commit 2e83d98

File tree

6 files changed

+92
-26
lines changed

6 files changed

+92
-26
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
"@slickgrid-universal/graphql": "~2.6.3",
9595
"@slickgrid-universal/odata": "~2.6.3",
9696
"@slickgrid-universal/text-export": "~2.6.3",
97-
"@types/dompurify": "^2.4.0",
97+
"@types/dompurify": "^3.0.0",
9898
"@types/flatpickr": "^3.1.2",
9999
"@types/fnando__sparkline": "^0.3.4",
100100
"@types/jest": "^29.5.0",

src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,56 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
14241424
expect(setColSpy).toHaveBeenCalledWith(mockCols);
14251425
});
14261426

1427+
it('should reflect columns with an extra row detail column in the grid when "enableRowDetailView" is set', () => {
1428+
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
1429+
const mockCol = { id: 'firstName', field: 'firstName' };
1430+
const mockCols = [{ id: '_detail_selector', field: '_detail_selector', editor: undefined, internalColumnEditor: {} }, mockCol];
1431+
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
1432+
const setColSpy = jest.spyOn(mockGrid, 'setColumns');
1433+
1434+
component.columnDefinitions = mockCols;
1435+
component.gridOptions = { ...gridOptions, enableRowDetailView: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
1436+
component.initialization(slickEventHandler);
1437+
1438+
expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
1439+
expect(setColSpy).toHaveBeenCalledWith(mockCols);
1440+
});
1441+
1442+
it('should reflect columns with an extra row move column in the grid when "enableRowMoveManager" is set', () => {
1443+
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
1444+
const mockCol = { id: 'firstName', field: 'firstName' };
1445+
const mockCols = [{ id: '_move', field: '_move', editor: undefined, internalColumnEditor: {} }, mockCol];
1446+
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
1447+
const setColSpy = jest.spyOn(mockGrid, 'setColumns');
1448+
1449+
component.columnDefinitions = mockCols;
1450+
component.gridOptions = { ...gridOptions, enableRowMoveManager: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
1451+
component.initialization(slickEventHandler);
1452+
1453+
expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
1454+
expect(setColSpy).toHaveBeenCalledWith(mockCols);
1455+
});
1456+
1457+
it('should reflect 3 dynamic columns (1-RowMove, 2-RowSelection, 3-RowDetail) when all associated extension flags are enabled', () => {
1458+
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
1459+
const mockCol = { id: 'firstName', field: 'firstName' };
1460+
const mockCols = [
1461+
{ id: '_move', field: '_move', editor: undefined, internalColumnEditor: {} },
1462+
{ id: '_checkbox_selector', field: '_checkbox_selector', editor: undefined, internalColumnEditor: {} },
1463+
{ id: '_detail_selector', field: '_detail_selector', editor: undefined, internalColumnEditor: {} },
1464+
mockCol
1465+
];
1466+
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
1467+
const setColSpy = jest.spyOn(mockGrid, 'setColumns');
1468+
1469+
component.columnDefinitions = mockCols;
1470+
component.gridOptions = { ...gridOptions, enableCheckboxSelector: true, enableRowDetailView: true, enableRowMoveManager: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
1471+
component.initialization(slickEventHandler);
1472+
1473+
expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
1474+
expect(setColSpy).toHaveBeenCalledWith(mockCols);
1475+
});
1476+
14271477
it('should execute backend service "init" method when set', () => {
14281478
const mockPagination = { pageNumber: 1, pageSizes: [10, 25, 50], pageSize: 10, totalItems: 100 };
14291479
const mockGraphqlOptions = { datasetName: 'users', extraQueryArguments: [{ field: 'userId', value: 123 }] } as GraphqlServiceOption;

src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,27 +1107,47 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy {
11071107
}
11081108
}
11091109

1110+
protected insertDynamicPresetColumns(columnId: string, gridPresetColumns: Column[]) {
1111+
if (this._columnDefinitions) {
1112+
const columnPosition = this._columnDefinitions.findIndex(c => c.id === columnId);
1113+
if (columnPosition >= 0) {
1114+
const dynColumn = this._columnDefinitions[columnPosition];
1115+
if (dynColumn?.id === columnId && !gridPresetColumns.some(c => c.id === columnId)) {
1116+
columnPosition > 0
1117+
? gridPresetColumns.splice(columnPosition, 0, dynColumn)
1118+
: gridPresetColumns.unshift(dynColumn);
1119+
}
1120+
}
1121+
}
1122+
}
1123+
11101124
/** Load any possible Columns Grid Presets */
11111125
private loadColumnPresetsWhenDatasetInitialized() {
11121126
// if user entered some Columns "presets", we need to reflect them all in the grid
11131127
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.columns) && this.gridOptions.presets.columns.length > 0) {
1114-
const gridColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.slickGrid, this.gridOptions.presets.columns);
1115-
if (gridColumns && Array.isArray(gridColumns) && gridColumns.length > 0) {
1116-
// make sure that the checkbox selector is also visible if it is enabled
1128+
const gridPresetColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.slickGrid, this.gridOptions.presets.columns);
1129+
if (gridPresetColumns && Array.isArray(gridPresetColumns) && gridPresetColumns.length > 0 && Array.isArray(this._columnDefinitions)) {
1130+
// make sure that the dynamic columns are included in presets (1.Row Move, 2. Row Selection, 3. Row Detail)
1131+
if (this.gridOptions.enableRowMoveManager) {
1132+
const rmmColId = this.gridOptions?.rowMoveManager?.columnId ?? '_move';
1133+
this.insertDynamicPresetColumns(rmmColId, gridPresetColumns);
1134+
}
11171135
if (this.gridOptions.enableCheckboxSelector) {
1118-
const checkboxColumn = (Array.isArray(this._columnDefinitions) && this._columnDefinitions.length > 0) ? this._columnDefinitions[0] : null;
1119-
if (checkboxColumn && checkboxColumn.id === '_checkbox_selector' && gridColumns[0].id !== '_checkbox_selector') {
1120-
gridColumns.unshift(checkboxColumn);
1121-
}
1136+
const chkColId = this.gridOptions?.checkboxSelector?.columnId ?? '_checkbox_selector';
1137+
this.insertDynamicPresetColumns(chkColId, gridPresetColumns);
1138+
}
1139+
if (this.gridOptions.enableRowDetailView) {
1140+
const rdvColId = this.gridOptions?.rowDetailView?.columnId ?? '_detail_selector';
1141+
this.insertDynamicPresetColumns(rdvColId, gridPresetColumns);
11221142
}
11231143

11241144
// keep copy the original optional `width` properties optionally provided by the user.
11251145
// We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
1126-
gridColumns.forEach(col => col.originalWidth = col.width);
1146+
gridPresetColumns.forEach(col => col.originalWidth = col.width);
11271147

11281148
// finally set the new presets columns (including checkbox selector if need be)
1129-
this.slickGrid.setColumns(gridColumns);
1130-
this.sharedService.visibleColumns = gridColumns;
1149+
this.slickGrid.setColumns(gridPresetColumns);
1150+
this.sharedService.visibleColumns = gridPresetColumns;
11311151
}
11321152
}
11331153
}

test/mockSlickEvent.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { SlickEvent, SlickEventHandler } from '@slickgrid-universal/common';
1+
import { SlickEvent, SlickEventData, SlickEventHandler } from '@slickgrid-universal/common';
22

33
// interface PubSubEvent {
44
// name: string;
55
// handler: (args: any) => void;
66
// }
77

88
export class MockSlickEvent implements SlickEvent {
9-
private _handlers = [];
9+
private _handlers: any[] = [];
1010

1111
notify(args: any, event?: any, scope?: any) {
1212
scope = scope || this;
@@ -19,21 +19,21 @@ export class MockSlickEvent implements SlickEvent {
1919
return returnValue;
2020
}
2121

22-
subscribe(handler: (data: any, e?: any) => void): any {
23-
this._handlers.push(handler);
22+
subscribe(fn: (data: any, e?: any) => void): any {
23+
this._handlers.push(fn);
2424
}
2525

26-
unsubscribe(handler: (data: any, e?: any) => void) {
26+
unsubscribe(fn?: (e: SlickEventData | Event, data?: any) => void) {
2727
this._handlers.forEach((handlerFn, index) => {
28-
if (handlerFn === handler) {
28+
if (handlerFn === fn) {
2929
this._handlers.splice(index, 1);
3030
}
3131
});
3232
}
3333
}
3434

3535
export class MockSlickEventHandler implements SlickEventHandler {
36-
private _handlers = [];
36+
private _handlers: any[] = [];
3737

3838
notify(eventName: string, data?: any) {
3939
const pubSub = this._handlers.find(subscription => subscription.name === eventName);

test/translaterServiceStub.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { TranslaterService, TranslateServiceEventName } from '@slickgrid-universal/common';
2-
import { I18N } from 'aurelia-i18n';
3-
42
export class TranslaterServiceStub implements TranslaterService {
53
eventName = 'onLanguageChange' as TranslateServiceEventName;
64
private _locale = 'en';
75

8-
constructor(private i18n?: I18N) { }
9-
106
getCurrentLanguage(): string {
117
return this._locale;
128
}

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,10 +2407,10 @@
24072407
dependencies:
24082408
"@types/node" "*"
24092409

2410-
"@types/dompurify@^2.4.0":
2411-
version "2.4.0"
2412-
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.4.0.tgz#fd9706392a88e0e0e6d367f3588482d817df0ab9"
2413-
integrity sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==
2410+
"@types/dompurify@^3.0.0":
2411+
version "3.0.0"
2412+
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.0.tgz#28388a1aff0ced6e635b5b912c5f5935711d45b9"
2413+
integrity sha512-EcSqmgm/xJwH8CcJPy9AHNypp/j58CYga3nWdl93/wLxX6OH+rSD3aAj75NQazcZd1YKHJ/pjNZ9qmgVajggwQ==
24142414
dependencies:
24152415
"@types/trusted-types" "*"
24162416

0 commit comments

Comments
 (0)