@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
210 lines (209 loc) • 9.94 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransposedPopup = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const FormLayout_1 = tslib_1.__importStar(require("../../components/FormLayout"));
const Panel_1 = tslib_1.__importDefault(require("../../components/Panel"));
const AdaptableContext_1 = require("../AdaptableContext");
const ColumnSelector_1 = require("../Components/Selectors/ColumnSelector");
const AdaptableAgGrid_1 = require("../../agGrid/AdaptableAgGrid");
const Flex_1 = require("../../components/Flex");
const ModuleConstants_1 = require("../../Utilities/Constants/ModuleConstants");
const StringExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/StringExtensions"));
const ADAPTABLE_CONTAINER_ID = 'transposed-adaptable-container';
const AG_GRID_CONTAINER_ID = 'transposed-adaptable-ag-grid-container';
/** Field used for the first column in transposed grid (hidden, holds column id). */
const TRANSPOSED_FIRST_COLUMN_FIELD = '_transposed_column_value';
/** Header used for the first visible column in transposed grid (shows friendly name). */
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: '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,
};
}
const TransposedPopup = (props) => {
const adaptable = (0, AdaptableContext_1.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_1.default.IsNotNullOrEmpty(rowsToTranspose)) {
adaptable.api.gridApi.getAllRowNodes().forEach((rn) => {
const shouldTransposeRow = adaptable.api.internalApi
.getQueryLanguageService()
.evaluateBooleanExpression(rowsToTranspose, ModuleConstants_1.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]);
/**
* Build transposed structure: original rows become columns (colId = primaryKey value),
* original columns become rows. Each transposed row has the column id/header plus
* one cell per original row keyed by primaryKey value.
*/
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_1.AdaptableAgGrid._initInternal({
variant: 'vanilla',
adaptableOptions,
gridOptions,
modules,
}).then((adaptableApi) => {
transposedAdaptableApiRef.current = adaptableApi;
adaptableApi.eventApi.on('ThemeChanged', (event) => {
transposedAdaptableApiRef.current?.themeApi.loadTheme(typeof event.theme === 'object' ? event.theme.Name : event.theme);
});
});
}, [elevatedColumnId, adaptable]);
React.useEffect(() => {
return () => {
requestAnimationFrame(() => {
transposedAdaptableApiRef.current?.destroy({ unmount: true, destroyAgGrid: true });
});
};
}, []);
return (React.createElement(Flex_1.Flex, { flexDirection: "column", className: "twa:w-full twa:h-full" },
React.createElement(Panel_1.default, null,
React.createElement(FormLayout_1.default, null,
React.createElement(FormLayout_1.FormRow, { label: "Elevated Column" },
React.createElement(ColumnSelector_1.ColumnSelector, { value: elevatedColumnId, onChange: setElevatedColumnId })))),
React.createElement(Flex_1.Flex, { className: "twa:h-full" },
React.createElement(Flex_1.Box, { id: ADAPTABLE_CONTAINER_ID }),
React.createElement(Flex_1.Box, { className: "twa:h-full twa:w-full", id: AG_GRID_CONTAINER_ID }))));
};
exports.TransposedPopup = TransposedPopup;