@adaptabletools/adaptable 22.0.10 → 22.1.0-canary.0

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 (71) hide show
  1. package/index.css +33 -1
  2. package/index.css.map +1 -1
  3. package/package.json +3 -4
  4. package/src/AdaptableState/Common/AdaptablePredicate.js +1 -1
  5. package/src/AdaptableState/InitialState.d.ts +2 -2
  6. package/src/AdaptableState/LayoutState.d.ts +47 -0
  7. package/src/Api/CalendarApi.d.ts +15 -0
  8. package/src/Api/ColumnScopeApi.d.ts +5 -0
  9. package/src/Api/DataChangeHistoryApi.d.ts +7 -2
  10. package/src/Api/Implementation/CalendarApiImpl.d.ts +3 -0
  11. package/src/Api/Implementation/CalendarApiImpl.js +10 -0
  12. package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -0
  13. package/src/Api/Implementation/ColumnScopeApiImpl.js +12 -0
  14. package/src/Api/Implementation/DataChangeHistoryApiImpl.d.ts +2 -1
  15. package/src/Api/Implementation/DataChangeHistoryApiImpl.js +7 -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/Utilities/Constants/GeneralConstants.js +2 -1
  22. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.d.ts +1 -1
  23. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.js +41 -2
  24. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.d.ts +1 -1
  25. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.js +31 -2
  26. package/src/Utilities/Helpers/AdaptableHelper.js +30 -4
  27. package/src/Utilities/Services/Interface/IQueryLanguageService.d.ts +1 -0
  28. package/src/Utilities/Services/MetamodelService.js +18 -18
  29. package/src/Utilities/Services/QueryLanguageService.d.ts +2 -0
  30. package/src/Utilities/Services/QueryLanguageService.js +20 -8
  31. package/src/Utilities/Services/ValidationService.js +3 -1
  32. package/src/View/Components/EntityRulesEditor/index.js +1 -1
  33. package/src/View/Components/ModuleValueSelector/index.js +9 -1
  34. package/src/View/Components/ReorderDraggable/index.js +22 -36
  35. package/src/View/Components/ValueSelector/index.js +46 -50
  36. package/src/View/Dashboard/PinnedToolbarsSelector.js +1 -1
  37. package/src/View/Layout/Wizard/LayoutWizard.js +16 -1
  38. package/src/View/Layout/Wizard/sections/RowSelectionSection.d.ts +8 -0
  39. package/src/View/Layout/Wizard/sections/RowSelectionSection.js +141 -0
  40. package/src/View/NamedQuery/Wizard/NamedQuerySettingsWizardSection.js +0 -1
  41. package/src/agGrid/AdaptableAgGrid.js +10 -0
  42. package/src/components/Dashboard/Dashboard.js +1 -1
  43. package/src/components/DragAndDropContext/ModuleManager.d.ts +1 -0
  44. package/src/components/DragAndDropContext/ModuleManager.js +12 -37
  45. package/src/components/DragAndDropContext/TabList.d.ts +11 -6
  46. package/src/components/DragAndDropContext/TabList.js +78 -36
  47. package/src/components/DragAndDropContext/UnusedPanel.js +10 -21
  48. package/src/components/ExpressionEditor/BaseEditorInput.d.ts +2 -0
  49. package/src/components/ExpressionEditor/BaseEditorInput.js +4 -0
  50. package/src/components/ExpressionEditor/EditorInput.d.ts +3 -1
  51. package/src/components/ExpressionEditor/EditorInput.js +20 -9
  52. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +2 -1
  53. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +3 -12
  54. package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +17 -19
  55. package/src/components/ExpressionEditor/index.d.ts +2 -1
  56. package/src/components/ExpressionEditor/index.js +1 -1
  57. package/src/components/Tree/TreeDropdown/index.js +38 -27
  58. package/src/components/dnd/index.d.ts +3 -13
  59. package/src/components/dnd/index.js +4 -55
  60. package/src/env.js +2 -2
  61. package/src/layout-manager/src/LayoutManagerModel.d.ts +2 -1
  62. package/src/layout-manager/src/index.d.ts +9 -0
  63. package/src/layout-manager/src/index.js +97 -1
  64. package/src/layout-manager/src/normalizeLayoutModel.js +8 -0
  65. package/src/layout-manager/src/simplifyLayoutModel.js +6 -0
  66. package/src/metamodel/adaptable-metamodel-model.d.ts +22 -13
  67. package/src/metamodel/adaptable.metamodel.d.ts +3773 -5143
  68. package/src/metamodel/adaptable.metamodel.js +1 -1
  69. package/src/parser/src/parser.js +55 -1218
  70. package/src/parser/src/types.d.ts +5 -0
  71. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -1,43 +1,29 @@
1
1
  import * as React from 'react';
2
- import { DragDropContext, Draggable, Droppable } from '../../../components/dnd';
2
+ import { defaultDragProxyMove, DragDropProvider, DragList } from '../../../components/dnd';
3
3
  import { Icon } from '../../../components/icons';
4
- import ArrayExtensions from '../../../Utilities/Extensions/ArrayExtensions';
5
4
  import { Box, Flex } from '../../../components/Flex';
6
5
  import clsx from 'clsx';
7
- import { twMerge } from '../../../twMerge';
8
6
  export function ReorderDraggable(props) {
9
- const { onChange, order, toIdentifier, isOptionDraggable, disabled, } = props;
7
+ const { onChange, order, toIdentifier, isOptionDraggable, disabled } = props;
10
8
  const baseClassName = 'ab-ReorderDraggable';
11
- const renderOption = (option, index) => {
12
- const identifier = toIdentifier(option);
13
- const renderNode = (flexProps, dragHandleProps) => {
14
- const reorderable = isOptionDraggable ? isOptionDraggable(option) : true;
15
- return (React.createElement(Flex, { alignItems: "center", key: identifier ?? index, "data-index": index, "data-id": identifier, "data-name": "option", ...flexProps, className: clsx(`${baseClassName}__option ${index ? 'twa:mt-1' : 'twa:mt-0'} twa:bg-primary twa:p-2 ${flexProps?.className || ''}`, props.optionClassName?.(option)), onClick: (e) => props.onOptionClick?.(option, e) },
16
- React.createElement(Flex, { className: "twa:flex-1", flexDirection: "row", alignItems: "center" },
17
- reorderable ? (React.createElement(Box, { ...dragHandleProps, className: `twa:mr-3 ${dragHandleProps?.className || ''}` },
18
- React.createElement(Icon, { name: "drag", style: { cursor: 'grab' } }))) : (React.createElement(Box, { className: "twa:mr-3" },
19
- React.createElement(Icon, { name: "drag", style: { cursor: 'not-allowed', opacity: 0.3 } }))),
20
- props.renderOption(option, index))));
21
- };
22
- const reorderable = isOptionDraggable ? isOptionDraggable(option) : true;
23
- return (React.createElement(Draggable, { key: identifier, index: index, draggableId: `${identifier}`, isDragDisabled: !reorderable || disabled }, (draggableProvided) => {
24
- return renderNode({
25
- ref: draggableProvided.innerRef,
26
- ...draggableProvided.draggableProps,
27
- style: draggableProvided.draggableProps.style,
28
- }, draggableProvided.dragHandleProps);
29
- }));
30
- };
31
- return (React.createElement(Flex, { style: props.style, className: twMerge(`${baseClassName} twa:flex-1`, props.className), flexDirection: "column" },
32
- React.createElement(DragDropContext, { onDragEnd: (result) => {
33
- const { source, destination } = result;
34
- const newOrder = ArrayExtensions.reorderArray(props.order, source.index, destination.index);
35
- onChange(newOrder);
36
- } },
37
- React.createElement(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column" },
38
- React.createElement(Droppable, { droppableId: "droppable" }, (droppableProvided) => {
39
- return (React.createElement("div", { ref: droppableProvided.innerRef, ...droppableProvided.droppableProps },
40
- order.map(renderOption),
41
- droppableProvided.placeholder));
42
- })))));
9
+ return (React.createElement(Flex, { style: props.style, className: `${baseClassName} twa:flex-1`, flexDirection: "column" },
10
+ React.createElement(DragDropProvider, null,
11
+ React.createElement(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-y-auto twa:overflow-x-hidden`, flexDirection: "column" },
12
+ React.createElement(DragList, { dragListId: "reorder-draggable", orientation: "vertical", dragStrategy: "proxy", preserveDragSpace: true, onDragProxyMove: defaultDragProxyMove, onDragProxySetup: ({ proxyElement }) => {
13
+ proxyElement.classList.add('twa:shadow-md');
14
+ }, onDrop: (sortedIndexes) => {
15
+ onChange(sortedIndexes.map((i) => order[i]));
16
+ } }, (listDomProps) => (React.createElement("div", { ...listDomProps }, order.map((option, index) => {
17
+ const identifier = toIdentifier(option);
18
+ const reorderable = isOptionDraggable ? isOptionDraggable(option) : true;
19
+ return (React.createElement(DragList.DraggableItem, { key: identifier, id: `${identifier}` }, (itemDomProps, itemContext) => {
20
+ const { onPointerDown, ...restDomProps } = itemDomProps;
21
+ return (React.createElement(Flex, { alignItems: "center", "data-index": index, "data-id": identifier, "data-name": "option", ...restDomProps, className: clsx(`${baseClassName}__option`, index ? 'twa:mt-1' : 'twa:mt-0', 'twa:bg-primary twa:p-2', itemContext.active ? 'twa:shadow-md' : '', restDomProps.className, props.optionClassName?.(option)), onClick: (e) => props.onOptionClick?.(option, e) },
22
+ React.createElement(Flex, { className: "twa:flex-1", flexDirection: "row", alignItems: "center" },
23
+ reorderable && !disabled ? (React.createElement(Box, { onPointerDown: onPointerDown, className: "twa:mr-3" },
24
+ React.createElement(Icon, { name: "drag", style: { cursor: 'grab' } }))) : (React.createElement(Box, { className: "twa:mr-3" },
25
+ React.createElement(Icon, { name: "drag", style: { cursor: 'not-allowed', opacity: 0.3 } }))),
26
+ props.renderOption(option, index))));
27
+ }));
28
+ }))))))));
43
29
  }
@@ -1,11 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { useState, useMemo, useCallback } from 'react';
3
- import { DragDropContext, Draggable, Droppable } from '../../../components/dnd';
3
+ import { defaultDragProxyMove, DragDropProvider, DragList } from '../../../components/dnd';
4
4
  import { CheckBox } from '../../../components/CheckBox';
5
5
  import { Icon } from '../../../components/icons';
6
6
  import Radio from '../../../components/Radio';
7
7
  import { AdaptableFormControlTextClear } from '../Forms/AdaptableFormControlTextClear';
8
- import ArrayExtensions from '../../../Utilities/Extensions/ArrayExtensions';
9
8
  import { Box, Flex } from '../../../components/Flex';
10
9
  import clsx from 'clsx';
11
10
  function useValuesMap({ options, value, toIdentifier, selectedMap, }) {
@@ -57,13 +56,14 @@ export function ValueSelector(props) {
57
56
  const identifier = toIdentifier(option);
58
57
  const label = !allowReorder ? preparedToLabel(option) : null;
59
58
  const reorderable = typeof allowReorder === 'function' ? allowReorder(option) : allowReorder;
60
- const renderNode = (props, dragHandleProps) => {
61
- return (React.createElement(Flex, { alignItems: "center", key: identifier ?? index, "data-index": index, "data-id": identifier, "data-name": "option", ...props, className: clsx(`twa:bg-primary twa:text-text-on-primary twa:rounded-standard twa:p-2`, {
59
+ return (React.createElement(DragList.DraggableItem, { key: identifier, id: `${identifier}` }, (itemDomProps) => {
60
+ const { onPointerDown, ...restDomProps } = itemDomProps;
61
+ return (React.createElement(Flex, { alignItems: "center", "data-index": index, "data-id": identifier, "data-name": "option", ...restDomProps, className: clsx('twa:bg-primary twa:text-text-on-primary twa:rounded-standard twa:p-2', {
62
62
  'twa:mt-1': index,
63
63
  'twa:mt-0': !index,
64
- }, props.className, `${baseClassName}__option`) },
64
+ }, restDomProps.className, `${baseClassName}__option`) },
65
65
  React.createElement(Flex, { flexDirection: "row", alignItems: "center", className: "twa:flex-1" },
66
- reorderable ? (React.createElement(Box, { ...dragHandleProps, className: clsx('twa:mr-3', dragHandleProps?.className) },
66
+ reorderable ? (React.createElement(Box, { onPointerDown: onPointerDown, className: "twa:mr-3" },
67
67
  React.createElement(Icon, { name: "drag", style: { cursor: 'grab' } }))) : null,
68
68
  singleSelect ? (React.createElement(Radio, { checked: selectedMap.has(identifier), "data-name": identifier, onChange: (checked) => {
69
69
  if (checked) {
@@ -84,13 +84,6 @@ export function ValueSelector(props) {
84
84
  notifyChange();
85
85
  }, checked: selectedMap.has(identifier) }, label)),
86
86
  React.createElement(Box, { className: "twa:ml-2 twa:flex-1" }, allowReorder ? preparedToLabel(option) : null))));
87
- };
88
- return (React.createElement(Draggable, { key: identifier, index: index, draggableId: `${identifier}`, isDragDisabled: !reorderable }, (draggableProvided) => {
89
- return renderNode({
90
- ref: draggableProvided.innerRef,
91
- ...draggableProvided.draggableProps,
92
- style: draggableProvided.draggableProps.style,
93
- }, draggableProvided.dragHandleProps);
94
87
  }));
95
88
  };
96
89
  const showOnlySelectedCheckbox = (React.createElement(CheckBox, { disabled: !value.length, checked: selectedOnly, onChange: setSelectedOnly }, showSelectedOnlyLabel ?? 'Show Selected Only'));
@@ -115,45 +108,48 @@ export function ValueSelector(props) {
115
108
  return (React.createElement(Flex, { style: props.style, className: clsx('twa:flex-1', baseClassName), flexDirection: "column" },
116
109
  React.createElement(Flex, { className: "twa:mb-1" }, showFilterInput && filter ? (React.createElement(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", className: "twa:flex-1 twa:border-0 twa:m-[3px]" })) : (React.createElement(Box, { className: "twa:flex-1" }))),
117
110
  renderSelectionSection(selectionSectionProps),
118
- React.createElement(DragDropContext, { onDragEnd: (result) => {
119
- const { source, destination } = result;
120
- const selection = [];
121
- const extraKeys = [];
122
- for (let [key, value] of selectedMap) {
123
- if (value != null) {
124
- selection.push(key);
125
- }
126
- else {
127
- // null/non-existent keys have to be stored separately
128
- extraKeys.push(key);
129
- }
130
- }
131
- const clone = new Map(selectedMap);
132
- const newSelection = ArrayExtensions.reorderArray(selection, source.index, destination.index);
133
- // and then pushed back in the new order, at the end
134
- newSelection.push(...extraKeys);
135
- selectedMap.clear();
136
- newSelection.forEach((key) => {
137
- selectedMap.set(key, clone.get(key));
138
- });
139
- notifyChange();
140
- } },
111
+ React.createElement(DragDropProvider, null,
141
112
  React.createElement(Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column" },
142
- React.createElement(Droppable, { droppableId: "droppable" }, (droppableProvided) => {
143
- return (React.createElement("div", { ref: droppableProvided.innerRef, ...droppableProvided.droppableProps },
144
- options
145
- .filter((option) => {
146
- let result = true;
147
- if (filter) {
148
- result = filter(option, searchInputValue);
113
+ React.createElement(DragList, { dragListId: "value-selector", orientation: "vertical", onDragProxyMove: defaultDragProxyMove, onDragProxySetup: ({ proxyElement }) => {
114
+ proxyElement.classList.add('twa:shadow-md');
115
+ }, onDrop: (_sortedIndexes) => {
116
+ const selection = [];
117
+ const extraKeys = [];
118
+ for (const [key, value] of selectedMap) {
119
+ if (value != null) {
120
+ selection.push(key);
149
121
  }
150
- result =
151
- result && (selectedOnly ? selectedMap.has(toIdentifier(option)) : true);
152
- return result;
153
- })
154
- .map(renderOption),
155
- droppableProvided.placeholder));
156
- })))));
122
+ else {
123
+ // null/non-existent keys have to be stored separately
124
+ extraKeys.push(key);
125
+ }
126
+ }
127
+ const clone = new Map(selectedMap);
128
+ // const newSelection: ID_TYPE[] = ArrayExtensions.reorderArray(
129
+ // selection,
130
+ // dragIndex,
131
+ // dropIndex
132
+ // );
133
+ const newSelection = _sortedIndexes
134
+ .map((index) => selection[index])
135
+ .filter((x) => x != null);
136
+ newSelection.push(...extraKeys);
137
+ selectedMap.clear();
138
+ newSelection.forEach((key) => {
139
+ selectedMap.set(key, clone.get(key));
140
+ });
141
+ notifyChange();
142
+ } }, (listDomProps) => (React.createElement("div", { ...listDomProps }, options
143
+ .filter((option) => {
144
+ let result = true;
145
+ if (filter) {
146
+ result = filter(option, searchInputValue);
147
+ }
148
+ result =
149
+ result && (selectedOnly ? selectedMap.has(toIdentifier(option)) : true);
150
+ return result;
151
+ })
152
+ .map(renderOption))))))));
157
153
  }
158
154
  export const renderSelectionSection = (props) => {
159
155
  const { value, options, disabled, singleSelect, toLabel, toIdentifier, } = props;
@@ -37,5 +37,5 @@ export const PinnedToolbarsSelector = (props) => {
37
37
  editTabName: false,
38
38
  }, onTabsChange: (tabs) => {
39
39
  dispatch(DashboardSetPinnedToolbars(tabs[0].Items));
40
- }, disabled: isDashboardDisabled, tabs: tabs, availableItems: toolbars, tabsTitle: 'Pinned Toolbars', unusedPanelTitle: "Available Pinned Toolbars", dragItemText: "Drag into the Panel below" }));
40
+ }, disabled: isDashboardDisabled, tabs: tabs, availableItems: toolbars, filterOutSelectedItems: true, tabsTitle: 'Pinned Toolbars', unusedPanelTitle: "Available Pinned Toolbars", dragItemText: "Drag into the Panel below" }));
41
41
  };
@@ -13,6 +13,7 @@ import { SortSection, SortSectionSummary } from './sections/SortSection';
13
13
  import { FilterSection, FilterSectionSummary, isColumnFiltersValid, } from './sections/FilterSection';
14
14
  import { GridFilterSection, GridFilterSectionSummary, isGridFiltersValid, } from './sections/GridFilterSection';
15
15
  import { areSummaryRowsValid, RowSummarySection, RowSummarySectionSummary, } from './sections/RowSummarySection';
16
+ import { RowSelectionSection, RowSelectionSectionSummary } from './sections/RowSelectionSection';
16
17
  import { WEIGHTED_AVERAGE_AGGREGATED_FUNCTION } from '../../../AdaptableState/Common/RowSummary';
17
18
  import { isPivotLayout } from '../../../Utilities/isPivotLayout';
18
19
  import { PivotRowGroupingSection, PivotRowGroupingSectionSummary, } from './sections/PivotRowGroupingSection';
@@ -114,7 +115,7 @@ export const LayoutWizard = (props) => {
114
115
  isValid: (data) => isPivotAggregationsSectionValid(data),
115
116
  render: () => (React.createElement(Box, { className: "twa:p-2 twa:h-full" },
116
117
  React.createElement(PivotAggregationsSection, { onChange: (layout) => {
117
- let newLayout = cloneObject(layout);
118
+ const newLayout = cloneObject(layout);
118
119
  setLayout(newLayout);
119
120
  } }))),
120
121
  },
@@ -144,6 +145,13 @@ export const LayoutWizard = (props) => {
144
145
  render: () => (React.createElement(Box, { className: "twa:p-2 twa:h-full" },
145
146
  React.createElement(GridFilterSection, { onChange: (newLayout) => setLayout(newLayout) }))),
146
147
  },
148
+ {
149
+ title: 'Row Selection',
150
+ details: 'Configure Row Selection',
151
+ renderSummary: () => React.createElement(RowSelectionSectionSummary, null),
152
+ render: () => (React.createElement(Box, { className: "twa:p-2" },
153
+ React.createElement(RowSelectionSection, { onChange: (newLayout) => setLayout(newLayout) }))),
154
+ },
147
155
  '-',
148
156
  {
149
157
  details: 'Review your Pivot Layout',
@@ -257,6 +265,13 @@ export const LayoutWizard = (props) => {
257
265
  render: () => (React.createElement(Box, { className: "twa:p-2 twa:h-full" },
258
266
  React.createElement(GridFilterSection, { onChange: (newLayout) => setLayout(newLayout) }))),
259
267
  },
268
+ {
269
+ title: 'Row Selection',
270
+ details: 'Configure Row Selection',
271
+ renderSummary: () => React.createElement(RowSelectionSectionSummary, null),
272
+ render: () => (React.createElement(Box, { className: "twa:p-2" },
273
+ React.createElement(RowSelectionSection, { onChange: (newLayout) => setLayout(newLayout) }))),
274
+ },
260
275
  '-',
261
276
  {
262
277
  details: 'Review your Table Layout',
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import { Layout } from '../../../../../types';
3
+ export declare const RowSelectionSectionSummary: React.FunctionComponent;
4
+ interface RowSelectionSectionProps {
5
+ onChange: (data: Layout) => void;
6
+ }
7
+ export declare const RowSelectionSection: React.FunctionComponent<RowSelectionSectionProps>;
8
+ export {};
@@ -0,0 +1,141 @@
1
+ import * as React from 'react';
2
+ import { CheckBox } from '../../../../components/CheckBox';
3
+ import Radio, { radioGroupStyling } from '../../../../components/Radio';
4
+ import { RadioGroup } from '../../../../components/Radio';
5
+ import { Tabs } from '../../../../components/Tabs';
6
+ import { Tag } from '../../../../components/Tag';
7
+ import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard';
8
+ import { Box, Flex } from '../../../../components/Flex';
9
+ import { twMerge } from '../../../../twMerge';
10
+ import HelpBlock from '../../../../components/HelpBlock';
11
+ import { AG_GRID_SELECTION_COLUMN } from '../../../../Utilities/Constants/GeneralConstants';
12
+ export const RowSelectionSectionSummary = () => {
13
+ const { data: layout } = useOnePageAdaptableWizardContext();
14
+ if (layout.RowSelection === false) {
15
+ return (React.createElement(Box, null,
16
+ React.createElement(Tag, null, "Row Selection Disabled")));
17
+ }
18
+ if (!layout.RowSelection) {
19
+ return (React.createElement(Box, null,
20
+ React.createElement(Tag, null, "Default (from Grid Options)")));
21
+ }
22
+ const rs = layout.RowSelection;
23
+ return (React.createElement(Box, null,
24
+ React.createElement(Tag, { className: "twa:mr-2" },
25
+ "Mode: ",
26
+ rs.Mode === 'multiRow' ? 'Multi Row' : 'Single Row'),
27
+ rs.Checkboxes != null && (React.createElement(Tag, { className: "twa:mr-2" },
28
+ "Checkboxes: ",
29
+ rs.Checkboxes ? 'Yes' : 'No')),
30
+ rs.HeaderCheckbox != null && (React.createElement(Tag, { className: "twa:mr-2" },
31
+ "Header Checkbox: ",
32
+ rs.HeaderCheckbox ? 'Yes' : 'No')),
33
+ rs.EnableClickSelection != null && (React.createElement(Tag, { className: "twa:mr-2" },
34
+ "Click Selection: ",
35
+ String(rs.EnableClickSelection))),
36
+ rs.CheckboxInGroupColumn != null && (React.createElement(Tag, { className: "twa:mr-2" },
37
+ "Checkbox Location: ",
38
+ rs.CheckboxInGroupColumn ? 'Group Column' : 'Selection Column')),
39
+ rs.GroupSelectMode != null && (React.createElement(Tag, { className: "twa:mr-2" },
40
+ "Group Select Mode: ",
41
+ rs.GroupSelectMode)),
42
+ rs.SelectAllMode != null && (React.createElement(Tag, { className: "twa:mr-2" },
43
+ "Select All Mode: ",
44
+ rs.SelectAllMode))));
45
+ };
46
+ function getMode(layout) {
47
+ if (!layout.RowSelection) {
48
+ return false;
49
+ }
50
+ return layout.RowSelection.Mode;
51
+ }
52
+ export const RowSelectionSection = (props) => {
53
+ const { data: layout } = useOnePageAdaptableWizardContext();
54
+ const mode = getMode(layout);
55
+ const rowSelection = layout.RowSelection ?? false;
56
+ const handleModeChange = (newMode) => {
57
+ if (newMode === false) {
58
+ props.onChange({ ...layout, RowSelection: false });
59
+ return;
60
+ }
61
+ const base = rowSelection
62
+ ? { ...rowSelection, Mode: newMode }
63
+ : { Mode: newMode };
64
+ if (newMode === 'singleRow') {
65
+ delete base.HeaderCheckbox;
66
+ delete base.GroupSelectMode;
67
+ delete base.SelectAllMode;
68
+ }
69
+ props.onChange({ ...layout, RowSelection: base });
70
+ };
71
+ const updateRowSelection = (patch) => {
72
+ if (!rowSelection) {
73
+ return;
74
+ }
75
+ const newLayout = {
76
+ ...layout,
77
+ RowSelection: { ...rowSelection, ...patch },
78
+ };
79
+ if (newLayout.RowSelection && !newLayout.RowSelection.CheckboxInGroupColumn) {
80
+ if (newLayout.TableColumns) {
81
+ if (!newLayout.TableColumns.includes(AG_GRID_SELECTION_COLUMN)) {
82
+ newLayout.TableColumns = [AG_GRID_SELECTION_COLUMN, ...(newLayout.TableColumns ?? [])];
83
+ }
84
+ }
85
+ else if (newLayout.PivotColumns) {
86
+ if (!newLayout.PivotColumns.includes(AG_GRID_SELECTION_COLUMN)) {
87
+ newLayout.PivotColumns = [AG_GRID_SELECTION_COLUMN, ...(newLayout.PivotColumns ?? [])];
88
+ }
89
+ }
90
+ }
91
+ props.onChange(newLayout);
92
+ };
93
+ return (React.createElement(React.Fragment, null,
94
+ React.createElement(Tabs, null,
95
+ React.createElement(Tabs.Tab, null, "Selection Mode"),
96
+ React.createElement(Tabs.Content, null,
97
+ React.createElement(Flex, { flexDirection: "column" },
98
+ React.createElement(RadioGroup, { orientation: "horizontal", variant: "text-only", className: twMerge(radioGroupStyling.horizontalTextOnly, 'twa:gap-2 twa:max-w-[500px] twa:bg-defaultbackground twa:p-2'), value: mode, name: "rowSelectionMode", onRadioChange: handleModeChange },
99
+ React.createElement(Radio, { value: false }, "Disabled"),
100
+ React.createElement(Radio, { value: "singleRow" }, "Single Row"),
101
+ React.createElement(Radio, { value: "multiRow" }, "Multi Row"))))),
102
+ rowSelection && (React.createElement(React.Fragment, null,
103
+ React.createElement(Tabs, { className: "twa:mt-2" },
104
+ React.createElement(Tabs.Tab, null, "Options"),
105
+ React.createElement(Tabs.Content, null,
106
+ React.createElement(Flex, { flexDirection: "row", className: "twa:gap-6" },
107
+ React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.Checkboxes ?? true, onChange: (checked) => updateRowSelection({ Checkboxes: checked }) }, "Show selection checkboxes"),
108
+ mode === 'multiRow' && (React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.HeaderCheckbox ?? true, onChange: (checked) => updateRowSelection({ HeaderCheckbox: checked }) }, "Show header checkbox for select all"))),
109
+ (rowSelection.Checkboxes ?? true) && (React.createElement(Flex, { flexDirection: "column", className: "twa:mt-3" },
110
+ React.createElement(Box, { className: "twa:my-3" }, "Checkbox Location"),
111
+ React.createElement(RadioGroup, { orientation: "vertical", value: rowSelection.CheckboxInGroupColumn ?? false, name: "checkboxLocation", onRadioChange: (value) => updateRowSelection({ CheckboxInGroupColumn: value }) },
112
+ React.createElement(Radio, { value: false }, "Show selection checkbox in dedicated selection column"),
113
+ React.createElement(Radio, { value: true }, "Show selection checkbox in group column")))))),
114
+ React.createElement(Tabs, { className: "twa:mt-2" },
115
+ React.createElement(Tabs.Tab, null, "Row Click Selection"),
116
+ React.createElement(Tabs.Content, null,
117
+ React.createElement(HelpBlock, { className: "twa:bg-primarydark/30 twa:text-text-on-primarydark twa:p-2 twa:rounded-standard twa:mb-2" },
118
+ React.createElement("p", null, "This describes the behaviour of the row selection when the user clicks on a row, but outside the row selection checkbox."),
119
+ React.createElement("p", null, "Should a click outside the checkbox select the row?")),
120
+ React.createElement(RadioGroup, { orientation: "vertical", value: rowSelection.EnableClickSelection ?? false, name: "clickSelection", onRadioChange: (value) => updateRowSelection({ EnableClickSelection: value }) },
121
+ React.createElement(Radio, { value: false }, "Disabled"),
122
+ React.createElement(Radio, { value: true }, "Enable selection and deselection"),
123
+ React.createElement(Radio, { value: 'enableSelection' }, "Enable selection only"),
124
+ React.createElement(Radio, { value: 'enableDeselection' }, "Enable deselection only")))),
125
+ mode === 'multiRow' && (React.createElement(Tabs, { className: "twa:mt-2" },
126
+ React.createElement(Tabs.Tab, null, "Group & Bulk Selection"),
127
+ React.createElement(Tabs.Content, null,
128
+ React.createElement(Flex, { flexDirection: "row", className: "twa:gap-6" },
129
+ React.createElement(Flex, { flexDirection: "row" },
130
+ React.createElement(Box, { className: "twa:self-center twa:mr-3" }, "Group Select"),
131
+ React.createElement(RadioGroup, { orientation: "vertical", value: rowSelection.GroupSelectMode ?? 'self', name: "groupSelectMode", onRadioChange: (value) => updateRowSelection({ GroupSelectMode: value }) },
132
+ React.createElement(Radio, { value: 'self' }, "Only select group row (no cascade)"),
133
+ React.createElement(Radio, { value: 'descendants' }, "Select group row and all descendants"),
134
+ React.createElement(Radio, { value: 'filteredDescendants' }, "Select group row and filtered descendants"))),
135
+ React.createElement(Flex, { flexDirection: "row", className: "twa:ml-6 twa:flex-1" },
136
+ React.createElement(Box, { className: "twa:self-center twa:mr-3" }, "Select All"),
137
+ React.createElement(RadioGroup, { orientation: "vertical", value: rowSelection.SelectAllMode ?? 'all', name: "selectAllMode", onRadioChange: (value) => updateRowSelection({ SelectAllMode: value }) },
138
+ React.createElement(Radio, { value: 'all' }, "All rows"),
139
+ React.createElement(Radio, { value: 'filtered' }, "Filtered rows only"),
140
+ React.createElement(Radio, { value: 'currentPage' }, "Current page only")))))))))));
141
+ };
@@ -1,4 +1,3 @@
1
- // TODO: move to named query
2
1
  import * as React from 'react';
3
2
  import WizardPanel from '../../../components/WizardPanel';
4
3
  import FormLayout, { FormRow } from '../../../components/FormLayout';
@@ -452,6 +452,7 @@ export class AdaptableAgGrid {
452
452
  columnDefs = LayoutManager.getColumnDefsChangesForLayout(layoutModel, columnDefs) ?? columnDefs;
453
453
  gridOptions.columnDefs = columnDefs;
454
454
  gridOptions.initialState = initialGridState;
455
+ const initialRowSelection = gridOptions.rowSelection;
455
456
  if (layoutModel) {
456
457
  if (isPivotLayoutModel(layoutModel)) {
457
458
  gridOptions.pivotDefaultExpanded = layoutModel.PivotExpandLevel;
@@ -460,6 +461,14 @@ export class AdaptableAgGrid {
460
461
  layoutModel.RowGroupDisplayType === 'multi' ? 'multipleColumns' : 'singleColumn';
461
462
  // fixes issue #3053
462
463
  gridOptions.suppressAggFuncInHeader = !!layoutModel.SuppressAggFuncInHeader;
464
+ if (!isPivotLayoutModel(layoutModel) &&
465
+ LayoutManager.isSelectionColumnInNonFirstPosition(layoutModel.TableColumns)) {
466
+ gridOptions.selectionColumnDef = {
467
+ ...gridOptions.selectionColumnDef,
468
+ lockPosition: false,
469
+ };
470
+ }
471
+ gridOptions.rowSelection = LayoutManager.getGridOptionForRowSelectionFromLayout(layoutModel.RowSelection, gridOptions.rowSelection);
463
472
  }
464
473
  this.lifecycleState = 'initAgGrid';
465
474
  this.agGridAdapter.initialGridOptions = gridOptions;
@@ -475,6 +484,7 @@ export class AdaptableAgGrid {
475
484
  this.layoutManager = new LayoutManager({
476
485
  gridApi: agGridApi,
477
486
  debugId: this.adaptableOptions.adaptableId,
487
+ initialRowSelection,
478
488
  });
479
489
  this.silentUpdateCurrentLayoutModel(layoutModel);
480
490
  // this shouldn't be needed
@@ -27,7 +27,7 @@ export function Dashboard(props) {
27
27
  left: position.x,
28
28
  top: position.y,
29
29
  };
30
- const renderTabs = () => (React.createElement("div", { className: "ab-Dashboard__tabs" }, children &&
30
+ const renderTabs = () => (React.createElement("div", { className: "ab-Dashboard__tabs twa:whitespace-nowrap" }, children &&
31
31
  React.Children.map(children, (child, index) => (React.createElement("button", { type: "button", className: join('ab-Dashboard__tab', !collapsed && activeTabIndex === index ? 'ab-Dashboard__tab--active' : ''), key: index, onClick: () => {
32
32
  if (activeTabIndex === index) {
33
33
  setCollapsed(!collapsed);
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { BaseModuleTab, ModuleDraggableItem } from './types';
3
3
  export interface ModuleManagerProps {
4
4
  availableItems: ModuleDraggableItem[];
5
+ filterOutSelectedItems?: boolean;
5
6
  className?: string;
6
7
  disabled: boolean;
7
8
  onTabsChange: (tabs: BaseModuleTab[]) => void;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { DragDropContext } from '../dnd';
2
+ import { DragDropProvider } from '../dnd';
3
3
  import { DragAndDropContext } from './DragAndDropContext';
4
4
  import { TabList } from './TabList';
5
5
  import { UnusedPanel } from './UnusedPanel';
@@ -14,7 +14,6 @@ export const ModuleManager = (props) => {
14
14
  editTabName: true,
15
15
  dragAndDropTab: true,
16
16
  deleteTab: true,
17
- // override default permitted actions
18
17
  ...permittedActions,
19
18
  };
20
19
  return {
@@ -22,34 +21,15 @@ export const ModuleManager = (props) => {
22
21
  availableItems: props.availableItems,
23
22
  };
24
23
  }, [props.availableItems, props.permittedActions]);
25
- const unusedItems = React.useMemo(() => availableItems
26
- .map((t) => t.Id)
27
- .filter((item) => {
28
- return !tabs.some((tab) => tab.Items?.includes(item));
29
- }), [tabs, availableItems]);
30
- const handleToolbarDragEnd = (result) => {
31
- const { source, destination, draggableId } = result;
32
- if (!source || !destination) {
33
- return;
24
+ const allowedItems = React.useMemo(() => {
25
+ let result = availableItems.map((t) => t.Id);
26
+ if (props.filterOutSelectedItems) {
27
+ result = result.filter((item) => {
28
+ return !tabs.some((tab) => tab.Items?.includes(item));
29
+ });
34
30
  }
35
- if (source.droppableId !== 'UNUSED') {
36
- const sourceTabToolbars = tabs[Number(source.droppableId)].Items;
37
- sourceTabToolbars.splice(source.index, 1);
38
- }
39
- if (destination.droppableId !== 'UNUSED') {
40
- const destinationTabToolbars = tabs[Number(destination.droppableId)].Items;
41
- destinationTabToolbars.splice(destination.index, 0, draggableId);
42
- }
43
- onTabsChange([...tabs]);
44
- };
45
- const handleTabDragEnd = (result) => {
46
- const { source, destination } = result;
47
- if (!source || !destination)
48
- return;
49
- const [removed] = tabs.splice(source.index, 1);
50
- tabs.splice(destination.index, 0, removed);
51
- onTabsChange([...tabs]);
52
- };
31
+ return result;
32
+ }, [tabs, availableItems]);
53
33
  const handleRemoveTab = (tabIndex) => {
54
34
  onTabsChange(tabs.filter((_, index) => index !== tabIndex));
55
35
  };
@@ -76,17 +56,12 @@ export const ModuleManager = (props) => {
76
56
  };
77
57
  }));
78
58
  };
79
- return (React.createElement(DragDropContext, { onDragEnd: (result) => {
80
- if (result.type === 'TAB')
81
- handleTabDragEnd(result);
82
- if (result.type === 'TOOLBAR')
83
- handleToolbarDragEnd(result);
84
- } },
59
+ return (React.createElement(DragDropProvider, null,
85
60
  React.createElement(DragAndDropContext.Provider, { value: contextValue },
86
61
  React.createElement(Flex, { flexDirection: "column", className: clsx('ab-ModuleSelector twa:flex-1', className) },
87
- React.createElement(UnusedPanel, { title: unusedPanelTitle, disabled: disabled, items: unusedItems, dragItemText: dragItemText }),
62
+ React.createElement(UnusedPanel, { title: unusedPanelTitle, disabled: disabled, items: allowedItems, dragItemText: dragItemText }),
88
63
  React.createElement(Card, { className: "twa:flex-1 twa:m-2 ab-ModuleSelector-UsedPanel" },
89
64
  React.createElement(Card.Title, { border: false }, tabsTitle),
90
65
  React.createElement(Card.Body, { className: "twa:px-2" },
91
- React.createElement(TabList, { disabled: disabled, tabs: tabs, onRemoveTab: handleRemoveTab, onRemoveToolbar: handleRemoveToolbar, onChangeTabName: handleChangeTabName, onNewTab: contextValue.permittedActions.createTab ? handleTabAdd : undefined })))))));
66
+ React.createElement(TabList, { disabled: disabled, tabs: tabs, onTabsChange: onTabsChange, onRemoveTab: handleRemoveTab, onRemoveToolbar: handleRemoveToolbar, onChangeTabName: handleChangeTabName, onNewTab: contextValue.permittedActions.createTab ? handleTabAdd : undefined })))))));
92
67
  };
@@ -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;