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

Commit 1b2c17b

Browse files
authored
Merge pull request #724 from ghiscoding/feat/grid-state-pinning
feat(state): add Pinning (frozen) to Grid State & Presets
2 parents fb7dcd6 + 0ea9fb4 commit 1b2c17b

25 files changed

+414
-205
lines changed

src/app/examples/grid-state.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ export class GridStateComponent implements OnInit, OnDestroy {
157157
hideForceFitButton: true
158158
},
159159
gridMenu: {
160-
hideForceFitButton: true
160+
hideForceFitButton: true,
161+
hideClearFrozenColumnsCommand: false,
162+
},
163+
headerMenu: {
164+
hideFreezeColumnsCommand: false,
161165
},
162166
enablePagination: true,
163167
pagination: {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
SortService,
2222
TreeDataService,
2323
} from '../../services';
24-
import { Column, CurrentFilter, CurrentSorter, GraphqlPaginatedResult, GraphqlServiceApi, GraphqlServiceOption, GridOption, GridState, GridStateChange, GridStateType, Pagination, ServicePagination } from '../../models';
24+
import { Column, CurrentFilter, CurrentPinning, CurrentSorter, GraphqlPaginatedResult, GraphqlServiceApi, GraphqlServiceOption, GridOption, GridState, GridStateChange, GridStateType, Pagination, ServicePagination } from '../../models';
2525
import { Filters } from '../../filters';
2626
import { Editors } from '../../editors';
2727
import * as utilities from '../../services/backend-utilities';
@@ -847,6 +847,15 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
847847
expect(backendSpy).toHaveBeenCalledWith(mockColumnFilter, false);
848848
});
849849

850+
it('should override frozen grid options when "pinning" is defined in the "presets" property', () => {
851+
const pinningMock = { frozenBottom: false, frozenColumn: -1, frozenRow: -1 } as CurrentPinning;
852+
853+
component.gridOptions.presets = { pinning: pinningMock };
854+
component.ngAfterViewInit();
855+
856+
expect(component.gridOptions).toEqual({ ...component.gridOptions, ...pinningMock });
857+
});
858+
850859
it('should call the "updateFilters" method when filters are defined in the "presets" property', () => {
851860
const spy = jest.spyOn(mockGraphqlService, 'updateFilters');
852861
const mockFilters = [{ columnId: 'company', searchTerms: ['xyz'], operator: 'IN' }] as CurrentFilter[];

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,11 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
849849
this.sharedService.visibleColumns = this._columnDefinitions;
850850
this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this.gridOptions);
851851

852+
// if user entered some Pinning/Frozen "presets", we need to apply them in the grid options
853+
if (this.gridOptions.presets?.pinning) {
854+
this.gridOptions = { ...this.gridOptions, ...this.gridOptions.presets.pinning };
855+
}
856+
852857
// build SlickGrid Grid, also user might optionally pass a custom dataview (e.g. remote model)
853858
this.grid = new Slick.Grid(`#${this.gridId}`, this.customDataView || this.dataView, this._columnDefinitions, this.gridOptions);
854859

src/app/modules/angular-slickgrid/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class Constants {
88
TEXT_CLEAR_ALL_FILTERS: 'Clear all Filters',
99
TEXT_CLEAR_ALL_GROUPING: 'Clear all Grouping',
1010
TEXT_CLEAR_ALL_SORTING: 'Clear all Sorting',
11-
TEXT_CLEAR_FROZEN_COLUMNS: 'Clear Frozen Columns',
11+
TEXT_CLEAR_PINNING: 'Unfreeze Columns/Rows',
1212
TEXT_COLLAPSE_ALL_GROUPS: 'Collapse all Groups',
1313
TEXT_CONTAINS: 'Contains',
1414
TEXT_COLUMNS: 'Columns',

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

Lines changed: 105 additions & 105 deletions
Large diffs are not rendered by default.

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

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,17 @@ export class GridMenuExtension implements Extension {
216216
const gridOptions = this.sharedService.gridOptions;
217217
const translationPrefix = getTranslationPrefix(gridOptions);
218218

219-
// show grid menu: Clear Frozen Columns
219+
// show grid menu: Unfreeze Columns/Rows
220220
if (this.sharedService.gridOptions && this._gridMenuOptions && !this._gridMenuOptions.hideClearFrozenColumnsCommand) {
221-
const commandName = 'clear-frozen-columns';
221+
const commandName = 'clear-pinning';
222222
if (!originalCustomItems.find(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
223223
gridMenuCustomItems.push(
224224
{
225225
iconCssClass: this._gridMenuOptions.iconClearFrozenColumnsCommand || 'fa fa-times',
226-
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}CLEAR_FROZEN_COLUMNS`) : this._locales && this._locales.TEXT_CLEAR_FROZEN_COLUMNS,
226+
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}CLEAR_PINNING`) : this._locales && this._locales.TEXT_CLEAR_PINNING,
227227
disabled: false,
228228
command: commandName,
229-
positionOrder: 49
229+
positionOrder: 52
230230
}
231231
);
232232
}
@@ -259,7 +259,7 @@ export class GridMenuExtension implements Extension {
259259
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}TOGGLE_FILTER_ROW`) : this._locales && this._locales.TEXT_TOGGLE_FILTER_ROW,
260260
disabled: false,
261261
command: commandName,
262-
positionOrder: 52
262+
positionOrder: 53
263263
}
264264
);
265265
}
@@ -275,7 +275,7 @@ export class GridMenuExtension implements Extension {
275275
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}REFRESH_DATASET`) : this._locales && this._locales.TEXT_REFRESH_DATASET,
276276
disabled: false,
277277
command: commandName,
278-
positionOrder: 56
278+
positionOrder: 57
279279
}
280280
);
281281
}
@@ -293,7 +293,7 @@ export class GridMenuExtension implements Extension {
293293
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}TOGGLE_PRE_HEADER_ROW`) : this._locales && this._locales.TEXT_TOGGLE_PRE_HEADER_ROW,
294294
disabled: false,
295295
command: commandName,
296-
positionOrder: 52
296+
positionOrder: 53
297297
}
298298
);
299299
}
@@ -328,7 +328,7 @@ export class GridMenuExtension implements Extension {
328328
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}EXPORT_TO_CSV`) : this._locales && this._locales.TEXT_EXPORT_TO_CSV,
329329
disabled: false,
330330
command: commandName,
331-
positionOrder: 53
331+
positionOrder: 54
332332
}
333333
);
334334
}
@@ -344,7 +344,7 @@ export class GridMenuExtension implements Extension {
344344
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}EXPORT_TO_EXCEL`) : this._locales && this._locales.TEXT_EXPORT_TO_EXCEL,
345345
disabled: false,
346346
command: commandName,
347-
positionOrder: 54
347+
positionOrder: 55
348348
}
349349
);
350350
}
@@ -360,7 +360,7 @@ export class GridMenuExtension implements Extension {
360360
title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant(`${translationPrefix}EXPORT_TO_TAB_DELIMITED`) : this._locales && this._locales.TEXT_EXPORT_TO_TAB_DELIMITED,
361361
disabled: false,
362362
command: commandName,
363-
positionOrder: 55
363+
positionOrder: 56
364364
}
365365
);
366366
}
@@ -383,15 +383,25 @@ export class GridMenuExtension implements Extension {
383383
private executeGridMenuInternalCustomCommands(e: Event, args: GridMenuItem) {
384384
if (args && args.command) {
385385
switch (args.command) {
386-
case 'clear-frozen-columns':
386+
case 'clear-pinning':
387387
const visibleColumns = [...this.sharedService.visibleColumns];
388-
this.sharedService.grid.setOptions({ frozenColumn: -1, enableMouseWheelScrollHandler: false });
388+
const newGridOptions = { frozenColumn: -1, frozenRow: -1, frozenBottom: false, enableMouseWheelScrollHandler: false };
389+
this.sharedService.grid.setOptions(newGridOptions);
390+
this.sharedService.gridOptions.frozenColumn = newGridOptions.frozenColumn;
391+
this.sharedService.gridOptions.frozenRow = newGridOptions.frozenRow;
392+
this.sharedService.gridOptions.frozenBottom = newGridOptions.frozenBottom;
393+
this.sharedService.gridOptions.enableMouseWheelScrollHandler = newGridOptions.enableMouseWheelScrollHandler;
389394

390395
// SlickGrid seems to be somehow resetting the columns to their original positions,
391396
// so let's re-fix them to the position we kept as reference
392397
if (Array.isArray(visibleColumns)) {
393398
this.sharedService.grid.setColumns(visibleColumns);
394399
}
400+
401+
// we also need to autosize columns if the option is enabled
402+
if (this.sharedService.gridOptions.enableAutoSizeColumns) {
403+
this.sharedService.grid.autosizeColumns();
404+
}
395405
break;
396406
case 'clear-filter':
397407
this.filterService.clearFilters();

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,22 @@ export class HeaderMenuExtension implements Extension {
344344
case 'freeze-columns':
345345
const visibleColumns = [...this.sharedService.visibleColumns];
346346
const columnPosition = visibleColumns.findIndex((col) => col.id === args.column.id);
347-
this.sharedService.grid.setOptions({ frozenColumn: columnPosition, enableMouseWheelScrollHandler: true } as GridOption);
347+
const newGridOptions = { frozenColumn: columnPosition, enableMouseWheelScrollHandler: true };
348+
this.sharedService.grid.setOptions(newGridOptions);
349+
this.sharedService.gridOptions.frozenColumn = newGridOptions.frozenColumn;
350+
this.sharedService.gridOptions.enableMouseWheelScrollHandler = newGridOptions.enableMouseWheelScrollHandler;
348351
this.sharedService.frozenVisibleColumnId = args.column.id;
349352

350353
// to freeze columns, we need to take only the visible columns and we also need to use setColumns() when some of them are hidden
351354
// to make sure that we only use the visible columns, not doing this will have the undesired effect of showing back some of the hidden columns
352355
if (this.sharedService.hasColumnsReordered || (Array.isArray(this.sharedService.allColumns) && visibleColumns.length !== this.sharedService.allColumns.length)) {
353356
this.sharedService.grid.setColumns(visibleColumns);
354357
}
358+
359+
// we also need to autosize columns if the option is enabled
360+
if (this.sharedService.gridOptions.enableAutoSizeColumns) {
361+
this.sharedService.grid.autosizeColumns();
362+
}
355363
break;
356364
case 'sort-asc':
357365
case 'sort-desc':
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface CurrentPinning {
2+
/** Defaults to false, do we want to freeze (pin) the bottom portion instead of the top */
3+
frozenBottom?: boolean;
4+
5+
/** Number of column index(es) to freeze (pin) in the grid */
6+
frozenColumn?: number;
7+
8+
/** Number of row index(es) to freeze (pin) in the grid */
9+
frozenRow?: number;
10+
}

src/app/modules/angular-slickgrid/models/gridMenu.interface.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface GridMenu {
3737
/** Defaults to false, which will hide the "Clear all Sorting" command in the Grid Menu (Grid Option "enableSorting: true" has to be enabled) */
3838
hideClearAllSortingCommand?: boolean;
3939

40-
/** Defaults to true, which will hide the "Clear Frozen Columns" command in the Grid Menu */
40+
/** Defaults to true, which will hide the "Unfreeze Columns/Rows" command in the Grid Menu */
4141
hideClearFrozenColumnsCommand?: boolean;
4242

4343
/** Defaults to false, which will hide the "Export to CSV" command in the Grid Menu (Grid Option "enableExport: true" has to be enabled) */
@@ -73,7 +73,7 @@ export interface GridMenu {
7373
/** icon for the "Clear all Sorting" command */
7474
iconClearAllSortingCommand?: string;
7575

76-
/** icon for the "Clear Frozen Columns" command */
76+
/** icon for the "Unfreeze Columns/Rows" command */
7777
iconClearFrozenColumnsCommand?: string;
7878

7979
/** icon for the "Export to CSV" command */

src/app/modules/angular-slickgrid/models/gridOption.interface.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,10 @@ export interface GridOption {
333333
/** Defaults to false, do we want to freeze (pin) the bottom portion instead of the top */
334334
frozenBottom?: boolean;
335335

336-
/** Number of column(s) to freeze (pin) in the grid */
336+
/** Number of column index(es) to freeze (pin) in the grid */
337337
frozenColumn?: number;
338338

339-
/** Number of row(s) to freeze (pin) in the grid */
339+
/** Number of row index(es) to freeze (pin) in the grid */
340340
frozenRow?: number;
341341

342342
/** Defaults to false, which leads to have row with full width */

0 commit comments

Comments
 (0)