Skip to content

Commit

Permalink
fix(presets): dynamic columns should be auto-inserted with Grid Presets
Browse files Browse the repository at this point in the history
- fixes issue brought in comment under issue #1092
- there are 3 dynamically created columns (RowMove, RowSelection & RowDetail) and all 3 should be auto-inserted when columns presets are used
- the 2nd issue will be fixed in Slickgrid-Universal, the issue is when Row Detail & Row Selection are used together, an extra checkbox appears in the filter section of the RowDetail column when it shouldn't
  • Loading branch information
ghiscoding committed Mar 22, 2023
1 parent ce01c2c commit 8091790
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,56 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
expect(setColSpy).toHaveBeenCalledWith(mockCols);
});

it('should reflect columns with an extra row detail column in the grid when "enableRowDetailView" is set', () => {
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
const mockCol = { id: 'firstName', field: 'firstName' };
const mockCols = [{ id: '_detail_selector', field: '_detail_selector', editor: undefined, internalColumnEditor: {} }, mockCol];
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
const setColSpy = jest.spyOn(mockGrid, 'setColumns');

component.columnDefinitions = mockCols;
component.gridOptions = { ...gridOptions, enableRowDetailView: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
component.initialization(slickEventHandler);

expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
expect(setColSpy).toHaveBeenCalledWith(mockCols);
});

it('should reflect columns with an extra row move column in the grid when "enableRowMoveManager" is set', () => {
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
const mockCol = { id: 'firstName', field: 'firstName' };
const mockCols = [{ id: '_move', field: '_move', editor: undefined, internalColumnEditor: {} }, mockCol];
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
const setColSpy = jest.spyOn(mockGrid, 'setColumns');

component.columnDefinitions = mockCols;
component.gridOptions = { ...gridOptions, enableRowMoveManager: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
component.initialization(slickEventHandler);

expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
expect(setColSpy).toHaveBeenCalledWith(mockCols);
});

it('should reflect 3 dynamic columns (1-RowMove, 2-RowSelection, 3-RowDetail) when all associated extension flags are enabled', () => {
const mockColsPresets = [{ columnId: 'firstName', width: 100 }];
const mockCol = { id: 'firstName', field: 'firstName' };
const mockCols = [
{ id: '_move', field: '_move', editor: undefined, internalColumnEditor: {} },
{ id: '_checkbox_selector', field: '_checkbox_selector', editor: undefined, internalColumnEditor: {} },
{ id: '_detail_selector', field: '_detail_selector', editor: undefined, internalColumnEditor: {} },
mockCol
];
const getAssocColSpy = jest.spyOn(gridStateServiceStub, 'getAssociatedGridColumns').mockReturnValue([mockCol]);
const setColSpy = jest.spyOn(mockGrid, 'setColumns');

component.columnDefinitions = mockCols;
component.gridOptions = { ...gridOptions, enableCheckboxSelector: true, enableRowDetailView: true, enableRowMoveManager: true, presets: { columns: mockColsPresets } } as unknown as GridOption;
component.initialization(slickEventHandler);

expect(getAssocColSpy).toHaveBeenCalledWith(mockGrid, mockColsPresets);
expect(setColSpy).toHaveBeenCalledWith(mockCols);
});

it('should execute backend service "init" method when set', () => {
const mockPagination = { pageNumber: 1, pageSizes: [10, 25, 50], pageSize: 10, totalItems: 100 };
const mockGraphqlOptions = { datasetName: 'users', extraQueryArguments: [{ field: 'userId', value: 123 }] } as GraphqlServiceOption;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1107,27 +1107,47 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy {
}
}

protected insertDynamicPresetColumns(columnId: string, gridPresetColumns: Column[]) {
if (this._columnDefinitions) {
const columnPosition = this._columnDefinitions.findIndex(c => c.id === columnId);
if (columnPosition >= 0) {
const dynColumn = this._columnDefinitions[columnPosition];
if (dynColumn?.id === columnId && !gridPresetColumns.some(c => c.id === columnId)) {
columnPosition > 0
? gridPresetColumns.splice(columnPosition, 0, dynColumn)
: gridPresetColumns.unshift(dynColumn);
}
}
}
}

/** Load any possible Columns Grid Presets */
private loadColumnPresetsWhenDatasetInitialized() {
// if user entered some Columns "presets", we need to reflect them all in the grid
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.columns) && this.gridOptions.presets.columns.length > 0) {
const gridColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.slickGrid, this.gridOptions.presets.columns);
if (gridColumns && Array.isArray(gridColumns) && gridColumns.length > 0) {
// make sure that the checkbox selector is also visible if it is enabled
const gridPresetColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.slickGrid, this.gridOptions.presets.columns);
if (gridPresetColumns && Array.isArray(gridPresetColumns) && gridPresetColumns.length > 0 && Array.isArray(this._columnDefinitions)) {
// make sure that the dynamic columns are included in presets (1.Row Move, 2. Row Selection, 3. Row Detail)
if (this.gridOptions.enableRowMoveManager) {
const rmmColId = this.gridOptions?.rowMoveManager?.columnId ?? '_move';
this.insertDynamicPresetColumns(rmmColId, gridPresetColumns);
}
if (this.gridOptions.enableCheckboxSelector) {
const checkboxColumn = (Array.isArray(this._columnDefinitions) && this._columnDefinitions.length > 0) ? this._columnDefinitions[0] : null;
if (checkboxColumn && checkboxColumn.id === '_checkbox_selector' && gridColumns[0].id !== '_checkbox_selector') {
gridColumns.unshift(checkboxColumn);
}
const chkColId = this.gridOptions?.checkboxSelector?.columnId ?? '_checkbox_selector';
this.insertDynamicPresetColumns(chkColId, gridPresetColumns);
}
if (this.gridOptions.enableRowDetailView) {
const rdvColId = this.gridOptions?.rowDetailView?.columnId ?? '_detail_selector';
this.insertDynamicPresetColumns(rdvColId, gridPresetColumns);
}

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

// finally set the new presets columns (including checkbox selector if need be)
this.slickGrid.setColumns(gridColumns);
this.sharedService.visibleColumns = gridColumns;
this.slickGrid.setColumns(gridPresetColumns);
this.sharedService.visibleColumns = gridPresetColumns;
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions test/mockSlickEvent.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { SlickEvent, SlickEventHandler } from '@slickgrid-universal/common';
import { SlickEvent, SlickEventData, SlickEventHandler } from '@slickgrid-universal/common';

// interface PubSubEvent {
// name: string;
// handler: (args: any) => void;
// }

export class MockSlickEvent implements SlickEvent {
private _handlers = [];
private _handlers: any[] = [];

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

subscribe(handler: (data: any, e?: any) => void): any {
this._handlers.push(handler);
subscribe(fn: (data: any, e?: any) => void): any {
this._handlers.push(fn);
}

unsubscribe(handler: (data: any, e?: any) => void) {
unsubscribe(fn?: (e: SlickEventData | Event, data?: any) => void) {
this._handlers.forEach((handlerFn, index) => {
if (handlerFn === handler) {
if (handlerFn === fn) {
this._handlers.splice(index, 1);
}
});
}
}

export class MockSlickEventHandler implements SlickEventHandler {
private _handlers = [];
private _handlers: any[] = [];

notify(eventName: string, data?: any) {
const pubSub = this._handlers.find(subscription => subscription.name === eventName);
Expand Down
4 changes: 0 additions & 4 deletions test/translaterServiceStub.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { TranslaterService, TranslateServiceEventName } from '@slickgrid-universal/common';
import { I18N } from 'aurelia-i18n';

export class TranslaterServiceStub implements TranslaterService {
eventName = 'onLanguageChange' as TranslateServiceEventName;
private _locale = 'en';

constructor(private i18n?: I18N) { }

getCurrentLanguage(): string {
return this._locale;
}
Expand Down

0 comments on commit 8091790

Please sign in to comment.