@evoke-platform/ui-components 1.0.0-dev.161 → 1.0.0-dev.163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +6 -18
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +44 -177
- package/dist/published/components/custom/CriteriaBuilder/ValueEditor.d.ts +8 -0
- package/dist/published/components/custom/CriteriaBuilder/ValueEditor.js +125 -0
- package/dist/published/components/custom/CriteriaBuilder/types.d.ts +25 -0
- package/dist/published/components/custom/CriteriaBuilder/types.js +1 -0
- package/dist/published/stories/CriteriaBuilder.stories.d.ts +4 -64
- package/package.json +1 -1
- package/types.ts +1 -1
@@ -1,25 +1,13 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { ValueEditorProps } from 'react-querybuilder';
|
3
2
|
import 'react-querybuilder/dist/query-builder.css';
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
declare type
|
7
|
-
values?: AutocompleteOption[] | any[];
|
8
|
-
};
|
9
|
-
declare type Operator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'contains' | 'beginsWith' | 'endsWith' | 'doesNotContain' | 'doesNotBeginWith' | 'doesNotEndWith' | 'null' | 'notNull' | 'in' | 'notIn' | 'between' | 'notBetween';
|
10
|
-
declare type CriteriaInputProps = {
|
3
|
+
import { Operator, ObjectProperty, PresetValue } from './types';
|
4
|
+
import { ValueEditorProps } from './ValueEditor';
|
5
|
+
export declare type CriteriaInputProps = {
|
11
6
|
properties: ObjectProperty[];
|
12
7
|
setCriteria: Function;
|
13
8
|
criteria?: Record<string, any>;
|
14
9
|
enablePresetValues?: boolean;
|
15
|
-
presetValues?:
|
16
|
-
label: string;
|
17
|
-
value: {
|
18
|
-
name: string;
|
19
|
-
label: string;
|
20
|
-
sublabel?: string;
|
21
|
-
};
|
22
|
-
}[];
|
10
|
+
presetValues?: PresetValue[];
|
23
11
|
dynamicContentInput?: {
|
24
12
|
component: React.ElementType;
|
25
13
|
previousSteps: unknown[];
|
@@ -27,8 +15,8 @@ declare type CriteriaInputProps = {
|
|
27
15
|
};
|
28
16
|
operators?: Operator[];
|
29
17
|
disabled?: boolean;
|
18
|
+
hideBorder?: boolean;
|
30
19
|
};
|
31
|
-
export declare const
|
32
|
-
export declare const customValueEditor: (props: CustomValueEditorProps) => JSX.Element;
|
20
|
+
export declare const valueEditor: (props: ValueEditorProps) => JSX.Element;
|
33
21
|
declare const CriteriaBuilder: (props: CriteriaInputProps) => JSX.Element;
|
34
22
|
export default CriteriaBuilder;
|
@@ -1,13 +1,13 @@
|
|
1
|
-
import {
|
1
|
+
import { AddRounded, RemoveCircleOutlineRounded } from '@mui/icons-material';
|
2
2
|
import { QueryBuilderMaterial } from '@react-querybuilder/material';
|
3
3
|
import React, { useEffect, useMemo, useState } from 'react';
|
4
4
|
import { QueryBuilder, formatQuery, parseMongoDB, useRuleGroup, TestID, RuleGroupBodyComponents, RuleGroupHeaderComponents, } from 'react-querybuilder';
|
5
5
|
import 'react-querybuilder/dist/query-builder.css';
|
6
|
-
import {
|
6
|
+
import { isEmpty, startCase } from 'lodash-es';
|
7
|
+
import { Autocomplete, Button, IconButton, TextField } from '../../core';
|
7
8
|
import { Box } from '../../layout';
|
8
|
-
import { NumericFormat } from '../FormField/InputFieldComponent';
|
9
|
-
import { isEmpty } from 'lodash-es';
|
10
9
|
import { difference } from '../util';
|
10
|
+
import ValueEditor from './ValueEditor';
|
11
11
|
const ALL_OPERATORS = [
|
12
12
|
{ name: '=', label: '=' },
|
13
13
|
{ name: '!=', label: '!=' },
|
@@ -57,13 +57,20 @@ const customButton = (props) => {
|
|
57
57
|
let buttonLabel = label;
|
58
58
|
switch (title) {
|
59
59
|
case 'Add group':
|
60
|
-
buttonLabel = '
|
60
|
+
buttonLabel = 'Condition Group';
|
61
61
|
break;
|
62
62
|
case 'Add rule':
|
63
|
-
buttonLabel = '
|
63
|
+
buttonLabel = 'Condition';
|
64
64
|
break;
|
65
65
|
}
|
66
|
-
return (React.createElement(Button, { variant: "contained", onClick: handleOnClick, size: "small",
|
66
|
+
return (React.createElement(Button, { variant: "contained", onClick: handleOnClick, size: "small", startIcon: React.createElement(AddRounded, null), sx: {
|
67
|
+
padding: '6px 20px',
|
68
|
+
fontSize: '14.5px',
|
69
|
+
backgroundColor: '#ebf4f8',
|
70
|
+
color: '#0678a9',
|
71
|
+
boxShadow: 'none',
|
72
|
+
'&:hover': { backgroundColor: '#dcecf3', boxShadow: 'none' },
|
73
|
+
} }, buttonLabel));
|
67
74
|
};
|
68
75
|
const customSelector = (props) => {
|
69
76
|
var _a, _b;
|
@@ -100,13 +107,10 @@ const customSelector = (props) => {
|
|
100
107
|
};
|
101
108
|
const customCombinator = (props) => {
|
102
109
|
const { options, value, handleOnChange } = props;
|
103
|
-
return (React.createElement(Autocomplete, { options: options, value: value === null ||
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
}, size: 'small', renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { size: "small" })), sx: {
|
108
|
-
width: '90px',
|
109
|
-
backgroundColor: '#eee',
|
110
|
+
return (React.createElement(Autocomplete, { options: options, value: startCase(value), getOptionLabel: (option) => { var _a; return startCase((_a = option === null || option === void 0 ? void 0 : option.name) !== null && _a !== void 0 ? _a : option); }, isOptionEqualToValue: (option, value) => option === value, onChange: (event, newValue) => handleOnChange(newValue === null || newValue === void 0 ? void 0 : newValue.value.name), size: 'small', renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { size: "small", sx: { "& fieldset": { border: 'none' } } })), sx: {
|
111
|
+
width: '80px',
|
112
|
+
backgroundColor: '#DFE3E8',
|
113
|
+
borderWidth: 'none',
|
110
114
|
borderRadius: '8px',
|
111
115
|
'.MuiInputBase-input': {
|
112
116
|
fontWeight: 550,
|
@@ -117,167 +121,22 @@ const customCombinator = (props) => {
|
|
117
121
|
const customDelete = (props) => {
|
118
122
|
const { handleOnClick } = props;
|
119
123
|
return (React.createElement(IconButton, { onClick: handleOnClick, size: "small" },
|
120
|
-
React.createElement(
|
124
|
+
React.createElement(RemoveCircleOutlineRounded, null)));
|
121
125
|
};
|
122
|
-
export const
|
123
|
-
var _a;
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
handleOnChange((_a = newValue === null || newValue === void 0 ? void 0 : newValue.value.name) !== null && _a !== void 0 ? _a : '');
|
129
|
-
}, options: presetValues !== null && presetValues !== void 0 ? presetValues : [
|
130
|
-
{
|
126
|
+
export const valueEditor = (props) => {
|
127
|
+
var _a, _b;
|
128
|
+
// For backward compatibility, if enable preset values is true, but preset
|
129
|
+
// values are not defined, add in the user id preset value
|
130
|
+
if (!((_a = props.context) === null || _a === void 0 ? void 0 : _a.presetValues) && ((_b = props.context) === null || _b === void 0 ? void 0 : _b.enablePresetValues)) {
|
131
|
+
props.context.presetValues = [{
|
131
132
|
label: 'User ID',
|
132
133
|
value: { name: '{{{user.id}}}', label: 'UserId', sublabel: 'Currently logged in user' },
|
133
|
-
}
|
134
|
-
], isOptionEqualToValue: (option, value) => {
|
135
|
-
return option === value;
|
136
|
-
}, getOptionLabel: (option) => {
|
137
|
-
var _a;
|
138
|
-
if (option === '{{{user.id}}}')
|
139
|
-
return 'User ID';
|
140
|
-
return (_a = option.label) !== null && _a !== void 0 ? _a : option;
|
141
|
-
}, disabled: ['null', 'notNull'].includes(props.operator), renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { size: "small", placeholder: 'Value', readOnly: value.includes('{{{') && value.includes('}}}'), onChange: (event) => {
|
142
|
-
handleOnChange(event.target.value);
|
143
|
-
} }))), renderOption: (props, option) => {
|
144
|
-
return (React.createElement(MenuItem, Object.assign({}, props, { sx: { padding: '0px 8px' } }),
|
145
|
-
React.createElement(Box, { padding: 0, margin: 0 },
|
146
|
-
React.createElement(Typography, { fontSize: '14px', fontWeight: 500 }, option.label),
|
147
|
-
option.value.sublabel && (React.createElement(Typography, { fontSize: '14px', fontWeight: 500, color: 'rgba(145, 158, 171, 1)' }, option.value.sublabel)))));
|
148
|
-
}, componentsProps: { popper: { style: { minWidth: '200px', width: 'fit-content' } } }, sx: { width: '33%' } }));
|
149
|
-
return determineValueEditor(valueEditor, props);
|
150
|
-
};
|
151
|
-
export const customValueEditor = (props) => {
|
152
|
-
const { value, handleOnChange, operator } = props;
|
153
|
-
let valueEditor = (React.createElement(TextField, { value: ['null', 'notNull'].includes(operator) ? '' : value, disabled: ['null', 'notNull'].includes(operator), onChange: (e) => {
|
154
|
-
handleOnChange(e.target.value);
|
155
|
-
}, placeholder: "Value", size: "small", sx: { width: '33%' } }));
|
156
|
-
return determineValueEditor(valueEditor, props);
|
157
|
-
};
|
158
|
-
const dynamicContentInputEditor = (props) => {
|
159
|
-
var _a, _b, _c, _d;
|
160
|
-
const { operator, value, handleOnChange } = props;
|
161
|
-
const DynamicContentInput = (_a = props.context) === null || _a === void 0 ? void 0 : _a.dynamicContentInput.component;
|
162
|
-
let valueEditor;
|
163
|
-
if (DynamicContentInput) {
|
164
|
-
valueEditor = (React.createElement(DynamicContentInput, { values: ['null', 'notNull'].includes(operator) ? '' : value, setValues: (e) => {
|
165
|
-
handleOnChange(e !== null && e !== void 0 ? e : '');
|
166
|
-
}, disabled: ['null', 'notNull'].includes(operator), size: 'small', previousSteps: (_c = (_b = props.context) === null || _b === void 0 ? void 0 : _b.dynamicContentInput.previousSteps) !== null && _c !== void 0 ? _c : [], trigger: (_d = props.context) === null || _d === void 0 ? void 0 : _d.dynamicContentInput.trigger, isSingleValue: true, width: '33%', useStringInterpolation: true }));
|
167
|
-
}
|
168
|
-
return determineValueEditor(valueEditor, props);
|
169
|
-
};
|
170
|
-
const determineValueEditor = (baseValueEditor, props) => {
|
171
|
-
var _a, _b, _c, _d;
|
172
|
-
const { handleOnChange, value, values, type, operator, inputType } = props;
|
173
|
-
const disabled = ['null', 'notNull'].includes(operator);
|
174
|
-
let valueEditor = baseValueEditor;
|
175
|
-
switch (inputType) {
|
176
|
-
case 'date':
|
177
|
-
valueEditor = (React.createElement(LocalizationProvider, null,
|
178
|
-
React.createElement(DatePicker, { disabled: disabled, value: disabled ? null : value, onChange: (value) => {
|
179
|
-
handleOnChange(value);
|
180
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { placeholder: "Value", size: "small", sx: { width: '33%' } }))) })));
|
181
|
-
break;
|
182
|
-
case 'integer':
|
183
|
-
{
|
184
|
-
const DynamicContentInput = (_b = (_a = props.context) === null || _a === void 0 ? void 0 : _a.dynamicContentInput) === null || _b === void 0 ? void 0 : _b.component;
|
185
|
-
if (DynamicContentInput) {
|
186
|
-
if ((operator === 'in' || operator === 'notIn') && type === 'select' && values) {
|
187
|
-
valueEditor = (React.createElement(Autocomplete, { multiple: true, options: values || [], getOptionLabel: (option) => (option.label ? option.label : ''), value: Array.isArray(value) ? (disabled ? [] : value) : [], disabled: disabled, onChange: (event, newValue) => {
|
188
|
-
const uniqueSelections = Array.from(new Set(newValue.map((item) => item.label))).map((label) => {
|
189
|
-
return newValue.find((item) => item.label === label);
|
190
|
-
});
|
191
|
-
handleOnChange(uniqueSelections.length ? uniqueSelections : '');
|
192
|
-
}, isOptionEqualToValue: (option, value) => {
|
193
|
-
return option === value;
|
194
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({ label: params.label }, params, { size: "small" }))), sx: { width: '33%' } }));
|
195
|
-
}
|
196
|
-
else if (type === 'select' && values) {
|
197
|
-
valueEditor = (React.createElement(Autocomplete, { freeSolo: true, options: values, multiple: ['in', 'notIn'].includes(operator), value: disabled ? '' : value, onChange: (event, newValue) => {
|
198
|
-
handleOnChange(newValue === null || newValue === void 0 ? void 0 : newValue.label);
|
199
|
-
}, disabled: disabled, isOptionEqualToValue: (option, value) => {
|
200
|
-
return option === value;
|
201
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { size: "small", placeholder: 'Value', readOnly: value === '{{user.id}}', onChange: (event) => {
|
202
|
-
handleOnChange(event.target.value);
|
203
|
-
} }))), sx: { width: '33%' }, disableClearable: true }));
|
204
|
-
}
|
205
|
-
}
|
206
|
-
else {
|
207
|
-
valueEditor = (React.createElement(TextField, { value: ['null', 'notNull'].includes(operator) ? '' : value, disabled: ['null', 'notNull'].includes(operator), onChange: (e) => {
|
208
|
-
handleOnChange(isNaN(parseInt(e.target.value)) ? '' : parseInt(e.target.value));
|
209
|
-
}, type: "number", placeholder: "Value", size: "small", sx: { width: '33%' } }));
|
210
|
-
}
|
211
|
-
}
|
212
|
-
break;
|
213
|
-
case 'number':
|
214
|
-
{
|
215
|
-
const DynamicContentInput = (_d = (_c = props.context) === null || _c === void 0 ? void 0 : _c.dynamicContentInput) === null || _d === void 0 ? void 0 : _d.component;
|
216
|
-
if (DynamicContentInput) {
|
217
|
-
if ((operator === 'in' || operator === 'notIn') && type === 'select' && values) {
|
218
|
-
valueEditor = (React.createElement(Autocomplete, { multiple: true, options: values || [], getOptionLabel: (option) => (option.label ? option.label : ''), value: Array.isArray(value) ? (disabled ? [] : value) : [], disabled: disabled, onChange: (event, newValue) => {
|
219
|
-
const uniqueSelections = Array.from(new Set(newValue.map((item) => item.label))).map((label) => {
|
220
|
-
return newValue.find((item) => item.label === label);
|
221
|
-
});
|
222
|
-
handleOnChange(uniqueSelections.length ? uniqueSelections : '');
|
223
|
-
}, isOptionEqualToValue: (option, value) => {
|
224
|
-
return option === value;
|
225
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({ label: params.label }, params, { size: "small" }))), sx: { width: '33%' } }));
|
226
|
-
}
|
227
|
-
else if (type === 'select' && values) {
|
228
|
-
valueEditor = (React.createElement(Autocomplete, { freeSolo: true, options: values, multiple: ['in', 'notIn'].includes(operator), value: disabled ? '' : value, onChange: (event, newValue) => {
|
229
|
-
handleOnChange(newValue === null || newValue === void 0 ? void 0 : newValue.label);
|
230
|
-
}, disabled: disabled, isOptionEqualToValue: (option, value) => {
|
231
|
-
return option === value;
|
232
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { size: "small", placeholder: 'Value', readOnly: value === '{{user.id}}', onChange: (event) => {
|
233
|
-
handleOnChange(event.target.value);
|
234
|
-
} }))), sx: { width: '33%' }, disableClearable: true }));
|
235
|
-
}
|
236
|
-
}
|
237
|
-
else {
|
238
|
-
valueEditor = (React.createElement(TextField, { value: ['null', 'notNull'].includes(operator) ? '' : value, disabled: ['null', 'notNull'].includes(operator), onChange: (e) => {
|
239
|
-
var _a;
|
240
|
-
handleOnChange((_a = e.target.value) !== null && _a !== void 0 ? _a : '');
|
241
|
-
}, InputProps: { inputComponent: NumericFormat }, placeholder: "Value", size: "small", sx: { width: '33%' } }));
|
242
|
-
}
|
243
|
-
}
|
244
|
-
break;
|
245
|
-
case 'array':
|
246
|
-
valueEditor = (React.createElement(Autocomplete, { multiple: true, options: values || [], getOptionLabel: (option) => (option.label ? option.label : ''), value: Array.isArray(value) ? (disabled ? [] : value) : [], disabled: disabled, onChange: (event, newValue) => {
|
247
|
-
const uniqueSelections = Array.from(new Set(newValue.map((item) => item.label))).map((label) => {
|
248
|
-
return newValue.find((item) => item.label === label);
|
249
|
-
});
|
250
|
-
handleOnChange(uniqueSelections.length ? uniqueSelections : '');
|
251
|
-
}, isOptionEqualToValue: (option, value) => {
|
252
|
-
return option === value;
|
253
|
-
}, renderInput: (params) => React.createElement(TextField, Object.assign({ label: params.label }, params, { size: "small" })), sx: { width: '33%' } }));
|
254
|
-
break;
|
255
|
-
case 'string':
|
256
|
-
if ((operator === 'in' || operator === 'notIn') && type === 'select' && values) {
|
257
|
-
valueEditor = (React.createElement(Autocomplete, { multiple: true, options: values || [], getOptionLabel: (option) => (option.label ? option.label : ''), value: Array.isArray(value) ? (disabled ? [] : value) : [], disabled: disabled, onChange: (event, newValue) => {
|
258
|
-
const uniqueSelections = Array.from(new Set(newValue.map((item) => item.label))).map((label) => {
|
259
|
-
return newValue.find((item) => item.label === label);
|
260
|
-
});
|
261
|
-
handleOnChange(uniqueSelections.length ? uniqueSelections : '');
|
262
|
-
}, isOptionEqualToValue: (option, value) => {
|
263
|
-
return option === value;
|
264
|
-
}, renderInput: (params) => React.createElement(TextField, Object.assign({ label: params.label }, params, { size: "small" })), sx: { width: '33%' } }));
|
265
|
-
}
|
266
|
-
else if (type === 'select' && values) {
|
267
|
-
valueEditor = (React.createElement(Autocomplete, { freeSolo: true, options: values, multiple: ['in', 'notIn'].includes(operator), value: disabled ? '' : value, onChange: (event, newValue) => {
|
268
|
-
handleOnChange(newValue === null || newValue === void 0 ? void 0 : newValue.label);
|
269
|
-
}, disabled: disabled, isOptionEqualToValue: (option, value) => {
|
270
|
-
return option === value;
|
271
|
-
}, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { size: "small", placeholder: 'Value', readOnly: value === '{{user.id}}', onChange: (event) => {
|
272
|
-
handleOnChange(event.target.value);
|
273
|
-
} }))), sx: { width: '33%' }, disableClearable: true }));
|
274
|
-
}
|
275
|
-
break;
|
134
|
+
}];
|
276
135
|
}
|
277
|
-
return
|
136
|
+
return ValueEditor(props);
|
278
137
|
};
|
279
138
|
const CriteriaBuilder = (props) => {
|
280
|
-
const { properties, criteria, setCriteria, enablePresetValues, presetValues, operators, dynamicContentInput, disabled, } = props;
|
139
|
+
const { properties, criteria, setCriteria, enablePresetValues, presetValues, operators, dynamicContentInput, disabled, hideBorder, } = props;
|
281
140
|
const [query, setQuery] = useState(undefined);
|
282
141
|
useEffect(() => {
|
283
142
|
if (criteria) {
|
@@ -330,17 +189,29 @@ const CriteriaBuilder = (props) => {
|
|
330
189
|
if (query) {
|
331
190
|
return (React.createElement(Box, { sx: {
|
332
191
|
border: '2px solid #ddd',
|
192
|
+
borderStyle: hideBorder ? 'hidden' : 'solid',
|
333
193
|
borderRadius: '10px',
|
334
194
|
'.container': {
|
335
195
|
background: '#fff',
|
336
196
|
borderColor: '#ddd',
|
337
197
|
borderRadius: '8px',
|
338
198
|
},
|
199
|
+
'.queryBuilder-branches .ruleGroup-body': {
|
200
|
+
marginLeft: hideBorder ? '0px' : 'calc(2 * 0.5rem)',
|
201
|
+
},
|
339
202
|
'.queryBuilder-branches': { color: '#ddd' },
|
340
|
-
'.queryBuilder-branches .betweenRules::before': {
|
341
|
-
|
203
|
+
'.queryBuilder-branches .betweenRules::before': {
|
204
|
+
borderColor: '#ddd',
|
205
|
+
borderStyle: hideBorder ? 'hidden' : 'solid',
|
206
|
+
},
|
207
|
+
'.ruleGroup': {
|
208
|
+
borderColor: '#ddd',
|
209
|
+
borderStyle: hideBorder ? 'hidden' : 'solid',
|
210
|
+
},
|
211
|
+
'.ruleGroup .ruleGroup': { borderStyle: 'solid' },
|
342
212
|
'.queryBuilder-branches .rule::before, .queryBuilder-branches .ruleGroup .ruleGroup::before, .queryBuilder-branches .rule::after, .queryBuilder-branches .ruleGroup .ruleGroup::after': {
|
343
213
|
borderColor: '#ddd',
|
214
|
+
borderStyle: hideBorder ? 'hidden' : 'solid',
|
344
215
|
},
|
345
216
|
} },
|
346
217
|
React.createElement(QueryBuilderMaterial, null,
|
@@ -355,12 +226,8 @@ const CriteriaBuilder = (props) => {
|
|
355
226
|
ruleGroup: CustomRuleGroup,
|
356
227
|
removeGroupAction: customDelete,
|
357
228
|
removeRuleAction: customDelete,
|
358
|
-
valueEditor:
|
359
|
-
|
360
|
-
: dynamicContentInput
|
361
|
-
? dynamicContentInputEditor
|
362
|
-
: customValueEditor,
|
363
|
-
}, context: { dynamicContentInput: dynamicContentInput, presetValues }, controlClassnames: {
|
229
|
+
valueEditor: valueEditor
|
230
|
+
}, context: { dynamicContentInput, presetValues, enablePresetValues }, controlClassnames: {
|
364
231
|
queryBuilder: 'queryBuilder-branches',
|
365
232
|
ruleGroup: 'container',
|
366
233
|
}, operators: operators
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { AutocompleteOption } from '../../core';
|
3
|
+
import { ValueEditorProps as ValueEditorBaseProps } from 'react-querybuilder';
|
4
|
+
export declare type ValueEditorProps = ValueEditorBaseProps & {
|
5
|
+
values?: AutocompleteOption[] | any[];
|
6
|
+
};
|
7
|
+
declare const ValueEditor: (props: ValueEditorProps) => JSX.Element;
|
8
|
+
export default ValueEditor;
|
@@ -0,0 +1,125 @@
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
2
|
+
import { Autocomplete, Chip, DatePicker, LocalizationProvider, Menu, MenuItem, TextField, Typography, } from '../../core';
|
3
|
+
import { NumericFormat } from '../FormField/InputFieldComponent';
|
4
|
+
import { Box, darken, lighten, styled } from '@mui/material';
|
5
|
+
import { ClearRounded } from '@mui/icons-material';
|
6
|
+
import { TimePicker } from '@mui/x-date-pickers';
|
7
|
+
const GroupHeader = styled('div')(({ theme }) => ({
|
8
|
+
position: 'sticky',
|
9
|
+
top: '-8px',
|
10
|
+
padding: '10px',
|
11
|
+
color: theme.palette.primary.main,
|
12
|
+
fontWeight: 600,
|
13
|
+
fontSize: '14px',
|
14
|
+
backgroundColor: theme.palette.mode === 'light'
|
15
|
+
? lighten(theme.palette.primary.light, 0.85)
|
16
|
+
: darken(theme.palette.primary.main, 0.8),
|
17
|
+
}));
|
18
|
+
const GroupItems = styled('ul')({ padding: 0 });
|
19
|
+
const ValueEditor = (props) => {
|
20
|
+
var _a, _b, _c, _d;
|
21
|
+
const { handleOnChange, value, values, operator, inputType, context } = props;
|
22
|
+
let inputRef = useRef(null);
|
23
|
+
const [openPresetValues, setOpenPresetValues] = useState(false);
|
24
|
+
const disabled = ['null', 'notNull'].includes(operator);
|
25
|
+
const presetValues = (_a = context.presetValues) !== null && _a !== void 0 ? _a : [];
|
26
|
+
const isPresetValue = (value) => (value === null || value === void 0 ? void 0 : value.includes('{{{')) && (value === null || value === void 0 ? void 0 : value.includes('}}}'));
|
27
|
+
const isPresetValueSelected = presetValues && typeof value === 'string' && isPresetValue(value);
|
28
|
+
const presetDisplayValue = (_c = (_b = presetValues === null || presetValues === void 0 ? void 0 : presetValues.find((option) => option.value.name === value)) === null || _b === void 0 ? void 0 : _b.label) !== null && _c !== void 0 ? _c : '';
|
29
|
+
const onClick = (e) => {
|
30
|
+
var _a;
|
31
|
+
// if property is date and date picker is open, don't open preset values
|
32
|
+
if (inputType && ['date', 'time'].includes(inputType) && ((_a = e.target) === null || _a === void 0 ? void 0 : _a.tagName) !== 'INPUT') {
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
setOpenPresetValues(true);
|
36
|
+
};
|
37
|
+
const onClose = () => {
|
38
|
+
setOpenPresetValues(false);
|
39
|
+
};
|
40
|
+
const clearValue = () => {
|
41
|
+
handleOnChange('');
|
42
|
+
};
|
43
|
+
const setPresetValue = (value) => {
|
44
|
+
handleOnChange(value);
|
45
|
+
onClose();
|
46
|
+
};
|
47
|
+
const groupRenderGroup = (params) => (React.createElement("li", { key: params.key },
|
48
|
+
React.createElement(GroupHeader, null, params.group),
|
49
|
+
React.createElement(GroupItems, null, params.children)));
|
50
|
+
const getEditor = () => {
|
51
|
+
var _a, _b;
|
52
|
+
if (isPresetValueSelected) {
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
if (inputType === 'date') {
|
56
|
+
// date editor
|
57
|
+
return (React.createElement(LocalizationProvider, null,
|
58
|
+
React.createElement(DatePicker, { inputRef: inputRef, disabled: disabled, value: disabled ? null : value, onChange: handleOnChange, onClose: onClose, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { onClick: onClick, placeholder: "Value", size: "small", sx: { width: '33%' } }))) })));
|
59
|
+
}
|
60
|
+
else if (inputType === 'time') {
|
61
|
+
return (React.createElement(LocalizationProvider, null,
|
62
|
+
React.createElement(TimePicker, { inputRef: inputRef, disabled: disabled, value: disabled || !value ? null : value, onChange: handleOnChange, renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { onClick: onClick, placeholder: "Value", size: "small", sx: { width: '33%' } })) })));
|
63
|
+
}
|
64
|
+
else if (inputType === 'number' || inputType === 'integer') {
|
65
|
+
const isMultiple = ['in', 'notIn'].includes(operator);
|
66
|
+
const options = presetValues;
|
67
|
+
if (isMultiple) {
|
68
|
+
return (React.createElement(Autocomplete, { freeSolo: true, multiple: true, options: options, getOptionLabel: (option) => (option.label ? option.label : option), value: Array.isArray(value) ? (disabled ? [] : value) : [], disabled: disabled, onChange: (event, newValue) => {
|
69
|
+
const uniqueSelections = newValue.map((item) => { var _a; return (_a = item.value) !== null && _a !== void 0 ? _a : Number(item); });
|
70
|
+
handleOnChange(uniqueSelections.length ? uniqueSelections : '');
|
71
|
+
}, isOptionEqualToValue: (option, value) => option === value, renderInput: (params) => React.createElement(TextField, Object.assign({ label: params.label }, params, { size: "small" })), groupBy: (option) => { var _a; return (isPresetValue((_a = option.value) === null || _a === void 0 ? void 0 : _a.name) ? 'Preset Values' : 'Options'); }, renderGroup: groupRenderGroup, sx: { width: '33%' } }));
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
return (React.createElement(TextField, Object.assign({ inputRef: inputRef, value: ['null', 'notNull'].includes(operator) ? '' : value, disabled: ['null', 'notNull'].includes(operator), onChange: (e) => {
|
75
|
+
var _a;
|
76
|
+
if (inputType === 'number') {
|
77
|
+
handleOnChange((_a = e.target.value) !== null && _a !== void 0 ? _a : '');
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
handleOnChange(isNaN(parseInt(e.target.value)) ? '' : parseInt(e.target.value));
|
81
|
+
}
|
82
|
+
} }, (inputType === 'number'
|
83
|
+
? { InputProps: { inputComponent: NumericFormat } }
|
84
|
+
: { type: 'number' }), { placeholder: "Value", size: "small", onClick: onClick, sx: { width: '33%' } })));
|
85
|
+
}
|
86
|
+
}
|
87
|
+
else {
|
88
|
+
const isMultiple = inputType === 'array' || ['in', 'notIn'].includes(operator);
|
89
|
+
const options = [
|
90
|
+
...((_a = values === null || values === void 0 ? void 0 : values.sort((a, b) => a.label.localeCompare(b.name))) !== null && _a !== void 0 ? _a : []),
|
91
|
+
...((_b = presetValues === null || presetValues === void 0 ? void 0 : presetValues.sort((a, b) => a.label.localeCompare(b.label))) !== null && _b !== void 0 ? _b : [])
|
92
|
+
];
|
93
|
+
if (isMultiple || (values === null || values === void 0 ? void 0 : values.length)) {
|
94
|
+
return (React.createElement(Autocomplete, { freeSolo: inputType !== 'array' && inputType !== 'select', multiple: isMultiple, options: options, value: isMultiple ? (disabled ? [] : value) : value, disabled: disabled, onChange: (event, newValue) => {
|
95
|
+
var _a, _b, _c;
|
96
|
+
let value;
|
97
|
+
if (isMultiple) {
|
98
|
+
value = (_a = Array.from(new Set(newValue.map((item) => item.label))).map((label) => newValue.find((item) => item.label === label))) !== null && _a !== void 0 ? _a : [];
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
value = (_c = (_b = newValue === null || newValue === void 0 ? void 0 : newValue.value) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '';
|
102
|
+
}
|
103
|
+
handleOnChange(value);
|
104
|
+
}, renderInput: (params) => (React.createElement(TextField, Object.assign({ inputRef: inputRef, label: params.label }, params, { size: "small" }))), groupBy: (option) => { var _a; return (isPresetValue((_a = option.value) === null || _a === void 0 ? void 0 : _a.name) ? 'Preset Values' : 'Options'); }, renderGroup: groupRenderGroup, sortBy: 'NONE', sx: { width: '33%' } }));
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
return (React.createElement(TextField, { inputRef: inputRef, value: ['null', 'notNull'].includes(operator) ? '' : value, disabled: ['null', 'notNull'].includes(operator), onChange: (e) => handleOnChange(e.target.value), onClick: onClick, placeholder: "Value", size: "small", sx: { width: '33%' } }));
|
108
|
+
}
|
109
|
+
}
|
110
|
+
};
|
111
|
+
return (React.createElement(React.Fragment, null,
|
112
|
+
isPresetValueSelected ? (React.createElement(Chip, { label: presetDisplayValue, sx: {
|
113
|
+
borderRadius: '8px',
|
114
|
+
fontSize: '14px',
|
115
|
+
width: '33%',
|
116
|
+
height: '40px',
|
117
|
+
padding: '0 5px',
|
118
|
+
justifyContent: 'space-between',
|
119
|
+
}, deleteIcon: React.createElement(ClearRounded, { fontSize: "small" }), onDelete: clearValue })) : (getEditor()),
|
120
|
+
!!(presetValues === null || presetValues === void 0 ? void 0 : presetValues.length) && (React.createElement(Menu, { open: openPresetValues, anchorEl: inputRef === null || inputRef === void 0 ? void 0 : inputRef.current, PaperProps: { sx: { borderRadius: '8px', width: (_d = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _d === void 0 ? void 0 : _d.offsetWidth } }, onClose: onClose }, presetValues === null || presetValues === void 0 ? void 0 : presetValues.map((option) => (React.createElement(MenuItem, Object.assign({}, props, { onClick: () => setPresetValue(option.value.name), sx: { padding: '8px', minHeight: '25px' } }),
|
121
|
+
React.createElement(Box, { padding: 0, margin: 0 },
|
122
|
+
React.createElement(Typography, { fontSize: '14px', fontWeight: 500, sx: { lineHeight: '20px' } }, option.label),
|
123
|
+
option.value.sublabel && (React.createElement(Typography, { fontSize: '14px', fontWeight: 500, color: 'rgba(145, 158, 171)', sx: { lineHeight: '20px' } }, option.value.sublabel))))))))));
|
124
|
+
};
|
125
|
+
export default ValueEditor;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { BaseSelectorProps } from 'react-querybuilder';
|
2
|
+
import { AutocompleteOption } from '../../core';
|
3
|
+
export declare type ObjectProperty = {
|
4
|
+
id: string;
|
5
|
+
name: string;
|
6
|
+
type: string;
|
7
|
+
enum?: string[];
|
8
|
+
required?: boolean;
|
9
|
+
searchable?: boolean;
|
10
|
+
objectId?: string;
|
11
|
+
formula?: string;
|
12
|
+
};
|
13
|
+
export declare type CustomSelectorProps = BaseSelectorProps & {
|
14
|
+
options: AutocompleteOption[] | any[];
|
15
|
+
fieldData?: Record<string, any>;
|
16
|
+
};
|
17
|
+
export declare type Operator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'contains' | 'beginsWith' | 'endsWith' | 'doesNotContain' | 'doesNotBeginWith' | 'doesNotEndWith' | 'null' | 'notNull' | 'in' | 'notIn' | 'between' | 'notBetween';
|
18
|
+
export declare type PresetValue = {
|
19
|
+
label: string;
|
20
|
+
value: {
|
21
|
+
name: string;
|
22
|
+
label: string;
|
23
|
+
sublabel?: string;
|
24
|
+
};
|
25
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -1,66 +1,6 @@
|
|
1
|
+
/// <reference types="react" />
|
1
2
|
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
2
|
-
import
|
3
|
-
declare const _default: ComponentMeta<(props: {
|
4
|
-
properties: import("../components/custom/types").ObjectProperty[];
|
5
|
-
setCriteria: Function;
|
6
|
-
criteria?: Record<string, any> | undefined;
|
7
|
-
enablePresetValues?: boolean | undefined;
|
8
|
-
presetValues?: {
|
9
|
-
label: string;
|
10
|
-
value: {
|
11
|
-
name: string;
|
12
|
-
label: string;
|
13
|
-
sublabel?: string | undefined;
|
14
|
-
};
|
15
|
-
}[] | undefined;
|
16
|
-
dynamicContentInput?: {
|
17
|
-
component: React.ElementType<any>;
|
18
|
-
previousSteps: unknown[];
|
19
|
-
trigger?: Record<string, unknown> | undefined;
|
20
|
-
} | undefined;
|
21
|
-
operators?: ("endsWith" | "in" | "=" | "!=" | "<" | ">" | "<=" | ">=" | "contains" | "beginsWith" | "doesNotContain" | "doesNotBeginWith" | "doesNotEndWith" | "null" | "notNull" | "notIn" | "between" | "notBetween")[] | undefined;
|
22
|
-
disabled?: boolean | undefined;
|
23
|
-
}) => JSX.Element>;
|
3
|
+
declare const _default: ComponentMeta<(props: import("../components/custom/CriteriaBuilder/CriteriaBuilder").CriteriaInputProps) => JSX.Element>;
|
24
4
|
export default _default;
|
25
|
-
export declare const CriteriaBuilder: ComponentStory<(props:
|
26
|
-
|
27
|
-
setCriteria: Function;
|
28
|
-
criteria?: Record<string, any> | undefined;
|
29
|
-
enablePresetValues?: boolean | undefined;
|
30
|
-
presetValues?: {
|
31
|
-
label: string;
|
32
|
-
value: {
|
33
|
-
name: string;
|
34
|
-
label: string;
|
35
|
-
sublabel?: string | undefined;
|
36
|
-
};
|
37
|
-
}[] | undefined;
|
38
|
-
dynamicContentInput?: {
|
39
|
-
component: React.ElementType<any>;
|
40
|
-
previousSteps: unknown[];
|
41
|
-
trigger?: Record<string, unknown> | undefined;
|
42
|
-
} | undefined;
|
43
|
-
operators?: ("endsWith" | "in" | "=" | "!=" | "<" | ">" | "<=" | ">=" | "contains" | "beginsWith" | "doesNotContain" | "doesNotBeginWith" | "doesNotEndWith" | "null" | "notNull" | "notIn" | "between" | "notBetween")[] | undefined;
|
44
|
-
disabled?: boolean | undefined;
|
45
|
-
}) => JSX.Element>;
|
46
|
-
export declare const CriteriaBuilderPresetValues: ComponentStory<(props: {
|
47
|
-
properties: import("../components/custom/types").ObjectProperty[];
|
48
|
-
setCriteria: Function;
|
49
|
-
criteria?: Record<string, any> | undefined;
|
50
|
-
enablePresetValues?: boolean | undefined;
|
51
|
-
presetValues?: {
|
52
|
-
label: string;
|
53
|
-
value: {
|
54
|
-
name: string;
|
55
|
-
label: string;
|
56
|
-
sublabel?: string | undefined;
|
57
|
-
};
|
58
|
-
}[] | undefined;
|
59
|
-
dynamicContentInput?: {
|
60
|
-
component: React.ElementType<any>;
|
61
|
-
previousSteps: unknown[];
|
62
|
-
trigger?: Record<string, unknown> | undefined;
|
63
|
-
} | undefined;
|
64
|
-
operators?: ("endsWith" | "in" | "=" | "!=" | "<" | ">" | "<=" | ">=" | "contains" | "beginsWith" | "doesNotContain" | "doesNotBeginWith" | "doesNotEndWith" | "null" | "notNull" | "notIn" | "between" | "notBetween")[] | undefined;
|
65
|
-
disabled?: boolean | undefined;
|
66
|
-
}) => JSX.Element>;
|
5
|
+
export declare const CriteriaBuilder: ComponentStory<(props: import("../components/custom/CriteriaBuilder/CriteriaBuilder").CriteriaInputProps) => JSX.Element>;
|
6
|
+
export declare const CriteriaBuilderPresetValues: ComponentStory<(props: import("../components/custom/CriteriaBuilder/CriteriaBuilder").CriteriaInputProps) => JSX.Element>;
|
package/package.json
CHANGED
package/types.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export * from './
|
1
|
+
export * from './dist/published/components/custom/types';
|