Skip to content

Commit

Permalink
fix(state): changeColumnsArrangement should work w/columnIndexPosition
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Jun 17, 2021
1 parent 1bb0358 commit 831773b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SortService } from '../sort.service';
import { TreeDataService } from '../treeData.service';
import {
BackendService,
CheckboxSelector,
CurrentFilter,
CurrentPagination,
CurrentPinning,
Expand All @@ -21,8 +22,11 @@ import {
GridState,
GridStateChange,
GridStateType,
RowDetailView,
RowMoveManager,
TreeToggleStateChange,
} from '../../models';
import { RowMoveManagerExtension } from '../../extensions';

declare const Slick: any;

Expand Down Expand Up @@ -165,9 +169,9 @@ describe('GridStateService', () => {

beforeEach(() => {
allColumnsMock = [
rowCheckboxColumnMock,
rowDetailColumnMock,
rowMoveColumnMock,
rowCheckboxColumnMock,
{ id: 'field1', field: 'field1', width: 100, cssClass: 'red' },
{ id: 'field2', field: 'field2', width: 150, headerCssClass: 'blue' },
{ id: 'field3', field: 'field3' },
Expand Down Expand Up @@ -196,14 +200,18 @@ describe('GridStateService', () => {
gridOptionMock.enableCheckboxSelector = true;
gridOptionMock.enableRowDetailView = true;
gridOptionMock.enableRowMoveManager = true;
gridOptionMock.rowDetailView = { columnIndexPosition: 0 } as unknown as RowDetailView;
gridOptionMock.rowMoveManager = { columnIndexPosition: 1 } as unknown as RowMoveManager;
gridOptionMock.checkboxSelector = { columnIndexPosition: 2 } as unknown as CheckboxSelector;

jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(allColumnsMock);
const setColsSpy = jest.spyOn(gridStub, 'setColumns');
const autoSizeSpy = jest.spyOn(gridStub, 'autosizeColumns');
const resizeByContentSpy = jest.spyOn(resizerServiceStub, 'resizeColumnsByCellContent');

service.changeColumnsArrangement(presetColumnsMock);

expect(setColsSpy).toHaveBeenCalledWith([rowCheckboxColumnMock, rowDetailColumnMock, rowMoveColumnMock, ...columnsWithoutCheckboxMock]);
expect(setColsSpy).toHaveBeenCalledWith([rowDetailColumnMock, rowMoveColumnMock, rowCheckboxColumnMock, ...columnsWithoutCheckboxMock]);
expect(autoSizeSpy).toHaveBeenCalled();
expect(resizeByContentSpy).not.toHaveBeenCalled();
});
Expand Down
12 changes: 6 additions & 6 deletions src/app/modules/angular-slickgrid/services/extension.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { SharedService } from './shared.service';

interface ExtensionWithColumnIndexPosition {
name: ExtensionName;
position: number;
columnIndexPosition: number;
extension: CheckboxSelectorExtension | RowDetailViewExtension | RowMoveManagerExtension;
}

Expand Down Expand Up @@ -286,23 +286,23 @@ export class ExtensionService {
* @param gridOptions
*/
createExtensionsBeforeGridCreation(columnDefinitions: Column[], gridOptions: GridOption) {
const featureWithColumnIndexPositions: { name: ExtensionName; position: number; extension: CheckboxSelectorExtension | RowDetailViewExtension | RowMoveManagerExtension; }[] = [];
const featureWithColumnIndexPositions: ExtensionWithColumnIndexPosition[] = [];

// the following 3 features might have `columnIndexPosition` that we need to respect their column order, we will execute them by their sort order further down
// we push them into a array and we'll process them by their position (if provided, else use same order that they were inserted)
if (gridOptions.enableCheckboxSelector) {
if (!this.getCreatedExtensionByName(ExtensionName.checkboxSelector)) {
featureWithColumnIndexPositions.push({ name: ExtensionName.checkboxSelector, extension: this.checkboxSelectorExtension, position: gridOptions?.checkboxSelector?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
featureWithColumnIndexPositions.push({ name: ExtensionName.checkboxSelector, extension: this.checkboxSelectorExtension, columnIndexPosition: gridOptions?.checkboxSelector?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
}
}
if (gridOptions.enableRowMoveManager) {
if (!this.getCreatedExtensionByName(ExtensionName.rowMoveManager)) {
featureWithColumnIndexPositions.push({ name: ExtensionName.rowMoveManager, extension: this.rowMoveManagerExtension, position: gridOptions?.rowMoveManager?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
featureWithColumnIndexPositions.push({ name: ExtensionName.rowMoveManager, extension: this.rowMoveManagerExtension, columnIndexPosition: gridOptions?.rowMoveManager?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
}
}
if (gridOptions.enableRowDetailView) {
if (!this.getCreatedExtensionByName(ExtensionName.rowDetailView)) {
featureWithColumnIndexPositions.push({ name: ExtensionName.rowDetailView, extension: this.rowDetailViewExtension, position: gridOptions?.rowDetailView?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
featureWithColumnIndexPositions.push({ name: ExtensionName.rowDetailView, extension: this.rowDetailViewExtension, columnIndexPosition: gridOptions?.rowDetailView?.columnIndexPosition ?? featureWithColumnIndexPositions.length });
}
}

Expand Down Expand Up @@ -462,7 +462,7 @@ export class ExtensionService {
*/
private createExtensionByTheirColumnIndex(featureWithIndexPositions: ExtensionWithColumnIndexPosition[], columnDefinitions: Column[], gridOptions: GridOption) {
// 1- first step is to sort them by their index position
featureWithIndexPositions.sort((feat1, feat2) => feat1.position - feat2.position);
featureWithIndexPositions.sort((feat1, feat2) => feat1.columnIndexPosition - feat2.columnIndexPosition);

// 2- second step, we can now proceed to create each extension/addon and that will position them accordingly in the column definitions list
featureWithIndexPositions.forEach(feature => {
Expand Down
51 changes: 33 additions & 18 deletions src/app/modules/angular-slickgrid/services/gridState.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,23 @@ export class GridStateService {
if (newArrangedColumns && Array.isArray(newArrangedColumns) && newArrangedColumns.length > 0) {
// make sure that the checkbox selector is still visible in the list when it is enabled
if (Array.isArray(this.sharedService.allColumns)) {
const dynamicAddonColumnByIndexPositionList: { columnId: string; columnIndexPosition: number; }[] = [];

if (this._gridOptions.enableCheckboxSelector) {
this.addColumnDynamicWhenFeatureEnabled('_checkbox_selector', this.sharedService.allColumns, newArrangedColumns);
const columnIndexPosition = this._gridOptions?.checkboxSelector?.columnIndexPosition ?? 0;
dynamicAddonColumnByIndexPositionList.push({ columnId: '_checkbox_selector', columnIndexPosition });
}
if (this._gridOptions.enableRowDetailView) {
this.addColumnDynamicWhenFeatureEnabled('_detail_selector', this.sharedService.allColumns, newArrangedColumns);
const columnIndexPosition = this._gridOptions?.rowDetailView?.columnIndexPosition ?? 0;
dynamicAddonColumnByIndexPositionList.push({ columnId: '_detail_selector', columnIndexPosition });
}
if (this._gridOptions.enableRowMoveManager) {
this.addColumnDynamicWhenFeatureEnabled('_move', this.sharedService.allColumns, newArrangedColumns);
const columnIndexPosition = this._gridOptions?.rowMoveManager?.columnIndexPosition ?? 0;
dynamicAddonColumnByIndexPositionList.push({ columnId: '_move', columnIndexPosition });
}

// since some features could have a `columnIndexPosition`, we need to make sure these indexes are respected in the column definitions
this.addColumnDynamicWhenFeatureEnabled(dynamicAddonColumnByIndexPositionList, this.sharedService.allColumns, newArrangedColumns);
}

// keep copy the original optional `width` properties optionally provided by the user.
Expand Down Expand Up @@ -475,21 +483,28 @@ export class GridStateService {
// ------------------

/**
* Add certain column(s), when the feature is/are enabled, to an output column definitions array (by reference).
* Basically some features (for example: Row Selection, Row Detail, Row Move) will be added as column(s) dynamically and internally by the lib,
* we just ask the developer to enable the feature, via flags, and internally the lib will create the necessary column.
* So specifically for these column(s) and feature(s), we need to re-add them internally when the user calls the `changeColumnsArrangement()` method.
* @param {String} dynamicColumnName - the column name that will be re-added (if it wasn't already found in the output array) dynamically
* @param {Array<Column>} fullColumnDefinitions - full column definitions array that includes every columns (including Row Selection, Row Detail, Row Move when enabled)
* @param {Array<Column>} newArrangedColumns - output array that will be use to show in the UI (it could have less columns than fullColumnDefinitions array since user might hide some columns)
*/
addColumnDynamicWhenFeatureEnabled(dynamicColumnName: string, fullColumnDefinitions: Column[], newArrangedColumns: Column[]) {
const checkboxColumnIdx = fullColumnDefinitions.findIndex(col => col.id === dynamicColumnName);
const associatedGridCheckboxColumnIdx = newArrangedColumns.findIndex(col => col.id === dynamicColumnName);
if (checkboxColumnIdx >= 0 && associatedGridCheckboxColumnIdx === -1) {
const checkboxColumn = fullColumnDefinitions[checkboxColumnIdx];
checkboxColumnIdx === 0 ? newArrangedColumns.unshift(checkboxColumn) : newArrangedColumns.splice(checkboxColumnIdx, 0, checkboxColumn);
}
* Add certain column(s), when the feature is/are enabled, to an output column definitions array (by reference).
* Basically some features (for example: Row Selection, Row Detail, Row Move) will be added as column(s) dynamically and internally by the lib,
* we just ask the developer to enable the feature, via flags, and internally the lib will create the necessary column.
* So specifically for these column(s) and feature(s), we need to re-add them internally when the user calls the `changeColumnsArrangement()` method.
* @param {Array<Object>} dynamicAddonColumnByIndexPositionList - array of plugin columnId and columnIndexPosition that will be re-added (if it wasn't already found in the output array) dynamically
* @param {Array<Column>} fullColumnDefinitions - full column definitions array that includes every columns (including Row Selection, Row Detail, Row Move when enabled)
* @param {Array<Column>} newArrangedColumns - output array that will be use to show in the UI (it could have less columns than fullColumnDefinitions array since user might hide some columns)
*/
private addColumnDynamicWhenFeatureEnabled(dynamicAddonColumnByIndexPositionList: Array<{ columnId: string; columnIndexPosition: number; }>, fullColumnDefinitions: Column[], newArrangedColumns: Column[]) {
// 1- first step is to sort them by their index position
dynamicAddonColumnByIndexPositionList.sort((feat1, feat2) => feat1.columnIndexPosition - feat2.columnIndexPosition);

// 2- second step, we can now proceed to create each extension/addon and that will position them accordingly in the column definitions list
dynamicAddonColumnByIndexPositionList.forEach(feature => {
const pluginColumnIdx = fullColumnDefinitions.findIndex(col => col.id === feature.columnId);
const associatedGridCheckboxColumnIdx = newArrangedColumns.findIndex(col => col.id === feature.columnId);

if (pluginColumnIdx >= 0 && associatedGridCheckboxColumnIdx === -1) {
const pluginColumn = fullColumnDefinitions[pluginColumnIdx];
pluginColumnIdx === 0 ? newArrangedColumns.unshift(pluginColumn) : newArrangedColumns.splice(pluginColumnIdx, 0, pluginColumn);
}
});
}

/**
Expand Down

0 comments on commit 831773b

Please sign in to comment.