@adaptabletools/adaptable 18.0.12 → 18.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 (124) hide show
  1. package/agGrid.d.ts +4 -3
  2. package/agGrid.js +4 -3
  3. package/base.css +7 -2
  4. package/base.css.map +1 -1
  5. package/index.css +11 -2
  6. package/index.css.map +1 -1
  7. package/package.json +2 -2
  8. package/src/AdaptableOptions/ActionColumnOptions.d.ts +1 -1
  9. package/src/AdaptableOptions/ColumnFilterOptions.d.ts +27 -1
  10. package/src/AdaptableOptions/ExportOptions.d.ts +20 -7
  11. package/src/AdaptableOptions/ExpressionOptions.d.ts +12 -2
  12. package/src/AdaptableOptions/Fdc3Options.d.ts +48 -43
  13. package/src/Api/ColumnApi.d.ts +1 -1
  14. package/src/Api/Events/Fdc3MessageInfo.d.ts +5 -7
  15. package/src/Api/ExpressionApi.d.ts +2 -2
  16. package/src/Api/Fdc3Api.d.ts +14 -19
  17. package/src/Api/Implementation/ConfigApiImpl.js +3 -0
  18. package/src/Api/Implementation/Fdc3ApiImpl.d.ts +14 -16
  19. package/src/Api/Implementation/Fdc3ApiImpl.js +36 -12
  20. package/src/Api/Internal/AlertInternalApi.d.ts +17 -2
  21. package/src/Api/Internal/AlertInternalApi.js +196 -25
  22. package/src/Api/Internal/ColumnFilterInternalApi.d.ts +2 -0
  23. package/src/Api/Internal/ColumnFilterInternalApi.js +20 -0
  24. package/src/Api/Internal/ExportInternalApi.d.ts +3 -3
  25. package/src/Api/Internal/ExportInternalApi.js +31 -17
  26. package/src/Api/Internal/ExpressionInternalApi.d.ts +5 -1
  27. package/src/Api/Internal/ExpressionInternalApi.js +79 -0
  28. package/src/Api/Internal/Fdc3InternalApi.d.ts +8 -10
  29. package/src/Api/Internal/Fdc3InternalApi.js +6 -10
  30. package/src/PredefinedConfig/Common/AdaptableField.d.ts +18 -0
  31. package/src/PredefinedConfig/Common/AdaptableField.js +1 -0
  32. package/src/PredefinedConfig/Common/AdaptableIcon.d.ts +1 -1
  33. package/src/PredefinedConfig/Common/AdaptablePredicate.js +18 -1
  34. package/src/PredefinedConfig/Common/Fdc3Context.d.ts +7 -226
  35. package/src/PredefinedConfig/Common/Fdc3Context.js +43 -31
  36. package/src/PredefinedConfig/Common/Fdc3Intent.d.ts +6 -89
  37. package/src/PredefinedConfig/Common/Fdc3Intent.js +26 -73
  38. package/src/PredefinedConfig/Common/RowSummary.d.ts +2 -1
  39. package/src/PredefinedConfig/StyledColumnState.d.ts +1 -1
  40. package/src/Redux/ActionsReducers/FormatColumnRedux.js +0 -3
  41. package/src/Strategy/AdaptableModuleBase.js +1 -3
  42. package/src/Strategy/AlertModule.d.ts +1 -1
  43. package/src/Strategy/AlertModule.js +8 -8
  44. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.d.ts +3 -1
  45. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.js +1 -1
  46. package/src/Utilities/Services/Fdc3Service.d.ts +1 -1
  47. package/src/Utilities/Services/Fdc3Service.js +2 -2
  48. package/src/Utilities/Services/QueryLanguageService.d.ts +8 -4
  49. package/src/Utilities/Services/QueryLanguageService.js +105 -6
  50. package/src/Utilities/Services/ReportService.js +8 -5
  51. package/src/Utilities/Services/RowSummaryService.js +3 -1
  52. package/src/Utilities/divideBy100.d.ts +1 -0
  53. package/src/Utilities/divideBy100.js +30 -0
  54. package/src/Utilities/times100.d.ts +1 -0
  55. package/src/Utilities/times100.js +23 -0
  56. package/src/View/Alert/Wizard/AlertMessageWizardSection.js +1 -1
  57. package/src/View/Alert/Wizard/AlertNotificationWizardSection.js +2 -2
  58. package/src/View/Alert/Wizard/AlertScopeWizardSection.js +2 -1
  59. package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +1 -1
  60. package/src/View/Components/EntityRulesEditor/index.d.ts +1 -0
  61. package/src/View/Components/EntityRulesEditor/index.js +11 -7
  62. package/src/View/Components/ExpressionWizard.js +1 -1
  63. package/src/View/Components/FilterForm/QuickFilterValues.js +28 -4
  64. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +6 -2
  65. package/src/View/Components/Selectors/FieldSelector.d.ts +13 -0
  66. package/src/View/Components/Selectors/FieldSelector.js +21 -0
  67. package/src/View/Components/Selectors/PermittedValuesSelector.js +8 -4
  68. package/src/View/Export/Wizard/ReportRowsWizardSection.js +1 -1
  69. package/src/View/FormatColumn/Wizard/FormatColumnRuleWizardSection.js +1 -1
  70. package/src/View/GridFilter/GridFilterExpressionEditor.js +1 -1
  71. package/src/View/Layout/Wizard/sections/GridFilterSection.js +4 -2
  72. package/src/View/Layout/Wizard/sections/RowSummarySection.js +7 -1
  73. package/src/View/NamedQuery/Wizard/NamedQueryExpressionWizardSection.js +1 -1
  74. package/src/View/Wizard/OnePageAdaptableWizard.js +3 -2
  75. package/src/agGrid/AdaptableAgGrid.d.ts +1 -2
  76. package/src/agGrid/AdaptableAgGrid.js +64 -33
  77. package/src/agGrid/AgGridColumnAdapter.d.ts +3 -0
  78. package/src/agGrid/AgGridColumnAdapter.js +22 -0
  79. package/src/agGrid/AgGridMenuAdapter.js +1 -1
  80. package/src/agGrid/editors/AdaptableDateEditor/InternalAdaptableDateEditor.d.ts +0 -1
  81. package/src/agGrid/editors/AdaptableDateEditor/InternalAdaptableDateEditor.js +0 -2
  82. package/src/agGrid/editors/AdaptableDateEditor/index.d.ts +4 -16
  83. package/src/agGrid/editors/AdaptableDateEditor/index.js +5 -18
  84. package/src/agGrid/editors/AdaptableNumberEditor/InternalAdaptableNumberEditor.js +6 -1
  85. package/src/agGrid/editors/AdaptableNumberEditor/index.d.ts +4 -3
  86. package/src/agGrid/editors/AdaptableNumberEditor/index.js +5 -2
  87. package/src/agGrid/editors/AdaptablePercentageEditor/InternalAdaptablePercentageEditor.d.ts +23 -0
  88. package/src/agGrid/editors/AdaptablePercentageEditor/InternalAdaptablePercentageEditor.js +80 -0
  89. package/src/agGrid/editors/AdaptablePercentageEditor/index.d.ts +47 -0
  90. package/src/agGrid/editors/AdaptablePercentageEditor/index.js +148 -0
  91. package/src/components/Accordion.js +1 -1
  92. package/src/components/Datepicker/DatepickerContext.d.ts +0 -2
  93. package/src/components/Datepicker/index.js +3 -4
  94. package/src/components/ExpressionEditor/DataTableEditor.d.ts +17 -0
  95. package/src/components/ExpressionEditor/DataTableEditor.js +63 -0
  96. package/src/components/ExpressionEditor/EditorInput.js +22 -9
  97. package/src/components/ExpressionEditor/NamedQueryEditor.d.ts +5 -0
  98. package/src/components/ExpressionEditor/NamedQueryEditor.js +30 -0
  99. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +10 -0
  100. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +7 -4
  101. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilderInputs.d.ts +3 -2
  102. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilderInputs.js +71 -13
  103. package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +30 -22
  104. package/src/components/ExpressionEditor/QueryBuilder/utils.d.ts +9 -1
  105. package/src/components/ExpressionEditor/QueryBuilder/utils.js +41 -3
  106. package/src/components/ExpressionEditor/index.d.ts +3 -1
  107. package/src/components/ExpressionEditor/index.js +66 -91
  108. package/src/components/Input/NumberInput.d.ts +2 -1
  109. package/src/components/Input/NumberInput.js +7 -4
  110. package/src/components/OverlayTrigger/index.js +10 -6
  111. package/src/components/icons/column-outline.d.ts +3 -0
  112. package/src/components/icons/column-outline.js +4 -0
  113. package/src/components/icons/index.js +5 -1
  114. package/src/components/icons/sync.d.ts +3 -0
  115. package/src/components/icons/sync.js +4 -0
  116. package/src/env.js +2 -2
  117. package/src/metamodel/adaptable.metamodel.d.ts +78 -200
  118. package/src/metamodel/adaptable.metamodel.js +1 -1
  119. package/src/parser/src/predicate/mapExpressionToQlPredicate.d.ts +1 -0
  120. package/src/parser/src/predicate/mapExpressionToQlPredicate.js +11 -2
  121. package/src/parser/src/predicate/mapQlPredicateToExpression.js +4 -1
  122. package/src/parser/src/types.d.ts +101 -1
  123. package/src/types.d.ts +9 -7
  124. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -0,0 +1,47 @@
1
+ import * as React from 'react';
2
+ import { ICellEditorComp } from '@ag-grid-community/core';
3
+ import { AdaptableNumberCellEditorParams } from '../AdaptableNumberEditor';
4
+ /**
5
+ * Adaptable percentage editor parameters extending the number editor params.
6
+ */
7
+ export interface AdaptablePercentageCellEditorParams extends AdaptableNumberCellEditorParams {
8
+ }
9
+ export declare const AdaptableReactPercentageEditor: React.ForwardRefExoticComponent<AdaptablePercentageCellEditorParams & React.RefAttributes<unknown>>;
10
+ /**
11
+ * Used by default for all `abColDefNumber` columns.
12
+ *
13
+ * You can configure it by specifying `cellEditorParams` in the colDef:
14
+ *
15
+ * colDef {
16
+ * field: 'stars',
17
+ * type: 'abColDefNumber',
18
+ * cellEditorParams: {
19
+ * emptyValue: 5, // defaults to ''
20
+ * showClearButton: false
21
+ * }
22
+ * }
23
+ *
24
+ * For now, there are 2 editor params you can configure:
25
+ *
26
+ * cellEditorParams.showClearButton - defaults to `true` - whether to show the clear button. If `true`, it works together with `cellEditorParams.emptyValue`
27
+ * cellEditorParams.emptyValue - defaults to `''` (empty string) - value to set for the cell, when the clear button is pressed.
28
+ *
29
+ * When the colDef has a `valueParser` provided as a function, it will be used before setting the value for the cell.
30
+ */
31
+ export declare class AdaptablePercentageEditor implements ICellEditorComp {
32
+ private value;
33
+ private columnId;
34
+ private el;
35
+ private params;
36
+ private editor;
37
+ private valueParser;
38
+ private unmountReactRoot?;
39
+ init(params: AdaptablePercentageCellEditorParams): void;
40
+ getGui(): HTMLDivElement;
41
+ getValue(): any;
42
+ focusIn(): void;
43
+ focusOut(): void;
44
+ afterGuiAttached(): void;
45
+ destroy(): void;
46
+ private onValueChange;
47
+ }
@@ -0,0 +1,148 @@
1
+ import * as React from 'react';
2
+ import { renderWithAdaptableContext } from '../../../View/renderWithAdaptableContext';
3
+ import { InternalAdaptablePercentageEditor, } from './InternalAdaptablePercentageEditor';
4
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
5
+ import { getStartValue } from '../AdaptableNumberEditor';
6
+ import { times100 } from '../../../Utilities/times100';
7
+ import { divideBy100 } from '../../../Utilities/divideBy100';
8
+ const defaultValueParser = ({ newValue, oldValue: _ }) => {
9
+ return newValue;
10
+ };
11
+ const style = {
12
+ position: 'absolute',
13
+ top: '0px',
14
+ left: '0px',
15
+ right: '0px',
16
+ bottom: '0px',
17
+ };
18
+ export const AdaptableReactPercentageEditor = forwardRef((props, ref) => {
19
+ var _a, _b;
20
+ const [initialValue] = useState(() => times100(getStartValue(props)));
21
+ const valueRef = useRef(initialValue);
22
+ const columnId = props.column.getColId();
23
+ const adaptable = props.context.__adaptable;
24
+ const colValueParser = props.column.getColDef().valueParser;
25
+ const valueParser = typeof colValueParser === 'function' ? colValueParser : defaultValueParser;
26
+ function onValueChange(value) {
27
+ var _a;
28
+ const newValue = valueParser
29
+ ? valueParser(Object.assign(Object.assign({}, props), { oldValue: props.value, newValue: value }))
30
+ : value;
31
+ valueRef.current = newValue;
32
+ (_a = props.onValueChange) === null || _a === void 0 ? void 0 : _a.call(props, divideBy100(newValue));
33
+ }
34
+ const editorRef = useRef(null);
35
+ useImperativeHandle(ref, () => {
36
+ return {
37
+ focusIn() {
38
+ var _a;
39
+ (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.focus();
40
+ },
41
+ // the final value to send to the grid, on completion of editing
42
+ getValue() {
43
+ return divideBy100(valueRef.current);
44
+ },
45
+ };
46
+ });
47
+ const editorElement = (React.createElement(InternalAdaptablePercentageEditor, { defaultValue: initialValue, showClearButton: (_a = props.showClearButton) !== null && _a !== void 0 ? _a : true, emptyValue: (_b = props.emptyValue) !== null && _b !== void 0 ? _b : '', onValueChange: onValueChange, ref: (editor) => {
48
+ editorRef.current = editor;
49
+ editor === null || editor === void 0 ? void 0 : editor.focus();
50
+ } }));
51
+ function onKeyDown(keyDownEvent) {
52
+ adaptable._emit('CellEditorKeyDown', {
53
+ keyDownEvent,
54
+ cellValue: valueRef.current,
55
+ columnId,
56
+ updateValueCallback: (updatedValue) => {
57
+ editorRef.current.setValue(updatedValue);
58
+ },
59
+ });
60
+ }
61
+ return (React.createElement("div", { style: style, onKeyDown: onKeyDown }, renderWithAdaptableContext(editorElement, adaptable)));
62
+ });
63
+ AdaptableReactPercentageEditor.displayName = 'AdaptableReactPercentageEditor';
64
+ /**
65
+ * Used by default for all `abColDefNumber` columns.
66
+ *
67
+ * You can configure it by specifying `cellEditorParams` in the colDef:
68
+ *
69
+ * colDef {
70
+ * field: 'stars',
71
+ * type: 'abColDefNumber',
72
+ * cellEditorParams: {
73
+ * emptyValue: 5, // defaults to ''
74
+ * showClearButton: false
75
+ * }
76
+ * }
77
+ *
78
+ * For now, there are 2 editor params you can configure:
79
+ *
80
+ * cellEditorParams.showClearButton - defaults to `true` - whether to show the clear button. If `true`, it works together with `cellEditorParams.emptyValue`
81
+ * cellEditorParams.emptyValue - defaults to `''` (empty string) - value to set for the cell, when the clear button is pressed.
82
+ *
83
+ * When the colDef has a `valueParser` provided as a function, it will be used before setting the value for the cell.
84
+ */
85
+ export class AdaptablePercentageEditor {
86
+ constructor() {
87
+ this.valueParser = defaultValueParser;
88
+ this.onValueChange = (value) => {
89
+ const newValue = this.valueParser
90
+ ? this.valueParser(Object.assign(Object.assign({}, this.params), { oldValue: this.params.value, newValue: value }))
91
+ : value;
92
+ this.value = divideBy100(newValue);
93
+ };
94
+ }
95
+ init(params) {
96
+ this.value = getStartValue(params);
97
+ this.params = params;
98
+ this.columnId = params.column.getColId();
99
+ const { valueParser } = params.column.getColDef();
100
+ if (typeof valueParser === 'function') {
101
+ this.valueParser = valueParser;
102
+ }
103
+ this.el = document.createElement('div');
104
+ Object.keys(style).forEach((key) => {
105
+ //@ts-ignore
106
+ this.el.style[key] = style[key];
107
+ });
108
+ }
109
+ /* Component Editor Lifecycle methods */
110
+ // gets called once when grid ready to insert the element
111
+ getGui() {
112
+ return this.el;
113
+ }
114
+ // the final value to send to the grid, on completion of editing
115
+ getValue() {
116
+ return this.value;
117
+ }
118
+ focusIn() {
119
+ var _a;
120
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.focus();
121
+ }
122
+ focusOut() { }
123
+ // after this component has been created and inserted into the grid
124
+ afterGuiAttached() {
125
+ var _a, _b;
126
+ const adaptable = this.params.context.__adaptable;
127
+ const defaultValue = times100(this.value);
128
+ const editorElement = (React.createElement(InternalAdaptablePercentageEditor, { defaultValue: defaultValue, showClearButton: (_a = this.params.showClearButton) !== null && _a !== void 0 ? _a : true, emptyValue: (_b = this.params.emptyValue) !== null && _b !== void 0 ? _b : '', onValueChange: this.onValueChange, ref: (editor) => {
129
+ this.editor = editor;
130
+ editor === null || editor === void 0 ? void 0 : editor.focus();
131
+ } }));
132
+ this.unmountReactRoot = adaptable.renderReactRoot(renderWithAdaptableContext(editorElement, adaptable), this.el);
133
+ this.getGui().addEventListener('keydown', (keyDownEvent) => {
134
+ adaptable._emit('CellEditorKeyDown', {
135
+ keyDownEvent,
136
+ cellValue: this.value,
137
+ columnId: this.columnId,
138
+ updateValueCallback: (updatedValue) => {
139
+ this.editor.setValue(updatedValue);
140
+ },
141
+ });
142
+ });
143
+ }
144
+ destroy() {
145
+ var _a;
146
+ (_a = this.unmountReactRoot) === null || _a === void 0 ? void 0 : _a.call(this);
147
+ }
148
+ }
@@ -26,7 +26,7 @@ export const Accordion = ({ title, children }) => {
26
26
  setIsOpen(!isOpen);
27
27
  };
28
28
  return (React.createElement(Panel, { className: "ab-Accordion" },
29
- React.createElement(SimpleButton, { iconPosition: 'end', icon: isOpen ? 'expand-all' : 'collapse-all', variant: "text", onClick: toggleAccordion, style: { width: '100%', textAlign: 'left' } }, title),
29
+ React.createElement(SimpleButton, { iconPosition: "end", icon: isOpen ? 'expand-all' : 'collapse-all', variant: "text", onClick: toggleAccordion, style: { width: '100%', textAlign: 'left' } }, title),
30
30
  React.createElement("div", { ref: content, style: {
31
31
  maxHeight: `${height}`,
32
32
  overflow: 'hidden',
@@ -2,10 +2,8 @@ import * as React from 'react';
2
2
  export declare const DatepickerContext: React.Context<{
3
3
  onHide?: (keyboardEventKey?: string) => void;
4
4
  onShow?: VoidFunction;
5
- showClearButton?: boolean;
6
5
  }>;
7
6
  export declare const useDatepickerContext: () => {
8
7
  onHide?: (keyboardEventKey?: string) => void;
9
8
  onShow?: VoidFunction;
10
- showClearButton?: boolean;
11
9
  };
@@ -34,9 +34,8 @@ const DatepickerOverlay = ({ onHide, children, onKeyDown, onMouseDown, }) => {
34
34
  };
35
35
  export const Datepicker = React.forwardRef((props, ref) => {
36
36
  var _a;
37
- const { dateProps, required, disabled, style, placeholder, showWeekNumber, showOutsideDays, value: _, defaultValue: __, onChange: ___, showClearButton: showClearButtonFromProps, datepickerButtons } = props, boxProps = __rest(props, ["dateProps", "required", "disabled", "style", "placeholder", "showWeekNumber", "showOutsideDays", "value", "defaultValue", "onChange", "showClearButton", "datepickerButtons"]);
37
+ const { dateProps, required, disabled, style, placeholder, showWeekNumber, showOutsideDays, value: _, defaultValue: __, onChange: ___, datepickerButtons } = props, boxProps = __rest(props, ["dateProps", "required", "disabled", "style", "placeholder", "showWeekNumber", "showOutsideDays", "value", "defaultValue", "onChange", "datepickerButtons"]);
38
38
  const datepickerContext = useDatepickerContext();
39
- const showClearButton = (showClearButtonFromProps !== null && showClearButtonFromProps !== void 0 ? showClearButtonFromProps : datepickerContext.showClearButton) === false ? false : true;
40
39
  let [value, setValue] = useProperty(props, 'value', undefined, {
41
40
  onChange: props.onChange,
42
41
  });
@@ -79,10 +78,10 @@ export const Datepicker = React.forwardRef((props, ref) => {
79
78
  '|': React.createElement("hr", { style: { width: '100%', height: 0, margin: 0, border: 'none' } }),
80
79
  };
81
80
  const footerButtons = datepickerButtons.map((buttonKey, index) => React.cloneElement(footerButtonsMap[buttonKey], { key: index }));
82
- const clearButton = showClearButton ? (React.createElement(SimpleButton, { "data-name": "clear", variant: "text", tooltip: "Clear", iconSize: 20, padding: 0, icon: "close", onMouseDown: (e) => {
81
+ const clearButton = (React.createElement(SimpleButton, { "data-name": "clear", variant: "text", tooltip: "Clear", iconSize: 20, padding: 0, icon: "close", onMouseDown: (e) => {
83
82
  e.preventDefault();
84
83
  clearValue();
85
- }, accessLevel: 'Full' })) : null;
84
+ }, accessLevel: 'Full' }));
86
85
  const calendarButton = (React.createElement(SimpleButton, { disabled: disabled, variant: "text", icon: "calendar", tooltip: "Date", iconSize: 20, px: 0, py: 0, onClick: () => setVisible(true) }));
87
86
  return (React.createElement(Flex, null,
88
87
  React.createElement(OverlayTrigger, { visible: visible, render: () => (React.createElement(DatepickerOverlay, { onMouseDown: props.onMouseDown, onHide: () => setVisible(false), onKeyDown: (e) => {
@@ -0,0 +1,17 @@
1
+ /// <reference types="react" />
2
+ import { AdaptableColumnDataType } from '../../types';
3
+ export declare const DataTableEditor: ({ fields, dataFormatter, data: initialData, type, labels, }: {
4
+ fields: {
5
+ label: string;
6
+ value: string;
7
+ dataType: AdaptableColumnDataType;
8
+ readOnly?: boolean;
9
+ }[];
10
+ type: string;
11
+ dataFormatter: (field: string) => string;
12
+ data: any;
13
+ labels?: {
14
+ showIds?: string;
15
+ filterPlaceholder?: string;
16
+ };
17
+ }) => JSX.Element;
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ import { Flex } from 'rebass';
3
+ import { baseClassName } from '.';
4
+ import { CheckBox } from '../CheckBox';
5
+ import { AdaptableFormControlTextClear } from '../../View/Components/Forms/AdaptableFormControlTextClear';
6
+ import FormLayout, { FormRow } from '../FormLayout';
7
+ import EditorButton from './EditorButton';
8
+ import Input from '../Input';
9
+ import { isValueValidDate } from '../../Utilities/Helpers/DateHelper';
10
+ import { useAdaptable } from '../../View/AdaptableContext';
11
+ import AdaptableInput from '../../View/Components/AdaptableInput';
12
+ export const DataTableEditor = ({ fields, dataFormatter, data: initialData, type = 'column', labels, }) => {
13
+ var _a, _b;
14
+ const adaptable = useAdaptable();
15
+ const [data, setData] = React.useState(initialData);
16
+ const [showColumnIds, setShowValues] = React.useState(false);
17
+ const [searchInputValue, setSearchInputValue] = React.useState('');
18
+ const getColValue = (fieldValue) => {
19
+ return adaptable.api.internalApi.getValueUsingField(data, fieldValue);
20
+ };
21
+ const updateColValue = (rowData, fielValue, newValue) => {
22
+ const updatedRowData = adaptable.api.internalApi.setValueUsingField(rowData, fielValue, newValue);
23
+ return Object.assign({}, updatedRowData);
24
+ };
25
+ const getColDateValue = (fieldValue) => {
26
+ const colValue = getColValue(fieldValue);
27
+ return colValue && isValueValidDate(colValue)
28
+ ? new Date(colValue).toISOString().substr(0, 10)
29
+ : '';
30
+ };
31
+ const hasFriendlyNames = React.useMemo(() => {
32
+ return fields.some((field) => field.label !== field.value);
33
+ }, []);
34
+ return (React.createElement(Flex, { flexDirection: "column", "data-name": `expression-${type}-picker`, style: { height: '100%' } },
35
+ React.createElement(Flex, { className: `${baseClassName}__${type}-list`, flexDirection: "column", alignItems: "start", style: { marginTop: 2 }, mb: 2 },
36
+ hasFriendlyNames && (React.createElement(CheckBox, { checked: showColumnIds, onChange: (checked) => setShowValues(checked), style: {
37
+ float: 'right',
38
+ margin: 0,
39
+ paddingTop: 'var(--ab-space-1)',
40
+ paddingBottom: 'var(--ab-space-1)',
41
+ } }, (_a = labels === null || labels === void 0 ? void 0 : labels.showIds) !== null && _a !== void 0 ? _a : 'Show Column IDs')),
42
+ React.createElement(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: (_b = labels === null || labels === void 0 ? void 0 : labels.filterPlaceholder) !== null && _b !== void 0 ? _b : 'Filter columns...', style: { flex: 1, marginBottom: 3 } })),
43
+ React.createElement(FormLayout, { className: "ab-ExpressionEditor__columns", gridColumnGap: "var(--ab-space-1)", gridRowGap: "var(--ab-space-1)", sizes: ['auto', '1fr'], style: { alignItems: 'stretch', overflow: 'auto' } }, fields
44
+ .filter((field) => {
45
+ var _a, _b;
46
+ if (!searchInputValue) {
47
+ return true;
48
+ }
49
+ return (field.label.includes(searchInputValue) || ((_b = (_a = field.value) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, searchInputValue)));
50
+ })
51
+ .map((field) => {
52
+ var _a, _b, _c;
53
+ const label = showColumnIds ? `[${field.value}]` : field.label;
54
+ return (React.createElement(FormRow, { key: field.label, label: React.createElement(EditorButton, { width: "100%", height: "100%", style: {
55
+ background: 'var(--ab-color-primary)',
56
+ cursor: 'grab',
57
+ marginRight: 'var(--ab-space-1)',
58
+ }, data: dataFormatter(field.value), "data-name": type, "data-value": field.value, icon: "drag" },
59
+ React.createElement(Flex, { flexDirection: "column", alignItems: "start" }, label)) }, field.dataType === 'Number' ? (React.createElement(Input, { type: "number", "data-name": `${type}-input`, "data-value": field.value, value: (_a = getColValue(field.value)) !== null && _a !== void 0 ? _a : '', onChange: (e) => setData(updateColValue(data, field.value, Number(e.target.value))), width: "100%", disabled: field.readOnly })) : field.dataType === 'String' ? (React.createElement(Input, { type: "text", "data-name": `${type}-input`, "data-value": field.value, value: (_b = getColValue(field.value)) !== null && _b !== void 0 ? _b : '', onChange: (e) => setData(updateColValue(data, field.value, e.target.value)), width: "100%", disabled: field.readOnly })) : field.dataType === 'Date' ? (React.createElement(AdaptableInput, { type: "date", "data-name": `${type}-input`, "data-value": field.value, value: (_c = getColDateValue(field.value)) !== null && _c !== void 0 ? _c : '', onChange: (e) => {
60
+ setData(updateColValue(data, field.value, new Date(e.target.value)));
61
+ }, style: { width: '100%' }, disabled: field.readOnly })) : field.dataType === 'Boolean' ? (React.createElement(CheckBox, { "data-name": `${type}-input`, "data-value": field.value, checked: Boolean(getColValue(field.value)), onChange: (checked) => setData(updateColValue(data, field.value, checked)), disabled: field.readOnly })) : null));
62
+ }))));
63
+ };
@@ -5,7 +5,7 @@ import { editorButtonsSearch } from './editorButtonsSearch';
5
5
  import { useExpressionEditor } from './EditorContext';
6
6
  import StringExtensions from '../../Utilities/Extensions/StringExtensions';
7
7
  import { editorButtonsAggregatedScalar } from './editorButtonsAggregatedScalar';
8
- import { aggregatedExpressionFunctions, cumulativeAggregatedExpressionFunctions, quantileAggregatedExpressionFunctions, } from '../../Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions';
8
+ import { cumulativeAggregatedExpressionFunctions, quantileAggregatedExpressionFunctions, } from '../../Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions';
9
9
  import { editorButtonsCumulativeAggregatedScalar } from './editorButtonsCumulativeAggregatedScalar';
10
10
  import { editorButtonsQuantileAggregatedScalar } from './editorButtonsQuantileAggregatedScalar';
11
11
  function EditorInput(props) {
@@ -13,14 +13,27 @@ function EditorInput(props) {
13
13
  .getQueryLanguageService()
14
14
  .getModuleExpressionFunctionsMap(props.module);
15
15
  const getFilteredAggregatedExpressionFunctions = (availableAggregatedExpressionFunctions, type) => {
16
- const sourceExpressionFunctions = type === 'cumulativeAggregatedScalar'
17
- ? cumulativeAggregatedExpressionFunctions
18
- : type === 'quantileAggregatedScalar'
19
- ? quantileAggregatedExpressionFunctions
20
- : aggregatedExpressionFunctions;
21
- return Object.keys(availableAggregatedExpressionFunctions)
22
- .filter((key) => sourceExpressionFunctions.includes(key))
23
- .reduce((obj, key) => {
16
+ let filteredCollection = [];
17
+ if (type === 'aggregatedScalar') {
18
+ const excludeSet = new Set([
19
+ // we cannot have a hardcodede set of functions,
20
+ // we need to allow custom expresions
21
+ ...cumulativeAggregatedExpressionFunctions,
22
+ ...quantileAggregatedExpressionFunctions,
23
+ ]);
24
+ filteredCollection = Object.keys(availableAggregatedExpressionFunctions).filter((key) =>
25
+ // need to allow standard ones
26
+ cumulativeAggregatedExpressionFunctions.includes(key) ||
27
+ // and anything else that is not cumul or quantile
28
+ !excludeSet.has(key));
29
+ }
30
+ else {
31
+ const includeExpressionFunctions = type === 'cumulativeAggregatedScalar'
32
+ ? cumulativeAggregatedExpressionFunctions
33
+ : quantileAggregatedExpressionFunctions;
34
+ filteredCollection = Object.keys(availableAggregatedExpressionFunctions).filter((key) => includeExpressionFunctions.includes(key));
35
+ }
36
+ return filteredCollection.reduce((obj, key) => {
24
37
  obj[key] = availableAggregatedExpressionFunctions[key];
25
38
  return obj;
26
39
  }, {});
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import { NamedQuery } from '../../types';
3
+ export declare const NamedQueryEditor: (props: {
4
+ namedQueries: NamedQuery[];
5
+ }) => JSX.Element;
@@ -0,0 +1,30 @@
1
+ import * as React from 'react';
2
+ import { Flex } from 'rebass';
3
+ import { useAdaptable } from '../../View/AdaptableContext';
4
+ import { CheckBox } from '../CheckBox';
5
+ import EditorButton from './EditorButton';
6
+ export const NamedQueryEditor = (props) => {
7
+ const adaptable = useAdaptable();
8
+ const [showColumnIds, setShowColumnIds] = React.useState(false);
9
+ const [inlineQuery, setInlineQuery] = React.useState(false);
10
+ return (React.createElement(Flex, { flexDirection: "column", alignItems: "start", style: { marginTop: 2 } },
11
+ React.createElement(CheckBox, { checked: showColumnIds, onChange: (checked) => setShowColumnIds(checked) }, "Show Column IDs"),
12
+ React.createElement(CheckBox, { checked: inlineQuery, onChange: (checked) => setInlineQuery(checked) }, "Inline Query"),
13
+ props.namedQueries.map((namedQuery) => (React.createElement(Flex, { key: namedQuery.Uuid, flexDirection: "column", alignItems: "start", style: {
14
+ padding: 3,
15
+ marginTop: 'var(--ab-space-2)',
16
+ marginBottom: 'var(--ab-space-2)',
17
+ width: '100%',
18
+ }, backgroundColor: "primarylight" },
19
+ ' ',
20
+ React.createElement(EditorButton, { width: "100%", height: "100%", style: {
21
+ background: 'var(--ab-color-primary)',
22
+ cursor: 'grab',
23
+ }, data: inlineQuery ? namedQuery.BooleanExpression : `QUERY("${namedQuery.Name}")`, "data-name": "column", icon: "drag" },
24
+ React.createElement(Flex, { flexDirection: "column", alignItems: "start" }, namedQuery.Name)),
25
+ React.createElement(Flex, { alignItems: "start", style: {
26
+ padding: 5,
27
+ } }, showColumnIds
28
+ ? namedQuery.BooleanExpression
29
+ : adaptable.api.expressionApi.getAdaptableQueryExpressionWithColumnFriendlyNames(namedQuery)))))));
30
+ };
@@ -7,10 +7,20 @@ interface QueryBuilderProps {
7
7
  value: string;
8
8
  type: AdaptableColumnDataType;
9
9
  }[];
10
+ getFields: (type?: AdaptableColumnDataType) => {
11
+ label?: string;
12
+ value: string;
13
+ type: AdaptableColumnDataType;
14
+ }[];
10
15
  onChange: (query: string) => void;
11
16
  module: AdaptableModule;
12
17
  }
13
18
  export declare function useQueryBuilderContext(): {
19
+ getColumns: (type?: AdaptableColumnDataType) => {
20
+ label?: string;
21
+ value: string;
22
+ type: AdaptableColumnDataType;
23
+ }[];
14
24
  getFields: (type?: AdaptableColumnDataType) => {
15
25
  label?: string;
16
26
  value: string;
@@ -54,7 +54,8 @@ export const QueryBuilder = (props) => {
54
54
  }, []);
55
55
  const context = React.useMemo(() => {
56
56
  return {
57
- getFields: props.getColumns,
57
+ getColumns: props.getColumns,
58
+ getFields: props.getFields,
58
59
  getExpressions: (columnType) => {
59
60
  return booleanExpressions
60
61
  ? getFunctionsForColumnType(columnType, Object.keys(booleanExpressions))
@@ -66,10 +67,12 @@ export const QueryBuilder = (props) => {
66
67
  const clearExpressionButton = (React.createElement(SimpleButton, { onClick: () => {
67
68
  clearExpression();
68
69
  } }, "Clear Expression"));
69
- const unsupportedExpressionFunction = getUnsuportedExpressionFromQlPredicate(qlPredicate);
70
+ const unsupportedExpressionFunction = getUnsuportedExpressionFromQlPredicate(qlPredicate, {
71
+ supportedFields: props.getFields(),
72
+ });
70
73
  let errorOrEditor = null;
71
74
  if (qlPredicate && 'errorMessage' in qlPredicate) {
72
- errorOrEditor = ((_b = (_a = props.query) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, 'QUERY')) ? (React.createElement(WarningBox, null,
75
+ errorOrEditor = ((_b = (_a = props.query) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, 'QUERY')) ? (React.createElement(WarningBox, { "data-name": "unsupported-query-warning" },
73
76
  React.createElement(Flex, { alignItems: "center" },
74
77
  "Named Queries are not supported in the Query Builder",
75
78
  React.createElement(Box, { flex: 1 }),
@@ -80,7 +83,7 @@ export const QueryBuilder = (props) => {
80
83
  clearExpressionButton)));
81
84
  }
82
85
  else if (unsupportedExpressionFunction) {
83
- errorOrEditor = React.createElement(WarningBox, null, unsupportedExpressionFunction);
86
+ errorOrEditor = (React.createElement(WarningBox, { "data-name": "unsupported-expression-warning" }, unsupportedExpressionFunction));
84
87
  }
85
88
  else if (qlPredicate && !('errorMessage' in qlPredicate)) {
86
89
  errorOrEditor = (React.createElement(QueryPredicateBuilder, { isRoot: true, index: 0, id: "0", predicate: qlPredicate, onNewPredicate: (type) => {
@@ -2,10 +2,11 @@
2
2
  import { QlLogicalOperator } from '../../../parser/src/predicate';
3
3
  import { ExpressionFunctionInputType } from '../../../parser/src/types';
4
4
  import { AdaptableColumn, AdaptableColumnDataType, BooleanFunctionName } from '../../../types';
5
- export declare const PrimitiveColumnSelector: (props: {
6
- columnId: string;
5
+ export declare const PrimitiveColumnOrFieldSelector: (props: {
6
+ fieldOrColumn: string;
7
7
  type?: AdaptableColumnDataType;
8
8
  onChange: (colId: string) => void;
9
+ hideFields?: boolean;
9
10
  }) => JSX.Element;
10
11
  export declare const PrimiteValueInput: (props: {
11
12
  inputType: ExpressionFunctionInputType;
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Box, Flex, Text } from 'rebass';
3
3
  import { getQlPredicateSymbol } from '../../../parser/src/predicate/mapQlPredicateToExpression';
4
+ import { useAdaptable } from '../../../View/AdaptableContext';
4
5
  import AdaptableInput from '../../../View/Components/AdaptableInput';
5
6
  import { ColumnSelector } from '../../../View/Components/Selectors/ColumnSelector';
7
+ import { FieldSelector } from '../../../View/Components/Selectors/FieldSelector';
6
8
  import { PermittedValuesSelector } from '../../../View/Components/Selectors/PermittedValuesSelector';
7
9
  import { CheckBox } from '../../CheckBox';
8
10
  import DropdownButton from '../../DropdownButton';
@@ -10,20 +12,61 @@ import { Icon } from '../../icons';
10
12
  import { InputGroup } from '../../InputGroup';
11
13
  import { Select } from '../../Select';
12
14
  import { useQueryBuilderContext } from './QueryBuilder';
13
- import { mapExpressionFunctionTypeToColumnDataType } from './utils';
14
- export const PrimitiveColumnSelector = (props) => {
15
- return (React.createElement(Box, null,
16
- React.createElement(ColumnSelector, { value: props.columnId, type: props.type, onChange: (columnId) => {
15
+ import { isFieldValue, mapColumnExpressionToColumnId, mapExpressionFunctionTypeToColumnDataType, mapExpressionToFieldValue, mapFieldValueToExpression, } from './utils';
16
+ export const PrimitiveColumnOrFieldSelector = (props) => {
17
+ const adaptable = useAdaptable();
18
+ const [type, setType] = React.useState(() => {
19
+ return (
20
+ // default to column
21
+ (!props.fieldOrColumn || props.fieldOrColumn.includes('[') ? 'column' : 'field')
22
+ );
23
+ });
24
+ const hasFields = React.useMemo(() => {
25
+ var _a;
26
+ return ((_a = adaptable.api.expressionApi.internalApi.getAvailableFields()) === null || _a === void 0 ? void 0 : _a.length) > 0;
27
+ }, []);
28
+ const hasFieldsOrValueIsField = hasFields || isFieldValue(props.fieldOrColumn);
29
+ let input = null;
30
+ if (type === 'column') {
31
+ const columnId = mapColumnExpressionToColumnId(props.fieldOrColumn);
32
+ input = (React.createElement(ColumnSelector, { value: columnId, type: props.type, onChange: (columnId) => {
17
33
  props.onChange(`[${columnId}]`);
18
- } })));
34
+ } }));
35
+ }
36
+ else {
37
+ input = (React.createElement(FieldSelector, { value: mapExpressionToFieldValue(props.fieldOrColumn), type: props.type, onChange: (fieldValue) => {
38
+ props.onChange(mapFieldValueToExpression(fieldValue));
39
+ } }));
40
+ }
41
+ const typeOptions = [
42
+ { label: 'Column', value: 'column', icon: 'grid' },
43
+ { label: 'Field', value: 'field', icon: 'column-outline' },
44
+ ];
45
+ return !hasFieldsOrValueIsField || props.hideFields ? (React.createElement(Box, null, input)) : (React.createElement(InputGroup, { Component: Flex, "data-id": "query-first-arg-wrapper" },
46
+ React.createElement(Select, { renderSingleValue: (value) => {
47
+ return React.createElement(React.Fragment, null, type === 'column' ? React.createElement(Icon, { name: "grid" }) : React.createElement(Icon, { name: "column-outline" }));
48
+ }, value: type, options: typeOptions, onChange: (value) => {
49
+ props.onChange(null);
50
+ setType(value);
51
+ } }),
52
+ input));
19
53
  };
20
54
  export const PrimiteValueInput = (props) => {
21
- var _a, _b;
22
- const [type, setType] = React.useState(() => {
55
+ const adaptable = useAdaptable();
56
+ const hasFields = React.useMemo(() => {
23
57
  var _a;
24
- return typeof (props === null || props === void 0 ? void 0 : props.value) === 'string' && ((_a = props === null || props === void 0 ? void 0 : props.value) === null || _a === void 0 ? void 0 : _a.includes('['))
25
- ? 'column-name'
26
- : 'input-value';
58
+ return ((_a = adaptable.api.expressionApi.internalApi.getAvailableFields()) === null || _a === void 0 ? void 0 : _a.length) > 0;
59
+ }, []);
60
+ const hasFieldsOrValueIsField = hasFields || isFieldValue(props.value);
61
+ const [type, setType] = React.useState(() => {
62
+ var _a, _b;
63
+ if (typeof (props === null || props === void 0 ? void 0 : props.value) === 'string' && ((_a = props === null || props === void 0 ? void 0 : props.value) === null || _a === void 0 ? void 0 : _a.includes('['))) {
64
+ return 'column-name';
65
+ }
66
+ if (typeof (props === null || props === void 0 ? void 0 : props.value) === 'string' && ((_b = props === null || props === void 0 ? void 0 : props.value) === null || _b === void 0 ? void 0 : _b.includes('FIELD'))) {
67
+ return 'field';
68
+ }
69
+ return 'input-value';
27
70
  });
28
71
  const handleTypeChange = (newType) => {
29
72
  if (type !== newType) {
@@ -67,12 +110,18 @@ export const PrimiteValueInput = (props) => {
67
110
  };
68
111
  let editor = null;
69
112
  if (type === 'column-name') {
70
- const columnId = props.value ? (_b = (_a = props === null || props === void 0 ? void 0 : props.value) === null || _a === void 0 ? void 0 : _a.replace) === null || _b === void 0 ? void 0 : _b.call(_a, '[', '').replace(']', '') : undefined;
71
113
  const abColType = mapExpressionFunctionTypeToColumnDataType(props.inputType);
72
- editor = (React.createElement(PrimitiveColumnSelector, { columnId: columnId, onChange: (col) => props.onChange(col), type: abColType }));
114
+ editor = (React.createElement(PrimitiveColumnOrFieldSelector, { hideFields: true, fieldOrColumn: props.value, type: abColType, onChange: (columnId) => {
115
+ props.onChange(columnId);
116
+ } }));
117
+ }
118
+ else if (type === 'field') {
119
+ editor = (React.createElement(FieldSelector, { value: mapExpressionToFieldValue(props.value), onChange: (fieldValue) => {
120
+ props.onChange(mapFieldValueToExpression(fieldValue));
121
+ } }));
73
122
  }
74
123
  else if (!['date', 'boolean'].includes(props.inputType)) {
75
- editor = (React.createElement(PermittedValuesSelector, { allowNewValues: true, value: props.value, columnId: props.lefthandColumnIdParam, onChange: (value) => {
124
+ editor = (React.createElement(PermittedValuesSelector, { allowNewValues: true, value: props.value, columnId: mapColumnExpressionToColumnId(props.lefthandColumnIdParam), onChange: (value) => {
76
125
  props.onChange(value);
77
126
  } }));
78
127
  }
@@ -95,6 +144,15 @@ export const PrimiteValueInput = (props) => {
95
144
  value: 'input-value',
96
145
  },
97
146
  ];
147
+ if (hasFieldsOrValueIsField || type === 'field') {
148
+ options.push({
149
+ label: (React.createElement(Flex, null,
150
+ React.createElement(Icon, { name: "column-outline" }),
151
+ React.createElement(Text, { ml: 2 }, "Field"))),
152
+ icon: 'column-outline',
153
+ value: 'field',
154
+ });
155
+ }
98
156
  const typeOption = options.find((option) => option.value === type);
99
157
  return (React.createElement(InputGroup, { Component: Flex, "data-id": "query-input-wrapper", mr: 2 },
100
158
  React.createElement(Select, { renderSingleValue: (value) => {