@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
200 lines (199 loc) • 8.7 kB
JavaScript
import * as React from 'react';
import { Box, Flex } from 'rebass';
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';
const adaptableContainerId = `transposed-adaptable-container`;
const agGridContainerId = `transposed-adaptable-ag-grid-container`;
export const TransposedPopup = (props) => {
const adaptable = useAdaptable();
const { transposedColumnId, hideTransposedColumn, visibleColumns, visibleRows, autosize } = props.popupProps;
const rowNodes = React.useMemo(() => {
return props.popupProps.visibleRows
? adaptable.api.gridApi.getVisibleRowNodes()
: adaptable.api.gridApi.getAllRowNodes();
}, [
// can be later triggered by tickng data
]);
const primaryKey = adaptable.api.optionsApi.getPrimaryKey();
const [syntheticTransposedByColumnId, doSetSyntheticTransposedByColumnId] = React.useState(transposedColumnId);
const setSyntheticTransposedByColumnId = (syntheticTransposedByColumnId) => {
transposedAdaptableApiRef.current?.destroy({ unmount: true, destroyAgGrid: true });
doSetSyntheticTransposedByColumnId(syntheticTransposedByColumnId);
};
const transposedAdaptableApiRef = React.useRef(null);
const columns = React.useMemo(() => {
// customisable
return visibleColumns
? adaptable.api.columnApi.getVisibleColumns()
: adaptable.api.columnApi.getColumns();
}, []);
/**
* This is used as first field
*/
const transposedFirstColumnField = '_transposed_column_value';
const transposedFirstColumnHeader = '_transposed_column_header';
const transposedRowsAndColumns = React.useMemo(() => {
/**
* transposed column values become primaryKey of the new tarnsposed rows
* we build row by row, might be easer
*/
const transposedColumns = [];
const transposedRows = [];
for (const row of rowNodes) {
// we force the col-ids to be strings, easer to work with
//row[transposeByColumnId] + '';
const colId = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, primaryKey) + '';
//row[synteticTransposedByColumnId] + '';
const header = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, syntheticTransposedByColumnId) +
'';
transposedColumns.push({
colId,
header,
});
}
for (const column of columns) {
/**
* We can hide the transposed column, if we want
*/
if (hideTransposedColumn && column.columnId === syntheticTransposedByColumnId) {
continue;
}
const transposedRow = {
// [transposed-by-column-id]: [other column id],
// the value can be set to friendlyname
[transposedFirstColumnField]: column.columnId,
[transposedFirstColumnHeader]: column.friendlyName,
};
for (let row of rowNodes) {
// [transposed-by-column-value[n]]: [other column value[n]]
const key = adaptable.api.gridApi.getNormalisedValueFromRowNode(row, primaryKey);
// row[column.field]
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, syntheticTransposedByColumnId]);
React.useEffect(() => {
// Mounting in an effect, so the nodes are rendered/available
const hostAdaptableOptions = adaptable.adaptableOptions;
const adaptableOptions = {
primaryKey: transposedFirstColumnField,
licenseKey: hostAdaptableOptions.licenseKey,
userName: `${hostAdaptableOptions.userName}`,
adaptableId: `${hostAdaptableOptions.adaptableId}::TransposedView`,
containerOptions: {
adaptableContainer: adaptableContainerId,
agGridContainer: agGridContainerId,
},
entitlementOptions: {
defaultAccessLevel: 'Hidden',
},
initialState: {
Layout: {
Revision: Date.now(),
CurrentLayout: 'TransposedView',
Layouts: [
{
Name: 'TransposedView',
TableColumns: [
transposedFirstColumnHeader,
...transposedRowsAndColumns.transposedColumns.map((c) => c.colId),
],
ColumnPinning: {
[transposedFirstColumnHeader]: 'left',
},
AutoSizeColumns: true,
},
],
},
Theme: {
CurrentTheme: adaptable.api.themeApi.getCurrentTheme(),
},
},
};
const firstColumn = {
field: transposedFirstColumnHeader, // use the column friendly name
headerName: adaptable.api.columnApi.getFriendlyNameForColumnId(syntheticTransposedByColumnId),
};
const agGridOptions = {
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: transposedFirstColumnField,
hide: true,
},
firstColumn,
...transposedRowsAndColumns.transposedColumns.map((col) => {
return {
field: col.colId,
type: null,
headerName: col.header,
};
}),
],
rowData: transposedRowsAndColumns.transposedRows,
sideBar: false,
};
const modules = adaptable.getAgGridRegisteredModules();
AdaptableAgGrid._initInternal({
variant: 'vanilla',
adaptableOptions,
gridOptions: agGridOptions,
modules,
}).then((adaptableApi) => {
transposedAdaptableApiRef.current = adaptableApi;
adaptableApi.eventApi.on('ThemeChanged', (event) => {
transposedAdaptableApiRef.current?.themeApi.loadTheme(typeof event.theme === 'object' ? event.theme.Name : event.theme);
});
});
}, [syntheticTransposedByColumnId]);
React.useEffect(() => {
// destroy when closing the popup
return () => {
requestAnimationFrame(() => {
transposedAdaptableApiRef.current?.destroy({ unmount: true, destroyAgGrid: true });
});
};
}, []);
/**
* Need to get all data, manualy pivot the grid using the primary key.
*
* 1. get the data, and pivot using the primary key
* 2. create the col definitios, a col definition for each row
* 3. create the grid
*/
return (React.createElement(Flex, { flexDirection: "column", width: "100%", height: "100%" },
React.createElement(Panel, null,
React.createElement(FormLayout, null,
React.createElement(FormRow, { label: "Elevated Column" },
React.createElement(ColumnSelector, { value: syntheticTransposedByColumnId, onChange: (colId) => {
setSyntheticTransposedByColumnId(colId);
} })))),
React.createElement(Flex, { height: "100%" },
React.createElement(Box, { id: adaptableContainerId }),
React.createElement(Box, { height: "100%", width: "100%", id: agGridContainerId }))));
};