@adaptabletools/adaptable-cjs 22.0.11 → 22.1.0-canary.1

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.
Files changed (75) hide show
  1. package/index.css +19 -1
  2. package/index.css.map +1 -1
  3. package/package.json +3 -4
  4. package/src/AdaptableOptions/DashboardOptions.d.ts +2 -2
  5. package/src/AdaptableState/Common/AdaptablePredicate.js +1 -1
  6. package/src/AdaptableState/InitialState.d.ts +2 -2
  7. package/src/AdaptableState/LayoutState.d.ts +44 -0
  8. package/src/Api/CalendarApi.d.ts +15 -0
  9. package/src/Api/ColumnScopeApi.d.ts +5 -0
  10. package/src/Api/Implementation/CalendarApiImpl.d.ts +3 -0
  11. package/src/Api/Implementation/CalendarApiImpl.js +10 -0
  12. package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
  13. package/src/Api/Implementation/ColumnApiImpl.js +15 -0
  14. package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -0
  15. package/src/Api/Implementation/ColumnScopeApiImpl.js +12 -0
  16. package/src/Api/Implementation/LayoutHelpers.js +12 -0
  17. package/src/Api/Internal/AlertInternalApi.js +4 -1
  18. package/src/Api/Internal/FormatColumnInternalApi.js +3 -3
  19. package/src/Strategy/FlashingCellModule.js +1 -0
  20. package/src/Strategy/PlusMinusModule.js +3 -3
  21. package/src/Strategy/SmartEditModule.js +1 -1
  22. package/src/Utilities/Constants/GeneralConstants.js +2 -1
  23. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.d.ts +1 -1
  24. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.js +41 -2
  25. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.d.ts +1 -1
  26. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.js +31 -2
  27. package/src/Utilities/Helpers/AdaptableHelper.js +30 -4
  28. package/src/Utilities/Services/Interface/IQueryLanguageService.d.ts +1 -0
  29. package/src/Utilities/Services/MetamodelService.js +18 -18
  30. package/src/Utilities/Services/QueryLanguageService.d.ts +2 -0
  31. package/src/Utilities/Services/QueryLanguageService.js +20 -8
  32. package/src/Utilities/Services/ValidationService.js +3 -1
  33. package/src/View/Components/EntityRulesEditor/index.js +1 -1
  34. package/src/View/Components/ModuleValueSelector/index.js +9 -1
  35. package/src/View/Components/ReorderDraggable/index.js +21 -35
  36. package/src/View/Components/ValueSelector/index.js +45 -49
  37. package/src/View/Dashboard/PinnedToolbarsSelector.js +1 -1
  38. package/src/View/Layout/Wizard/LayoutWizard.js +16 -1
  39. package/src/View/Layout/Wizard/sections/ColumnsSection.js +30 -18
  40. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +1 -1
  41. package/src/View/Layout/Wizard/sections/RowSelectionSection.d.ts +8 -0
  42. package/src/View/Layout/Wizard/sections/RowSelectionSection.js +146 -0
  43. package/src/View/NamedQuery/Wizard/NamedQuerySettingsWizardSection.js +0 -1
  44. package/src/agGrid/AdaptableAgGrid.js +10 -0
  45. package/src/components/Dashboard/Dashboard.js +1 -1
  46. package/src/components/DragAndDropContext/ModuleManager.d.ts +1 -0
  47. package/src/components/DragAndDropContext/ModuleManager.js +11 -36
  48. package/src/components/DragAndDropContext/TabList.d.ts +11 -6
  49. package/src/components/DragAndDropContext/TabList.js +77 -35
  50. package/src/components/DragAndDropContext/UnusedPanel.js +9 -20
  51. package/src/components/ExpressionEditor/BaseEditorInput.d.ts +2 -0
  52. package/src/components/ExpressionEditor/BaseEditorInput.js +4 -0
  53. package/src/components/ExpressionEditor/EditorInput.d.ts +3 -1
  54. package/src/components/ExpressionEditor/EditorInput.js +20 -9
  55. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +2 -1
  56. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +1 -10
  57. package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +16 -18
  58. package/src/components/ExpressionEditor/index.d.ts +2 -1
  59. package/src/components/ExpressionEditor/index.js +1 -1
  60. package/src/components/Tree/TreeDropdown/index.js +37 -26
  61. package/src/components/dnd/index.d.ts +3 -13
  62. package/src/components/dnd/index.js +11 -59
  63. package/src/env.js +2 -2
  64. package/src/layout-manager/src/LayoutManagerModel.d.ts +2 -1
  65. package/src/layout-manager/src/index.d.ts +10 -0
  66. package/src/layout-manager/src/index.js +156 -4
  67. package/src/layout-manager/src/normalizeLayoutModel.js +8 -0
  68. package/src/layout-manager/src/simplifyLayoutModel.js +6 -0
  69. package/src/metamodel/adaptable-metamodel-model.d.ts +22 -13
  70. package/src/metamodel/adaptable.metamodel.d.ts +3792 -5143
  71. package/src/metamodel/adaptable.metamodel.js +1 -1
  72. package/src/parser/src/parser.js +55 -1218
  73. package/src/parser/src/types.d.ts +5 -0
  74. package/src/types.d.ts +1 -1
  75. package/tsconfig.cjs.tsbuildinfo +1 -1
@@ -18,7 +18,6 @@ const ModuleManager = (props) => {
18
18
  editTabName: true,
19
19
  dragAndDropTab: true,
20
20
  deleteTab: true,
21
- // override default permitted actions
22
21
  ...permittedActions,
23
22
  };
24
23
  return {
@@ -26,34 +25,15 @@ const ModuleManager = (props) => {
26
25
  availableItems: props.availableItems,
27
26
  };
28
27
  }, [props.availableItems, props.permittedActions]);
29
- const unusedItems = React.useMemo(() => availableItems
30
- .map((t) => t.Id)
31
- .filter((item) => {
32
- return !tabs.some((tab) => tab.Items?.includes(item));
33
- }), [tabs, availableItems]);
34
- const handleToolbarDragEnd = (result) => {
35
- const { source, destination, draggableId } = result;
36
- if (!source || !destination) {
37
- return;
28
+ const allowedItems = React.useMemo(() => {
29
+ let result = availableItems.map((t) => t.Id);
30
+ if (props.filterOutSelectedItems) {
31
+ result = result.filter((item) => {
32
+ return !tabs.some((tab) => tab.Items?.includes(item));
33
+ });
38
34
  }
39
- if (source.droppableId !== 'UNUSED') {
40
- const sourceTabToolbars = tabs[Number(source.droppableId)].Items;
41
- sourceTabToolbars.splice(source.index, 1);
42
- }
43
- if (destination.droppableId !== 'UNUSED') {
44
- const destinationTabToolbars = tabs[Number(destination.droppableId)].Items;
45
- destinationTabToolbars.splice(destination.index, 0, draggableId);
46
- }
47
- onTabsChange([...tabs]);
48
- };
49
- const handleTabDragEnd = (result) => {
50
- const { source, destination } = result;
51
- if (!source || !destination)
52
- return;
53
- const [removed] = tabs.splice(source.index, 1);
54
- tabs.splice(destination.index, 0, removed);
55
- onTabsChange([...tabs]);
56
- };
35
+ return result;
36
+ }, [tabs, availableItems]);
57
37
  const handleRemoveTab = (tabIndex) => {
58
38
  onTabsChange(tabs.filter((_, index) => index !== tabIndex));
59
39
  };
@@ -80,18 +60,13 @@ const ModuleManager = (props) => {
80
60
  };
81
61
  }));
82
62
  };
83
- return (React.createElement(dnd_1.DragDropContext, { onDragEnd: (result) => {
84
- if (result.type === 'TAB')
85
- handleTabDragEnd(result);
86
- if (result.type === 'TOOLBAR')
87
- handleToolbarDragEnd(result);
88
- } },
63
+ return (React.createElement(dnd_1.DragDropProvider, null,
89
64
  React.createElement(DragAndDropContext_1.DragAndDropContext.Provider, { value: contextValue },
90
65
  React.createElement(Flex_1.Flex, { flexDirection: "column", className: (0, clsx_1.default)('ab-ModuleSelector twa:flex-1', className) },
91
- React.createElement(UnusedPanel_1.UnusedPanel, { title: unusedPanelTitle, disabled: disabled, items: unusedItems, dragItemText: dragItemText }),
66
+ React.createElement(UnusedPanel_1.UnusedPanel, { title: unusedPanelTitle, disabled: disabled, items: allowedItems, dragItemText: dragItemText }),
92
67
  React.createElement(Card_1.Card, { className: "twa:flex-1 twa:m-2 ab-ModuleSelector-UsedPanel" },
93
68
  React.createElement(Card_1.Card.Title, { border: false }, tabsTitle),
94
69
  React.createElement(Card_1.Card.Body, { className: "twa:px-2" },
95
- React.createElement(TabList_1.TabList, { disabled: disabled, tabs: tabs, onRemoveTab: handleRemoveTab, onRemoveToolbar: handleRemoveToolbar, onChangeTabName: handleChangeTabName, onNewTab: contextValue.permittedActions.createTab ? handleTabAdd : undefined })))))));
70
+ React.createElement(TabList_1.TabList, { disabled: disabled, tabs: tabs, onTabsChange: onTabsChange, onRemoveTab: handleRemoveTab, onRemoveToolbar: handleRemoveToolbar, onChangeTabName: handleChangeTabName, onNewTab: contextValue.permittedActions.createTab ? handleTabAdd : undefined })))))));
96
71
  };
97
72
  exports.ModuleManager = ModuleManager;
@@ -1,30 +1,35 @@
1
1
  import * as React from 'react';
2
2
  import { BaseModuleTab } from './types';
3
- export declare function TabList({ tabs, onRemoveTab, onRemoveToolbar, onChangeTabName, disabled, onNewTab, }: {
3
+ export declare function TabList({ tabs, onTabsChange, onRemoveTab, onRemoveToolbar, onChangeTabName, disabled, onNewTab, }: {
4
4
  disabled: boolean;
5
5
  tabs: BaseModuleTab[];
6
+ onTabsChange: (tabs: BaseModuleTab[]) => void;
6
7
  onRemoveTab: (tabIndex: number) => void;
7
8
  onRemoveToolbar: (tabIndex: number, toolbarIndex: number) => void;
8
9
  onChangeTabName: (tabIndex: number, tabName: string) => void;
9
10
  onNewTab?: () => void;
10
11
  }): React.JSX.Element;
11
- export declare function TabItem({ tab, tabIndex, onRemove, onRemoveToolbar, onChangeTabName, disabled, }: {
12
+ export declare function TabItem({ tab, tabId, tabIndex, tabs, onTabsChange, onRemove, onRemoveToolbar, onChangeTabName, disabled, }: {
12
13
  tab: BaseModuleTab;
14
+ tabId: string;
13
15
  tabIndex: number;
16
+ tabs: BaseModuleTab[];
17
+ onTabsChange: (tabs: BaseModuleTab[]) => void;
14
18
  disabled: boolean;
15
19
  onRemove: () => void;
16
20
  onRemoveToolbar: (toolbarIndex: number) => void;
17
21
  onChangeTabName: (tabName: string) => void;
18
22
  }): React.JSX.Element;
19
- export declare function ToolbarList({ toolbars, droppableId, onRemove, disabled, }: {
23
+ export declare function ToolbarList({ toolbars, tabIndex, tabs, onTabsChange, onRemove, disabled, }: {
20
24
  toolbars: string[];
21
- droppableId: string;
25
+ tabIndex: number;
26
+ tabs: BaseModuleTab[];
27
+ onTabsChange: (tabs: BaseModuleTab[]) => void;
22
28
  disabled: boolean;
23
29
  onRemove: (toolbarIndex: number) => void;
24
30
  }): React.JSX.Element;
25
- export declare function ToolbarItem({ toolbar, toolbarIndex, onRemove, disabled, }: {
31
+ export declare function ToolbarItem({ toolbar, onRemove, disabled, }: {
26
32
  disabled: boolean;
27
33
  toolbar: string;
28
- toolbarIndex: number;
29
34
  onRemove: () => void;
30
35
  }): React.JSX.Element;
@@ -11,62 +11,104 @@ const icons_1 = require("../icons");
11
11
  const SimpleButton_1 = tslib_1.__importDefault(require("../SimpleButton"));
12
12
  const DragAndDropContext_1 = require("./DragAndDropContext");
13
13
  const Flex_1 = require("../Flex");
14
- function TabList({ tabs, onRemoveTab, onRemoveToolbar, onChangeTabName, disabled, onNewTab, }) {
15
- return (React.createElement(dnd_1.Droppable, { droppableId: "MAIN", type: "TAB", direction: "horizontal" }, (provided) => (React.createElement("div", { ...provided.droppableProps, className: "ab-ModuleSelector__TabList twa:flex twa:flex-1 twa:overflow-auto", ref: provided.innerRef, "data-name": "dashboard-tabs" },
16
- tabs.map((tab, tabIndex) => (React.createElement(TabItem, { disabled: disabled, key: tabIndex, tabIndex: tabIndex, tab: tab, onRemove: () => onRemoveTab(tabIndex), onRemoveToolbar: (toolbarIndex) => onRemoveToolbar(tabIndex, toolbarIndex), onChangeTabName: (tabName) => onChangeTabName(tabIndex, tabName) }))),
14
+ const clsx_1 = tslib_1.__importDefault(require("clsx"));
15
+ function TabList({ tabs, onTabsChange, onRemoveTab, onRemoveToolbar, onChangeTabName, disabled, onNewTab, }) {
16
+ const tabIdsRef = React.useRef(new WeakMap());
17
+ const nextTabIdRef = React.useRef(0);
18
+ const getTabStableId = React.useCallback((tab) => {
19
+ const existingId = tabIdsRef.current.get(tab);
20
+ if (existingId) {
21
+ return existingId;
22
+ }
23
+ const newId = `dashboard-tab-${String(nextTabIdRef.current++)}`;
24
+ tabIdsRef.current.set(tab, newId);
25
+ return newId;
26
+ }, []);
27
+ return (React.createElement(dnd_1.DragList, { dragListId: "TABS", orientation: "horizontal", dragStrategy: "proxy", preserveDragSpace: true, onDragProxyMove: dnd_1.defaultDragProxyMove, onDrop: (sortedIndexes) => {
28
+ const newTabs = sortedIndexes.map((i) => tabs[i]);
29
+ onTabsChange(newTabs);
30
+ } }, (listDomProps) => (React.createElement("div", { ...listDomProps, className: (0, clsx_1.default)('ab-ModuleSelector__TabList twa:flex twa:flex-1 twa:overflow-auto', listDomProps.className), "data-name": "dashboard-tabs" },
31
+ tabs.map((tab, tabIndex) => {
32
+ const tabId = getTabStableId(tab);
33
+ return (React.createElement(TabItem, { disabled: disabled, key: tabIndex, tabId: tabId, tabIndex: tabIndex, tabs: tabs, onTabsChange: onTabsChange, tab: tab, onRemove: () => onRemoveTab(tabIndex), onRemoveToolbar: (toolbarIndex) => onRemoveToolbar(tabIndex, toolbarIndex), onChangeTabName: (tabName) => onChangeTabName(tabIndex, tabName) }));
34
+ }),
17
35
  !disabled && onNewTab ? (React.createElement(Flex_1.Flex, { alignItems: "center", justifyContent: "center", className: "ab-ModuleSelector__TabItem twa:min-w-32 twa:border-dashed twa:cursor-pointer twa:bg-primarylight twa:text-primary-foreground twa:hover:bg-primary", onClick: onNewTab },
18
36
  React.createElement("div", { className: "twa:text-8 twa:flex twa:flex-col twa:gap-4 twa:items-center twa:italic" },
19
37
  React.createElement(icons_1.Icon, { name: "plus", size: 32 }),
20
- "Click to add tab"))) : null,
21
- provided.placeholder))));
38
+ "Click to add tab"))) : null))));
22
39
  }
23
- function TabItem({ tab, tabIndex, onRemove, onRemoveToolbar, onChangeTabName, disabled, }) {
40
+ function TabItem({ tab, tabId, tabIndex, tabs, onTabsChange, onRemove, onRemoveToolbar, onChangeTabName, disabled, }) {
24
41
  const context = React.useContext(DragAndDropContext_1.DragAndDropContext);
25
42
  const isDragDisabled = disabled || !context.permittedActions.dragAndDropTab;
26
- return (React.createElement(dnd_1.Draggable, { isDragDisabled: isDragDisabled, draggableId: String(tabIndex), index: tabIndex }, (provided) => {
43
+ return (React.createElement(dnd_1.DragList.DraggableItem, { dragListId: "TABS", id: tabId }, (itemDomProps) => {
44
+ const { onPointerDown, ...restDomProps } = itemDomProps;
27
45
  let showHeader = true;
28
46
  if (tab.Name === '' &&
29
47
  !context.permittedActions.editTabName &&
30
48
  !context.permittedActions.deleteTab) {
31
49
  showHeader = false;
32
50
  }
33
- return (React.createElement("div", { className: "ab-ModuleSelector__TabItem twa:min-w-32", "data-name": "dashboard-tab", ref: provided.innerRef, ...provided.draggableProps, style: {
34
- ...(isDragDisabled ? {} : provided.draggableProps.style),
35
- } },
51
+ return (React.createElement("div", { ...restDomProps, className: (0, clsx_1.default)('twa:bg-defaultbackground', 'twa:select-none', 'ab-ModuleSelector__TabItem twa:min-w-32', restDomProps.className), "data-name": "dashboard-tab" },
36
52
  showHeader ? (React.createElement("div", { className: "ab-ModuleSelector__TabItem__header" },
37
- React.createElement("div", { ...(disabled ? {} : provided.dragHandleProps), style: context.permittedActions.dragAndDropTab
38
- ? {}
39
- : {
40
- display: 'none',
41
- } },
53
+ React.createElement("div", { ...(!isDragDisabled ? { onPointerDown } : {}), style: context.permittedActions.dragAndDropTab ? {} : { display: 'none' } },
42
54
  React.createElement(icons_1.Icon, { name: "drag" })),
43
55
  context.permittedActions.editTabName ? (React.createElement("input", { className: "ab-ModuleSelector__TabItem__header-input", type: "text", disabled: disabled, value: tab.Name, onChange: (event) => {
44
56
  onChangeTabName(event.target.value);
45
57
  } })) : (tab.Name),
46
58
  context.permittedActions.deleteTab && (React.createElement(SimpleButton_1.default, { disabled: disabled, icon: "delete", variant: "text", onClick: onRemove })))) : null,
47
- React.createElement(ToolbarList, { disabled: disabled, toolbars: tab.Items, droppableId: String(tabIndex), onRemove: onRemoveToolbar })));
59
+ React.createElement(ToolbarList, { disabled: disabled, toolbars: tab.Items, tabIndex: tabIndex, tabs: tabs, onTabsChange: onTabsChange, onRemove: onRemoveToolbar })));
48
60
  }));
49
61
  }
50
- function ToolbarList({ toolbars, droppableId, onRemove, disabled, }) {
51
- return (React.createElement(dnd_1.Droppable, { droppableId: droppableId, type: "TOOLBAR" }, (provided, snapshot) => (React.createElement(Flex_1.Box, { className: "ab-ModuleSelector__ToolbarList", ref: provided.innerRef, ...(disabled ? {} : provided.droppableProps), "data-name": "dashboard-toolbar-drop-target", style: {
52
- backgroundColor: snapshot.isDraggingOver
53
- ? 'var(--ab-dashboard-tab-drop-target__background)'
54
- : '',
55
- } },
56
- toolbars?.map((toolbar, toolbarIndex) => (React.createElement(ToolbarItem, { disabled: disabled, key: toolbar, toolbar: toolbar, toolbarIndex: toolbarIndex, onRemove: () => onRemove(toolbarIndex) }))),
57
- toolbars.length === 0 ? (React.createElement("div", { className: "ab-ModuleSelector__ToolbarList__placeholder twa:flex twa:items-center twa:justify-center twa:h-full twa:italic twa:text-center" }, "Drag and drop toolbar here")) : null,
58
- provided.placeholder))));
62
+ function ToolbarList({ toolbars, tabIndex, tabs, onTabsChange, onRemove, disabled, }) {
63
+ const acceptDropsFrom = React.useMemo(() => {
64
+ const sources = ['UNUSED'];
65
+ tabs.forEach((_, i) => {
66
+ if (i !== tabIndex)
67
+ sources.push(String(i));
68
+ });
69
+ return sources;
70
+ }, [tabIndex, tabs]);
71
+ return (React.createElement(dnd_1.DragList, { dragListId: String(tabIndex), orientation: "vertical", acceptDropsFrom: [...acceptDropsFrom, String(tabIndex)], onDragProxyMove: dnd_1.defaultDragProxyMove,
72
+ // this is called when reordering inside the same list
73
+ onDrop: (sortedIndexes) => {
74
+ const newItems = sortedIndexes.map((i) => toolbars[i]);
75
+ onTabsChange(tabs.map((t, i) => (i === tabIndex ? { ...t, Items: newItems } : t)));
76
+ }, shouldAcceptDrop: ({ dragItem, dragSourceListId }) => {
77
+ const dragItemId = dragItem.id;
78
+ // if the tab contains an item with the same id, don't accept the drop
79
+ if (dragSourceListId != String(tabIndex) && tabs[tabIndex].Items.includes(dragItemId)) {
80
+ return false;
81
+ }
82
+ return true;
83
+ },
84
+ // this is called when dropping an item from a different list
85
+ onAcceptDrop: ({ dragItemId, dragSourceListId, dropIndex }) => {
86
+ const newTabs = tabs.map((tab, i) => {
87
+ let items = [...tab.Items];
88
+ if (dragSourceListId !== 'UNUSED' && i === Number(dragSourceListId)) {
89
+ items = items.filter((item) => item !== dragItemId);
90
+ }
91
+ if (i === tabIndex) {
92
+ items.splice(dropIndex, 0, dragItemId);
93
+ }
94
+ return { ...tab, Items: items };
95
+ });
96
+ onTabsChange(newTabs);
97
+ } }, (listDomProps, context) => (React.createElement(Flex_1.Box, { ...listDomProps, className: (0, clsx_1.default)('ab-ModuleSelector__ToolbarList', listDomProps.className, {
98
+ 'twa:bg-(--ab-dashboard-tab-drop-target__background) ab-ModuleSelector__ToolbarList--accent-drop': context.dropTargetListId === String(tabIndex) && context.status === 'accepted',
99
+ 'twa:bg-error/30 ab-ModuleSelector__ToolbarList--reject-drop': context.dropTargetListId === String(tabIndex) && context.status === 'rejected',
100
+ }), "data-name": "dashboard-toolbar-drop-target" },
101
+ toolbars?.map((toolbar, toolbarIndex) => (React.createElement(ToolbarItem, { disabled: disabled, key: toolbar, toolbar: toolbar, onRemove: () => onRemove(toolbarIndex) }))),
102
+ toolbars.length === 0 ? (React.createElement("div", { className: "ab-ModuleSelector__ToolbarList__placeholder twa:flex twa:items-center twa:justify-center twa:h-full twa:italic twa:text-center" }, "Drag and drop toolbar here")) : null))));
59
103
  }
60
- function ToolbarItem({ toolbar, toolbarIndex, onRemove, disabled, }) {
104
+ function ToolbarItem({ toolbar, onRemove, disabled, }) {
61
105
  const { availableItems } = React.useContext(DragAndDropContext_1.DragAndDropContext);
62
- let currentItem = availableItems.find((t) => t.Id === toolbar);
106
+ const currentItem = availableItems.find((t) => t.Id === toolbar);
63
107
  const title = currentItem ? currentItem.Title : toolbar;
64
- return (React.createElement(dnd_1.Draggable, { isDragDisabled: disabled, draggableId: toolbar, index: toolbarIndex }, (provided, snapshot) => (React.createElement(Flex_1.Flex, { className: `ab-ModuleSelector__ToolbarItem twa:mb-1 twa:pl-1`, alignItems: "center", ref: provided.innerRef, ...provided.draggableProps, ...provided.dragHandleProps, style: {
65
- ...provided.draggableProps.style,
66
- backgroundColor: snapshot.isDragging
67
- ? 'var(--ab-dashboard-toolbar-drag__background)'
68
- : 'var(--ab-color-primarylight)',
69
- } },
70
- React.createElement("div", { className: "twa:flex-1" }, title),
71
- React.createElement(SimpleButton_1.default, { disabled: disabled, icon: "close", variant: "text", className: "twa:p-1", onClick: onRemove })))));
108
+ return (React.createElement(dnd_1.DragList.DraggableItem, { id: toolbar }, (itemDomProps) => {
109
+ const { onPointerDown, ...restDomProps } = itemDomProps;
110
+ return (React.createElement(Flex_1.Flex, { ...restDomProps, ...(disabled ? {} : { onPointerDown }), className: (0, clsx_1.default)('ab-ModuleSelector__ToolbarItem twa:mb-1 twa:pl-1 twa:text-3', 'twa:bg-primarylight', restDomProps.className), alignItems: "center" },
111
+ React.createElement("div", { className: "twa:flex-1" }, title),
112
+ React.createElement(SimpleButton_1.default, { disabled: disabled, icon: "close", variant: "text", className: "twa:p-1", onClick: onRemove })));
113
+ }));
72
114
  }
@@ -16,29 +16,18 @@ function UnusedPanel({ items, disabled, title, dragItemText, }) {
16
16
  ")"),
17
17
  React.createElement(UnusedItemList, { disabled: disabled, items: items })));
18
18
  }
19
+ const EMPTY_ARRAY = [];
19
20
  function UnusedItemList({ items, disabled }) {
20
- return (React.createElement(dnd_1.Droppable, { droppableId: "UNUSED", type: "TOOLBAR", isDropDisabled: true, direction: "horizontal" }, (provided) => (React.createElement("div", { ref: provided.innerRef, "data-name": "unusedpanel-items-list", ...provided.droppableProps, className: 'twa:px-2 twa:flex-wrap twa:flex twa:flex-row twa:gap-1' },
21
- items.map((unusedItem, unusedItemIndex) => (React.createElement(UnusedItem, { disabled: disabled, key: unusedItem, unusedItem: unusedItem, unusedItemIndex: unusedItemIndex }))),
22
- provided.placeholder))));
21
+ return (React.createElement(dnd_1.DragList, { dragStrategy: "proxy", preserveDragSpace: true, dragListId: "UNUSED", orientation: "horizontal", onDragProxyMove: dnd_1.defaultDragProxyMove, acceptDropsFrom: EMPTY_ARRAY, onDragProxySetup: ({ proxyElement }) => {
22
+ proxyElement.classList.add('twa:shadow-md');
23
+ }, onDrop: () => { } }, (listDomProps) => (React.createElement("div", { ...listDomProps, "data-name": "unusedpanel-items-list", className: (0, clsx_1.default)('twa:px-2 twa:flex-wrap twa:flex twa:flex-row twa:gap-1', listDomProps.className) }, items.map((unusedItem) => (React.createElement(UnusedItem, { disabled: disabled, key: unusedItem, unusedItem: unusedItem })))))));
23
24
  }
24
- function UnusedItem({ unusedItem, unusedItemIndex, disabled, }) {
25
+ function UnusedItem({ unusedItem, disabled }) {
25
26
  const { availableItems } = React.useContext(DragAndDropContext_1.DragAndDropContext);
26
- let currentItem = availableItems.find((t) => t.Id === unusedItem);
27
+ const currentItem = availableItems.find((t) => t.Id === unusedItem);
27
28
  const title = currentItem ? currentItem.Title : unusedItem;
28
- return (React.createElement(dnd_1.Draggable, { isDragDisabled: disabled, draggableId: unusedItem, index: unusedItemIndex }, (provided, snapshot) => {
29
- const eventHandlers = disabled
30
- ? {}
31
- : {
32
- ...provided.draggableProps,
33
- ...provided.dragHandleProps,
34
- };
35
- const dragStyle = disabled ? {} : provided.draggableProps.style;
36
- return (React.createElement("div", { "data-name": "unused-item", ref: provided.innerRef, ...eventHandlers, className: (0, clsx_1.default)('twa:rounded-md twa:text-sm twa:text-text-on-primary twa:p-2'), style: {
37
- ...dragStyle,
38
- border: '1px solid var(--ab-color-primary)',
39
- backgroundColor: snapshot.isDragging
40
- ? 'var(--ab-dashboard-toolbar-drag__background)'
41
- : 'var(--ab-color-primary)',
42
- } }, title));
29
+ return (React.createElement(dnd_1.DragList.DraggableItem, { id: unusedItem }, (itemDomProps) => {
30
+ const { onPointerDown, ...restDomProps } = itemDomProps;
31
+ return (React.createElement("div", { "data-name": "unused-item", ...restDomProps, ...(disabled ? {} : { onPointerDown }), className: (0, clsx_1.default)('twa:rounded-md twa:text-sm twa:text-text-on-primary twa:p-2 twa:select-none', 'twa:bg-primary', restDomProps.className) }, title));
43
32
  }));
44
33
  }
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { ExpressionFunction, ExpressionFunctionMap } from '../../parser/src/types';
3
3
  import { AdaptableApi } from '../../Api/AdaptableApi';
4
4
  import { CSSProperties } from 'react';
5
+ import { ColumnScope } from '../../types';
5
6
  interface BaseEditorInputProps {
6
7
  type: 'main' | 'secondary';
7
8
  value: string;
@@ -16,6 +17,7 @@ interface BaseEditorInputProps {
16
17
  hideResultPreview?: boolean;
17
18
  api: AdaptableApi;
18
19
  style?: CSSProperties;
20
+ columnScope?: ColumnScope;
19
21
  }
20
22
  export interface OperatorEditorButton {
21
23
  functionName: string;
@@ -206,6 +206,9 @@ function BaseEditorInput(props) {
206
206
  // clone the class instance to still keep the prototype methods
207
207
  return Object.assign(Object.create(Object.getPrototypeOf(firstRowNode)), firstRowNode);
208
208
  }, []);
209
+ const scopeColumnId = (0, react_1.useMemo)(() => {
210
+ return props.api.columnScopeApi.getAnyColumnIdForScope(props.columnScope);
211
+ }, [props.columnScope]);
209
212
  try {
210
213
  // explicitly parsing & evaluating the expression because we need full control of the resulted AST
211
214
  const expr = parser.parse(props.value || '');
@@ -222,6 +225,7 @@ function BaseEditorInput(props) {
222
225
  functions: expressionFunctions,
223
226
  evaluateCustomQueryVariable: props.api.internalApi.getQueryLanguageService().evaluateCustomQueryVariable,
224
227
  dataChangedEvent,
228
+ columnScope: scopeColumnId,
225
229
  ...props.api.internalApi.buildBaseContext(),
226
230
  });
227
231
  }
@@ -1,14 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { AdaptableApi } from '../../Api/AdaptableApi';
3
3
  import { AdaptableModule } from '../../AdaptableState/Common/Types';
4
+ import { ColumnScope } from '../../AdaptableState/Common/ColumnScope';
4
5
  interface EditorInputProps {
5
6
  type: 'boolean' | 'scalar' | 'aggregatedScalar' | 'cumulativeAggregatedScalar' | 'quantileAggregatedScalar';
6
7
  module: AdaptableModule;
7
8
  value: string;
8
9
  onChange: (value: string) => void;
10
+ api: AdaptableApi;
9
11
  testData: any;
10
12
  isFullExpression?: boolean;
11
- api: AdaptableApi;
13
+ columnScope?: ColumnScope;
12
14
  }
13
15
  declare function EditorInput(props: EditorInputProps): React.JSX.Element;
14
16
  export default EditorInput;
@@ -41,15 +41,26 @@ function EditorInput(props) {
41
41
  }, {});
42
42
  };
43
43
  const expressionFunctions = (0, react_1.useMemo)(() => {
44
- return props.type === 'aggregatedScalar' ||
44
+ if (props.type === 'aggregatedScalar' ||
45
45
  props.type === 'cumulativeAggregatedScalar' ||
46
- props.type === 'quantileAggregatedScalar'
47
- ? getFilteredAggregatedExpressionFunctions(moduleExpressionFunctions.aggregatedScalarFunctions, props.type)
48
- : {
49
- ...moduleExpressionFunctions.booleanFunctions,
50
- ...moduleExpressionFunctions.scalarFunctions,
51
- };
52
- }, [props.type]);
46
+ props.type === 'quantileAggregatedScalar') {
47
+ return getFilteredAggregatedExpressionFunctions(moduleExpressionFunctions.aggregatedScalarFunctions, props.type);
48
+ }
49
+ let booleanAndScalarFunctions = {
50
+ ...moduleExpressionFunctions.booleanFunctions,
51
+ ...moduleExpressionFunctions.scalarFunctions,
52
+ };
53
+ if (!props.columnScope) {
54
+ // filter out $SCOPE function if no columnScope is provided
55
+ booleanAndScalarFunctions = Object.keys(booleanAndScalarFunctions)
56
+ .filter((key) => key !== '$SCOPE')
57
+ .reduce((obj, key) => {
58
+ obj[key] = booleanAndScalarFunctions[key];
59
+ return obj;
60
+ }, {});
61
+ }
62
+ return booleanAndScalarFunctions;
63
+ }, [props.type, props.columnScope]);
53
64
  const { setSelectedFunction } = (0, EditorContext_1.useExpressionEditor)();
54
65
  let queryName;
55
66
  switch (props.type) {
@@ -77,6 +88,6 @@ function EditorInput(props) {
77
88
  ? editorButtonsQuantileAggregatedScalar_1.editorButtonsQuantileAggregatedScalar
78
89
  : editorButtonsSearch_1.editorButtonsSearch, testData: props.testData, isFullExpression: props.isFullExpression, hideResultPreview: props.type === 'aggregatedScalar' ||
79
90
  props.type === 'cumulativeAggregatedScalar' ||
80
- props.type === 'quantileAggregatedScalar', api: props.api }));
91
+ props.type === 'quantileAggregatedScalar', api: props.api, columnScope: props.columnScope }));
81
92
  }
82
93
  exports.default = EditorInput;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AdaptableColumnDataType, AdaptableModule, BooleanFunctionName } from '../../../types';
2
+ import { AdaptableColumnDataType, AdaptableModule, BooleanFunctionName, ColumnScope } from '../../../types';
3
3
  interface QueryBuilderProps {
4
4
  query: string;
5
5
  getColumns: (type?: AdaptableColumnDataType) => {
@@ -14,6 +14,7 @@ interface QueryBuilderProps {
14
14
  }[];
15
15
  onChange: (query: string) => void;
16
16
  module: AdaptableModule;
17
+ columnScope?: ColumnScope;
17
18
  }
18
19
  export declare function useQueryBuilderContext(): {
19
20
  getColumns: QueryBuilderProps["getColumns"];
@@ -91,7 +91,6 @@ const QueryBuilder = (props) => {
91
91
  }
92
92
  else if (qlPredicate && !('errorMessage' in qlPredicate)) {
93
93
  errorOrEditor = (React.createElement(QueryPredicateBuilder_1.QueryPredicateBuilder, { isRoot: true, index: 0, id: "0", predicate: qlPredicate, onNewPredicate: (type) => {
94
- // add to its children
95
94
  const newPredicate = {
96
95
  operator: type === 'filter' ? undefined : 'AND',
97
96
  args: [],
@@ -104,15 +103,7 @@ const QueryBuilder = (props) => {
104
103
  handleQlPredicateChange(predicate);
105
104
  } }));
106
105
  }
107
- return (React.createElement(dnd_1.DragDropContext, { onDragEnd: (result) => {
108
- if (!result.destination) {
109
- return;
110
- }
111
- const toPath = `${result.destination.droppableId}/${result.destination.index}`;
112
- const fromPath = result.draggableId;
113
- const predicate = (0, utils_1.reorder)(qlPredicate, fromPath, toPath);
114
- handleQlPredicateChange(predicate);
115
- } },
106
+ return (React.createElement(dnd_1.DragDropProvider, null,
116
107
  React.createElement(QueryBuilderContext.Provider, { value: context },
117
108
  React.createElement(Flex_1.Box, { className: QUERY_BUILDER_CLASSNAME },
118
109
  React.createElement(HelpBlock_1.default, { "data-name": "query-builder-help", className: "twa:my-2 twa:p-2 twa:text-3" }, "Build the Grid Filter by adding Column Conditions and AND / OR Groups as required"),
@@ -15,6 +15,7 @@ const SimpleButton_1 = tslib_1.__importDefault(require("../../SimpleButton"));
15
15
  const QueryBuilderInputs_1 = require("./QueryBuilderInputs");
16
16
  const utils_1 = require("./utils");
17
17
  const Flex_1 = require("../../Flex");
18
+ const clsx_1 = tslib_1.__importDefault(require("clsx"));
18
19
  const ITEM_HEIGHT = 40;
19
20
  const BASE_CLASS_NAME = 'ab-QueryBuilder-predicate-editor';
20
21
  const Handle = (props) => (react_1.default.createElement(Flex_1.Flex, { className: `${BASE_CLASS_NAME}__handle twa:mr-1`, style: { height: ITEM_HEIGHT }, alignItems: "center", ...props },
@@ -39,8 +40,12 @@ const LogicalFunctionEditor = (props) => {
39
40
  ${props.lastChild ? `${BASE_CLASS_NAME}--last-child` : ''}
40
41
  ${props.isRoot ? `${BASE_CLASS_NAME}--root` : `${BASE_CLASS_NAME}--child`}
41
42
  `;
42
- const getCombinatorEl = (handleProps, className) => (react_1.default.createElement(dnd_1.Droppable, { droppableId: props.id, type: props.id }, (provided, snapshot) => {
43
- return (react_1.default.createElement("div", { ...provided.droppableProps, ref: provided.innerRef, className: className },
43
+ const handleDrop = (sortedIndexes) => {
44
+ const newArgs = sortedIndexes.map((i) => props.predicate.args[i]);
45
+ props.onChange({ ...props.predicate, args: newArgs });
46
+ };
47
+ const getCombinatorEl = (handleProps) => (react_1.default.createElement(dnd_1.DragList, { dragListId: props.id, orientation: "vertical", onDrop: handleDrop, onDragProxyMove: dnd_1.defaultDragProxyMove }, (listDomProps) => {
48
+ return (react_1.default.createElement("div", { ...listDomProps, className: (0, clsx_1.default)(listDomProps.className) },
44
49
  react_1.default.createElement(Flex_1.Flex, null,
45
50
  props.isRoot ? null : react_1.default.createElement(Handle, { ...handleProps }),
46
51
  react_1.default.createElement(Flex_1.Flex, { className: "twa:flex-1", alignItems: "center", height: ITEM_HEIGHT },
@@ -98,21 +103,18 @@ const LogicalFunctionEditor = (props) => {
98
103
  });
99
104
  } }));
100
105
  }),
101
- provided.placeholder,
102
106
  react_1.default.createElement("div", { className: `${BASE_CLASS_NAME}__root-actions` },
103
107
  react_1.default.createElement(QueryPredicateButtons, { ...props, hideDelete: true })))));
104
108
  }));
105
109
  if (props.isRoot) {
106
- return getCombinatorEl({ className: className });
107
- }
108
- else {
109
- return (react_1.default.createElement(dnd_1.Draggable, { key: props.id, draggableId: props.id, index: props.index }, (provided, snapshot) => {
110
- return (react_1.default.createElement("div", { ...provided.draggableProps, ref: provided.innerRef, className: className }, getCombinatorEl(provided.dragHandleProps)));
111
- }));
110
+ return getCombinatorEl({ className });
112
111
  }
112
+ return (react_1.default.createElement(dnd_1.DragList.DraggableItem, { id: props.id }, (itemDomProps) => {
113
+ const { onPointerDown, ...restDomProps } = itemDomProps;
114
+ return (react_1.default.createElement("div", { ...restDomProps, className: (0, clsx_1.default)(className, restDomProps.className) }, getCombinatorEl({ onPointerDown })));
115
+ }));
113
116
  };
114
117
  const PrimitiveFunctionEditor = (props) => {
115
- // [handle] [column] [operator-dropdown] [...args] [delete-button] [plus-button]
116
118
  const adaptable = (0, AdaptableContext_1.useAdaptable)();
117
119
  const [columnOrFieldExpression, ...restOfArgs] = props.predicate.args;
118
120
  const columnOrField = columnOrFieldExpression;
@@ -120,15 +122,12 @@ const PrimitiveFunctionEditor = (props) => {
120
122
  let columnOrFieldDataType = null;
121
123
  let columnInputDataType = null;
122
124
  let functionInputInputDataTypes = null;
123
- // Thsese are the type of inputs ommiting the column
124
- // [[column-data-type], number, number]
125
125
  let restOfFunctionInputDataTypes = [];
126
126
  if (columnOrField) {
127
127
  if (!(0, predicate_1.isArgumentColumnOrField)(columnOrField)) {
128
128
  return react_1.default.createElement(ErrorBox_1.default, null, "Expression must start with a column or a filed!");
129
129
  }
130
130
  if (columnOrField.includes('FIELD')) {
131
- // we let the full expression so we can difirienciate between column and field
132
131
  columnOrFieldId = columnOrField;
133
132
  const fieldValue = (0, utils_1.mapExpressionToFieldValue)(columnOrField);
134
133
  columnOrFieldDataType = adaptable.api.expressionApi.internalApi.getFieldType(fieldValue);
@@ -145,9 +144,10 @@ const PrimitiveFunctionEditor = (props) => {
145
144
  : [];
146
145
  }
147
146
  const level = props.id.split('/').length - 1;
148
- return (react_1.default.createElement(dnd_1.Draggable, { key: props.id, draggableId: props.id, index: props.index }, (provided) => {
149
- return (react_1.default.createElement(Flex_1.Flex, { className: `twa:pb-2 ${BASE_CLASS_NAME} ${BASE_CLASS_NAME}-level-${level} ${BASE_CLASS_NAME}-primitive ${props.lastChild ? `${BASE_CLASS_NAME}--last-child` : ''} `, ref: provided.innerRef, ...provided.draggableProps, style: { ...provided.draggableProps.style, minHeight: ITEM_HEIGHT } },
150
- react_1.default.createElement(Handle, { ...provided.dragHandleProps }),
147
+ return (react_1.default.createElement(dnd_1.DragList.DraggableItem, { id: props.id }, (itemDomProps) => {
148
+ const { onPointerDown, ...restDomProps } = itemDomProps;
149
+ return (react_1.default.createElement(Flex_1.Flex, { ...restDomProps, className: (0, clsx_1.default)(`twa:pb-2 ${BASE_CLASS_NAME} ${BASE_CLASS_NAME}-level-${level} ${BASE_CLASS_NAME}-primitive ${props.lastChild ? `${BASE_CLASS_NAME}--last-child` : ''}`, restDomProps.className), style: { minHeight: ITEM_HEIGHT } },
150
+ react_1.default.createElement(Handle, { onPointerDown: onPointerDown }),
151
151
  react_1.default.createElement(Flex_1.Flex, { alignItems: "center", style: { height: ITEM_HEIGHT } },
152
152
  react_1.default.createElement(Flex_1.Box, { className: "twa:mr-2" },
153
153
  react_1.default.createElement(QueryBuilderInputs_1.PrimitiveColumnOrFieldSelector, { onChange: (colOrField) => {
@@ -165,7 +165,6 @@ const PrimitiveFunctionEditor = (props) => {
165
165
  props.onChange({
166
166
  ...props.predicate,
167
167
  operator,
168
- // discard arguments
169
168
  args,
170
169
  });
171
170
  }, value: props.predicate.operator })),
@@ -186,7 +185,6 @@ const PrimitiveFunctionEditor = (props) => {
186
185
  }
187
186
  return (react_1.default.createElement(QueryBuilderInputs_1.PrimitiveValueInput, { ...commonProps, key: key, value: restOfArgs[index] ?? null, onChange: (value) => {
188
187
  const args = [...props.predicate.args];
189
- // +1 because col is the first argument
190
188
  args[index + 1] = value;
191
189
  props.onChange({
192
190
  ...props.predicate,
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AdaptableApi, AdaptableColumn, AdaptableField, AdaptableModule, NamedQuery } from '../../types';
2
+ import { AdaptableApi, AdaptableColumn, AdaptableField, AdaptableModule, ColumnScope, NamedQuery } from '../../types';
3
3
  export type ExpressionEditorType = 'boolean' | 'scalar' | 'observable' | 'aggregatedBoolean' | 'aggregatedScalar' | 'cumulativeAggregatedScalar' | 'quantileAggregatedScalar';
4
4
  interface ExpressionEditorProps {
5
5
  value: string;
@@ -19,6 +19,7 @@ interface ExpressionEditorProps {
19
19
  api: AdaptableApi;
20
20
  showQueryBuilder?: boolean;
21
21
  showExpressionEditor?: boolean;
22
+ columnScope?: ColumnScope;
22
23
  }
23
24
  export declare const baseClassName = "ab-ExpressionEditor";
24
25
  export declare function ExpressionEditor(props: ExpressionEditorProps): React.JSX.Element;
@@ -40,7 +40,7 @@ function ExpressionEditor(props) {
40
40
  // 'boolean','scalar','aggregatedScalar'/'cumulativeAggregatedScalar'/'quantileAggregatedScalar'
41
41
  (React.createElement(
42
42
  EditorInput_1.default,
43
- { type: type, module: module, value: props.value, onChange: (value) => {
43
+ { type: type, module: module, columnScope: props.columnScope, value: props.value, onChange: (value) => {
44
44
  setExpressionText(value);
45
45
  props.onChange(value);
46
46
  }, testData: props.initialData, isFullExpression: props.isFullExpression, api: props.api }