Skip to content

Commit

Permalink
feat(plugins): sync column definitions to user after plugin adds colu…
Browse files Browse the repository at this point in the history
…mn (#781)

* feat(plugins): sync column definitions to user after add plugin columns
- for some extensions/plugins, that is RowDetail, RowMove, RowSelections, are adding extra columns dynamically when the grid is created and are not synced to the user, this PR will help with that but has to be implement differently in each lib wrappers (Angular, Aurelia, ...)
  • Loading branch information
ghiscoding authored Oct 25, 2022
1 parent 8ad54b5 commit 0755b65
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 175 deletions.
11 changes: 6 additions & 5 deletions examples/webpack-demo-vanilla-bundle/src/examples/example07.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,13 @@ export class Example7 {
this.sgb.columnDefinitions.pop();
this.sgb.columnDefinitions = this.sgb.columnDefinitions.slice();

// NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way
// you MUST use the code below, first you must reassign the Editor facade (from the internalColumnEditor back to the editor)
// in other words, SlickGrid is not using the same as Slickgrid-Universal uses (editor with a "model" and other properties are a facade, SlickGrid only uses what is inside the model)
// NOTE if you use an Extensions (Row Move, Row Detail, Row Selections) that modifies the column definitions in any way
// it will update the column definitions but only on the sgb instance, so you can use "this.sgb.columnDefinitions" to get full list.
// However please note that this will ALWAYS return all columns in their original positions,
// in other words, if you change column reordering, that unfortunately won't be reflected.
/*
const allColumns = this.slickerGridInstance.gridService.getAllColumnDefinitions();
const allOriginalColumns = allColumns.map((column) => {
const allOriginalColumns = this.sgb.columnDefinitions(); // or: this.slickerGridInstance.gridService.getAllColumnDefinitions();
const allOriginalColumns = allOriginalColumns.map((column) => {
column.editor = column.internalColumnEditor;
return column;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
AutocompleterOption,
BindingEventService,
Column,
EditCommand,
Editors,
EventNamingStyle,
FieldType,
Expand Down Expand Up @@ -84,7 +85,7 @@ export class Example14 {
isGridEditable = true;
classDefaultResizeButton = 'button is-small';
classNewResizeButton = 'button is-small is-selected is-primary';
editQueue = [];
editQueue: Array<{ item: any; columns: Column[]; editCommand: EditCommand }> = [];
editedItems = {};
sgb: SlickVanillaGridBundle;
gridContainerElm: HTMLDivElement;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'jest-extended';
import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';

import { SlickCheckboxSelectColumn } from '../slickCheckboxSelectColumn';
import { Column, OnSelectedRowsChangedEventArgs, SlickGrid, SlickNamespace, } from '../../interfaces/index';
import { SlickRowSelectionModel } from '../../extensions/slickRowSelectionModel';
Expand Down Expand Up @@ -66,6 +68,13 @@ const mockRowSelectionModel = {
onSelectedRangesChanged: new Slick.Event(),
} as unknown as SlickRowSelectionModel;

const pubSubServiceStub = {
publish: jest.fn(),
subscribe: jest.fn(),
unsubscribe: jest.fn(),
unsubscribeAll: jest.fn(),
} as BasePubSubService;

jest.mock('../../extensions/slickRowSelectionModel', () => ({
SlickRowSelectionModel: jest.fn().mockImplementation(() => mockRowSelectionModel),
}));
Expand All @@ -81,7 +90,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
let plugin: SlickCheckboxSelectColumn;

beforeEach(() => {
plugin = new SlickCheckboxSelectColumn();
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub);
jest.spyOn(gridStub.getEditorLock(), 'isActive').mockReturnValue(false);
jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit').mockReturnValue(true);
// jest.spyOn(gridStub, 'getSelectedRows').mockReturnValue([]);
Expand Down Expand Up @@ -203,17 +212,17 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
nodeElm.className = 'slick-headerrow-column';
const updateColHeaderSpy = jest.spyOn(gridStub, 'updateColumnHeader');

plugin = new SlickCheckboxSelectColumn({ hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, });
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub, { hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, });
plugin.init(gridStub);
gridStub.onHeaderRowCellRendered.notify({ column: { id: '_checkbox_selector', field: 'sel' }, node: nodeElm, grid: gridStub });
plugin.setOptions({ hideInColumnTitleRow: true, hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, });
let filterSelectAll = plugin.headerRowNode.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;
let filterSelectAll = plugin.headerRowNode!.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;

expect(plugin).toBeTruthy();
expect(updateColHeaderSpy).toHaveBeenCalledWith('_checkbox_selector', '', '');
expect(filterSelectAll.style.display).toEqual('flex');

filterSelectAll = plugin.headerRowNode.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;
filterSelectAll = plugin.headerRowNode!.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;
plugin.hideSelectAllFromColumnHeaderFilterRow();
expect(filterSelectAll.style.display).toEqual('none');
});
Expand Down Expand Up @@ -265,7 +274,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
jest.spyOn(gridStub, 'getSelectedRows').mockReturnValue([1, 2]);
const setActiveCellSpy = jest.spyOn(gridStub, 'setActiveCell');

plugin = new SlickCheckboxSelectColumn({ selectableOverride: () => false });
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub, { selectableOverride: () => false });
plugin.init(gridStub);
plugin.selectRows([2, 3]);
plugin.toggleRowSelection(2);
Expand Down Expand Up @@ -306,7 +315,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
});

it('should create a new row selection column definition', () => {
plugin = new SlickCheckboxSelectColumn();
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub);
plugin.init(gridStub);

expect(plugin.getColumnDefinition()).toEqual({
Expand All @@ -333,39 +342,42 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
const nodeElm = document.createElement('div');
nodeElm.className = 'slick-headerrow-column';

plugin = new SlickCheckboxSelectColumn({ hideInFilterHeaderRow: false, });
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub, { hideInFilterHeaderRow: false, });
plugin.init(gridStub);

gridStub.onHeaderRowCellRendered.notify({ column: { id: '_checkbox_selector', field: 'sel' }, node: nodeElm, grid: gridStub });
const checkboxContainerElm = nodeElm.querySelector('span#filter-checkbox-selectall-container');
const inputCheckboxElm = checkboxContainerElm.querySelector('input[type=checkbox]');
const checkboxContainerElm = nodeElm.querySelector('span#filter-checkbox-selectall-container') as HTMLDivElement;
const inputCheckboxElm = checkboxContainerElm.querySelector('input[type=checkbox]') as HTMLDivElement;
inputCheckboxElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true }));

expect(inputCheckboxElm).toBeTruthy();
expect(setSelectedRowSpy).toHaveBeenCalledWith([], 'click.unselectAll');
});

it('should call the "create" method and expect plugin to be created with checkbox column to be created at position 0 when using default', () => {
plugin.create(mockColumns, { checkboxSelector: { columnId: 'chk-id' } });

expect(plugin).toBeTruthy();
expect(mockColumns[0]).toEqual({
const pubSubSpy = jest.spyOn(pubSubServiceStub, 'publish');
const checkboxColumnMock = {
cssClass: null,
excludeFromColumnPicker: true,
excludeFromExport: true,
excludeFromGridMenu: true,
excludeFromHeaderMenu: true,
excludeFromQuery: true,
field: 'sel',
formatter: expect.toBeFunction(),
hideSelectAllCheckbox: false,
id: 'chk-id',
name: `<input id="header-selector${plugin.selectAllUid}" type="checkbox"><label for="header-selector${plugin.selectAllUid}"></label>`,
resizable: false,
sortable: false,
toolTip: 'Select/Deselect All',
width: 30,
});
};

plugin.create(mockColumns, { checkboxSelector: { columnId: 'chk-id' } });

expect(pubSubSpy).toHaveBeenCalledWith('onPluginColumnsChanged', { columns: expect.arrayContaining([{ ...checkboxColumnMock, formatter: expect.toBeFunction() }]), pluginName: 'CheckboxSelectColumn' });
expect(plugin).toBeTruthy();
expect(mockColumns[0]).toEqual(expect.objectContaining({ ...checkboxColumnMock, formatter: expect.toBeFunction() }));
});

it('should call the "create" method and expect plugin to be created at position 1 when defined', () => {
Expand Down Expand Up @@ -394,7 +406,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
it('should process the "checkboxSelectionFormatter" and expect necessary Formatter to return null when selectableOverride is returning False', () => {
plugin.selectableOverride(() => false);
plugin.create(mockColumns, {});
const output = plugin.getColumnDefinition().formatter(0, 0, null, { id: 'checkbox_selector', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);
const output = plugin.getColumnDefinition().formatter!(0, 0, null, { id: 'checkbox_selector', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);

expect(plugin).toBeTruthy();
expect(output).toEqual(null);
Expand All @@ -403,7 +415,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
it('should process the "checkboxSelectionFormatter" and expect necessary Formatter to return null when selectableOverride is returning False', () => {
plugin.init(gridStub);
plugin.selectableOverride(() => true);
const output = plugin.getColumnDefinition().formatter(0, 0, null, { id: 'checkbox_selector', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);
const output = plugin.getColumnDefinition().formatter!(0, 0, null, { id: 'checkbox_selector', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);

expect(plugin).toBeTruthy();
expect(output).toContain(`<input id="selector`);
Expand Down Expand Up @@ -529,7 +541,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
const setSelectedRowSpy = jest.spyOn(gridStub, 'setSelectedRows');
jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit').mockReturnValue(true);

plugin = new SlickCheckboxSelectColumn({ hideInColumnTitleRow: false, hideSelectAllCheckbox: false });
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub, { hideInColumnTitleRow: false, hideSelectAllCheckbox: false });
plugin.init(gridStub);
const checkboxElm = document.createElement('input');
checkboxElm.type = 'checkbox';
Expand All @@ -556,7 +568,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
const setSelectedRowSpy = jest.spyOn(gridStub, 'setSelectedRows');
jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit').mockReturnValue(true);

plugin = new SlickCheckboxSelectColumn({ hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, selectableOverride: () => false });
plugin = new SlickCheckboxSelectColumn(pubSubServiceStub, { hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, selectableOverride: () => false });
plugin.init(gridStub);
plugin.selectedRowsLookup = { 1: false, 2: true };

Expand Down
Loading

0 comments on commit 0755b65

Please sign in to comment.