Skip to content

Commit 996125d

Browse files
authored
fix(pinning): recalculate frozen idx properly when column shown changes (#682)
- when using ColumnPicker, GridMenu or hiding a column via HeaderMenu, it has to recalculate the frozenColumn index because SlickGrid doesn't take care of that and the previous fix that I implement sometimes become out of sync. This PR simplifies the frozenColumn index position, it will simply update it when the index is different, as simple as that.
1 parent ceb0d77 commit 996125d

File tree

7 files changed

+27
-40
lines changed

7 files changed

+27
-40
lines changed

src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ describe('columnPickerExtension', () => {
132132
{ notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
133133
expect.anything()
134134
);
135-
expect(readjustSpy).toHaveBeenCalledWith('field1', 0, false, columnsMock, columnsMock.slice(0, 1));
135+
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock.slice(0, 1));
136136
});
137137

138138
it('should dispose of the addon', () => {

src/app/modules/angular-slickgrid/extensions/__tests__/extensionUtility.spec.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -156,42 +156,42 @@ describe('ExtensionUtility', () => {
156156
jest.clearAllMocks();
157157
});
158158

159-
it('should increase "frozenColumn" from 0 to 1 when showing a column that was previously hidden and its index is lower or equal to provided argument (2nd arg, frozenColumnIndex)', () => {
159+
it('should increase "frozenColumn" from 0 to 1 when showing a column that was previously hidden and its index is lower or equal to provided argument of frozenColumnIndex', () => {
160160
const allColumns = [{ id: 'field1' }, { id: 'field2' }, { id: 'field3' }] as Column[];
161161
const visibleColumns = [{ id: 'field1' }, { id: 'field2' }] as Column[];
162162
const setOptionSpy = jest.spyOn(SharedService.prototype.grid, 'setOptions');
163163

164-
utility.readjustFrozenColumnIndexWhenNeeded('field1', 0, true, allColumns, visibleColumns);
164+
utility.readjustFrozenColumnIndexWhenNeeded(0, allColumns, visibleColumns);
165165

166166
expect(setOptionSpy).toHaveBeenCalledWith({ frozenColumn: 1 });
167167
});
168168

169-
it('should keep "frozenColumn" at 0 when showing a column that was previously hidden and its index is greater than provided argument (2nd arg, frozenColumnIndex)', () => {
170-
const allColumns = [{ id: 'field1' }, { id: 'field2' }, { id: 'field3' }] as Column[];
169+
it('should keep "frozenColumn" at 1 when showing a column that was previously hidden and its index is greater than provided argument of frozenColumnIndex', () => {
170+
const allColumns = [{ id: 'field1' }, { id: 'field2' }] as Column[];
171171
const visibleColumns = [{ id: 'field1' }, { id: 'field2' }, { id: 'field3' }] as Column[];
172172
const setOptionSpy = jest.spyOn(SharedService.prototype.grid, 'setOptions');
173173

174-
utility.readjustFrozenColumnIndexWhenNeeded('field3', 0, true, allColumns, visibleColumns);
174+
utility.readjustFrozenColumnIndexWhenNeeded(1, allColumns, visibleColumns);
175175

176176
expect(setOptionSpy).not.toHaveBeenCalled();
177177
});
178178

179-
it('should decrease "frozenColumn" from 1 to 0 when hiding a column that was previously shown and its index is lower or equal to provided argument (2nd arg, frozenColumnIndex)', () => {
179+
it('should decrease "frozenColumn" from 1 to 0 when hiding a column that was previously shown and its index is lower or equal to provided argument of frozenColumnIndex', () => {
180180
const allColumns = [{ id: 'field1' }, { id: 'field2' }, { id: 'field3' }] as Column[];
181-
const visibleColumns = [{ id: 'field1' }, { id: 'field2' }] as Column[];
181+
const visibleColumns = [{ id: 'field2' }] as Column[];
182182
const setOptionSpy = jest.spyOn(SharedService.prototype.grid, 'setOptions');
183183

184-
utility.readjustFrozenColumnIndexWhenNeeded('field1', 1, false, allColumns, visibleColumns);
184+
utility.readjustFrozenColumnIndexWhenNeeded(1, allColumns, visibleColumns);
185185

186186
expect(setOptionSpy).toHaveBeenCalledWith({ frozenColumn: 0 });
187187
});
188188

189-
it('should keep "frozenColumn" at 1 when hiding a column that was previously hidden and its index is greater than provided argument (2nd arg, frozenColumnIndex)', () => {
189+
it('should keep "frozenColumn" at 1 when hiding a column that was previously hidden and its index is greater than provided argument of frozenColumnIndex', () => {
190190
const allColumns = [{ id: 'field1' }, { id: 'field2' }, { id: 'field3' }] as Column[];
191191
const visibleColumns = [{ id: 'field1' }, { id: 'field2' }] as Column[];
192192
const setOptionSpy = jest.spyOn(SharedService.prototype.grid, 'setOptions');
193193

194-
utility.readjustFrozenColumnIndexWhenNeeded('field3', 1, false, allColumns, visibleColumns);
194+
utility.readjustFrozenColumnIndexWhenNeeded(1, allColumns, visibleColumns);
195195

196196
expect(setOptionSpy).not.toHaveBeenCalled();
197197
});
@@ -201,7 +201,7 @@ describe('ExtensionUtility', () => {
201201
const visibleColumns = [{ id: 'field1' }, { field: 'field2' }] as Column[];
202202
const setOptionSpy = jest.spyOn(SharedService.prototype.grid, 'setOptions');
203203

204-
utility.readjustFrozenColumnIndexWhenNeeded('fiel3', 0, true, allColumns, visibleColumns);
204+
utility.readjustFrozenColumnIndexWhenNeeded(0, allColumns, visibleColumns);
205205

206206
expect(setOptionSpy).not.toHaveBeenCalled();
207207
});

src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ describe('gridMenuExtension', () => {
253253
{ notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
254254
expect.anything()
255255
);
256-
expect(readjustSpy).toHaveBeenCalledWith('field1', 0, false, columnsMock, columnsMock.slice(0, 1));
256+
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock.slice(0, 1));
257257
});
258258

259259
it('should call internal event handler subscribe and expect the "onBeforeMenuShow" option to be called when addon notify is called', () => {
@@ -355,8 +355,8 @@ describe('gridMenuExtension', () => {
355355
const autoSizeSpy = jest.spyOn(gridStub, 'autosizeColumns');
356356

357357
const instance = extension.register();
358-
instance.onColumnsChanged.notify(columnsMock.slice(0, 1), new Slick.EventData(), gridStub);
359-
instance.onMenuClose.notify({ grid: gridStub, menu: {} }, new Slick.EventData(), gridStub);
358+
instance.onColumnsChanged.notify({ columnId: 'field1', showing: true, grid: gridStub, allColumns: columnsMock, columns: columnsMock.slice(0, 1) }, new Slick.EventData(), gridStub);
359+
instance.onMenuClose.notify({ allColumns: columnsMock, visibleColumns: columnsMock, grid: gridStub }, new Slick.EventData(), gridStub);
360360

361361
expect(handlerSpy).toHaveBeenCalled();
362362
expect(onCloseSpy).toHaveBeenCalled();

src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ export class ColumnPickerExtension implements Extension {
6666
// we need to readjust frozenColumn index because SlickGrid freezes by index and has no knowledge of the columns themselves
6767
const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn !== undefined ? this.sharedService.gridOptions.frozenColumn : -1;
6868
if (frozenColumnIndex >= 0) {
69-
const { showing: isColumnShown, columnId, allColumns, columns: visibleColumns } = args;
70-
this.extensionUtility.readjustFrozenColumnIndexWhenNeeded(columnId, frozenColumnIndex, isColumnShown, allColumns, visibleColumns);
69+
const { allColumns, columns: visibleColumns } = args;
70+
this.extensionUtility.readjustFrozenColumnIndexWhenNeeded(frozenColumnIndex, allColumns, visibleColumns);
7171
}
7272
});
7373
}

src/app/modules/angular-slickgrid/extensions/extensionUtility.ts

+5-18
Original file line numberDiff line numberDiff line change
@@ -75,28 +75,15 @@ export class ExtensionUtility {
7575
* When using ColumnPicker/GridMenu to show/hide a column, we potentially need to readjust the grid option "frozenColumn" index.
7676
* That is because SlickGrid freezes by column index and it has no knowledge of the columns themselves and won't change the index, we need to do that ourselves whenever necessary.
7777
* Note: we call this method right after the visibleColumns array got updated, it won't work properly if we call it before the setting the visibleColumns.
78-
* @param {String} pickerColumnId - what is the column id triggered by the picker
7978
* @param {Number} frozenColumnIndex - current frozenColumn index
80-
* @param {Boolean} showingColumn - is the column being shown or hidden?
8179
* @param {Array<Object>} allColumns - all columns (including hidden ones)
8280
* @param {Array<Object>} visibleColumns - only visible columns (excluding hidden ones)
8381
*/
84-
readjustFrozenColumnIndexWhenNeeded(pickerColumnId: string | number, frozenColumnIndex: number, showingColumn: boolean, allColumns: Column[], visibleColumns: Column[]) {
85-
if (frozenColumnIndex >= 0 && pickerColumnId) {
86-
// calculate a possible frozenColumn index variance
87-
let frozenColIndexVariance = 0;
88-
if (showingColumn) {
89-
const definedFrozenColumnIndex = visibleColumns.findIndex(col => col.id === this.sharedService.frozenVisibleColumnId);
90-
const columnIndex = visibleColumns.findIndex(col => col.id === pickerColumnId);
91-
frozenColIndexVariance = (columnIndex >= 0 && (frozenColumnIndex >= columnIndex || definedFrozenColumnIndex === columnIndex)) ? 1 : 0;
92-
} else {
93-
const columnIndex = allColumns.findIndex(col => col.id === pickerColumnId);
94-
frozenColIndexVariance = (columnIndex >= 0 && frozenColumnIndex >= columnIndex) ? -1 : 0;
95-
}
96-
// if we have a variance different than 0 then apply it
97-
const newFrozenColIndex = frozenColumnIndex + frozenColIndexVariance;
98-
if (frozenColIndexVariance !== 0) {
99-
this.sharedService.grid.setOptions({ frozenColumn: newFrozenColIndex });
82+
readjustFrozenColumnIndexWhenNeeded(frozenColumnIndex: number, allColumns: Column[], visibleColumns: Column[]) {
83+
if (frozenColumnIndex >= 0) {
84+
const recalculatedFrozenColumnIndex = visibleColumns.findIndex(col => col.id === this.sharedService.frozenVisibleColumnId);
85+
if (recalculatedFrozenColumnIndex >= 0 && recalculatedFrozenColumnIndex !== frozenColumnIndex) {
86+
this.sharedService.grid.setOptions({ frozenColumn: recalculatedFrozenColumnIndex });
10087
}
10188

10289
// to freeze columns, we need to take only the visible columns and we also need to use setColumns() when some of them are hidden

src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ export class GridMenuExtension implements Extension {
124124
// we need to readjust frozenColumn index because SlickGrid freezes by index and has no knowledge of the columns themselves
125125
const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn !== undefined ? this.sharedService.gridOptions.frozenColumn : -1;
126126
if (frozenColumnIndex >= 0) {
127-
const { showing: isColumnShown, columnId, allColumns, columns: visibleColumns } = args;
128-
this.extensionUtility.readjustFrozenColumnIndexWhenNeeded(columnId, frozenColumnIndex, isColumnShown, allColumns, visibleColumns);
127+
const { allColumns, columns: visibleColumns } = args;
128+
this.extensionUtility.readjustFrozenColumnIndexWhenNeeded(frozenColumnIndex, allColumns, visibleColumns);
129129
}
130130
});
131131
this._eventHandler.subscribe(this._addon.onCommand, (e: any, args: MenuCommandItemCallbackArgs) => {

src/app/modules/angular-slickgrid/extensions/headerMenuExtension.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -219,17 +219,17 @@ export class HeaderMenuExtension implements Extension {
219219
hideColumn(column: Column) {
220220
if (this.sharedService.grid && this.sharedService.grid.getColumns && this.sharedService.grid.setColumns && this.sharedService.grid.getColumnIndex) {
221221
const columnIndex = this.sharedService.grid.getColumnIndex(column.id);
222-
const currentColumns = this.sharedService.grid.getColumns() as Column[];
222+
const currentVisibleColumns = this.sharedService.grid.getColumns() as Column[];
223223

224224
// if we're using frozen columns, we need to readjust pinning when the new hidden column is on the left pinning container
225225
// we need to do this because SlickGrid freezes by index and has no knowledge of the columns themselves
226-
const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn || -1;
226+
const frozenColumnIndex = this.sharedService.gridOptions.frozenColumn !== undefined ? this.sharedService.gridOptions.frozenColumn : -1;
227227
if (frozenColumnIndex >= 0 && frozenColumnIndex >= columnIndex) {
228228
this.sharedService.grid.setOptions({ frozenColumn: frozenColumnIndex - 1 });
229229
}
230230

231231
// then proceed with hiding the column in SlickGrid & trigger an event when done
232-
const visibleColumns = arrayRemoveItemByIndex(currentColumns, columnIndex);
232+
const visibleColumns = arrayRemoveItemByIndex(currentVisibleColumns, columnIndex);
233233
this.sharedService.visibleColumns = visibleColumns;
234234
this.sharedService.grid.setColumns(visibleColumns);
235235
this.sharedService.onHeaderMenuHideColumns.next(visibleColumns);

0 commit comments

Comments
 (0)