@adaptabletools/adaptable 23.0.0-canary.1 → 23.0.0-canary.3
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 +130 -137
- package/package.json +1 -1
- package/src/AdaptableOptions/UserInterfaceOptions.d.ts +1 -3
- package/src/AdaptableState/Common/AdaptableFormat.d.ts +1 -1
- package/src/AdaptableState/LayoutState.d.ts +5 -4
- package/src/AdaptableState/StyledColumnState.d.ts +7 -16
- package/src/AdaptableState/StyledColumnState.js +9 -1
- package/src/Api/EventApi.d.ts +1 -1
- package/src/Api/Events/ReportScheduleRan.d.ts +4 -0
- package/src/Api/Internal/EventInternalApi.js +2 -1
- package/src/View/AdaptablePopover/index.js +1 -1
- 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/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/ValueSelector/index.js +1 -1
- package/src/View/FormatColumn/Wizard/FormatColumnScopeWizardSection.js +3 -8
- package/src/View/GridFilter/GridFilterViewPanel.js +1 -1
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +4 -4
- package/src/View/Layout/Wizard/sections/PivotColumnsSection.js +1 -1
- package/src/View/Layout/Wizard/sections/RowGroupingSection.js +6 -2
- 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 +1 -1
- package/src/agGrid/AdaptableAgGrid.js +2 -2
- package/src/components/Card/index.js +1 -1
- package/src/components/Combobox/index.js +11 -5
- package/src/components/Datepicker/index.js +6 -6
- 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 +3 -3
- package/src/components/NewSelect/index.d.ts +2 -0
- package/src/components/NewSelect/index.js +12 -9
- package/src/components/NewTooltip/index.js +1 -1
- 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 +4 -8
- package/src/components/ui/button.d.ts +5 -2
- package/src/components/ui/button.js +6 -5
- package/src/components/ui/calendar.d.ts +1 -1
- package/src/components/ui/calendar.js +2 -2
- package/src/components/ui/combobox.d.ts +16 -16
- package/src/components/ui/combobox.js +39 -39
- package/src/components/ui/dropdown-menu.js +1 -1
- package/src/components/ui/input-group.d.ts +10 -9
- package/src/components/ui/input-group.js +17 -16
- package/src/components/ui/input.d.ts +2 -2
- package/src/components/ui/input.js +6 -5
- package/src/components/ui/popover.d.ts +5 -5
- package/src/components/ui/popover.js +8 -8
- package/src/components/ui/select.d.ts +7 -6
- package/src/components/ui/select.js +14 -13
- package/src/components/ui/textarea.d.ts +2 -2
- package/src/components/ui/textarea.js +5 -4
- package/src/components/ui/tooltip.d.ts +6 -5
- package/src/components/ui/tooltip.js +9 -8
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +2 -2
- package/src/layout-manager/src/index.js +5 -4
- package/src/layout-manager/src/normalizeLayoutModel.js +5 -1
- package/src/layout-manager/src/rowGroupDisplayType.d.ts +6 -0
- package/src/layout-manager/src/rowGroupDisplayType.js +24 -0
- package/src/lib/utils.d.ts +20 -0
- package/src/lib/utils.js +45 -0
- package/src/metamodel/adaptable.metamodel.d.ts +7 -26
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/migration/VersionUpgrade23.d.ts +2 -3
- package/src/migration/VersionUpgrade23.js +4 -16
- package/themes/dark.css +7 -17
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -99,7 +99,8 @@ export class EventInternalApi extends ApiBase {
|
|
|
99
99
|
fireScheduledReportRanEvent(reportSchedule) {
|
|
100
100
|
const reportScheduleRanInfo = {
|
|
101
101
|
...this.getAdaptableInternalApi().buildBaseContext(),
|
|
102
|
-
reportSchedule
|
|
102
|
+
reportSchedule,
|
|
103
|
+
RanAt: new Date().toISOString(),
|
|
103
104
|
};
|
|
104
105
|
this.getEventApi().emit('ReportScheduleRan', reportScheduleRanInfo);
|
|
105
106
|
}
|
|
@@ -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))) })] })] }) }));
|
|
@@ -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',
|
|
@@ -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)) {
|
|
@@ -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 = [];
|
|
@@ -55,9 +55,7 @@ export const FormatColumnScopeWizardSection = (props) => {
|
|
|
55
55
|
newData.Rule.BooleanExpression = '';
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
|
-
const validPredicateIds = new Set(api.formatColumnApi.internalApi
|
|
59
|
-
.getFormatColumnDefsForScope(Scope)
|
|
60
|
-
.map((def) => def.id));
|
|
58
|
+
const validPredicateIds = new Set(api.formatColumnApi.internalApi.getFormatColumnDefsForScope(Scope).map((def) => def.id));
|
|
61
59
|
newData.Rule = {
|
|
62
60
|
Predicates: newData.Rule.Predicates.filter((p) => validPredicateIds.has(p.PredicateId)).filter((predicate) => {
|
|
63
61
|
// if there are more than 1 column, then we must eliminate the IN/NotIn predicates
|
|
@@ -82,11 +80,8 @@ export const FormatColumnScopeWizardSection = (props) => {
|
|
|
82
80
|
});
|
|
83
81
|
};
|
|
84
82
|
const showRowToggles = data.Target === 'cell';
|
|
85
|
-
return (_jsxs(Flex, { flexDirection: "column", style: { height: '100%' }, children: [_jsxs(Flex, { flexDirection: "column", className: "twa:flex-1 twa:min-h-0", children: [_jsxs(Flex, { flexDirection: "row", alignItems: "center", className: "twa:p-2 twa:gap-3 twa:border-b twa:border-b-
|
|
83
|
+
return (_jsxs(Flex, { flexDirection: "column", style: { height: '100%' }, children: [_jsxs(Flex, { flexDirection: "column", className: "twa:flex-1 twa:min-h-0", children: [_jsxs(Flex, { flexDirection: "row", alignItems: "center", className: "twa:p-2 twa:gap-3 twa:border-b twa:mb-2 twa:border-b-foreground/20", children: [_jsx(Box, { className: "twa:text-5 twa:font-medium", children: "Columns" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70", children: "Which Columns the Format Column will be applied to" })] }), _jsx(Box, { className: "twa:flex-1 twa:min-h-0 twa:overflow-auto twa:p-2", children: _jsx(NewScopeComponent, { descriptions: {
|
|
86
84
|
rowScope: 'Format all columns in the row',
|
|
87
85
|
columnScope: 'Select columns to format',
|
|
88
|
-
}, scope: data.Scope, updateScope: handleScopeChange }) })] }), showRowToggles && (_jsxs(Box, { className: "twa:border-t twa:border-border twa:
|
|
89
|
-
FORMAT_COLUMN_ROW_KINDS.slice(0, 2),
|
|
90
|
-
FORMAT_COLUMN_ROW_KINDS.slice(2),
|
|
91
|
-
].map((rowKindGroup, groupIndex) => (_jsx(Box, { className: "twa:flex-1 twa:min-w-[220px]", children: _jsx(FormLayout, { sizes: ['180px', '1fr'], children: rowKindGroup.map((kind) => (_jsx(FormRow, { label: `${ROW_KIND_LABELS[kind]}:`, children: _jsx(Flex, { alignItems: "center", className: "twa:ml-2", children: _jsx(CheckBox, { "data-name": `include-${kind.toLowerCase()}-rows-checkbox`, className: "twa:mr-2", checked: isRowKindIncluded(data, kind), onChange: (checked) => handleRowKindChange(kind, checked) }) }) }, kind))) }) }, groupIndex))) })] }))] }));
|
|
86
|
+
}, scope: data.Scope, updateScope: handleScopeChange }) })] }), showRowToggles && (_jsxs(Box, { className: "twa:border-t twa:border-border twa:py-3 twa:shrink-0", children: [_jsxs(Flex, { alignItems: "center", className: "twa:gap-3 twa:px-2 twa:pb-2 twa:mb-3 twa:flex-wrap twa:border-b twa:border-b-foreground/20", children: [_jsx(Box, { className: "twa:text-5 twa:font-medium", children: "Rows" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:max-w-[520px]", children: "Which kinds of Rows the Format Column will be applied to" })] }), _jsx(Flex, { flexDirection: "row", className: "twa:gap-6 twa:flex-wrap", children: [FORMAT_COLUMN_ROW_KINDS.slice(0, 2), FORMAT_COLUMN_ROW_KINDS.slice(2)].map((rowKindGroup, groupIndex) => (_jsx(Box, { className: "twa:flex-1 twa:min-w-[220px]", children: _jsx(FormLayout, { sizes: ['180px', '1fr'], children: rowKindGroup.map((kind) => (_jsx(FormRow, { label: `${ROW_KIND_LABELS[kind]}:`, children: _jsx(Flex, { alignItems: "center", className: "twa:ml-2", children: _jsx(CheckBox, { "data-name": `include-${kind.toLowerCase()}-rows-checkbox`, className: "twa:mr-2", checked: isRowKindIncluded(data, kind), onChange: (checked) => handleRowKindChange(kind, checked) }) }) }, kind))) }) }, groupIndex))) })] }))] }));
|
|
92
87
|
};
|
|
@@ -22,7 +22,7 @@ const QueryViewPanelComponent = (props) => {
|
|
|
22
22
|
const disabled = isReadOnly || isSuspended || gridFilterAccessLevel === ACCESS_LEVEL_READ_ONLY;
|
|
23
23
|
const buttonExpand = (_jsx(ButtonExpand, { disabled: disabled, accessLevel: gridFilterAccessLevel, variant: "text", tone: "neutral", onClick: onExpand, tooltip: "Edit the Expression in UI", className: "twa:ml-1" }));
|
|
24
24
|
const renderExpressionLabel = () => {
|
|
25
|
-
const baseClasses = 'twa:font-mono twa:text-s twa:py-2 twa:px-2 twa:overflow-hidden twa:text-ellipsis twa:whitespace-nowrap twa:bg-
|
|
25
|
+
const baseClasses = 'twa:font-mono twa:text-s twa:py-2 twa:px-2 twa:overflow-hidden twa:text-ellipsis twa:whitespace-nowrap twa:bg-background twa:text-foreground twa:rounded twa:cursor-pointer twa:leading-4 twa:flex twa:items-center';
|
|
26
26
|
const placeholderClasses = 'twa:text-gray-400 twa:italic';
|
|
27
27
|
const labelClassName = clsx(baseClasses, {
|
|
28
28
|
[placeholderClasses]: !expression,
|
|
@@ -189,7 +189,7 @@ export const ColumnsSection = (props) => {
|
|
|
189
189
|
if (layout.RowGroupDisplayType === 'single') {
|
|
190
190
|
allColumns.unshift(generateAutoRowGroupSingleColumn());
|
|
191
191
|
}
|
|
192
|
-
else {
|
|
192
|
+
else if (layout.RowGroupDisplayType === 'multi') {
|
|
193
193
|
[...layout.RowGroupedColumns].reverse().forEach((col) => {
|
|
194
194
|
const groupCol = generateAutoRowGroupColumnForColumn(adaptable.api.columnApi.getColumnWithColumnId(col));
|
|
195
195
|
allColumns.unshift(groupCol);
|
|
@@ -423,7 +423,7 @@ export const ColumnsSection = (props) => {
|
|
|
423
423
|
const visible = isColumnVisible({ columnId: selectedColumnId, layout });
|
|
424
424
|
handleColumnVisibilityChange(selectedColumnId, !visible);
|
|
425
425
|
}
|
|
426
|
-
}, children: _jsxs(Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:h-full twa:overflow-hidden twa:p-1", children: [_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Search Columns...", className: "twa:w-full twa:
|
|
426
|
+
}, children: _jsxs(Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:h-full twa:overflow-hidden twa:p-1", children: [_jsx(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Search Columns...", className: "twa:w-full twa:p-1" }), _jsx(Box, { className: clsx('twa:font-bold', 'twa:border-b twa:border-primarydark/30 twa:rounded-standard'), children: _jsx(CheckBox, { checked: currentlyDisplayedColumnIds.length
|
|
427
427
|
? currentlyDisplayedColumnIds.length === visibleIdsCurrentlyDisplayed.length
|
|
428
428
|
? true
|
|
429
429
|
: visibleIdsCurrentlyDisplayed.length
|
|
@@ -460,7 +460,7 @@ const ColumnPropertiesEditor = (props) => {
|
|
|
460
460
|
const adaptable = useAdaptable();
|
|
461
461
|
const baseCls = 'ab-Layout-Wizard__ColumnPropertiesEditor twa:border twa:rounded-standard';
|
|
462
462
|
if (!props.column) {
|
|
463
|
-
return (_jsx(Box, { className: clsx(baseCls, 'twa:border-input-border twa:grid twa:place-items-center twa:border-dashed twa:border-2'), children: _jsxs(Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:items-center twa:justify-center", children: [_jsx(Box, { className: "twa:text-
|
|
463
|
+
return (_jsx(Box, { className: clsx(baseCls, 'twa:border-input-border twa:grid twa:place-items-center twa:border-dashed twa:border-2'), children: _jsxs(Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:items-center twa:justify-center", children: [_jsx(Box, { className: "twa:text-muted-foreground ab-Layout-Wizard__ColumnPropertiesEditor__Placeholder__Icon", children: _jsx(NaturallySizedIcon, { name: "inspector", style: { stroke: 'currentColor', fill: 'none', strokeWidth: 2 } }) }), _jsx(Box, { className: "twa:text-4 twa:font-bold ab-Layout-Wizard__ColumnPropertiesEditor__Placeholder__Title", children: "No Column Selected" }), _jsx(Box, { className: "twa:text-3 twa:opacity-80 ab-Layout-Wizard__ColumnPropertiesEditor__Placeholder__Description", children: "Select a Column to view and edit its properties" })] }) }));
|
|
464
464
|
}
|
|
465
465
|
const { column } = props;
|
|
466
466
|
const columnWidth = props.layout.ColumnSizing?.[column.columnId]?.Width;
|
|
@@ -472,7 +472,7 @@ const ColumnPropertiesEditor = (props) => {
|
|
|
472
472
|
const columnPinning = props.layout.ColumnPinning?.[props.column.columnId] || 'None';
|
|
473
473
|
const initialHeader = adaptable.api.columnApi.getFriendlyNameForColumnId(props.column.columnId, props.layout);
|
|
474
474
|
const customHeader = props.layout.ColumnHeaders?.[props.column.columnId] ?? initialHeader;
|
|
475
|
-
return (_jsxs(Box, { className: clsx(baseCls, 'ab-Layout-Wizard__ColumnPropertiesEditor__Container twa:border-none twa:bg-
|
|
475
|
+
return (_jsxs(Box, { className: clsx(baseCls, 'ab-Layout-Wizard__ColumnPropertiesEditor__Container twa:border-none twa:bg-background twa:shadow-md', 'twa:max-h-full twa:overflow-hidden twa:flex twa:flex-col'), children: [_jsxs(Box, { className: "twa:px-4 twa:pt-4", children: [_jsxs(Box, { className: "twa:text-5 twa:font-bold twa:leading-relaxed ab-Layout-Wizard__ColumnPropertiesEditor__Title", children: ["Column Settings: ", column.friendlyName] }), _jsxs(Box, { className: "twa:text-3 twa:opacity-80 twa:flex twa:flex-row twa:gap-1 twa:items-center", children: ["Column ID:", ' ', _jsx(Box, { className: "twa:bg-primarydark/20 twa:text-muted-foreground twa:px-1 twa:py-0.5 twa:rounded-standard", children: column.columnId })] }), props.column.columnGroup && props.column.columnGroup.groupCount > 1 ? (_jsxs(Box, { className: "ab-Layout-Wizard__ColumnRow__Title twa:mx-2 twa:p-1", children: ["Column Group: ", props.column.columnGroup.friendlyName] })) : null] }), hr, _jsxs(Box, { className: "twa:px-4 twa:flex-1 twa:overflow-y-auto twa:pb-3", children: [_jsxs(Flex, { flexDirection: "column", className: "twa:gap-3 twa:mt-3", children: [_jsxs(Flex, { flexDirection: "column", className: "twa:gap-1", children: ["Header", _jsx(Input, { "data-name": "column-header", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input twa:w-full", placeholder: "Custom name (optional)", disabled: props.column.isGeneratedSelectionColumn, onChange: () => {
|
|
476
476
|
props.onColumnNameChange(props.column.columnId, event.target.value);
|
|
477
477
|
}, value: customHeader })] }), _jsxs(Box, { className: "twa:grid twa:grid-cols-[1fr_1fr] twa:gap-2", children: [_jsx(Box, { children: "Width:" }), " ", _jsx(Box, { children: "Flex:" }), _jsx(Input, { "data-name": "column-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column width", disabled: resizable === false, onChange: (event) => {
|
|
478
478
|
let value = parseFloat(event.target.value);
|
|
@@ -12,7 +12,7 @@ import { CheckBox } from '../../../../components/CheckBox';
|
|
|
12
12
|
export const PivotColumnsSectionSummary = () => {
|
|
13
13
|
const adaptable = useAdaptable();
|
|
14
14
|
const { data: layout } = useOnePageAdaptableWizardContext();
|
|
15
|
-
return (_jsx(Box, { className: "twa:p-2 twa:rounded-standard twa:bg-
|
|
15
|
+
return (_jsx(Box, { className: "twa:p-2 twa:rounded-standard twa:bg-background", children: layout.PivotColumns?.length ? (layout.PivotColumns.map((columnId) => (_jsx(Tag, { className: "twa:mr-1", children: adaptable.api.columnApi.getFriendlyNameForColumnId(columnId) }, columnId)))) : (_jsx(Tag, { children: "No Pivot Columns Defined" })) }));
|
|
16
16
|
};
|
|
17
17
|
export const PivotColumnsSection = (props) => {
|
|
18
18
|
const adaptable = useAdaptable();
|
|
@@ -73,9 +73,13 @@ export const RowGroupingSection = (props) => {
|
|
|
73
73
|
if (RowGroupDisplayType === 'single') {
|
|
74
74
|
newLayout.TableColumns = (newLayout.TableColumns || []).filter((colId) => !adaptable.api.columnApi.isAutoRowGroupColumnForMulti(colId));
|
|
75
75
|
}
|
|
76
|
-
else {
|
|
76
|
+
else if (RowGroupDisplayType === 'multi') {
|
|
77
77
|
newLayout.TableColumns = (newLayout.TableColumns || []).filter((colId) => !adaptable.api.columnApi.isAutoRowGroupColumnForSingle(colId));
|
|
78
78
|
}
|
|
79
|
+
else {
|
|
80
|
+
newLayout.TableColumns = (newLayout.TableColumns || []).filter((colId) => !adaptable.api.columnApi.isAutoRowGroupColumnForSingle(colId) &&
|
|
81
|
+
!adaptable.api.columnApi.isAutoRowGroupColumnForMulti(colId));
|
|
82
|
+
}
|
|
79
83
|
onChange(newLayout);
|
|
80
|
-
}, children: [_jsx(TypeRadio, { value: "single", text: "Single Column", description: "All Row Grouped Columns display in one hierarchical Column" }), _jsx(TypeRadio, { value: "multi", text: "Multiple Columns", description: "Each Row Grouped Column displays in its own, separate, Column" })] }) }) })] }), _jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Row Grouped Columns" }), _jsx(Tabs.Tab, { children: rowGroupsText }), _jsx(Tabs.Content, { children: _jsx(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (option) => (_jsxs(Flex, { alignItems: "center", children: [option.friendlyName ?? option.columnId, _jsx(ColumnGroupTag, { column: option })] })), options: sortedGroupableColumns, value: layout.RowGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange }) }), _jsx(Tabs.Content, { children: _jsx(RowGroupBehaviorSection, { layout: layout, onChange: onChange }) })] })] }));
|
|
84
|
+
}, children: [_jsx(TypeRadio, { value: "single", text: "Single Column", description: "All Row Grouped Columns display in one hierarchical Column" }), _jsx(TypeRadio, { value: "multi", text: "Multiple Columns", description: "Each Row Grouped Column displays in its own, separate, Column" }), _jsx(TypeRadio, { value: "groupRows", text: "Full Width Group Rows", description: "Row groups display as full-width rows (no group column and no aggregations)" })] }) }) })] }), _jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Row Grouped Columns" }), _jsx(Tabs.Tab, { children: rowGroupsText }), _jsx(Tabs.Content, { children: _jsx(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (option) => (_jsxs(Flex, { alignItems: "center", children: [option.friendlyName ?? option.columnId, _jsx(ColumnGroupTag, { column: option })] })), options: sortedGroupableColumns, value: layout.RowGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange }) }), _jsx(Tabs.Content, { children: _jsx(RowGroupBehaviorSection, { layout: layout, onChange: onChange }) })] })] }));
|
|
81
85
|
};
|
|
@@ -69,5 +69,5 @@ export const RowSelectionSection = (props) => {
|
|
|
69
69
|
}
|
|
70
70
|
props.onChange(newLayout);
|
|
71
71
|
};
|
|
72
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Tabs, { children: [_jsx(Tabs.Tab, { children: "Row Selection Mode" }), _jsx(Tabs.Content, { children: _jsx(Flex, { flexDirection: "column", children: _jsxs(RadioGroup, { orientation: "horizontal", variant: "text-only", className: twMerge(radioGroupStyling.horizontalTextOnly, 'twa:gap-2 twa:max-w-[500px] twa:bg-
|
|
72
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Tabs, { children: [_jsx(Tabs.Tab, { children: "Row Selection Mode" }), _jsx(Tabs.Content, { children: _jsx(Flex, { flexDirection: "column", children: _jsxs(RadioGroup, { orientation: "horizontal", variant: "text-only", className: twMerge(radioGroupStyling.horizontalTextOnly, 'twa:gap-2 twa:max-w-[500px] twa:bg-background twa:p-2'), value: mode, name: "rowSelectionMode", onRadioChange: handleModeChange, children: [_jsx(Radio, { value: false, children: "Disabled" }), _jsx(Radio, { value: "singleRow", children: "Single Row" }), _jsx(Radio, { value: "multiRow", children: "Multi Row" })] }) }) })] }), !rowSelection && _jsx(HelpBlock, { children: "There is no Row Selection configured for this Layout" }), rowSelection && (_jsxs(_Fragment, { children: [_jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Row Selection Column Checkboxes" }), _jsx(Tabs.Content, { children: _jsxs(Flex, { flexDirection: "row", className: "twa:gap-6", children: [_jsx(CheckBox, { className: "twa:flex-1", checked: rowSelection.Checkboxes ?? true, onChange: (checked) => updateRowSelection({ Checkboxes: checked }), children: "Checkboxes in Column Cells" }), mode === 'multiRow' && (_jsx(CheckBox, { className: "twa:flex-1", checked: rowSelection.HeaderCheckbox ?? true, onChange: (checked) => updateRowSelection({ HeaderCheckbox: checked }), children: "Checkbox in Column Header (to enable Select All)" }))] }) })] }), (rowSelection.Checkboxes ?? true) && (_jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Row Grouping Selection Checkboxes" }), _jsx(Tabs.Content, { children: _jsxs(RadioGroup, { orientation: "vertical", value: rowSelection.CheckboxInGroupColumn ?? false, name: "checkboxLocation", onRadioChange: (value) => updateRowSelection({ CheckboxInGroupColumn: value }), children: [_jsx(Radio, { value: false, children: "Display in dedicated Selection Column" }), _jsx(Radio, { value: true, children: "Display in Row Grouped Column" })] }) })] })), _jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Row Click Selection (when user clicks on Row outside of Selection Checkbox)" }), _jsx(Tabs.Content, { children: _jsxs(RadioGroup, { orientation: "vertical", value: rowSelection.EnableClickSelection ?? false, name: "clickSelection", onRadioChange: (value) => updateRowSelection({ EnableClickSelection: value }), children: [_jsx(Radio, { value: false, children: "Disabled (Cannot select or deselect by clicking in Row)" }), _jsx(Radio, { value: true, children: "Full (Enable selection by clicking in Row and deselection by Ctrl+clicking in Row)" }), _jsx(Radio, { value: 'enableSelection', children: "Selection Only (Enable selection by clicking in Row)" }), _jsx(Radio, { value: 'enableDeselection', children: "Deselection Only (Enable deselection by Ctrl+clicking in Row)" })] }) })] }), mode === 'multiRow' && !isPivot && (_jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Grouped Row Selection Behaviour" }), _jsx(Tabs.Content, { children: _jsxs(RadioGroup, { orientation: "vertical", value: rowSelection.GroupSelectMode ?? 'self', name: "groupSelectMode", onRadioChange: (value) => updateRowSelection({ GroupSelectMode: value }), children: [_jsx(Radio, { value: 'self', children: "Select Grouped Row Only (no cascade)" }), _jsx(Radio, { value: 'descendants', children: "Select Grouped Row and all descendants" }), _jsx(Radio, { value: 'filteredDescendants', children: "Select Grouped Row and only filtered descendants" })] }) })] })), mode === 'multiRow' && (_jsxs(Tabs, { className: "twa:mt-2", children: [_jsx(Tabs.Tab, { children: "Select All (in Header) Behaviour" }), _jsx(Tabs.Content, { children: _jsxs(RadioGroup, { orientation: "vertical", value: rowSelection.SelectAllMode ?? 'all', name: "selectAllMode", onRadioChange: (value) => updateRowSelection({ SelectAllMode: value }), children: [_jsx(Radio, { value: 'all', children: "All rows" }), _jsx(Radio, { value: 'filtered', children: "Filtered rows only" }), _jsx(Radio, { value: 'currentPage', children: "Current page only" })] }) })] }))] }))] }));
|
|
73
73
|
};
|
|
@@ -20,5 +20,5 @@ export const SettingsSection = (props) => {
|
|
|
20
20
|
Name: event.target.value,
|
|
21
21
|
});
|
|
22
22
|
};
|
|
23
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Tabs, { className: "twa:mb-
|
|
23
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Tabs, { className: "twa:mb-2", children: [_jsx(Tabs.Tab, { children: "Settings" }), _jsx(Tabs.Content, { children: _jsx(Flex, { flexDirection: "row", children: _jsx(FormLayout, { className: "twa:max-w-[300px] twa:w-full", children: _jsx(FormRow, { label: "Name", children: _jsx(Input, { className: "twa:w-full", "data-name": "layout-name", onChange: onNameChange, value: layout?.Name ?? '' }) }) }) }) })] }), _jsxs(Tabs, { className: "twa:mb-2", children: [_jsx(Tabs.Tab, { children: "Grid Type" }), _jsx(Tabs.Content, { children: _jsxs(Flex, { flexDirection: "column", children: [_jsx(Radio, { "data-name": "layout-type-table", disabled: true, checked: !isPivotLayout(layout), children: "Table" }), _jsx(Radio, { "data-name": "layout-type-pivot", disabled: true, checked: isPivotLayout(layout), children: "Pivot" })] }) })] })] }));
|
|
24
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as r,jsxs as t}from"react/jsx-runtime";import*as e from"react";import{Logo as o}from"../../components/Logo";import{Flex as n}from"../../components/Flex";const i={border:"1px solid var(--ab-color-error)",padding:"5px",fontWeight:600,margin:"5px",fontSize:"14px",alignItems:"center",color:"var(--ab-color-foreground)",background:"var(--ab-color-
|
|
1
|
+
import{jsx as r,jsxs as t}from"react/jsx-runtime";import*as e from"react";import{Logo as o}from"../../components/Logo";import{Flex as n}from"../../components/Flex";const i={border:"1px solid var(--ab-color-error)",padding:"5px",fontWeight:600,margin:"5px",fontSize:"14px",alignItems:"center",color:"var(--ab-color-foreground)",background:"var(--ab-color-background)"},s=r=>{const t=[["display","none"],["opacity","0"],["position","absolute"],["position","fixed"],["position","relative"],["visibility","hidden"]];for(const[e,o]of t)if(r.style[e]===o)return!1;return!0};export const LicenseWatermark=l=>{const a=e.useRef(null);return e.useEffect(()=>{const r=setInterval(()=>{a.current?.isConnected||alert("It is not allowed to remove the Adaptable watermark."),s(a.current)||alert("It is not allowed to modify the Adaptable watermark."),a?.current?.style&&(a.current.style.border=i.border,a.current.style.padding=i.padding,a.current.style.fontWeight=`${i.fontWeight}`,a.current.style.margin=i.margin,a.current.style.fontSize=i.fontSize,a.current.style.color=i.color,a.current.style.background=i.background,a.current.style.display="flex",a.current.style.position="static",a.current.style.opacity="1",a.current.style.visibility="visible")},5e3);return()=>clearTimeout(r)},[]),t(n,{style:i,ref:a,children:[r(o,{style:{marginRight:10}}),r("div",{children:l.children})]})};
|
|
@@ -227,7 +227,7 @@ export const StyledColumnWizardScopeSection = (props) => {
|
|
|
227
227
|
// -------------------------------------------------------------------------
|
|
228
228
|
// Render
|
|
229
229
|
// -------------------------------------------------------------------------
|
|
230
|
-
return (_jsxs(Flex, { flexDirection: "column", style: { height: '100%' }, children: [_jsxs(Flex, { flexDirection: "column", className: "twa:flex-1 twa:min-h-0", children: [_jsxs(Flex, { flexDirection: "row", alignItems: "center", className: "twa:p-2 twa:gap-3 twa:border-b twa:border-b-
|
|
230
|
+
return (_jsxs(Flex, { flexDirection: "column", style: { height: '100%' }, children: [_jsxs(Flex, { flexDirection: "column", className: "twa:flex-1 twa:min-h-0", children: [_jsxs(Flex, { flexDirection: "row", alignItems: "center", className: "twa:p-2 twa:gap-3 twa:border-b twa:border-b-foreground/20", children: [_jsx(Box, { className: "twa:text-5 twa:font-medium", children: "Column" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70", children: "The Column the Style is applied to" }), _jsx(Box, { className: "twa:flex-1" }), _jsx(AdaptableFormControlTextClear, { value: columnsSearchText, OnTextChange: setColumnsSearchText, placeholder: "Type to search columns", style: { flex: 1, maxWidth: 320 } })] }), _jsx(Box, { className: "twa:flex-1 twa:min-h-0 twa:overflow-auto", children: _jsx(NewColumnSelector, { columnFilterText: columnsSearchText, availableColumns: sortableCols, selected: data.ColumnId ? [data.ColumnId] : [], singleSelect: true, onChange: handleColumnsChange, allowReorder: false }) })] }), _jsxs(Box, { className: "twa:border-t twa:border-border twa:px-2 twa:py-3 twa:shrink-0", children: [_jsxs(Flex, { alignItems: "center", className: "twa:gap-3 twa:pb-2 twa:mb-3 twa:flex-wrap twa:border-b twa:border-b-foreground/20", children: [_jsx(Box, { className: "twa:text-5 twa:font-medium", children: "Rows" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:max-w-[520px]", children: "Which kinds of Rows should the Styled Column render on" })] }), _jsx(Flex, { flexDirection: "row", className: "twa:gap-6 twa:flex-wrap", children: [
|
|
231
231
|
STYLED_COLUMN_ROW_KINDS.slice(0, 2),
|
|
232
232
|
STYLED_COLUMN_ROW_KINDS.slice(2),
|
|
233
233
|
].map((rowKindGroup, groupIndex) => (_jsx(Box, { className: "twa:flex-1 twa:min-w-[220px]", children: _jsx(FormLayout, { sizes: ['180px', '1fr'], children: rowKindGroup.map((kind) => {
|
|
@@ -78,7 +78,7 @@ export const OnePageWizard = (props) => {
|
|
|
78
78
|
if (section === '-') {
|
|
79
79
|
return _jsx(React.Fragment, {}, index);
|
|
80
80
|
}
|
|
81
|
-
return (_jsx(Flex, { flexDirection: "column", "data-name": `section-${index}`, className: "twa:min-h-full twa:mr-2", children: _jsx(Box, { className: "ab-OnePageWizard__section twa:flex-1 twa:rounded-standard twa:overflow-auto twa:bg-
|
|
81
|
+
return (_jsx(Flex, { flexDirection: "column", "data-name": `section-${index}`, className: "twa:min-h-full twa:mr-2", children: _jsx(Box, { className: "ab-OnePageWizard__section twa:flex-1 twa:rounded-standard twa:overflow-auto twa:bg-background", children: section.render(props.data, index) }) }, index));
|
|
82
82
|
};
|
|
83
83
|
const handleNavigation = useKeyboardNavigation(setCurrentSection, visibleSections);
|
|
84
84
|
const selectedNodeRef = useRef(null);
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Provider } from 'react-redux';
|
|
3
3
|
import AdaptableContext from './AdaptableContext';
|
|
4
4
|
import { WithAdaptableComputedCSSVars } from './AdaptableComputedCSSVarsContext';
|
|
5
|
-
import { TooltipProvider } from
|
|
5
|
+
import { TooltipProvider } from '../components/ui/tooltip';
|
|
6
6
|
export const renderWithAdaptableContext = (children, adaptable) => {
|
|
7
7
|
return (_jsx(TooltipProvider, { delay: 300, children: _jsx(Provider, { store: adaptable.adaptableStore.TheStore, children: _jsx(WithAdaptableComputedCSSVars, { children: _jsx(AdaptableContext.Provider, { value: adaptable, children: children }) }) }) }));
|
|
8
8
|
};
|
|
@@ -96,6 +96,7 @@ import { FlashingCellService } from '../Utilities/Services/FlashingCellService';
|
|
|
96
96
|
import { AgGridExportAdapter } from './AgGridExportAdapter';
|
|
97
97
|
import { checkForDuplicateColumns, getLayoutRowGroupValuesExceptionGroupKeys, isPivotLayout, layoutModelToLayoutState, layoutStateToLayoutModel, normalizeLayout, } from '../Api/Implementation/LayoutHelpers';
|
|
98
98
|
import { LayoutManager } from '../layout-manager/src';
|
|
99
|
+
import { rowGroupDisplayTypeToGridOption } from '../layout-manager/src/rowGroupDisplayType';
|
|
99
100
|
import { isPivotLayoutModel } from '../layout-manager/src/isPivotLayoutModel';
|
|
100
101
|
import { ACTION_COLUMN_TYPE, CALCULATED_COLUMN_TYPE, FDC3_COLUMN_TYPE, FREE_TEXT_COLUMN_TYPE, HIDDEN_COLUMN_TYPE, hiddenColDefConfig, PIVOT_AGGREGATION_TOTAL_COLUMN_TYPE, PIVOT_ANY_TOTAL_COLUMN_TYPE, PIVOT_COLUMN_TOTAL_COLUMN_TYPE, PIVOT_GRAND_TOTAL_COLUMN_TYPE, } from '../AdaptableState/Common/AdaptableColumn';
|
|
101
102
|
import { agGridDataTypeDefinitions } from './agGridDataTypeDefinitions';
|
|
@@ -461,8 +462,7 @@ export class AdaptableAgGrid {
|
|
|
461
462
|
if (isPivotLayoutModel(layoutModel)) {
|
|
462
463
|
gridOptions.pivotDefaultExpanded = layoutModel.PivotExpandLevel;
|
|
463
464
|
}
|
|
464
|
-
gridOptions.groupDisplayType =
|
|
465
|
-
layoutModel.RowGroupDisplayType === 'multi' ? 'multipleColumns' : 'singleColumn';
|
|
465
|
+
gridOptions.groupDisplayType = rowGroupDisplayTypeToGridOption(layoutModel.RowGroupDisplayType);
|
|
466
466
|
// fixes issue #3053
|
|
467
467
|
gridOptions.suppressAggFuncInHeader = !!layoutModel.SuppressAggFuncInHeader;
|
|
468
468
|
if (!isPivotLayoutModel(layoutModel) &&
|