UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

466 lines (465 loc) 22.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LayoutModule = void 0; const tslib_1 = require("tslib"); const AdaptableModuleBase_1 = require("./AdaptableModuleBase"); const ModuleConstants = tslib_1.__importStar(require("../Utilities/Constants/ModuleConstants")); const LayoutRedux = tslib_1.__importStar(require("../Redux/ActionsReducers/LayoutRedux")); const ArrayExtensions_1 = tslib_1.__importDefault(require("../Utilities/Extensions/ArrayExtensions")); const LayoutRadioSelector_1 = require("../View/Layout/LayoutRadioSelector"); const LayoutStatusBarSubPanelPopover_1 = require("../View/Layout/LayoutStatusBarSubPanelPopover"); const EditCurrentLayoutButton_1 = require("../View/Layout/EditCurrentLayoutButton"); const LayoutCloneButton_1 = require("../View/Layout/LayoutCloneButton"); const LayoutWizard_1 = require("../View/Layout/Wizard/LayoutWizard"); const getLayoutFilterViewItems_1 = require("./Utilities/Layout/getLayoutFilterViewItems"); const getLayoutSortViewItems_1 = require("./Utilities/Layout/getLayoutSortViewItems"); const AggregationColumns_1 = require("../AdaptableState/Common/AggregationColumns"); const windowFactory_1 = require("../View/Components/Popups/WindowPopups/windowFactory"); const flattenDeep_1 = tslib_1.__importDefault(require("lodash/flattenDeep")); const StringExtensions_1 = tslib_1.__importDefault(require("../Utilities/Extensions/StringExtensions")); const getGridFilterPreview_1 = require("../View/Layout/Wizard/getGridFilterPreview"); const RowSummaryService_1 = require("../Utilities/Services/RowSummaryService"); const LayoutHelpers_1 = require("../Api/Implementation/LayoutHelpers"); class LayoutModule extends AdaptableModuleBase_1.AdaptableModuleBase { constructor(api) { super(ModuleConstants.LayoutModuleId, ModuleConstants.LayoutFriendlyName, 'grid', 'LayoutPopup', 'Named sets of column visibility, order, groupings, aggregation, pivots etc.', api); this.rowSummaryService = new RowSummaryService_1.RowSummaryService(this.api); } onAdaptableReady() { this.rowSummaryService.onAdaptableReady(); this.api.eventApi.on('LayoutChanged', (layoutChangedInfo) => { if (layoutChangedInfo.actionName === 'LAYOUT_SELECT' && layoutChangedInfo.newLayoutState.CurrentLayout !== layoutChangedInfo.oldLayoutState?.CurrentLayout) { this.handleLayoutSelection(); } }); requestAnimationFrame(() => { if (this.api.isDestroyed()) { return; } this.api.eventApi.internalApi.fireLayoutChangedEvent('ADAPTABLE_READY', null, this.api.layoutApi.getLayoutState()); }); } getModuleAdaptableObjects() { return this.api.layoutApi.getLayouts(); } getExplicitlyReferencedColumnIds(layout) { const columnIds = []; if (!(0, LayoutHelpers_1.isPivotLayout)(layout) && layout.TableColumns) { const visibility = layout.ColumnVisibility || {}; columnIds.push(...layout.TableColumns.filter((colId) => { return visibility[colId] !== false; })); } if (layout.TableAggregationColumns) { columnIds.push(...Object.keys(layout.TableAggregationColumns)); } if ((0, LayoutHelpers_1.isPivotLayout)(layout)) { if (layout.PivotColumns) { columnIds.push(...layout.PivotColumns); } if (layout.PivotAggregationColumns) { columnIds.push(...layout.PivotAggregationColumns.map((x) => x.ColumnId)); } if (layout.PivotGroupedColumns) { columnIds.push(...layout.PivotGroupedColumns); } } if (layout.RowGroupedColumns) { columnIds.push(...layout.RowGroupedColumns); } return Array.from(new Set(columnIds)); } getTeamSharingReferences(adaptableObject) { const teamSharingReferences = super.getTeamSharingReferences(adaptableObject); const layoutName = adaptableObject.Name; if (this.api.layoutApi.internalApi.hasLayoutSpecificObjects() && !!layoutName) { const layoutAssociatedObjectReferences = []; const loadConfig = { associatedWithLayout: layoutName, }; // we ensured that there are layout specific objects, so all the "getAll*()" api methods will return only the objects available in the current layout this.api.alertApi.getAlertDefinitions(loadConfig).forEach((alertDefinition) => layoutAssociatedObjectReferences.push({ Reference: alertDefinition, Module: 'Alert', })); this.api.customSortApi.getCustomSorts(loadConfig).forEach((customSort) => layoutAssociatedObjectReferences.push({ Reference: customSort, Module: 'CustomSort', })); this.api.flashingCellApi.getFlashingCellDefinitions(loadConfig).forEach((flashingCell) => layoutAssociatedObjectReferences.push({ Reference: flashingCell, Module: 'FlashingCell', })); this.api.formatColumnApi.getFormatColumns(loadConfig).forEach((formatColumn) => layoutAssociatedObjectReferences.push({ Reference: formatColumn, Module: 'FormatColumn', })); this.api.styledColumnApi.getStyledColumns(loadConfig).forEach((styledcolumn) => layoutAssociatedObjectReferences.push({ Reference: styledcolumn, Module: 'StyledColumn', })); this.api.plusMinusApi.getAllPlusMinus(loadConfig).forEach((plusMinusNudge) => layoutAssociatedObjectReferences.push({ Reference: plusMinusNudge, Module: 'PlusMinus', })); this.api.shortcutApi.getShortcuts(loadConfig).forEach((shortcut) => layoutAssociatedObjectReferences.push({ Reference: shortcut, Module: 'Shortcut', })); [ ...this.api.scheduleApi.getReportSchedules(loadConfig), ...this.api.scheduleApi.getReminderSchedules(loadConfig), ...this.api.scheduleApi.getIPushPullSchedules(loadConfig), ...this.api.scheduleApi.getOpenFinSchedules(loadConfig), ].forEach((schedule) => layoutAssociatedObjectReferences.push({ Reference: schedule, Module: 'Schedule', })); teamSharingReferences.push(...layoutAssociatedObjectReferences); } return teamSharingReferences; } hasNamedQueryReferences() { return true; } createColumnMenuItems(column) { if (!this.isModuleEditable()) { return; } let returnColumnMenuItems = []; const isReadOnlyLayout = this.isCurrentLayoutReadOnly(); if (!isReadOnlyLayout) { returnColumnMenuItems.push(this.createMenuItemShowPopup('layout-edit', 'Edit Layout', this.moduleInfo.Popup, 'edit-table', { action: 'Edit', source: 'ColumnMenu', value: this.api.layoutApi.getCurrentLayout(), })); if (column && !column.isTreeColumn) { returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-column-caption-change', 'Change Caption', 'edit', () => this.api.layoutApi.showChangeColumnCaption(column))); } } if (column) { if (column.hideable) { returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-column-hide', 'Hide Column', 'visibility-off-bold', () => { this.api.columnApi.hideColumn(column.columnId); })); } const hasExistingSelection = this.api.gridApi.getSelectedCellInfo()?.gridCells?.length; if (hasExistingSelection) { returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-column-select-preserve', 'Select Column (Preserve Selection)', 'select-fwd', () => { this.api.columnApi.addColumnToSelection(column.columnId); })); returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-column-select-reset', 'Select Column (Reset Selection)', 'tab-unselected', () => { this.api.columnApi.selectColumn(column.columnId); })); } else { returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-column-select', 'Select Column', 'tab-unselected', () => { this.api.columnApi.selectColumn(column.columnId); })); } } returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-grid-select', 'Select Grid', 'select-all', () => { this.api.gridApi.selectAll(); })); return returnColumnMenuItems; } createContextMenuItems(menuContext) { let returnColumnMenuItems = []; if (this.isModuleEditable() && !this.isCurrentLayoutReadOnly()) { returnColumnMenuItems.push(this.createMenuItemShowPopup('layout-edit', 'Edit Layout', this.moduleInfo.Popup, 'edit-table', { action: 'Edit', source: 'ColumnMenu', })); } if ((menuContext.selectedCellInfo && ArrayExtensions_1.default.IsNotNullOrEmpty(menuContext.selectedCellInfo.columns)) || (menuContext.selectedRowInfo && ArrayExtensions_1.default.IsNotNullOrEmpty(menuContext.selectedRowInfo.gridRows))) { returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-clear-selection', 'Clear Selected Cells', 'select-off', () => { this.api.gridApi.deselectAll(); })); } returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-select-all', 'Select Grid', 'select-all', () => { this.api.gridApi.selectAll(); })); returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-auto-size', 'Auto Size', 'arrow-expand', () => { this.api.columnApi.autosizeAllColumns(); })); const viewPivotItemsMenuItem = this.createViewPivotItemsMenuItem(menuContext); if (viewPivotItemsMenuItem) { returnColumnMenuItems.push(viewPivotItemsMenuItem); } return returnColumnMenuItems; } // TODO next time this method is touched, it should be extracted in an internal Api createViewPivotItemsMenuItem(menuContext) { // current group => menuContext.rowNode.field; const selectedCellInfo = menuContext.selectedCellInfo ?? this.api.gridApi.getSelectedCellInfo(); if (selectedCellInfo?.gridCells?.length !== 1) { return; } const gridCell = menuContext.gridCell ?? selectedCellInfo.gridCells[0]; const currentLayout = this.api.layoutApi.getCurrentLayout(); if (!(0, LayoutHelpers_1.isPivotLayout)(currentLayout)) { return; } const { agGridColumn } = menuContext; const columnId = agGridColumn.getColId(); const isPivotColumn = this.api.columnApi.isPivotResultColumn(columnId); if (!isPivotColumn && this.api.columnApi.getColumnDataTypeForColumnId(columnId) !== 'number') { return; } /** * Cannot base the values on the pivot column id, because the value or the field may have underscrores * * * e.g. pivot_license_MIT License_stargazers_count */ // pivot_status_Booked_price // price const aggColumn = agGridColumn?.getColDef?.().pivotValueColumn?.getColDef?.()?.field; // Booked const pivotValue = agGridColumn?.getColDef?.()?.pivotKeys?.[0]; // status - the preview works only with one column const pivotColumnId = currentLayout?.PivotColumns?.[0]; function getData(rows) { return [ ...rows.map((row) => { if (row.childrenAfterFilter) { return getData(row.childrenAfterFilter); } return row.data; }), ]; } const data = (0, flattenDeep_1.default)(getData(menuContext.rowNode.childrenAfterFilter)); const rowGroups = currentLayout.RowGroupedColumns; const cellValue = isPivotColumn ? menuContext.rowNode?.aggData?.[columnId] : gridCell.displayValue; const popupProps = { hasPivotValue: isPivotColumn, columnId, rowGroups, rows: data, layout: currentLayout, aggColumn, pivotValue, pivotColumnId, }; return { name: 'layout-aggregated-view', category: this.moduleInfo.ModuleName, isVisible: true, label: 'Expand Aggregated Value', onClick: () => { this.api.internalApi.showPopupWindow({ // force only one window instance opened id: windowFactory_1.SHOW_PIVOT_COLUMN_DETAILS, factoryId: windowFactory_1.SHOW_PIVOT_COLUMN_DETAILS, title: `Rows for Aggregated Value: ${cellValue}`, icon: undefined, popupProps, }); }, icon: { name: 'arrow-expand', }, }; } getTeamSharingAction() { return { ModuleEntities: this.api.layoutApi.getLayouts(), AddAction: LayoutRedux.LayoutAdd, EditAction: LayoutRedux.LayoutSave, }; } toViewAll() { return this.getModuleAdaptableObjects().map((layout) => this.toView(layout)); } toView(layout) { const maxColumnsToDisplay = this.api.optionsApi.getLayoutOptions().layoutViewOptions?.maxColumnsToDisplay ?? 10; const columnIdToFriendlyName = (columnId) => { return this.api.columnApi.getFriendlyNameForColumnId(columnId); }; let columns = (layout.TableColumns || []) .filter((c) => !this.api.columnApi.isAutoRowGroupColumn(c)) .filter((c) => !this.api.columnApi.isPivotResultColumn(c)); if (columns.length > maxColumnsToDisplay + 1 /* +1 is to show tag only beginning with 2, 'other 2' */) { const extraColumns = columns.length - maxColumnsToDisplay; const firstNColumns = columns .slice(0, maxColumnsToDisplay) .map((column) => columnIdToFriendlyName(column)); columns = [...firstNColumns, `and ${extraColumns} more`]; } else { columns = columns.map((column) => columnIdToFriendlyName(column)); } return { items: [ { name: 'Grid Type', values: [(0, LayoutHelpers_1.isPivotLayout)(layout) ? 'Pivot' : 'Table'], }, { name: 'Name', values: [layout.Name], }, /** * Hide pivot columns. * * The generated pivot columns cannot be prevented from beeing on the layout object. * When they are removed/not added, they no longer appear in the grid. */ !(0, LayoutHelpers_1.isPivotLayout)(layout) && { name: 'Columns', values: columns, }, layout.ColumnSorts?.length && (0, getLayoutSortViewItems_1.getLayoutSortViewItems)(layout, this.api), layout?.ColumnFilters?.length && (0, getLayoutFilterViewItems_1.getLayoutFilterViewItems)(layout, this.api), layout?.RowGroupedColumns?.length && { name: 'Row Groups', values: layout.RowGroupedColumns.map((colId) => columnIdToFriendlyName(colId)), }, layout?.PivotColumns?.length && { name: 'Pivot Columns', values: layout.PivotColumns.map((colId) => columnIdToFriendlyName(colId)), }, layout?.PivotGroupedColumns?.length && { name: 'Pivot Row Groups', values: layout.PivotGroupedColumns.map((colId) => columnIdToFriendlyName(colId)), }, layout?.TableAggregationColumns && layout.TableAggregationColumns.length && { name: 'Aggregations', values: layout.TableAggregationColumns.map(({ ColumnId, AggFunc: aggFn }) => { if (ColumnId === 'Source' || ColumnId === 'Uuid' || ColumnId === 'AdaptableVersion') { return ''; } let aggFnName = ''; if (typeof aggFn === 'string') { aggFnName = aggFn; } else if (typeof aggFn === 'object' && aggFn.type === 'weightedAverage') { aggFnName = AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME; } return `${aggFnName}(${columnIdToFriendlyName(ColumnId)})`; }).filter(Boolean), }, (0, LayoutHelpers_1.isPivotLayout)(layout) && layout?.PivotAggregationColumns && layout.PivotAggregationColumns.length && { name: 'Pivot Aggregations', values: layout.PivotAggregationColumns.map(({ ColumnId, AggFunc: aggFn }) => { if (ColumnId === 'Source' || ColumnId === 'Uuid' || ColumnId === 'AdaptableVersion') { return ''; } let aggFnName = ''; if (typeof aggFn === 'string') { aggFnName = aggFn; } else if (typeof aggFn === 'object' && aggFn.type === 'weightedAverage') { aggFnName = AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME; } return `${aggFnName}(${columnIdToFriendlyName(ColumnId)})`; }).filter(Boolean), }, layout?.GridFilter && StringExtensions_1.default.IsNotNullOrEmpty(layout.GridFilter.Expression) && (0, getGridFilterPreview_1.getGridFilterViewItems)(layout), layout && !(0, LayoutHelpers_1.isPivotLayout)(layout) && layout.RowSummaries?.length && { name: 'Row Summaries', values: layout.RowSummaries.map((rowSummary) => { const columns = Object.entries(rowSummary.ColumnsMap ?? {}) .map(([columnId, expression]) => { if (columnId === 'Source' || columnId === 'Uuid' || columnId === 'AdaptableVersion') { return ''; } return `${expression}(${columnIdToFriendlyName(columnId)})`; }) .filter(Boolean) .join(', '); return `${rowSummary.Position}: ${columns}`; }), }, ].filter(Boolean), abObject: layout, }; } getViewProperties() { return { abObjectTypes: [ { name: 'Table Layout', accessLevel: this.AccessLevel, }, !this.api.gridApi.isTreeDataGrid() && { name: 'Pivot Layout', accessLevel: this.AccessLevel, }, ].filter(Boolean), actions: [LayoutRadioSelector_1.LayoutRadioSelector, LayoutCloneButton_1.LayoutCloneButton], getDeleteAction: (layout) => { // make sure we do not delete the last layout if (this.getModuleAdaptableObjects().length === 1) { return null; } return LayoutRedux.LayoutDelete(layout); }, getEditWizard: () => LayoutWizard_1.LayoutWizard, getStatusBarPanelProps: () => { return { triggerActionOnWrapperClick: false, content: LayoutStatusBarSubPanelPopover_1.LayoutStatusbar, extraActions: [EditCurrentLayoutButton_1.EditCurrentLayoutButton], }; }, }; } handleLayoutSelection() { if (!this.api.layoutApi.internalApi.hasLayoutSpecificObjects()) { // no need if no callback implementation is provided or no auto checking return; } // PlusMinus this.api.internalApi .getModuleService() .getModuleById('PlusMinus') .checkListenToKeyDown(); // Shortcut this.api.internalApi .getModuleService() .getModuleById('Shortcut') .checkListenToKeyDown(); // Schedule this.api.internalApi .getModuleService() .getModuleById('Schedule') .setUpScheduleJobs(); // CustomSort, FlashingCell, FormatColumn, StyledColumn // we need to re-setup the column defs, as some colDefs properties may be changed this.api.internalApi.getAdaptableInstance().updateColumnModelAndRefreshGrid(); } getReferencedNamedQueryNames(layout) { if (!layout.GridFilter?.Expression) { return []; } return this.api.namedQueryApi.internalApi.getReferencedNamedQueryNames(layout.GridFilter.Expression); } isCurrentLayoutReadOnly() { const currentLayout = this.api.layoutApi.getCurrentLayout(); if (currentLayout) { return currentLayout.IsReadOnly; } return true; } } exports.LayoutModule = LayoutModule;