UNPKG

@adaptabletools/adaptable

Version:

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

198 lines (197 loc) 9.62 kB
import * as React from 'react'; import { Box, Flex, Text } from 'rebass'; import { CheckBox } from '../../../../components/CheckBox'; import DropdownButton from '../../../../components/DropdownButton'; import FormLayout, { FormRow } from '../../../../components/FormLayout'; import { Tabs } from '../../../../components/Tabs'; import { Tag } from '../../../../components/Tag'; import { useAdaptable } from '../../../AdaptableContext'; import { ValueSelector } from '../../../Components/ValueSelector'; import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard'; import { columnFilter } from './Utilities'; import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions'; const WEIGHTED_AVERAGE_AGG_FN_NAME = 'weightedAvg'; export const isAggregationsSectionValid = (data) => { const weightedAvg = data.TableAggregationColumns ? (data.TableAggregationColumns || []).find(({ AggFunc }) => typeof AggFunc === 'object' && AggFunc.type === 'weightedAverage')?.AggFunc : null; if (weightedAvg && !weightedAvg.weightedColumnId) { return 'The Weighted Average Aggregation requires a Weighted Column'; } return true; }; export const AggregationsSectionSummary = () => { const adaptable = useAdaptable(); const { data: layout } = useOnePageAdaptableWizardContext(); const entries = layout.TableAggregationColumns || []; let content = null; if (entries.length) { content = (React.createElement(FormLayout, null, entries.map(({ ColumnId, AggFunc }) => (React.createElement(FormRow, { key: ColumnId, label: adaptable.api.columnApi.getFriendlyNameForColumnId(ColumnId) }, React.createElement(Tag, null, typeof AggFunc === 'object' ? AggFunc.type : AggFunc)))))); } else { content = React.createElement(Tag, null, "No Aggregations"); } return React.createElement(Box, null, content); }; const ColumnRow = (props) => { const adaptable = useAdaptable(); const aggValue = props.layout?.TableAggregationColumns?.find((agg) => agg.ColumnId === props.column.columnId)?.AggFunc; const adaptableAggFunctions = []; if (props.column.dataType === 'number') { adaptableAggFunctions.push(WEIGHTED_AVERAGE_AGG_FN_NAME); } const aggOptions = [...props.column.availableAggregationFunctions, ...adaptableAggFunctions].map((fnName) => { return { label: fnName, onClick: () => { let aggCols = props.layout.TableAggregationColumns || []; if (!aggCols) { return; } const AggFuncValue = fnName === WEIGHTED_AVERAGE_AGG_FN_NAME ? { type: 'weightedAverage', weightedColumnId: null, } : fnName; let found = false; aggCols = aggCols.map(({ ColumnId, AggFunc }) => { if (ColumnId === props.column.columnId) { found = true; return { ColumnId, AggFunc: AggFuncValue, }; } return { ColumnId, AggFunc }; }); if (!found) { aggCols.push({ ColumnId: props.column.columnId, AggFunc: AggFuncValue, }); } props.onChangeAggFunction(aggCols); }, }; }); const numericColumnsOptions = props.numberColumns .filter((col) => col.columnId !== props.column.columnId) .map((col) => { return { label: col.friendlyName, onClick: () => { let aggCols = [...(props.layout.TableAggregationColumns || [])]; if (!aggCols || !aggCols.length) { return; } const AggFuncValue = { type: 'weightedAverage', weightedColumnId: col.columnId, }; let found = false; aggCols = aggCols.map(({ ColumnId, AggFunc }) => { if (ColumnId === props.column.columnId) { found = true; return { ColumnId, AggFunc: AggFuncValue, }; } return { ColumnId, AggFunc }; }); if (!found) { aggCols.push({ ColumnId: props.column.columnId, AggFunc: AggFuncValue, }); } props.onChangeAggFunction(aggCols); }, }; }); const currentAggFnName = props.aggregationColumnsMap[props.column.columnId]; let weightName = null; if (typeof aggValue === 'object' && aggValue.type === 'weightedAverage') { weightName = aggValue.weightedColumnId ? adaptable.api.columnApi.getFriendlyNameForColumnId(aggValue.weightedColumnId) : 'Select Weight'; } return (React.createElement(Flex, { alignItems: "center" }, props.column.friendlyName, aggValue && (React.createElement(DropdownButton, { columns: ['label'], items: aggOptions, ml: 2 }, currentAggFnName)), currentAggFnName === WEIGHTED_AVERAGE_AGG_FN_NAME && (React.createElement(Flex, { backgroundColor: "primary", ml: 3, alignItems: "center" }, React.createElement(Text, null, "Weight"), ' ', React.createElement(DropdownButton, { columns: ['label'], items: numericColumnsOptions, ml: 2 }, weightName))))); }; export const AggregationsSection = (props) => { const adaptable = useAdaptable(); const { data: layout } = useOnePageAdaptableWizardContext(); const allAggregableColumns = adaptable.api.columnApi.getAggregatableColumns(); const allColumns = adaptable.api.columnApi.getUIAvailableColumns(); const numberColumns = adaptable.api.columnApi.getNumericColumns(); const sortedAggregableColumns = React.useMemo(() => { return ArrayExtensions.sortArrayWithOrder(allAggregableColumns.map((col) => col.columnId), (layout.TableAggregationColumns ?? []).map((agg) => agg.ColumnId), { sortUnorderedItems: false }).map((colId) => adaptable.api.columnApi.getColumnWithColumnId(colId)); }, [layout, allAggregableColumns]); const handleColumnsSelectionChange = React.useCallback((columnIds) => { const currentAggsMap = (layout.TableAggregationColumns || []).reduce((acc, { ColumnId, AggFunc }) => { acc[ColumnId] = AggFunc; return acc; }, {}); props.onChange({ ...layout, TableAggregationColumns: columnIds.map((colId) => { const AggFunc = currentAggsMap[colId] ?? adaptable.api.columnApi.getDefaultAggFunc(colId); return { ColumnId: colId, AggFunc, }; }), }); }, [layout]); const handleAggregationChange = React.useCallback((aggFunctions) => { props.onChange({ ...layout, TableAggregationColumns: aggFunctions, }); }, [layout]); const aggregationColumnsMap = React.useMemo(() => { const allColumnsMap = allColumns.reduce((acc, col) => { acc[col.columnId] = col; return acc; }, {}); return (layout.TableAggregationColumns || []).reduce((acc, { ColumnId: colId, AggFunc }) => { let fn = AggFunc; let fnName = ''; if (typeof fn === 'boolean') { fnName = allColumnsMap[colId].aggregationFunction; } if (typeof fn === 'object' && fn.type === 'weightedAverage') { fnName = WEIGHTED_AVERAGE_AGG_FN_NAME; } else if (typeof fn === 'string') { fnName = fn; } acc[colId] = fnName; return acc; }, {}); }, [layout]); const handleSuppressAggFuncInHeader = (checked) => { props.onChange({ ...layout, SuppressAggFuncInHeader: checked, }); }; return (React.createElement(Tabs, { style: { height: '100%' } }, React.createElement(Tabs.Tab, null, "Column Aggregations"), React.createElement(Tabs.Content, null, React.createElement(Flex, null, React.createElement(FormLayout, null, React.createElement(CheckBox, { checked: layout.SuppressAggFuncInHeader, onChange: handleSuppressAggFuncInHeader }, "Suppress Aggregation Function Text in Column Header"))), React.createElement(ValueSelector, { showFilterInput: true, showSelectedOnlyPosition: "top", filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (column) => (React.createElement(ColumnRow, { onChangeAggFunction: handleAggregationChange, layout: layout, column: column, aggregationColumnsMap: aggregationColumnsMap, numberColumns: numberColumns })), options: sortedAggregableColumns, value: (layout.TableAggregationColumns || []).map((agg) => agg.ColumnId), allowReorder: () => true, xSelectedLabel: () => { return `Active aggregations:`; }, onChange: handleColumnsSelectionChange })))); };