| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import uniq from 'lodash/fp/uniq'; |
| import difference from 'lodash/difference'; |
| import findLast from 'lodash/findLast'; |
| |
| const hasGrouping = (changes) => { |
| return changes.gridApi.currentValue !== changes.gridApi.previousValue && changes.gridApi.currentValue.grouping; |
| }; |
| const id = (column) => column.categoryDisplayName || column.displayName || column.name; |
| const picksrc = (state) => state.categories.length ? state.categories : state.columns; |
| |
| export default class GridColumnSelectorController { |
| static $inject = ['$scope', 'uiGridConstants']; |
| |
| constructor($scope, uiGridConstants) { |
| Object.assign(this, {$scope, uiGridConstants}); |
| } |
| |
| $onChanges(changes) { |
| if (changes && 'gridApi' in changes && changes.gridApi.currentValue) { |
| this.applyValues(); |
| this.gridApi.grid.registerDataChangeCallback(() => this.applyValues(), [this.uiGridConstants.dataChange.COLUMN]); |
| if (hasGrouping(changes)) this.gridApi.grouping.on.groupingChanged(this.$scope, () => this.applyValues()); |
| } |
| } |
| |
| applyValues() { |
| this.state = this.getState(); |
| this.columnsMenu = this.makeMenu(); |
| this.selectedColumns = this.getSelectedColumns(); |
| this.setSelectedColumns(); |
| } |
| |
| getSelectedColumns() { |
| return picksrc(this.state).filter((i) => i.isVisible && i.isInMenu).map((i) => id(i.item)); |
| } |
| |
| makeMenu() { |
| return picksrc(this.state).filter((i) => i.isInMenu).map((i) => ({ |
| name: id(i.item), |
| item: i.item |
| })); |
| } |
| |
| getState() { |
| const api = this.gridApi; |
| const columns = api.grid.options.columnDefs; |
| const categories = api.grid.options.categories || []; |
| const grouping = api.grouping |
| ? api.grouping.getGrouping().grouping.map((g) => columns.find((c) => c.name === g.colName).categoryDisplayName) |
| : []; |
| const mapfn = (item) => ({ |
| item, |
| isInMenu: item.enableHiding !== false && !grouping.includes(item.name), |
| isVisible: grouping.includes(item.name) || item.visible !== false |
| }); |
| return ({ |
| categories: categories.map(mapfn), |
| columns: columns.map(mapfn) |
| }); |
| } |
| |
| findScrollToNext(columns, prevColumns) { |
| if (!prevColumns) |
| return; |
| |
| const diff = difference(columns, prevColumns); |
| |
| if (diff.length === 1 && columns.includes(diff[0])) |
| return diff[0]; |
| } |
| |
| setSelectedColumns() { |
| const {selectedColumns} = this; |
| const scrollToNext = this.findScrollToNext(selectedColumns, this.prevSelectedColumns); |
| this.prevSelectedColumns = selectedColumns; |
| const all = this.state.categories.concat(this.state.columns); |
| const itemsToShow = uniq(all.filter((i) => !i.isInMenu && i.isVisible).map((i) => id(i.item)).concat(selectedColumns)); |
| (this.gridApi.grid.options.categories || []).concat(this.gridApi.grid.options.columnDefs).forEach((item) => { |
| item.visible = itemsToShow.includes(id(item)); |
| }); |
| // Scrolls to the last matching columnDef, useful if it was out of view after being enabled. |
| this.refreshColumns().then(() => { |
| if (scrollToNext) { |
| const column = findLast(this.gridApi.grid.options.columnDefs, (c) => id(c) === scrollToNext); |
| this.gridApi.grid.scrollTo(null, column); |
| } |
| }); |
| } |
| |
| // gridApi.grid.refreshColumns method does not allow to wait until async operation completion. |
| // This method does roughly the same, but returns a Promise. |
| refreshColumns() { |
| return this.gridApi.grid.processColumnsProcessors(this.gridApi.grid.columns) |
| .then((renderableColumns) => this.gridApi.grid.setVisibleColumns(renderableColumns)) |
| .then(() => this.gridApi.grid.redrawInPlace()) |
| .then(() => this.gridApi.grid.refreshCanvas(true)); |
| } |
| } |