@adaptabletools/adaptable 23.0.0-canary.2 → 23.0.0-canary.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.css +68 -73
- package/package.json +1 -1
- package/src/AdaptableOptions/DefaultAdaptableOptions.js +0 -4
- package/src/AdaptableOptions/FilterOptions.d.ts +0 -7
- package/src/AdaptableOptions/UserInterfaceOptions.d.ts +1 -3
- package/src/AdaptableState/Common/AdaptableForm.d.ts +18 -1
- package/src/AdaptableState/Common/AdaptableForm.js +31 -0
- package/src/AdaptableState/Common/AdaptableFormat.d.ts +1 -1
- package/src/AdaptableState/Common/CellDataChangedInfo.d.ts +3 -2
- package/src/AdaptableState/Common/Enums.d.ts +0 -5
- package/src/AdaptableState/Common/Enums.js +0 -6
- package/src/Api/EventApi.d.ts +1 -1
- package/src/Api/Events/ReportScheduleRan.d.ts +4 -0
- package/src/Api/Implementation/LayoutHelpers.js +12 -0
- package/src/Api/Internal/EventInternalApi.js +2 -1
- package/src/Strategy/CalculatedColumnModule.js +3 -1
- package/src/Utilities/Services/CalculatedColumnExpressionService.d.ts +1 -0
- package/src/Utilities/Services/CalculatedColumnExpressionService.js +7 -0
- package/src/Utilities/Services/CalculatedColumnSyntheticChange.d.ts +4 -0
- package/src/Utilities/Services/CalculatedColumnSyntheticChange.js +115 -0
- package/src/Utilities/Services/Interface/ICalculatedColumnExpressionService.d.ts +1 -0
- package/src/View/AdaptablePopover/index.js +1 -1
- package/src/View/Charting/ChartingWizard/AgChargingWizard/SettingsSection.js +8 -16
- package/src/View/Components/Buttons/ButtonInfo.d.ts +1 -1
- package/src/View/Components/Buttons/ButtonInfo.js +4 -3
- package/src/View/Components/ColumnFilter/AdaptableColumnFilter.js +1 -1
- package/src/View/Components/ColumnFilter/ColumnFilter.js +15 -5
- package/src/View/Components/ColumnFilter/ColumnFilterWindow.js +1 -1
- package/src/View/Components/ColumnFilter/FloatingFilter.js +58 -60
- package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -1
- package/src/View/Components/Forms/AdaptableFormControlTextClear.js +2 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopup.js +1 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +2 -2
- package/src/View/Components/Selectors/ColumnSelector.js +5 -0
- package/src/View/Components/ValueSelector/index.js +1 -1
- package/src/View/FlashingCell/Wizard/FlashingCellScopeWizardSection.js +3 -1
- package/src/View/FormatColumn/Wizard/FormatColumnScopeWizardSection.js +3 -8
- package/src/View/GridFilter/GridFilterViewPanel.js +1 -1
- package/src/View/Layout/LayoutViewPanel.js +23 -21
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +3 -3
- package/src/View/Layout/Wizard/sections/PivotColumnsSection.js +1 -1
- package/src/View/Layout/Wizard/sections/RowSelectionSection.js +1 -1
- package/src/View/Layout/Wizard/sections/SettingsSection.js +1 -1
- package/src/View/License/LicenseWatermark.js +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardScopeSection.js +1 -1
- package/src/View/Wizard/OnePageWizards.js +1 -1
- package/src/View/renderWithAdaptableContext.js +2 -3
- package/src/agGrid/AdaptableAgGrid.d.ts +0 -1
- package/src/agGrid/AdaptableAgGrid.js +3 -18
- package/src/agGrid/AgGridColumnAdapter.js +1 -4
- package/src/components/AdaptableFormComponent/AdaptableFormComponent.js +11 -6
- package/src/components/Card/index.js +1 -1
- package/src/components/Combobox/VirtualizedList.js +5 -5
- package/src/components/Combobox/comboboxUtils.d.ts +4 -1
- package/src/components/Combobox/comboboxUtils.js +2 -0
- package/src/components/Combobox/index.d.ts +1 -0
- package/src/components/Combobox/index.js +38 -12
- package/src/components/Datepicker/index.js +2 -2
- package/src/components/Dialog/index.js +1 -1
- package/src/components/DragAndDropContext/TabList.js +1 -1
- package/src/components/Dropdown/Arrows.js +0 -1
- package/src/components/ExpressionEditor/BaseEditorInput.js +1 -1
- package/src/components/ExpressionEditor/index.js +1 -1
- package/src/components/Input/index.js +1 -1
- package/src/components/NewDropdownButton/index.d.ts +1 -0
- package/src/components/NewDropdownButton/index.js +2 -2
- package/src/components/NewSelect/index.d.ts +2 -0
- package/src/components/NewSelect/index.js +10 -7
- package/src/components/Panel/index.js +1 -1
- package/src/components/SimpleButton/index.js +1 -1
- package/src/components/Tabs/index.js +1 -1
- package/src/components/Tree/TreeDropdown/index.js +6 -14
- package/src/components/ui/button.d.ts +5 -2
- package/src/components/ui/button.js +5 -4
- package/src/components/ui/combobox.d.ts +16 -16
- package/src/components/ui/combobox.js +37 -37
- package/src/components/ui/input-group.d.ts +10 -9
- package/src/components/ui/input-group.js +13 -12
- package/src/components/ui/input.d.ts +2 -2
- package/src/components/ui/input.js +5 -4
- package/src/components/ui/popover.d.ts +5 -5
- package/src/components/ui/popover.js +7 -7
- package/src/components/ui/select.d.ts +7 -6
- package/src/components/ui/select.js +13 -12
- package/src/components/ui/textarea.d.ts +2 -2
- package/src/components/ui/textarea.js +4 -3
- package/src/components/ui/tooltip.d.ts +6 -5
- package/src/components/ui/tooltip.js +8 -7
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +5 -1
- package/src/lib/utils.d.ts +20 -0
- package/src/lib/utils.js +45 -0
- package/src/metamodel/adaptable.metamodel.d.ts +7 -19
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/migration/VersionUpgrade23.d.ts +2 -3
- package/src/migration/VersionUpgrade23.js +4 -16
- package/src/types.d.ts +0 -1
- package/themes/dark.css +7 -17
- package/tsconfig.esm.tsbuildinfo +1 -1
- package/src/AdaptableState/Common/FilterActionOnDataChange.d.ts +0 -17
- package/src/AdaptableState/Common/FilterActionOnDataChange.js +0 -4
- package/src/View/AdaptableComputedCSSVarsContext.d.ts +0 -12
- package/src/View/AdaptableComputedCSSVarsContext.js +0 -29
- package/src/components/Select/CSSNumericVariableWatch.d.ts +0 -11
- package/src/components/Select/CSSNumericVariableWatch.js +0 -45
|
@@ -32,7 +32,9 @@ export class CalculatedColumnModule extends AdaptableModuleBase {
|
|
|
32
32
|
this.api.internalApi
|
|
33
33
|
.getDataService()
|
|
34
34
|
.on('CellDataChanged', (cellDataChangedInfo) => {
|
|
35
|
-
if (cellDataChangedInfo.trigger !== 'aggChange' &&
|
|
35
|
+
if (cellDataChangedInfo.trigger !== 'aggChange' &&
|
|
36
|
+
cellDataChangedInfo.trigger !== 'calculatedColumnChange' &&
|
|
37
|
+
!cellDataChangedInfo.preventEdit) {
|
|
36
38
|
this.api.internalApi
|
|
37
39
|
.getCalculatedColumnExpressionService()
|
|
38
40
|
.listentoCellDataChange(cellDataChangedInfo);
|
|
@@ -8,6 +8,7 @@ export declare class CalculatedColumnExpressionService implements ICalculatedCol
|
|
|
8
8
|
private adaptableApi;
|
|
9
9
|
private aggregatedScalarLiveValuesMap;
|
|
10
10
|
constructor(adaptableApi: AdaptableApi);
|
|
11
|
+
buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo: CellDataChangedInfo): CellDataChangedInfo[];
|
|
11
12
|
listentoCellDataChange(cellDataChangedInfo: CellDataChangedInfo): void;
|
|
12
13
|
listentoRowDataChange(rowDataChangedInfo: RowDataChangedInfo): void;
|
|
13
14
|
destroy(): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CalculatedColumnModuleId } from '../Constants/ModuleConstants';
|
|
2
2
|
import { AggregatedScalarLiveValue } from './AggregatedScalarLiveValue';
|
|
3
|
+
import { buildSyntheticCellDataChangedInfosForCalcColumns } from './CalculatedColumnSyntheticChange';
|
|
3
4
|
export class CalculatedColumnExpressionService {
|
|
4
5
|
adaptableApi;
|
|
5
6
|
aggregatedScalarLiveValuesMap = new Map();
|
|
@@ -7,7 +8,13 @@ export class CalculatedColumnExpressionService {
|
|
|
7
8
|
this.adaptableApi = adaptableApi;
|
|
8
9
|
this.adaptableApi = adaptableApi;
|
|
9
10
|
}
|
|
11
|
+
buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo) {
|
|
12
|
+
return buildSyntheticCellDataChangedInfosForCalcColumns(this.adaptableApi, cellDataChangedInfo);
|
|
13
|
+
}
|
|
10
14
|
listentoCellDataChange(cellDataChangedInfo) {
|
|
15
|
+
if (cellDataChangedInfo.trigger === 'calculatedColumnChange') {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
11
18
|
const refreshedCalculatedColumns = [];
|
|
12
19
|
this.aggregatedScalarLiveValuesMap.forEach((aggregatedScalarLiveValue, calculatedColumnId) => {
|
|
13
20
|
const calculatedColumn = this.adaptableApi.calculatedColumnApi.getCalculatedColumnById(calculatedColumnId);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AdaptableApi } from '../../types';
|
|
2
|
+
import { CellDataChangedInfo } from '../../AdaptableState/Common/CellDataChangedInfo';
|
|
3
|
+
export declare function buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi: AdaptableApi, info: CellDataChangedInfo): CellDataChangedInfo[];
|
|
4
|
+
export declare function expandCellDataChangedInfosWithCalculatedColumns(adaptableApi: AdaptableApi, cellDataChangedInfos: CellDataChangedInfo[]): CellDataChangedInfo[];
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as parser from '../../parser/src';
|
|
2
|
+
import { CalculatedColumnModuleId } from '../Constants/ModuleConstants';
|
|
3
|
+
import Helper from '../Helpers/Helper';
|
|
4
|
+
function isScalarCalculatedColumn(calculatedColumn) {
|
|
5
|
+
return !!calculatedColumn.Query?.ScalarExpression;
|
|
6
|
+
}
|
|
7
|
+
function collectDependentScalarCalculatedColumns(adaptableApi, rootColumnId) {
|
|
8
|
+
const collected = [];
|
|
9
|
+
const seenCalcColumnIds = new Set();
|
|
10
|
+
const queue = [rootColumnId];
|
|
11
|
+
while (queue.length > 0) {
|
|
12
|
+
const columnId = queue.shift();
|
|
13
|
+
const adaptableColumn = adaptableApi.columnApi.getColumnWithColumnId(columnId);
|
|
14
|
+
if (!adaptableColumn) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const dependentColumnIds = adaptableApi.calculatedColumnApi.internalApi.getCalculatedColumnsDependentOnColumn(adaptableColumn);
|
|
18
|
+
dependentColumnIds.forEach((dependentColumnId) => {
|
|
19
|
+
if (seenCalcColumnIds.has(dependentColumnId)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const calculatedColumn = adaptableApi.calculatedColumnApi.getCalculatedColumnForColumnId(dependentColumnId);
|
|
23
|
+
if (!calculatedColumn || !isScalarCalculatedColumn(calculatedColumn)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
seenCalcColumnIds.add(dependentColumnId);
|
|
27
|
+
collected.push(calculatedColumn);
|
|
28
|
+
queue.push(dependentColumnId);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return collected;
|
|
32
|
+
}
|
|
33
|
+
function buildShadowRowData(adaptableApi, info) {
|
|
34
|
+
const shadowData = Helper.cloneObject(info.rowNode?.data ?? info.rowData ?? {});
|
|
35
|
+
const fieldName = info.column.field ?? info.column.columnId;
|
|
36
|
+
adaptableApi.internalApi.setValueUsingField(shadowData, fieldName, info.oldValue);
|
|
37
|
+
return shadowData;
|
|
38
|
+
}
|
|
39
|
+
function evaluateScalarExpressionWithShadowData(adaptableApi, calculatedColumn, rowNode, shadowData) {
|
|
40
|
+
const internalApi = adaptableApi.internalApi;
|
|
41
|
+
const moduleFns = internalApi
|
|
42
|
+
.getQueryLanguageService()
|
|
43
|
+
.getModuleExpressionFunctionsMap(CalculatedColumnModuleId);
|
|
44
|
+
const baseFunctions = { ...moduleFns.booleanFunctions, ...moduleFns.scalarFunctions };
|
|
45
|
+
const resolveColumnValue = (columnId) => {
|
|
46
|
+
const childCalculatedColumn = adaptableApi.calculatedColumnApi.getCalculatedColumnForColumnId(columnId);
|
|
47
|
+
if (childCalculatedColumn?.Query?.ScalarExpression) {
|
|
48
|
+
return evaluateScalarExpressionWithShadowData(adaptableApi, childCalculatedColumn, rowNode, shadowData);
|
|
49
|
+
}
|
|
50
|
+
const adaptableColumn = adaptableApi.columnApi.getColumnWithColumnId(columnId);
|
|
51
|
+
return internalApi.getValueUsingField(shadowData, adaptableColumn?.field ?? columnId);
|
|
52
|
+
};
|
|
53
|
+
const customFunctions = {
|
|
54
|
+
...baseFunctions,
|
|
55
|
+
COL: {
|
|
56
|
+
...baseFunctions.COL,
|
|
57
|
+
handler: (args) => resolveColumnValue(args[0]),
|
|
58
|
+
},
|
|
59
|
+
FIELD: {
|
|
60
|
+
...baseFunctions.FIELD,
|
|
61
|
+
handler: (args) => internalApi.getValueUsingField(shadowData, args[0]),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
return parser.evaluate(calculatedColumn.Query.ScalarExpression, {
|
|
65
|
+
node: { ...rowNode, data: shadowData },
|
|
66
|
+
functions: customFunctions,
|
|
67
|
+
...internalApi.buildBaseContext(),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export function buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi, info) {
|
|
71
|
+
if (!info.rowNode ||
|
|
72
|
+
info.preventEdit ||
|
|
73
|
+
info.trigger === 'undo' ||
|
|
74
|
+
info.trigger === 'aggChange' ||
|
|
75
|
+
info.trigger === 'calculatedColumnChange') {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const calculatedColumns = collectDependentScalarCalculatedColumns(adaptableApi, info.column.columnId);
|
|
79
|
+
if (!calculatedColumns.length) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const shadowData = buildShadowRowData(adaptableApi, info);
|
|
83
|
+
const expressionService = adaptableApi.internalApi.getCalculatedColumnExpressionService();
|
|
84
|
+
const syntheticEvents = [];
|
|
85
|
+
calculatedColumns.forEach((calculatedColumn) => {
|
|
86
|
+
const oldValue = evaluateScalarExpressionWithShadowData(adaptableApi, calculatedColumn, info.rowNode, shadowData);
|
|
87
|
+
const newValue = expressionService.evaluateCalculatedColumnQuery(calculatedColumn, info.rowNode);
|
|
88
|
+
if (oldValue == newValue) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const column = adaptableApi.columnApi.getColumnWithColumnId(calculatedColumn.ColumnId);
|
|
92
|
+
if (!column) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
syntheticEvents.push(adaptableApi.internalApi.buildCellDataChangedInfo({
|
|
96
|
+
oldValue,
|
|
97
|
+
newValue,
|
|
98
|
+
column,
|
|
99
|
+
primaryKeyValue: info.primaryKeyValue,
|
|
100
|
+
rowNode: info.rowNode,
|
|
101
|
+
trigger: 'calculatedColumnChange',
|
|
102
|
+
}));
|
|
103
|
+
});
|
|
104
|
+
return syntheticEvents;
|
|
105
|
+
}
|
|
106
|
+
export function expandCellDataChangedInfosWithCalculatedColumns(adaptableApi, cellDataChangedInfos) {
|
|
107
|
+
if (!cellDataChangedInfos.length) {
|
|
108
|
+
return cellDataChangedInfos;
|
|
109
|
+
}
|
|
110
|
+
const syntheticEvents = cellDataChangedInfos.flatMap((info) => buildSyntheticCellDataChangedInfosForCalcColumns(adaptableApi, info));
|
|
111
|
+
if (!syntheticEvents.length) {
|
|
112
|
+
return cellDataChangedInfos;
|
|
113
|
+
}
|
|
114
|
+
return [...cellDataChangedInfos, ...syntheticEvents];
|
|
115
|
+
}
|
|
@@ -11,4 +11,5 @@ export interface ICalculatedColumnExpressionService extends IAdaptableService {
|
|
|
11
11
|
destroyAggregatedScalarLiveValue(calculatedColumn: CalculatedColumn): void;
|
|
12
12
|
listentoCellDataChange(cellDataChangedInfo: CellDataChangedInfo): void;
|
|
13
13
|
listentoRowDataChange(rowDataChangedInfo: RowDataChangedInfo): void;
|
|
14
|
+
buildSyntheticCellDataChangedInfosForCalcColumns(cellDataChangedInfo: CellDataChangedInfo): CellDataChangedInfo[];
|
|
14
15
|
}
|
|
@@ -25,7 +25,7 @@ export class AdaptablePopover extends React.Component {
|
|
|
25
25
|
const openOnHover = showEvent === 'mouseenter';
|
|
26
26
|
const triggerElement = useButton ? (_jsx(ButtonInfo, { style: iconStyle, variant: "text", onClick: () => null, icon: showIcon && icon, tooltip: this.props.tooltipText, disabled: this.props.disabled, children: this.props.children })) : (_jsxs("div", { title: this.props.tooltipText, tabIndex: 0, style: { cursor: 'pointer', display: 'inline-block' }, children: [this.props.children, showIcon && _jsx(Icon, { name: icon, style: iconStyle })] }));
|
|
27
27
|
const controlledProps = this.props.visible !== undefined ? { open: this.props.visible } : {};
|
|
28
|
-
return (_jsx(Flex, { alignItems: "center", className: this.props.className, children: _jsxs(Popover, { ...controlledProps, children: [_jsx(PopoverTrigger, { nativeButton: !!useButton, openOnHover: openOnHover, delay: 0, closeDelay: 0, render: triggerElement }), _jsxs(PopoverContent, { align: "start", sideOffset: 10, className: "ab-Popover twa:w-auto twa:gap-0 twa:p-0", style: {
|
|
28
|
+
return (_jsx(Flex, { alignItems: "center", className: this.props.className, children: _jsxs(Popover, { ...controlledProps, children: [_jsx(PopoverTrigger, { nativeButton: !!useButton, openOnHover: openOnHover, delay: 0, closeDelay: 0, render: triggerElement }), _jsxs(PopoverContent, { align: "start", sideOffset: 10, className: "ab-Popover twa:border twa:border-primarylight twa:w-auto twa:gap-0 twa:p-0", style: {
|
|
29
29
|
minWidth: popoverMinWidth,
|
|
30
30
|
maxWidth: this.props.popoverMaxWidth ?? 300,
|
|
31
31
|
}, children: [title ? _jsx(Box, { className: "twa:text-4 twa:p-2", children: title }) : null, _jsx(Box, { className: `ab-Popover__body ${(this.props.popupPadding ?? 2) === 0 ? 'twa:p-0' : 'twa:p-2'}`, children: this.props.bodyText.map((textOrHTML, index) => (_jsx("span", { children: textOrHTML }, index))) })] })] }) }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { CheckBox } from '../../../../components/CheckBox';
|
|
4
|
-
import
|
|
4
|
+
import { SingleSelect } from '../../../../components/NewSelect';
|
|
5
5
|
import FormLayout, { FormRow } from '../../../../components/FormLayout';
|
|
6
6
|
import { validateChartName } from '../../../../Utilities/Helpers/chartingHelper';
|
|
7
7
|
import AdaptableInput from '../../../Components/AdaptableInput';
|
|
@@ -35,27 +35,19 @@ export const SettingsSection = (props) => {
|
|
|
35
35
|
});
|
|
36
36
|
}, [props.chartDefinition]);
|
|
37
37
|
const aggFuncs = ['sum', 'min', 'max', 'count', 'avg', 'first', 'last'];
|
|
38
|
-
const aggFuncsOptions = aggFuncs.map((aggFunc) => ({
|
|
39
|
-
label: aggFunc,
|
|
40
|
-
onClick: () => {
|
|
41
|
-
props.onChange({
|
|
42
|
-
...props.chartDefinition,
|
|
43
|
-
Model: {
|
|
44
|
-
...props.chartDefinition.Model,
|
|
45
|
-
aggFunc,
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
}));
|
|
50
38
|
const aggFunc = props.chartDefinition.Model.aggFunc;
|
|
51
|
-
const
|
|
39
|
+
const handleAggFuncChange = React.useCallback((value) => {
|
|
52
40
|
props.onChange({
|
|
53
41
|
...props.chartDefinition,
|
|
54
42
|
Model: {
|
|
55
43
|
...props.chartDefinition.Model,
|
|
56
|
-
aggFunc:
|
|
44
|
+
aggFunc: value,
|
|
57
45
|
},
|
|
58
46
|
});
|
|
59
47
|
}, [props.chartDefinition]);
|
|
60
|
-
|
|
48
|
+
const aggFuncsOptions = aggFuncs.map((option) => ({
|
|
49
|
+
label: option,
|
|
50
|
+
value: option,
|
|
51
|
+
}));
|
|
52
|
+
return (_jsxs(FormLayout, { children: [_jsx(FormRow, { label: "Name", children: _jsx(AdaptableInput, { onChange: handleNameChange, value: props.chartDefinition.Name }) }), _jsx(FormRow, { label: "Unlink Chart", children: _jsx(CheckBox, { onClick: handleUnLinkChange, checked: props.chartDefinition.Model.unlinkChart }) }), _jsx(FormRow, { label: "Suppress Chart Ranges", children: _jsx(CheckBox, { onClick: handleSuppressChartRanges, checked: props.chartDefinition.Model.suppressChartRanges }) }), props.chartDefinition.Model.modelType === 'range' && typeof aggFunc !== 'function' && (_jsx(FormRow, { label: "Agg Func", children: _jsx(SingleSelect, { placeholder: "Select", items: aggFuncsOptions, value: aggFunc || undefined, onValueChange: handleAggFuncChange }) }))] }));
|
|
61
53
|
};
|
|
@@ -4,4 +4,4 @@ export interface InfoButtonProps extends SimpleButtonProps {
|
|
|
4
4
|
glyph?: string;
|
|
5
5
|
tooltip?: string;
|
|
6
6
|
}
|
|
7
|
-
export declare const ButtonInfo: React.
|
|
7
|
+
export declare const ButtonInfo: React.ForwardRefExoticComponent<Omit<InfoButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
import SimpleButton from '../../../components/SimpleButton';
|
|
3
|
-
export const ButtonInfo = (props)
|
|
4
|
-
return (_jsx(SimpleButton, { "data-name": "info", iconSize: 20, icon: "info", variant: "raised", tone: "accent", ...props }));
|
|
5
|
-
};
|
|
4
|
+
export const ButtonInfo = React.forwardRef(function ButtonInfo(props, ref) {
|
|
5
|
+
return (_jsx(SimpleButton, { ref: ref, "data-name": "info", iconSize: 20, icon: "info", variant: "raised", tone: "accent", ...props }));
|
|
6
|
+
});
|
|
@@ -19,7 +19,7 @@ export const AdaptableColumnFilter = (props) => {
|
|
|
19
19
|
handlePredicateChange(predicate);
|
|
20
20
|
}, [handlePredicateChange]) }) }));
|
|
21
21
|
if (props.location === 'filtersToolPanel') {
|
|
22
|
-
return (_jsx(Panel, { className: "twa:
|
|
22
|
+
return (_jsx(Panel, { className: "twa:p-1", bodyProps: { className: 'twa:p-0 twa:border-none' }, children: filterContent }));
|
|
23
23
|
}
|
|
24
24
|
return filterContent;
|
|
25
25
|
};
|
|
@@ -11,11 +11,13 @@ import clsx from 'clsx';
|
|
|
11
11
|
import { twMerge } from '../../../twMerge';
|
|
12
12
|
import { SingleSelect } from '../../../components/NewSelect';
|
|
13
13
|
import { isEmbeddedColumnFilterLocation } from './columnFilterLocation';
|
|
14
|
+
import { captureTab } from '../../../lib/utils';
|
|
14
15
|
const ColumnFilterPredicateDropdown = (props) => {
|
|
15
16
|
const predicateDef = usePredicateDef(props.predicate?.operator, props.predicateDefs);
|
|
16
17
|
const options = props.predicateDefs.map((predicateDef) => {
|
|
17
18
|
return {
|
|
18
|
-
label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(SimpleButton, { as: "span", variant: "raised", className: "twa:mr-2", tone: "accent", children: predicateDef.icon }), predicateDef.label] })),
|
|
19
|
+
label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(SimpleButton, { as: "span", variant: "raised", className: "twa:mr-2 twa:p-0.5", tone: "accent", children: predicateDef.icon }), predicateDef.label] })),
|
|
20
|
+
tooltip: predicateDef.label,
|
|
19
21
|
value: predicateDef.operator,
|
|
20
22
|
};
|
|
21
23
|
});
|
|
@@ -23,15 +25,14 @@ const ColumnFilterPredicateDropdown = (props) => {
|
|
|
23
25
|
const isAndOr = operator === 'AND' || operator === 'OR';
|
|
24
26
|
return (_jsx(Box, { className: "twa:flex twa:items-center ab-ColumnFilterPredicateDropdown twa:p-0.5", style: {
|
|
25
27
|
//@ts-ignore ignore
|
|
26
|
-
'--ab-cmp-input__background': 'var(--ab-color-primary)',
|
|
27
28
|
'--ab-color-input-background': 'var(--ab-color-primary)',
|
|
28
|
-
}, children: _jsx(SingleSelect, { "data-name": "filter-predicate-dropdown",
|
|
29
|
+
}, children: _jsx(SingleSelect, { "data-name": "filter-predicate-dropdown", extraWidthChars: 8,
|
|
29
30
|
// The trigger lives inside ag-grid's column menu, which closes itself
|
|
30
31
|
// on mousedowns outside its DOM subtree. Since the popup is portaled
|
|
31
32
|
// to `document.body`, mousedowns inside it would otherwise bubble to
|
|
32
33
|
// `document` and unmount the trigger mid-interaction (causing the
|
|
33
34
|
// popup to re-align to (0,0) before disappearing).
|
|
34
|
-
stopMouseDownPropagation: true, className: predicateDef ? `twa:min-w-[10rem]` : null, onValueChange: (value) => {
|
|
35
|
+
stopMouseDownPropagation: true, showItemTooltip: true, className: predicateDef ? `twa:min-w-[10rem]` : null, onValueChange: (value) => {
|
|
35
36
|
props.onPredicateChange({
|
|
36
37
|
operator: value,
|
|
37
38
|
args: [],
|
|
@@ -60,6 +61,7 @@ const AndOrInput = (props) => {
|
|
|
60
61
|
export const ColumnFilterComponent = (props) => {
|
|
61
62
|
const adaptable = useAdaptable();
|
|
62
63
|
const manuallyApplyColumnFilter = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId);
|
|
64
|
+
const rootRef = React.useRef(null);
|
|
63
65
|
const contentWrapperRef = React.useRef(null);
|
|
64
66
|
React.useEffect(() => {
|
|
65
67
|
if (props.location !== 'columnMenu')
|
|
@@ -69,6 +71,14 @@ export const ColumnFilterComponent = (props) => {
|
|
|
69
71
|
const dropdown = contentWrapperRef.current?.querySelector('[data-name="filter-predicate-dropdown"]');
|
|
70
72
|
dropdown?.focus();
|
|
71
73
|
}, [props.location]);
|
|
74
|
+
// When rendered inside ag-grid's column menu, Tabbing would otherwise escape
|
|
75
|
+
// to the surrounding menu/grid. Trap focus so Tab / Shift+Tab cycle within the filter.
|
|
76
|
+
const handleFocusTrap = React.useCallback((e) => {
|
|
77
|
+
if (props.location !== 'columnMenu') {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
captureTab(rootRef.current, e);
|
|
81
|
+
}, [props.location]);
|
|
72
82
|
const [predicateNotYetApplied, setPredicateNotYetApplied] = React.useState(props.predicate);
|
|
73
83
|
const applyFilter = () => {
|
|
74
84
|
props.onPredicateChange(currentPredicateRef.current);
|
|
@@ -129,7 +139,7 @@ export const ColumnFilterComponent = (props) => {
|
|
|
129
139
|
.map((qlPredicate) => mapQlPredicateToAdaptablePredicate(qlPredicate))
|
|
130
140
|
.some((adaptablePredicate) => adaptable.api.predicateApi.isValidPredicate(adaptablePredicate));
|
|
131
141
|
};
|
|
132
|
-
return (_jsxs(
|
|
142
|
+
return (_jsxs("div", { ref: rootRef, onKeyDown: handleFocusTrap, className: "twa:contents", children: [_jsxs(Flex, { flexDirection: "column", className: clsx({
|
|
133
143
|
'twa:pb-2': !props.hideActionButtons,
|
|
134
144
|
'twa:mb-2': isEmbeddedColumnFilterLocation(props.location),
|
|
135
145
|
'twa:mt-2 twa:ml-2 twa:mr-2': props.location === 'columnMenu',
|
|
@@ -28,5 +28,5 @@ export const ColumnFilterWindow = (props) => {
|
|
|
28
28
|
return (_jsxs(Flex, { children: [label, _jsx(Box, { className: "twa:flex-1" }), _jsx(AdaptableIconComponent, { icon: { name: 'filter' } })] }));
|
|
29
29
|
}
|
|
30
30
|
return label;
|
|
31
|
-
}, onChange: (column) => setColumnId(column), filterColumn: (column) => column.queryable,
|
|
31
|
+
}, onChange: (column) => setColumnId(column), filterColumn: (column) => column.queryable, value: columnId }) }) }) }), _jsx(AdaptableColumnFilter, { columnId: columnId, location: 'filterForm' })] }));
|
|
32
32
|
};
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import OverlayTrigger from '../../../components/OverlayTrigger';
|
|
4
3
|
import SimpleButton from '../../../components/SimpleButton';
|
|
5
4
|
import { useAdaptable } from '../../AdaptableContext';
|
|
6
5
|
import { AdaptableIconComponent } from '../AdaptableIconComponent';
|
|
7
|
-
import {
|
|
6
|
+
import { SingleSelect } from '../../../components/NewSelect';
|
|
8
7
|
import { FloatingFilterInputList } from './components/FloatingFilterInputList';
|
|
9
8
|
import { isPredicateEmpty, qlPredicateToString } from './utils';
|
|
10
9
|
import { AG_GRID_GROUPED_COLUMN } from '../../../Utilities/Constants/GeneralConstants';
|
|
11
10
|
import { Box, Flex } from '../../../components/Flex';
|
|
12
|
-
import { cn } from '../../../lib/utils';
|
|
11
|
+
import { cn, getFocusableElements } from '../../../lib/utils';
|
|
13
12
|
import { Maximize2 } from 'lucide-react';
|
|
14
13
|
export const FloatingFilter = (props) => {
|
|
15
14
|
const adaptable = useAdaptable();
|
|
@@ -40,75 +39,74 @@ export const FloatingFilter = (props) => {
|
|
|
40
39
|
const colDef = adaptable.api.columnApi.getAGGridColDefForColumnId(props.columnId);
|
|
41
40
|
const showExpandFilterButton = colDef?.suppressHeaderFilterButton !== true;
|
|
42
41
|
const handleClear = () => props.onClear?.();
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
42
|
+
const [selectOpen, setSelectOpen] = React.useState(false);
|
|
43
|
+
const currentOperator = props.predicate?.args[0]?.operator;
|
|
44
|
+
const operatorOptions = props.predicateDefs.map((predicateDef) => ({
|
|
45
|
+
label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(Box, { className: "twa:mr-2 twa:flex twa:items-center", children: predicateDef.icon }), _jsx(Box, { className: "twa:truncate", "data-name": "filter-predicate-label", "data-label": predicateDef.label, children: predicateDef.label })] })),
|
|
46
|
+
tooltip: predicateDef.label,
|
|
47
|
+
value: predicateDef.operator,
|
|
48
|
+
}));
|
|
49
|
+
const renderTriggerValue = () => (_jsxs(Flex, { alignItems: "center", className: "twa:min-w-0", children: [_jsx(Box, { className: "twa:flex twa:items-center", children: !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (_jsx(AdaptableIconComponent, { icon: { name: 'filter' } })) }), showLabel && (_jsx(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1 twa:truncate", title: label, children: label }))] }));
|
|
46
50
|
let filterDropdown = null;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}, "data-value": props.predicate?.args[0]?.operator, onClick: () => {
|
|
52
|
-
if (!isInlineEditable) {
|
|
51
|
+
const filterDropdownSelect = (_jsx(SingleSelect, { chevronIcon: null, "data-name": "floating-filter-button", ariaLabel: "Column Filter Operator Dropdown", size: "small", stopMouseDownPropagation: true, disabled: props.disabled, open: selectOpen, extraWidthChars: 5, onOpenChange: (nextOpen) => {
|
|
52
|
+
// In non-inline mode the select doesn't pick an operator inline; opening it
|
|
53
|
+
// instead opens the full column filter popup, so keep the dropdown closed.
|
|
54
|
+
if (nextOpen && !isInlineEditable) {
|
|
53
55
|
adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId);
|
|
56
|
+
return;
|
|
54
57
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
flex: 1,
|
|
63
|
-
}
|
|
64
|
-
: {}),
|
|
65
|
-
}, children: [_jsx(Box, { children: !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (_jsx(AdaptableIconComponent, { icon: { name: 'filter' } })) }), showLabel && (_jsx(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1", title: label, children: label }))] }));
|
|
58
|
+
setSelectOpen(nextOpen);
|
|
59
|
+
}, value: currentOperator, placeholder: label, items: operatorOptions, showItemTooltip: true, renderValue: renderTriggerValue, onValueChange: (operator) => {
|
|
60
|
+
props.onPredicateChange({
|
|
61
|
+
operator: props.predicate.operator,
|
|
62
|
+
args: [{ operator: operator, args: [] }],
|
|
63
|
+
});
|
|
64
|
+
}, className: cn('twa:self-center twa:mx-0.5 twa:my-0.5 twa:text-left twa:p-0.5 twa:border-none', 'twa:shadow-none', !isInlineEditable && 'twa:min-w-0 twa:flex-1') }));
|
|
66
65
|
if (isInlineEditable) {
|
|
67
|
-
filterDropdown = showQuickFilterDropdown &&
|
|
68
|
-
// we render this only for single filter
|
|
69
|
-
return (_jsx(ColumnFilterMenu, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
|
|
70
|
-
setOverlayVisible(false);
|
|
71
|
-
props.onPredicateChange({
|
|
72
|
-
operator: props.predicate.operator,
|
|
73
|
-
args: [predicate],
|
|
74
|
-
});
|
|
75
|
-
} }));
|
|
76
|
-
}, children: filterDropdownButton }));
|
|
66
|
+
filterDropdown = showQuickFilterDropdown && filterDropdownSelect;
|
|
77
67
|
}
|
|
78
68
|
else {
|
|
79
|
-
filterDropdown =
|
|
69
|
+
filterDropdown = filterDropdownSelect;
|
|
80
70
|
}
|
|
81
71
|
const showClearButton = isMultiple ||
|
|
82
72
|
!isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef);
|
|
83
73
|
return (_jsxs(Flex, { className: "ab-FloatingFilter twa:w-full", onKeyDownCapture: (e) => {
|
|
84
74
|
// AG Grid's header keyboard navigation intercepts Tab and calls preventDefault(),
|
|
85
|
-
// which prevents focus from moving between
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
selectInput.focus();
|
|
98
|
-
// When the DummyInput gets focus the combobox sets isFocused=true,
|
|
99
|
-
// triggering a React re-render. During this re-render, unstable component
|
|
100
|
-
// references can cause the DummyInput to be removed from the DOM and
|
|
101
|
-
// recreated, losing focus. We restore focus after the re-render.
|
|
102
|
-
requestAnimationFrame(() => {
|
|
103
|
-
if (document.activeElement === document.body || document.activeElement === null) {
|
|
104
|
-
const newInput = wrapper.querySelector('[data-name="Select Values"] input');
|
|
105
|
-
newInput?.focus();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
75
|
+
// which prevents focus from moving between the controls inside the floating filter
|
|
76
|
+
// (operator select, filter input(s), expand/clear buttons). We handle Tab ourselves
|
|
77
|
+
// in the capture phase (before AG Grid's handlers) and move focus to the next/previous
|
|
78
|
+
// focusable control. At the boundaries we let the event through so AG Grid can move
|
|
79
|
+
// to the adjacent header cell.
|
|
80
|
+
if (e.key !== 'Tab') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const wrapper = e.currentTarget;
|
|
84
|
+
const focusable = getFocusableElements(wrapper);
|
|
85
|
+
if (focusable.length === 0) {
|
|
86
|
+
return;
|
|
111
87
|
}
|
|
88
|
+
const active = document.activeElement;
|
|
89
|
+
const currentIndex = active ? focusable.indexOf(active) : -1;
|
|
90
|
+
if (currentIndex === -1) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const nextIndex = currentIndex + (e.shiftKey ? -1 : 1);
|
|
94
|
+
if (nextIndex < 0 || nextIndex >= focusable.length) {
|
|
95
|
+
// boundary reached: let AG Grid navigate between header cells
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
e.nativeEvent.stopImmediatePropagation();
|
|
100
|
+
focusable[nextIndex]?.focus();
|
|
101
|
+
// Focusing the values combobox's input makes it set isFocused=true, which
|
|
102
|
+
// re-renders and can momentarily recreate the input, dropping focus to <body>.
|
|
103
|
+
// Re-resolve the target after the re-render and restore focus to it.
|
|
104
|
+
requestAnimationFrame(() => {
|
|
105
|
+
if (document.activeElement === document.body || document.activeElement === null) {
|
|
106
|
+
const refreshed = getFocusableElements(wrapper);
|
|
107
|
+
refreshed[Math.min(nextIndex, refreshed.length - 1)]?.focus();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
112
110
|
}, children: [filterDropdown, isInlineEditable && (_jsx(Flex, { className: "twa:flex-1 twa:min-w-0", children: _jsx(FloatingFilterInputList, { onKeyDown: props.onKeydown, columnId: props.columnId, disabled: props.disabled,
|
|
113
111
|
// It works only with a predicate
|
|
114
112
|
predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
|
|
@@ -162,7 +162,7 @@ export const ColumnValuesSelect = (props) => {
|
|
|
162
162
|
: props.onChange, items: options,
|
|
163
163
|
// for dates, the treeDateOptions have ids that are numbers
|
|
164
164
|
// so we have to add the `toDateValue` function to convert the values to the correct format
|
|
165
|
-
value: selectedColumnValues, primaryKey: 'value', isLoading: props.isLoading, onOpenChange: onOpenChange, showClear: isEmbeddedColumnFilterLocation(location) })) : (_jsx(GridFilterCombobox, { disabled: props.disabled, ...selectProps, onOpenChange: onOpenChange, items: options, value: value, isLoading: props.isLoading, onValueChange: props.onChange, showClear: isEmbeddedColumnFilterLocation(location) }, "select"));
|
|
165
|
+
value: selectedColumnValues, "data-name": "Select Values", primaryKey: 'value', isLoading: props.isLoading, onOpenChange: onOpenChange, showClear: isEmbeddedColumnFilterLocation(location) })) : (_jsx(GridFilterCombobox, { disabled: props.disabled, ...selectProps, onOpenChange: onOpenChange, items: options, value: value, isLoading: props.isLoading, onValueChange: props.onChange, showClear: isEmbeddedColumnFilterLocation(location) }, "select"));
|
|
166
166
|
return (_jsx("div", { className: join(baseClassName, 'twa:relative', props.isLoading && `${baseClassName}--loading`, !value.length && `${baseClassName}--empty`), onKeyDownCapture: (e) => {
|
|
167
167
|
if (e.key === 'Tab') {
|
|
168
168
|
// Prevent AG Grid from hijacking Tab; keep browser default focus navigation.
|
|
@@ -9,6 +9,7 @@ export const AdaptableFormControlTextClear = React.forwardRef((props, ref) => {
|
|
|
9
9
|
let closeButtonTooltip = props.value ? 'Clear' : null;
|
|
10
10
|
const inputRef = React.useRef(null);
|
|
11
11
|
const { focusOnClear = true } = props;
|
|
12
|
+
const clearDisabled = StringExtensions.IsNullOrEmpty(props.value.toString());
|
|
12
13
|
return (_jsxs(FieldWrap, { onClick: props.onClick, className: twMerge('twa:bg-input-background twa:text-input-foreground twa:overflow-visible twa:w-full twa:rounded-input', props.className), style: props.style, children: [_jsx(Input, { "aria-label": props['aria-label'], autoFocus: props.autoFocus, style: props.inputStyle, className: props.inputClassName, ref: (r) => {
|
|
13
14
|
inputRef.current = r;
|
|
14
15
|
if (!ref) {
|
|
@@ -31,5 +32,5 @@ export const AdaptableFormControlTextClear = React.forwardRef((props, ref) => {
|
|
|
31
32
|
input.focus();
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
|
-
}, disabled:
|
|
35
|
+
}, disabled: clearDisabled })] }));
|
|
35
36
|
});
|
|
@@ -67,7 +67,7 @@ export const AdaptablePopup = (props) => {
|
|
|
67
67
|
props.onHide();
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
|
-
}, children: _jsxs(AdaptablePopupDialog, { dataName: componentModule, baseClassName: baseClassName, className: className, friendlyName: friendlyName, isActionModule: isStandalone, isWindowModal: isWindowModal, onHide: props.onHide, modalContainer: modalContainer, children: [!isStandalone && _jsx(TopBar, { icon: settingsPanelOptions.icon, children: settingsPanelTitle }), _jsxs(Box, { className: clsx('twa:flex twa:flex-row twa:flex-1 twa:min-h-0', 'twa:bg-
|
|
70
|
+
}, children: _jsxs(AdaptablePopupDialog, { dataName: componentModule, baseClassName: baseClassName, className: className, friendlyName: friendlyName, isActionModule: isStandalone, isWindowModal: isWindowModal, onHide: props.onHide, modalContainer: modalContainer, children: [!isStandalone && _jsx(TopBar, { icon: settingsPanelOptions.icon, children: settingsPanelTitle }), _jsxs(Box, { className: clsx('twa:flex twa:flex-row twa:flex-1 twa:min-h-0', 'twa:bg-background twa:text-foreground', 'twa:rounded-bl-standard twa:rounded-br-standard', accessLevel == GeneralConstants.ACCESS_LEVEL_READ_ONLY
|
|
71
71
|
? GeneralConstants.READ_ONLY_STYLE
|
|
72
72
|
: ''), children: [!isStandalone && (_jsx(Navigation, { menuItems: menuItems, api: props.api, activeItem: activeItem, customSettingsPanels: settingsPanelOptions.customSettingsPanels })), _jsx(Box, { className: clsx('ab-Adaptable-Popup__Body', 'twa:bg-primarylight twa:text-primarylight-foreground', 'twa:flex twa:flex-1 twa:min-w-0 twa:overflow-auto', 'twa:rounded-br-standard', !isStandalone && 'twa:*:p-3'), children: moduleViewContent })] })] }) }));
|
|
73
73
|
};
|
|
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useDispatch, useSelector } from 'react-redux';
|
|
4
4
|
import { ACCESS_LEVEL_READ_ONLY } from '../../../../Utilities/Constants/GeneralConstants';
|
|
5
|
-
import DropdownButton from '../../../../components/DropdownButton';
|
|
6
5
|
import EmptyContent from '../../../../components/EmptyContent';
|
|
7
6
|
import { Icon } from '../../../../components/icons';
|
|
8
7
|
import { AdaptableObjectList } from '../../AdaptableObjectList';
|
|
@@ -17,6 +16,7 @@ import { useRerender } from '../../../../components/utils/useRerender';
|
|
|
17
16
|
import { Box, Flex } from '../../../../components/Flex';
|
|
18
17
|
import Panel from '../../../../components/Panel';
|
|
19
18
|
import { Tabs } from '../../../../components/Tabs';
|
|
19
|
+
import { NewDropdownButton } from '../../../../components/NewDropdownButton';
|
|
20
20
|
export const AdaptablePopupModuleView = (props) => {
|
|
21
21
|
/**
|
|
22
22
|
* This triggers a render for each state change.
|
|
@@ -80,7 +80,7 @@ export const AdaptablePopupModuleView = (props) => {
|
|
|
80
80
|
label: abObjectType.label ?? abObjectType.name,
|
|
81
81
|
};
|
|
82
82
|
});
|
|
83
|
-
newButton = (_jsxs(
|
|
83
|
+
newButton = (_jsxs(NewDropdownButton, { showDivider: false, tone: "accent", variant: "raised", items: items, tooltip: toolTipText, children: [_jsx(Icon, { name: "plus" }), " New"] }));
|
|
84
84
|
}
|
|
85
85
|
else if (!moduleViewProperties.hideNewButton &&
|
|
86
86
|
(EditWizard || moduleViewProperties.onOpenEditPopup)) {
|
|
@@ -15,6 +15,7 @@ export const ColumnSelector = function (props) {
|
|
|
15
15
|
return {
|
|
16
16
|
label,
|
|
17
17
|
textLabel,
|
|
18
|
+
tooltip: textLabel,
|
|
18
19
|
value: column.columnId,
|
|
19
20
|
};
|
|
20
21
|
})
|
|
@@ -31,7 +32,11 @@ export const ColumnSelector = function (props) {
|
|
|
31
32
|
virtualized: true,
|
|
32
33
|
items: options,
|
|
33
34
|
showClear: false,
|
|
35
|
+
showItemTooltip: true,
|
|
34
36
|
onValueChange: (colId) => {
|
|
37
|
+
if (colId === null) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
35
40
|
props.onChange(colId);
|
|
36
41
|
},
|
|
37
42
|
value: props.value,
|
|
@@ -101,7 +101,7 @@ export function ValueSelector(props) {
|
|
|
101
101
|
notifyChange();
|
|
102
102
|
},
|
|
103
103
|
};
|
|
104
|
-
return (_jsxs(Flex, { style: props.style, className: clsx('twa:flex-1', baseClassName), flexDirection: "column", children: [_jsx(Flex, { className: "twa:mb-1", children: showFilterInput && filter ? (_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", inputClassName: "twa:p-3", className: "twa:flex-1 twa:
|
|
104
|
+
return (_jsxs(Flex, { style: props.style, className: clsx('twa:flex-1', baseClassName), flexDirection: "column", children: [_jsx(Flex, { className: "twa:mb-1", children: showFilterInput && filter ? (_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", inputClassName: "twa:p-3", className: "twa:flex-1 twa:m-[3px]" })) : (_jsx(Box, { className: "twa:flex-1" })) }), renderSelectionSection(selectionSectionProps), _jsx(DragDropProvider, { children: _jsx(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column", children: _jsx(DragList, { dragListId: "value-selector", orientation: "vertical", onDragProxyMove: defaultDragProxyMove, onDragProxySetup: ({ proxyElement }) => {
|
|
105
105
|
proxyElement.classList.add('twa:shadow-md');
|
|
106
106
|
}, onDrop: (_sortedIndexes) => {
|
|
107
107
|
const selection = [];
|
|
@@ -6,7 +6,9 @@ import { Flex } from '../../../components/Flex';
|
|
|
6
6
|
import { isScopeColumnIds } from '../../../AdaptableState/Common/ColumnScope';
|
|
7
7
|
export const FlashingAlertScopeWizardSection = (props) => {
|
|
8
8
|
const { data, api } = useOnePageAdaptableWizardContext();
|
|
9
|
-
const availableColumns = React.useMemo(() => api.columnApi
|
|
9
|
+
const availableColumns = React.useMemo(() => api.columnApi
|
|
10
|
+
.getUIAvailableColumns()
|
|
11
|
+
.filter((column) => !column.isActionColumn && !api.columnApi.isFdc3Column(column.columnId)), [api]);
|
|
10
12
|
return (_jsx(Flex, { flexDirection: "column", className: "twa:p-2 twa:h-full", children: _jsx(NewScopeComponent, { descriptions: {
|
|
11
13
|
rowScope: 'Changes anywhere in the row will trigger an Flashing Cell',
|
|
12
14
|
columnScope: 'Changes in selected columns will trigger an Flashing Cell',
|