diff --git a/CHANGELOG.md b/CHANGELOG.md index 2320dbcdbe..59217b7dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ handling of millions with `m`. * Enhancements to admin log viewer. Log file metadata (size & last modified) available with optional upgrade to `hoist-core >= 13.2`. +* Added `GridModel.hideGroupedColumns` and `GridModel.showUngroupedColumns` to manage visibility of + columns when grouped and ungrouped. Both default to true. ### 💥 Breaking Changes @@ -32,6 +34,9 @@ that adds an empty line beneath the range pasted from the clipboard in editable grids. * Fixes an issue where NumberInput would initially render blank values when `max` and `min` were set. * Fixes an issue where tree maps would always show green for a `heatValue` of zero. +* Set ag-Grid's `suppressMakeColumnVisibleAfterUnGroup` to `true` to avoid unwanted visibility state + changes when `Column.excludeFromChooser` is set to `true`. New `GridModel.hideGroupedColumns` and + `GridModel.showUngroupedColumns` will not affect columns that have their visibility or hidden states locked. ### 📚 Libraries diff --git a/cmp/grid/Grid.js b/cmp/grid/Grid.js index 08a0234ce5..436a993dab 100644 --- a/cmp/grid/Grid.js +++ b/cmp/grid/Grid.js @@ -232,6 +232,7 @@ class GridLocalModel extends HoistModel { navigateToNextCell: this.navigateToNextCell, processCellForClipboard: this.processCellForClipboard, defaultGroupOrderComparator: model.groupSortFn ? this.groupSortComparator : undefined, + suppressMakeColumnVisibleAfterUnGroup: true, groupDefaultExpanded: 1, groupDisplayType: 'groupRows', groupRowRenderer: model.groupRowElementRenderer, diff --git a/cmp/grid/GridModel.js b/cmp/grid/GridModel.js index 34f01363fe..3754daa929 100644 --- a/cmp/grid/GridModel.js +++ b/cmp/grid/GridModel.js @@ -32,6 +32,7 @@ import { compact, defaults, defaultsDeep, + difference, find, forEach, isArray, @@ -102,6 +103,10 @@ export class GridModel extends HoistModel { /** @member {boolean} */ showGroupRowCounts; /** @member {boolean} */ + hideGroupedColumns; + /** @member {boolean} */ + showUngroupedColumns; + /** @member {boolean} */ enableColumnPinning; /** @member {boolean} */ enableExport; @@ -267,6 +272,8 @@ export class GridModel extends HoistModel { * @param {GridGroupSortFn} [c.groupSortFn] - function to use to sort full-row groups. * Called with two group values to compare in the form of a standard JS comparator. * Default is an ascending string sort. Set to `null` to prevent sorting of groups. + * @param {boolean} [c.hideGroupedColumns] - true to hide grouped columns. Default true. + * @param {boolean} [c.showUngroupedColumns] - true to show ungrouped columns. Default true. * @param {function} [c.onKeyDown] - Callback when a key down event is detected on the * grid. Function will receive an event with the standard 'target' element. Note that * the ag-Grid API provides limited ability to customize keyboard handling. This handler @@ -352,6 +359,8 @@ export class GridModel extends HoistModel { groupRowRenderer, groupRowElementRenderer, groupSortFn, + hideGroupedColumns = true, + showUngroupedColumns = true, onKeyDown, onRowClicked, @@ -389,6 +398,8 @@ export class GridModel extends HoistModel { this.groupRowElementRenderer = groupRowElementRenderer; this.groupSortFn = withDefault(groupSortFn, this.defaultGroupSortFn); this.showGroupRowCounts = showGroupRowCounts; + this.hideGroupedColumns = hideGroupedColumns; + this.showUngroupedColumns = showUngroupedColumns; this.contextMenu = withDefault(contextMenu, GridModel.defaultContextMenu); this.useVirtualColumns = useVirtualColumns; this.externalSort = externalSort; @@ -708,13 +719,33 @@ export class GridModel extends HoistModel { @action setGroupBy(colIds) { colIds = isNil(colIds) ? [] : castArray(colIds); + const getCol = (colId) => this.findColumn(this.columns, colId), + invalidColIds = colIds.filter(it => !getCol(it)); - const invalidColIds = colIds.filter(it => !this.findColumn(this.columns, it)); if (invalidColIds.length) { console.warn('Unknown colId specified in groupBy - grid will not be grouped.', invalidColIds); colIds = []; } + // Set column visibility as specified, respecting locked visible/hidden states. + const {groupBy, hideGroupedColumns, showUngroupedColumns, colChooserModel} = this, + ungroupedColIds = difference(groupBy, colIds); + + colIds.forEach(it => { + if (getCol(it).lockVisible) return; + if (hideGroupedColumns) this.hideColumn(it); + }); + + ungroupedColIds.forEach(it => { + const col = getCol(it); + if (col.lockHidden) return; + if (showUngroupedColumns) this.showColumn(it); + + if (!showUngroupedColumns && hideGroupedColumns && (col.excludeFromChooser || !colChooserModel)) { + console.warn('Column cannot be made visible after grouping due to GridModel and/or Column configuration. colId:', col.colId); + } + }); + this.groupBy = colIds; } diff --git a/cmp/grid/columns/Column.js b/cmp/grid/columns/Column.js index bf3ad7086f..ab415b8952 100644 --- a/cmp/grid/columns/Column.js +++ b/cmp/grid/columns/Column.js @@ -94,7 +94,7 @@ export class Column { align; /** @member {boolean} */ - hidden + hidden; /** @member {(boolean|number)} */ flex; /** @member {number} */ @@ -275,8 +275,8 @@ export class Column { * @param {string} [c.chooserName] - name to display within the column chooser component. * Defaults to `displayName`, can be longer / less abbreviated than `headerName` might be. * @param {string} [c.chooserGroup] - group name to display within the column chooser - * component. - * Chooser will automatically group its "available columns" grid if any cols provide. + * component. Chooser will automatically group its "available columns" grid if any cols + * provide. * @param {string} [c.chooserDescription] - additional descriptive text to display within the * column chooser. Appears when the column is selected within the chooser UI. * @param {boolean} [c.excludeFromChooser] - true to hide the column from the column chooser @@ -504,6 +504,16 @@ export class Column { warnIf(this.agOptions.valueGetter, `Column '${this.colId}' uses valueGetter through agOptions. Remove and use custom getValueFn if needed.`); } + /** @return {boolean} - true if column should always remain visible */ + get lockVisible() { + return !this.hideable || !this.gridModel.colChooserModel; + } + + /** @return {boolean} - true if column is initialized as hidden and cannot be made visible via ChooserModel. */ + get lockHidden() { + return this.hidden && (this.excludeFromChooser || !this.gridModel.colChooserModel); + } + /** * @param {StoreRecord} record * @return {boolean} - true if this column supports editing its field for the given StoreRecord. @@ -540,7 +550,7 @@ export class Column { suppressMovable: !this.movable, lockPinned: !gridModel.enableColumnPinning || XH.isMobileApp, pinned: this.pinned, - lockVisible: !this.hideable || !gridModel.colChooserModel || XH.isMobileApp, + lockVisible: this.lockVisible || XH.isMobileApp, headerComponentParams: {gridModel, xhColumn: this}, suppressColumnsToolPanel: this.excludeFromChooser, suppressFiltersToolPanel: this.excludeFromChooser,