@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
193 lines (192 loc) • 9.02 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import FormLayout, { FormRow } from '../../components/FormLayout';
import Panel from '../../components/Panel';
import { useAdaptable } from '../AdaptableContext';
import { ColumnSelector } from '../Components/Selectors/ColumnSelector';
import { AdaptableAgGrid } from '../../agGrid/AdaptableAgGrid';
import { Box, Flex } from '../../components/Flex';
import { ACCESS_LEVEL_HIDDEN } from '../../Utilities/Constants/GeneralConstants';
import { ExportModuleId } from '../../Utilities/Constants/ModuleConstants';
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
const ADAPTABLE_CONTAINER_ID = 'transposed-adaptable-container';
const AG_GRID_CONTAINER_ID = 'transposed-adaptable-ag-grid-container';
const TRANSPOSED_FIRST_COLUMN_FIELD = '_transposed_column_value';
const TRANSPOSED_FIRST_COLUMN_HEADER = '_transposed_column_header';
function buildTransposedAdaptableOptions({ hostOptions, transposedRowsAndColumns, currentTheme, }) {
return {
primaryKey: TRANSPOSED_FIRST_COLUMN_FIELD,
licenseKey: hostOptions.licenseKey,
userName: `${hostOptions.userName}`,
adaptableId: `${hostOptions.adaptableId}::TransposedView`,
containerOptions: {
adaptableContainer: ADAPTABLE_CONTAINER_ID,
agGridContainer: AG_GRID_CONTAINER_ID,
},
entitlementOptions: { defaultAccessLevel: ACCESS_LEVEL_HIDDEN },
initialState: {
Layout: {
Revision: Date.now(),
CurrentLayout: 'TransposedView',
Layouts: [
{
Name: 'TransposedView',
TableColumns: [
TRANSPOSED_FIRST_COLUMN_HEADER,
...transposedRowsAndColumns.transposedColumns.map((c) => c.colId),
],
ColumnPinning: { [TRANSPOSED_FIRST_COLUMN_HEADER]: 'left' },
AutoSizeColumns: true,
},
],
},
Theme: { CurrentTheme: currentTheme },
},
};
}
function buildTransposedGridOptions({ transposedRowsAndColumns, elevatedColumnId, adaptableApi, }) {
const firstColumn = {
field: TRANSPOSED_FIRST_COLUMN_HEADER,
headerName: adaptableApi.columnApi.getFriendlyNameForColumnId(elevatedColumnId),
};
return {
loading: false,
defaultColDef: {
floatingFilter: false,
filter: false,
sortable: true,
resizable: true,
enableRowGroup: false,
editable: false,
enablePivot: false,
enableValue: false,
lockPinned: true,
menuTabs: [],
width: 120,
},
columnDefs: [
{ field: TRANSPOSED_FIRST_COLUMN_FIELD, hide: true },
firstColumn,
...transposedRowsAndColumns.transposedColumns.map((col) => ({ field: col.colId, headerName: col.header })),
],
rowData: transposedRowsAndColumns.transposedRows,
sideBar: false,
};
}
export const TransposedPopup = (props) => {
const adaptable = useAdaptable();
const primaryKey = adaptable.api.optionsApi.getPrimaryKey();
const rawConfig = (props.popupProps ?? {});
const transposeConfig = {
transposedColumnId: rawConfig.transposedColumnId ?? primaryKey,
hideTransposedColumn: rawConfig.hideTransposedColumn ?? true,
columnsToTranspose: rawConfig.columnsToTranspose,
rowsToTranspose: rawConfig.rowsToTranspose,
};
const rowNodes = React.useMemo(() => {
let transposableRowNodes = [];
const rowsToTranspose = transposeConfig.rowsToTranspose;
if (rowsToTranspose === 'VisibleOnly') {
return adaptable.api.gridApi.getVisibleRowNodes();
}
if (rowsToTranspose === 'All') {
return adaptable.api.gridApi.getAllRowNodes();
}
if (StringExtensions.IsNotNullOrEmpty(rowsToTranspose)) {
adaptable.api.gridApi.getAllRowNodes().forEach((rn) => {
const shouldTransposeRow = adaptable.api.internalApi
.getQueryLanguageService()
.evaluateBooleanExpression(rowsToTranspose, ExportModuleId, rn);
if (shouldTransposeRow) {
transposableRowNodes.push(rn);
}
});
return transposableRowNodes;
}
return adaptable.api.gridApi.getAllRowNodes();
}, [transposeConfig.rowsToTranspose, adaptable.api]);
const [elevatedColumnId, setElevatedColumnIdState] = React.useState(() => transposeConfig.transposedColumnId ?? primaryKey);
const setElevatedColumnId = (newElevatedColumnId) => {
transposedAdaptableApiRef.current?.destroy({ unmount: true, destroyAgGrid: true });
setElevatedColumnIdState(newElevatedColumnId);
};
const transposedAdaptableApiRef = React.useRef(null);
const columns = React.useMemo(() => {
const allUIColumns = adaptable.api.columnApi.getUIAvailableColumns();
const columnsToTranspose = transposeConfig.columnsToTranspose;
if (!columnsToTranspose) {
return allUIColumns;
}
const columnIds = typeof columnsToTranspose === 'function'
? columnsToTranspose({
...adaptable.api.internalApi.buildBaseContext(),
columns: allUIColumns,
})
: columnsToTranspose;
return columnIds
.map((c) => adaptable.api.columnApi.getColumnWithColumnId(c))
.filter((col) => col != null);
}, [transposeConfig.columnsToTranspose, adaptable.api]);
const transposedRowsAndColumns = React.useMemo(() => {
const transposedColumns = [];
const transposedRows = [];
for (const row of rowNodes) {
const colId = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, primaryKey) + '';
const header = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, elevatedColumnId) + '';
transposedColumns.push({ colId, header });
}
for (const column of columns) {
if (transposeConfig.hideTransposedColumn &&
column.columnId === elevatedColumnId) {
continue;
}
const transposedRow = {
[TRANSPOSED_FIRST_COLUMN_FIELD]: column.columnId,
[TRANSPOSED_FIRST_COLUMN_HEADER]: column.friendlyName,
};
for (const row of rowNodes) {
const key = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, primaryKey);
let value = adaptable.api.gridApi.getDisplayValueFromRowNode(row, column.columnId);
if (value instanceof Date) {
value = value.toLocaleString();
}
transposedRow[key] = value;
}
transposedRows.push(transposedRow);
}
return { transposedColumns, transposedRows };
}, [rowNodes, primaryKey, elevatedColumnId, columns, transposeConfig.hideTransposedColumn, adaptable.api]);
React.useEffect(() => {
const hostOptions = adaptable.adaptableOptions;
const adaptableOptions = buildTransposedAdaptableOptions({
hostOptions,
transposedRowsAndColumns,
currentTheme: adaptable.api.themeApi.getCurrentTheme(),
});
const gridOptions = buildTransposedGridOptions({
transposedRowsAndColumns,
elevatedColumnId,
adaptableApi: adaptable.api,
});
const modules = adaptable.agGridModulesAdapter.getAgGridRegisteredModules();
AdaptableAgGrid._initInternal({
variant: 'vanilla',
adaptableOptions,
gridOptions,
modules,
}).then((adaptableApi) => {
transposedAdaptableApiRef.current = adaptableApi;
adaptableApi.eventApi.on('ThemeSelected', (event) => {
transposedAdaptableApiRef.current?.themeApi.loadTheme(event.theme);
});
});
}, [elevatedColumnId, adaptable]);
React.useEffect(() => {
return () => {
requestAnimationFrame(() => {
transposedAdaptableApiRef.current?.destroy({ unmount: true, destroyAgGrid: true });
});
};
}, []);
return (_jsxs(Flex, { flexDirection: "column", className: "twa:w-full twa:h-full", children: [_jsx(Panel, { children: _jsx(FormLayout, { children: _jsx(FormRow, { label: "Elevated Column", children: _jsx(ColumnSelector, { value: elevatedColumnId, onChange: setElevatedColumnId }) }) }) }), _jsxs(Flex, { className: "twa:h-full", children: [_jsx(Box, { id: ADAPTABLE_CONTAINER_ID }), _jsx(Box, { className: "twa:h-full twa:w-full", id: AG_GRID_CONTAINER_ID })] })] }));
};