| /* |
| * 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 debounce from 'lodash/debounce'; |
| import headerTemplate from 'app/primitives/ui-grid-header/index.tpl.pug'; |
| |
| import ResizeObserver from 'resize-observer-polyfill'; |
| |
| export default class IgniteUiGrid { |
| /** @type {import('ui-grid').IGridOptions} */ |
| grid; |
| |
| /** @type */ |
| gridApi; |
| |
| /** @type */ |
| gridThin; |
| |
| /** @type */ |
| gridHeight; |
| |
| /** @type */ |
| items; |
| |
| /** @type */ |
| columnDefs; |
| |
| /** @type */ |
| categories; |
| |
| /** @type {boolean} */ |
| singleSelect; |
| |
| /** @type */ |
| onSelectionChange; |
| |
| /** @type */ |
| selectedRows; |
| |
| /** @type */ |
| selectedRowsId; |
| |
| /** @type */ |
| _selected; |
| |
| static $inject = ['$scope', '$element', '$timeout', 'gridUtil']; |
| |
| /** |
| * @param {ng.IScope} $scope |
| * @param $element |
| * @param $timeout |
| * @param gridUtil |
| */ |
| constructor($scope, $element, $timeout, gridUtil) { |
| this.$scope = $scope; |
| this.$element = $element; |
| this.$timeout = $timeout; |
| this.gridUtil = gridUtil; |
| |
| this.rowIdentityKey = '_id'; |
| |
| this.rowHeight = 48; |
| this.headerRowHeight = 70; |
| } |
| |
| $onInit() { |
| this.SCROLLBAR_WIDTH = this.gridUtil.getScrollbarWidth(); |
| |
| if (this.gridThin) { |
| this.rowHeight = 36; |
| this.headerRowHeight = 48; |
| } |
| |
| this.grid = { |
| appScopeProvider: this.$scope.$parent, |
| data: this.items, |
| columnDefs: this.columnDefs, |
| categories: this.categories, |
| rowHeight: this.rowHeight, |
| multiSelect: !this.singleSelect, |
| enableSelectAll: !this.singleSelect, |
| headerRowHeight: this.headerRowHeight, |
| columnVirtualizationThreshold: 30, |
| enableColumnMenus: false, |
| enableFullRowSelection: true, |
| enableFiltering: true, |
| enableRowHashing: false, |
| fastWatch: true, |
| showTreeExpandNoChildren: false, |
| modifierKeysToMultiSelect: true, |
| selectionRowHeaderWidth: 52, |
| exporterCsvColumnSeparator: ';', |
| onRegisterApi: (api) => { |
| this.gridApi = api; |
| |
| api.core.on.rowsVisibleChanged(this.$scope, () => { |
| this.adjustHeight(); |
| |
| // Without property existence check non-set selectedRows or selectedRowsId |
| // binding might cause unwanted behavior, |
| // like unchecking rows during any items change, |
| // even if nothing really changed. |
| if (this._selected && this._selected.length && this.onSelectionChange) { |
| this.applyIncomingSelectionRows(this._selected); |
| |
| // Change selected rows if filter was changed. |
| this.onRowsSelectionChange([]); |
| } |
| }); |
| |
| if (this.onSelectionChange) { |
| api.selection.on.rowSelectionChanged(this.$scope, (row, e) => { |
| this.onRowsSelectionChange([row], e); |
| }); |
| |
| api.selection.on.rowSelectionChangedBatch(this.$scope, (rows, e) => { |
| this.onRowsSelectionChange(rows, e); |
| }); |
| } |
| |
| api.core.on.filterChanged(this.$scope, (column) => { |
| this.onFilterChange(column); |
| }); |
| |
| this.$timeout(() => { |
| if (this.selectedRowsId) this.applyIncomingSelectionRowsId(this.selectedRowsId); |
| }); |
| |
| this.resizeObserver = new ResizeObserver(() => api.core.handleWindowResize()); |
| this.resizeObserver.observe(this.$element[0]); |
| |
| if (this.onApiRegistered) |
| this.onApiRegistered({$event: api}); |
| } |
| }; |
| |
| if (this.grid.categories) |
| this.grid.headerTemplate = headerTemplate; |
| } |
| |
| $onChanges(changes) { |
| const hasChanged = (binding) => |
| binding in changes && changes[binding].currentValue !== changes[binding].previousValue; |
| |
| if (hasChanged('items') && this.grid) |
| this.grid.data = changes.items.currentValue; |
| |
| if (hasChanged('selectedRows') && this.grid && this.grid.data && this.onSelectionChange) |
| this.applyIncomingSelectionRows(changes.selectedRows.currentValue); |
| |
| if (hasChanged('selectedRowsId') && this.grid && this.grid.data) |
| this.applyIncomingSelectionRowsId(changes.selectedRowsId.currentValue); |
| |
| if (hasChanged('gridHeight') && this.grid) |
| this.adjustHeight(); |
| } |
| |
| $onDestroy() { |
| if (this.resizeObserver) |
| this.resizeObserver.disconnect(); |
| } |
| |
| applyIncomingSelectionRows = (selected = []) => { |
| this.gridApi.selection.clearSelectedRows({ ignore: true }); |
| |
| const visibleRows = this.gridApi.core.getVisibleRows(this.gridApi.grid) |
| .map(({ entity }) => entity); |
| |
| const rows = visibleRows.filter((r) => |
| selected.map((row) => row[this.rowIdentityKey]).includes(r[this.rowIdentityKey])); |
| |
| rows.forEach((r) => { |
| this.gridApi.selection.selectRow(r, { ignore: true }); |
| }); |
| }; |
| |
| applyIncomingSelectionRowsId = (selected = []) => { |
| if (this.onSelectionChange) { |
| this.gridApi.selection.clearSelectedRows({ ignore: true }); |
| |
| const visibleRows = this.gridApi.core.getVisibleRows(this.gridApi.grid) |
| .map(({ entity }) => entity); |
| |
| const rows = visibleRows.filter((r) => |
| selected.includes(r[this.rowIdentityKey])); |
| |
| rows.forEach((r) => { |
| this.gridApi.selection.selectRow(r, { ignore: true }); |
| }); |
| } |
| }; |
| |
| onRowsSelectionChange = debounce((rows, e = {}) => { |
| if (e.ignore) |
| return; |
| |
| this._selected = this.gridApi.selection.legacyGetSelectedRows(); |
| |
| if (this.onSelectionChange) |
| this.onSelectionChange({ $event: this._selected }); |
| }); |
| |
| onFilterChange = debounce((column) => { |
| if (!this.gridApi.selection) |
| return; |
| |
| if (this.selectedRows && this.onSelectionChange) |
| this.applyIncomingSelectionRows(this.selectedRows); |
| |
| if (this.selectedRowsId) |
| this.applyIncomingSelectionRowsId(this.selectedRowsId); |
| }); |
| |
| adjustHeight() { |
| let height = this.gridHeight; |
| |
| if (!height) { |
| const maxRowsToShow = this.maxRowsToShow || 5; |
| const headerBorder = 1; |
| const visibleRows = this.gridApi.core.getVisibleRows().length; |
| const header = this.grid.headerRowHeight + headerBorder; |
| const optionalScroll = (visibleRows ? this.gridUtil.getScrollbarWidth() : 0); |
| |
| height = Math.min(visibleRows, maxRowsToShow) * this.grid.rowHeight + header + optionalScroll; |
| } |
| |
| this.gridApi.grid.element.css('height', height + 'px'); |
| this.gridApi.core.handleWindowResize(); |
| } |
| } |