@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
380 lines (379 loc) • 17.9 kB
JavaScript
import { AdaptableModuleBase } from './AdaptableModuleBase';
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
import * as LayoutRedux from '../Redux/ActionsReducers/LayoutRedux';
import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
import { LayoutRadioSelector } from '../View/Layout/LayoutRadioSelector';
import { LayoutStatusbar } from '../View/Layout/LayoutStatusBarSubPanelPopover';
import { EditCurrentLayoutButton } from '../View/Layout/EditCurrentLayoutButton';
import { LayoutCloneButton } from '../View/Layout/LayoutCloneButton';
import { LayoutWizard } from '../View/Layout/Wizard/LayoutWizard';
import { getLayoutFilterViewItems } from './Utilities/Layout/getLayoutFilterViewItems';
import { getLayoutTableColumnsViewItems, getLayoutPivotSortingViewItem, } from './Utilities/Layout/columnsSummaryHelpers';
import { getLayoutPivotRowGroupViewItems, getLayoutTableRowGroupViewItems, } from './Utilities/Layout/rowGroupSummaryHelpers';
import { getLayoutTableAggregationViewItems, getLayoutPivotAggregationViewItems, } from './Utilities/Layout/aggregationSummaryHelpers';
import { SHOW_PIVOT_COLUMN_DETAILS } from '../View/Components/Popups/WindowPopups/windowFactory';
import { flattenDeep } from '../Utilities/Extensions/ArrayExtensions';
import StringExtensions from '../Utilities/Extensions/StringExtensions';
import { getGridFilterViewItems } from '../View/Layout/Wizard/getGridFilterPreview';
import { RowSummaryService } from '../Utilities/Services/RowSummaryService';
import { isPivotLayout } from '../Api/Implementation/LayoutHelpers';
export class LayoutModule extends AdaptableModuleBase {
LayoutState;
rowSummaryService = new RowSummaryService(this.api);
constructor(api) {
super(ModuleConstants.LayoutModuleId, ModuleConstants.LayoutFriendlyName, 'grid', 'LayoutPopup', 'Named sets of column visibility, order, groupings, aggregation, pivots etc.', 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('LAYOUT_READY', null, this.api.layoutApi.getLayoutState());
});
}
getModuleAdaptableObjects() {
return this.api.layoutApi.getLayouts();
}
getExplicitlyReferencedColumnIds(layout) {
const columnIds = [];
if (!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 (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 LayoutExtensionObjectReferences = [];
const loadConfig = {
extendedLayoutName: layoutName,
};
this.api.alertApi.getAlertDefinitions(loadConfig).forEach((alertDefinition) => LayoutExtensionObjectReferences.push({
Reference: alertDefinition,
Module: 'Alert',
}));
this.api.customSortApi.getCustomSorts(loadConfig).forEach((customSort) => LayoutExtensionObjectReferences.push({
Reference: customSort,
Module: 'CustomSort',
}));
this.api.flashingCellApi.getFlashingCellDefinitions(loadConfig).forEach((flashingCell) => LayoutExtensionObjectReferences.push({
Reference: flashingCell,
Module: 'FlashingCell',
}));
this.api.formatColumnApi.getFormatColumns(loadConfig).forEach((formatColumn) => LayoutExtensionObjectReferences.push({
Reference: formatColumn,
Module: 'FormatColumn',
}));
this.api.styledColumnApi.getStyledColumns(loadConfig).forEach((styledcolumn) => LayoutExtensionObjectReferences.push({
Reference: styledcolumn,
Module: 'StyledColumn',
}));
this.api.plusMinusApi.getAllPlusMinus(loadConfig).forEach((plusMinusNudge) => LayoutExtensionObjectReferences.push({
Reference: plusMinusNudge,
Module: 'PlusMinus',
}));
this.api.shortcutApi.getShortcuts(loadConfig).forEach((shortcut) => LayoutExtensionObjectReferences.push({
Reference: shortcut,
Module: 'Shortcut',
}));
this.api.exportApi.getScheduledReports(loadConfig).forEach((reportSchedule) => LayoutExtensionObjectReferences.push({
Reference: reportSchedule,
Module: 'Export',
}));
teamSharingReferences.push(...LayoutExtensionObjectReferences);
}
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);
}));
}
if (this.api.gridApi.isGridRangeSelectable()) {
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.IsNotNullOrEmpty(menuContext.selectedCellInfo.columns)) ||
(menuContext.selectedRowInfo &&
ArrayExtensions.IsNotNullOrEmpty(menuContext.selectedRowInfo.gridRows))) {
returnColumnMenuItems.push(this.createMenuItemClickFunction('layout-clear-selection', 'Clear Selected Cells', 'select-off', () => {
this.api.gridApi.deselectAll();
}));
}
if (this.api.gridApi.isGridRangeSelectable()) {
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;
}
createViewPivotItemsMenuItem(menuContext) {
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 (!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;
}
const aggColumn = agGridColumn?.getColDef?.().pivotValueColumn?.getColDef?.()?.field;
const pivotValue = agGridColumn?.getColDef?.()?.pivotKeys?.[0];
const pivotColumnId = currentLayout?.PivotColumns?.[0];
function getData(rows) {
return [
...rows.map((row) => {
if (row.childrenAfterFilter) {
return getData(row.childrenAfterFilter);
}
return row.data;
}),
];
}
const data = flattenDeep(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({
id: SHOW_PIVOT_COLUMN_DETAILS,
factoryId: 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 columnIdToFriendlyName = (columnId) => {
return this.api.columnApi.getFriendlyNameForColumnId(columnId);
};
return {
items: [
{
name: 'Name',
values: [layout.Name],
},
{
name: 'Grid Type',
values: [isPivotLayout(layout) ? 'Pivot' : 'Table'],
},
...(!isPivotLayout(layout)
? getLayoutTableColumnsViewItems(layout, this.api, {
maxColumnsToDisplay: this.api.optionsApi.getAdaptableOptions()?.layoutOptions?.layoutViewOptions
?.maxColumnsToDisplay,
})
: []),
layout?.ColumnFilters?.length && getLayoutFilterViewItems(layout, this.api),
...(!isPivotLayout(layout) ? getLayoutTableRowGroupViewItems(layout, this.api) : []),
layout?.PivotColumns?.length && {
name: 'Pivot Columns',
values: layout.PivotColumns.map((colId) => columnIdToFriendlyName(colId)),
tagVariant: 'column',
},
isPivotLayout(layout) && getLayoutPivotSortingViewItem(layout, this.api),
...(isPivotLayout(layout) ? getLayoutPivotRowGroupViewItems(layout, this.api) : []),
...(!isPivotLayout(layout) ? getLayoutTableAggregationViewItems(layout, this.api) : []),
...(isPivotLayout(layout) ? getLayoutPivotAggregationViewItems(layout, this.api) : []),
layout?.GridFilter &&
StringExtensions.IsNotNullOrEmpty(layout.GridFilter.Expression) &&
getGridFilterViewItems(layout),
layout &&
!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, LayoutCloneButton],
getDeleteAction: (layout) => {
if (this.getModuleAdaptableObjects().length === 1) {
return null;
}
return LayoutRedux.LayoutDelete(layout);
},
getEditWizard: () => LayoutWizard,
getStatusBarPanelProps: () => {
return {
triggerActionOnWrapperClick: false,
content: LayoutStatusbar,
extraActions: [EditCurrentLayoutButton],
};
},
};
}
handleLayoutSelection() {
if (!this.api.layoutApi.internalApi.hasLayoutSpecificObjects()) {
return;
}
this.api.internalApi
.getModuleService()
.getModuleById('PlusMinus')
.checkListenToKeyDown();
this.api.internalApi
.getModuleService()
.getModuleById('Shortcut')
.checkListenToKeyDown();
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;
}
}