@pega/cosmos-react-condition-builder 8.0.0-build.54.5 → 8.0.0-build.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ConditionBuilder/ConditionBuilder.d.ts.map +1 -1
- package/lib/components/ConditionBuilder/ConditionBuilder.js +36 -56
- package/lib/components/ConditionBuilder/ConditionBuilder.js.map +1 -1
- package/lib/components/ConditionBuilder/ConditionBuilder.styles.d.ts.map +1 -1
- package/lib/components/ConditionBuilder/ConditionBuilder.styles.js +15 -3
- package/lib/components/ConditionBuilder/ConditionBuilder.styles.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionBuilder.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAc5D,OAAO,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"ConditionBuilder.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAc5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,KAAK,qBAAqB,MAAM,0BAA0B,CAAC;AA8BlE,QAAA,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,GAAG,YAAY,CAwX7E,CAAC;AAGF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment, useState, useReducer, useImperativeHandle, useRef, useEffect } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { Button, Flex, Icon, Input, MenuButton, hasProp, useI18n, getFocusables, useLiveLog, Switch } from '@pega/cosmos-react-core';
|
|
4
4
|
import AtomicCondition, { isValidCondition } from './AtomicCondition';
|
|
5
5
|
import { splitConditionForBuilder, parseLogicString, disambiguateLogic, isBasicModeApplicable, getBasicModeOperators, getLogicFromBasicMode } from './core/utils';
|
|
6
6
|
import rowsReducer, { INSERT_ROW, UPDATE_ROW, REMOVE_ROW } from './core/rows-reducer';
|
|
@@ -24,16 +24,14 @@ const ConditionBuilder = (props) => {
|
|
|
24
24
|
const [isBasicMode, setBasicMode] = useState(() => isBasicModeApplicable(clonedCondition));
|
|
25
25
|
const [operatorsList, setOperatorsList] = useState(() => getBasicModeOperators(seedLogic)); // Operators-list used in Basic-mode to render dropdowns between the rows. NOTE: When in Advanced-mode, this can contain stale values.
|
|
26
26
|
const [logicString, setLogicString] = useState(seedLogic); // Logic-string used in Advanced-mode. NOTE: When in Basic-mode, this can contain stale values.
|
|
27
|
+
const [cachedLogicString, setCachedLogicString] = useState(seedLogic); // Logic-string used to store the last valid logic-string in Advanced-mode. This is used to restore the logic-string when switching back from Basic-mode to Advanced-mode.
|
|
27
28
|
const [conditionRows, dispatch] = useReducer(rowsReducer, seedRows); // Conditions-rows
|
|
28
29
|
const [logicError, setLogicError] = useState(null); // Used to indicate errors in the logic string
|
|
29
|
-
const [showModeWarning, setModeWarning] = useState(false); // Used to warn user about losing information when moving away from Advanced mode
|
|
30
30
|
const [showErrorIndicators, setErrorIndicators] = useState(false); // Used to enable inline error indicators in the condition rows
|
|
31
31
|
const enableShading = isBasicMode && operatorsList.includes('AND') && operatorsList.includes('OR'); // In Basic mode, enable shading to indicate grouping only when both operators are present
|
|
32
32
|
const newOperatorButtonRef = useRef(null);
|
|
33
33
|
const focusRowRef = useRef(null);
|
|
34
34
|
const [focusRowIndex, setFocusRowIndex] = useState(null);
|
|
35
|
-
const bannerHandleRef = useRef(null);
|
|
36
|
-
const buttonRef = useRef(null);
|
|
37
35
|
// Upon adding/removing rows in Advanced mode, update the logic string to reflect the change in labels
|
|
38
36
|
// NOTE: The input is updated only if the previous logicString was simple enough
|
|
39
37
|
const updateLogicString = (actionType) => {
|
|
@@ -121,6 +119,7 @@ const ConditionBuilder = (props) => {
|
|
|
121
119
|
};
|
|
122
120
|
// Update a Basic-mode operator at the given index
|
|
123
121
|
const updateOperator = (updateAt, newValue) => {
|
|
122
|
+
setCachedLogicString('');
|
|
124
123
|
setOperatorsList([
|
|
125
124
|
...operatorsList.slice(0, updateAt),
|
|
126
125
|
newValue,
|
|
@@ -147,37 +146,27 @@ const ConditionBuilder = (props) => {
|
|
|
147
146
|
// If no errors
|
|
148
147
|
setLogicError(null); // Clear any previous error
|
|
149
148
|
setLogicString(disambiguateLogic(logicToUse)); // Disambiguating the logic string by placing parentheses at appropriate places
|
|
149
|
+
setCachedLogicString(disambiguateLogic(logicToUse));
|
|
150
150
|
return parseResult.condition;
|
|
151
151
|
};
|
|
152
152
|
// Toggle between the Basic and Advanced modes
|
|
153
|
-
|
|
154
|
-
const toggleMode = (forceToggle) => {
|
|
155
|
-
setModeWarning(false); // Clear any previous warning
|
|
153
|
+
const toggleMode = () => {
|
|
156
154
|
if (isBasicMode) {
|
|
157
155
|
// Update the logicString to match the operatorsList before switching the mode
|
|
158
|
-
setLogicString(getLogicFromBasicMode(operatorsList));
|
|
156
|
+
setLogicString(cachedLogicString || getLogicFromBasicMode(operatorsList));
|
|
159
157
|
setBasicMode(false);
|
|
160
158
|
}
|
|
161
|
-
else if (forceToggle) {
|
|
162
|
-
// If forcibly toggling from Advanced to Basic despite a loss of operators
|
|
163
|
-
// Set up the default `AND` operator between all rows before switching to Basic mode
|
|
164
|
-
setOperatorsList(new Array(conditionRows.length - 1).fill('AND'));
|
|
165
|
-
setBasicMode(true);
|
|
166
|
-
}
|
|
167
159
|
else {
|
|
168
|
-
// If
|
|
160
|
+
// If switched from advanced to basic mode the condition will be stored until another action takes place
|
|
161
|
+
setCachedLogicString(logicString);
|
|
169
162
|
const condition = validateLogicString(logicString); // Validate the logicString. If it is an invalid, an appropriate error is shown for the user to act on
|
|
170
163
|
if (condition !== null) {
|
|
171
|
-
// If
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
else {
|
|
178
|
-
// If the logic is too complex show a warning for the user to act on
|
|
179
|
-
setModeWarning(true);
|
|
180
|
-
}
|
|
164
|
+
// If the logic is simple enough, identify the new set of operators before switching to Basic mode.
|
|
165
|
+
// If the logic is too complex fallback to using 'AND' between all rows
|
|
166
|
+
setOperatorsList(isBasicModeApplicable(condition)
|
|
167
|
+
? getBasicModeOperators(logicString)
|
|
168
|
+
: new Array(conditionRows.length - 1).fill('AND'));
|
|
169
|
+
setBasicMode(true);
|
|
181
170
|
}
|
|
182
171
|
}
|
|
183
172
|
};
|
|
@@ -207,15 +196,14 @@ const ConditionBuilder = (props) => {
|
|
|
207
196
|
getCondition
|
|
208
197
|
}), [getCondition]);
|
|
209
198
|
const t = useI18n();
|
|
210
|
-
useEffect(() => {
|
|
211
|
-
if (showModeWarning)
|
|
212
|
-
bannerHandleRef.current?.focus();
|
|
213
|
-
}, [showModeWarning]);
|
|
214
199
|
const { announceAssertive } = useLiveLog();
|
|
215
200
|
useEffect(() => {
|
|
216
201
|
announceAssertive({ message: t('condition_builder_mode_switch') });
|
|
217
202
|
}, [isBasicMode]);
|
|
218
|
-
return (_jsxs(StyledConditionBuilder, { container: { direction: 'column', gap:
|
|
203
|
+
return (_jsxs(StyledConditionBuilder, { container: { direction: 'column', gap: 1 }, children: [_jsx(Flex, { container: true, children: _jsx(Switch, { label: t('condition_builder_advanced_mode_button_label'), "aria-label": t('condition_builder_advanced_mode_button_label'), on: !isBasicMode, onChange: () => {
|
|
204
|
+
toggleMode();
|
|
205
|
+
} }) }), _jsx("div", { role: 'group', children: conditionRows.map(({ id, label, ...leaf }, index) => {
|
|
206
|
+
const rowIndexAriaLabel = `${t('condition_builder_row', [index + 1])}`;
|
|
219
207
|
const deleteAriaLabel = `${t('condition_builder_field_label')} ${leaf.lhs.field
|
|
220
208
|
.split('.')
|
|
221
209
|
.pop()}`;
|
|
@@ -223,50 +211,42 @@ const ConditionBuilder = (props) => {
|
|
|
223
211
|
if (showErrorIndicators && !isValidCondition(leaf, fields, false)) {
|
|
224
212
|
alignItems = 'center';
|
|
225
213
|
}
|
|
226
|
-
return (_jsxs(Fragment, { children: [isBasicMode && index > 0 && (_jsx(StyledRowWithSeparator, { container: true, shaded: enableShading && operatorsList[index - 1] === 'AND', children: _jsx(MenuButton, { popover: { hideOnTargetHidden: false }, text: operatorsList[index - 1]
|
|
214
|
+
return (_jsxs(Fragment, { children: [isBasicMode && index > 0 && (_jsx(StyledRowWithSeparator, { container: true, shaded: enableShading && operatorsList[index - 1] === 'AND', children: _jsx(MenuButton, { popover: { hideOnTargetHidden: false }, text: operatorsList[index - 1] === 'AND' ? 'And' : 'Or', variant: 'simple', menu: {
|
|
227
215
|
items: [
|
|
228
216
|
{
|
|
229
217
|
id: 'AND',
|
|
230
|
-
primary: '
|
|
218
|
+
primary: 'And',
|
|
231
219
|
onClick: () => updateOperator(index - 1, 'AND')
|
|
232
220
|
},
|
|
233
221
|
{
|
|
234
222
|
id: 'OR',
|
|
235
|
-
primary: '
|
|
223
|
+
primary: 'Or',
|
|
236
224
|
onClick: () => updateOperator(index - 1, 'OR')
|
|
237
225
|
}
|
|
238
226
|
]
|
|
239
|
-
}, ref: index === focusRowIndex ? newOperatorButtonRef : null }) })), _jsxs(StyledRow, { container: { gap: 0.5, alignItems }, shaded: isBasicMode && enableShading, ref: index === focusRowIndex ? focusRowRef : null, children: [!isBasicMode && _jsx(StyledLabel, { children: label }), _jsx(Flex, { item: { grow: 1 }, children: _jsx(AtomicCondition, { condition: leaf, fields: fields, indicateErrors: showErrorIndicators, validComparators: validComparators, dateFunctions: dateFunctions, onChange: (newCondition) => {
|
|
227
|
+
}, ref: index === focusRowIndex ? newOperatorButtonRef : null }) })), _jsxs(StyledRow, { "aria-label": rowIndexAriaLabel, container: { gap: 0.5, alignItems }, shaded: isBasicMode && enableShading, ref: index === focusRowIndex ? focusRowRef : null, children: [!isBasicMode && _jsx(StyledLabel, { children: label }), _jsx(Flex, { item: { grow: 1 }, children: _jsx(AtomicCondition, { condition: leaf, fields: fields, indicateErrors: showErrorIndicators, validComparators: validComparators, dateFunctions: dateFunctions, onChange: (newCondition) => {
|
|
240
228
|
const newRow = { id, label, ...newCondition };
|
|
241
229
|
dispatch({ type: UPDATE_ROW, payload: { updateAt: index, newRow } });
|
|
242
|
-
}, validRhsTypes: validRhsTypes }) }), _jsx(Button, { icon: true, variant: 'simple', onClick: () =>
|
|
230
|
+
}, validRhsTypes: validRhsTypes }) }), _jsx(Button, { icon: true, variant: 'simple', onClick: () => {
|
|
231
|
+
insertRow(index + 1);
|
|
232
|
+
setCachedLogicString('');
|
|
233
|
+
}, label: t('add_condition'), children: _jsx(Icon, { name: 'plus' }) }), _jsx(Button, { icon: true, variant: 'simple', onClick: () => {
|
|
234
|
+
removeRow(index);
|
|
235
|
+
setCachedLogicString('');
|
|
236
|
+
}, label: t('delete'), "aria-label": deleteAriaLabel ? t('delete_noun', [deleteAriaLabel]) : undefined, children: _jsx(Icon, { name: 'trash' }) })] })] }, id));
|
|
243
237
|
}) }), !isBasicMode && (_jsx("div", { children: _jsx(Flex, { container: { gap: 0.25, direction: 'column' }, children: _jsx(Input, { label: t('condition_builder_advanced_condition_label'), additionalInfo: {
|
|
244
238
|
heading: t('condition_builder_advanced_condition_label'),
|
|
245
239
|
content: (_jsx("div", { children: t('condition_builder_advanced_condition_tooltip', [
|
|
246
240
|
disallowNOT ? 'AND/OR' : 'AND/OR/NOT',
|
|
247
241
|
disallowNOT ? '(1 OR 2) AND (3 OR 4 OR 5)' : '(1 AND 2) OR (3 AND NOT 4)'
|
|
248
242
|
]) }))
|
|
249
|
-
}, type: 'text', placeholder: t('condition_builder_advanced_condition_placeholder'), value: logicString
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
buttonRef.current?.focus();
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
], onDismiss: () => {
|
|
261
|
-
setModeWarning(false);
|
|
262
|
-
buttonRef.current?.focus();
|
|
263
|
-
}, handle: bannerHandleRef })), _jsx(Flex, { container: { justify: 'between' }, children: _jsx(Button, { name: 'mode-switch', variant: 'simple', onClick: () => {
|
|
264
|
-
toggleMode(false);
|
|
265
|
-
}, "aria-label": isBasicMode
|
|
266
|
-
? t('condition_builder_advanced_mode_button_aria_label')
|
|
267
|
-
: t('condition_builder_basic_mode_button_aria_label'), ref: buttonRef, children: isBasicMode
|
|
268
|
-
? t('condition_builder_advanced_mode_button_label')
|
|
269
|
-
: t('condition_builder_basic_mode_button_label') }) })] })] }));
|
|
243
|
+
}, type: 'text', placeholder: t('condition_builder_advanced_condition_placeholder'), value: logicString
|
|
244
|
+
.replace(/\bAND\b/g, 'and')
|
|
245
|
+
.replace(/\bOR\b/g, 'or')
|
|
246
|
+
.replace(/\bNOT\b/g, 'not'), onChange: (e) => {
|
|
247
|
+
setLogicString(e.target.value);
|
|
248
|
+
setCachedLogicString(e.target.value);
|
|
249
|
+
}, onBlur: () => validateLogicString(logicString), status: logicError !== null ? 'error' : undefined, info: logicError, required: true }) }) }))] }));
|
|
270
250
|
};
|
|
271
251
|
ConditionBuilder.defaultProps = defaultProps;
|
|
272
252
|
export default ConditionBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionBuilder.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Fragment, useState, useReducer, useImperativeHandle, useRef, useEffect } from 'react';\nimport type { FunctionComponent, ChangeEvent } from 'react';\n\nimport {\n Banner,\n Button,\n Flex,\n Icon,\n Input,\n MenuButton,\n hasProp,\n useI18n,\n getFocusables,\n useLiveLog\n} from '@pega/cosmos-react-core';\nimport type { ForwardProps, BannerHandleValue } from '@pega/cosmos-react-core';\n\nimport AtomicCondition, { isValidCondition } from './AtomicCondition';\nimport type ConditionBuilderProps from './ConditionBuilder.types';\nimport type { Condition, HandleValue, LeafCondition } from './ConditionBuilder.types';\nimport {\n splitConditionForBuilder,\n parseLogicString,\n disambiguateLogic,\n isBasicModeApplicable,\n getBasicModeOperators,\n getLogicFromBasicMode\n} from './core/utils';\nimport rowsReducer, { INSERT_ROW, UPDATE_ROW, REMOVE_ROW } from './core/rows-reducer';\nimport type { RHSType } from './core/types';\nimport {\n StyledRowWithSeparator,\n StyledRow,\n StyledLabel,\n StyledConditionBuilder\n} from './ConditionBuilder.styles';\n\n// Default props for the builder\nconst defaultProps: Partial<ConditionBuilderProps> = {\n condition: {\n condition: {\n comparator: 'IS_NOT_NULL',\n lhs: { field: '' }\n }\n }\n};\n\n// Component for the builder\nconst ConditionBuilder: FunctionComponent<ConditionBuilderProps & ForwardProps> = (\n props: ConditionBuilderProps\n) => {\n const {\n fields,\n condition: seedCondition,\n validComparators,\n validRhsTypes = new Set<RHSType>(['LITERAL', 'FIELD']),\n dateFunctions,\n disallowNOT,\n handle\n } = props;\n\n // Split the condition tree into a logic-string and a list of condition-rows.\n const clonedCondition: Condition = JSON.parse(JSON.stringify(seedCondition)); // Cloning to avoid modifying the original\n const { logic: seedLogic, rows: seedRows } = splitConditionForBuilder(clonedCondition);\n\n // On load, look to use the Basic-mode if the seed-condition is simple enough\n const [isBasicMode, setBasicMode] = useState(() => isBasicModeApplicable(clonedCondition));\n const [operatorsList, setOperatorsList] = useState(() => getBasicModeOperators(seedLogic)); // Operators-list used in Basic-mode to render dropdowns between the rows. NOTE: When in Advanced-mode, this can contain stale values.\n const [logicString, setLogicString] = useState(seedLogic); // Logic-string used in Advanced-mode. NOTE: When in Basic-mode, this can contain stale values.\n const [conditionRows, dispatch] = useReducer(rowsReducer, seedRows); // Conditions-rows\n const [logicError, setLogicError] = useState<string | null>(null); // Used to indicate errors in the logic string\n const [showModeWarning, setModeWarning] = useState(false); // Used to warn user about losing information when moving away from Advanced mode\n const [showErrorIndicators, setErrorIndicators] = useState(false); // Used to enable inline error indicators in the condition rows\n const enableShading =\n isBasicMode && operatorsList.includes('AND') && operatorsList.includes('OR'); // In Basic mode, enable shading to indicate grouping only when both operators are present\n\n const newOperatorButtonRef = useRef<HTMLButtonElement | null>(null);\n const focusRowRef = useRef<HTMLElement | null>(null);\n const [focusRowIndex, setFocusRowIndex] = useState<number | null>(null);\n const bannerHandleRef = useRef<BannerHandleValue>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n // Upon adding/removing rows in Advanced mode, update the logic string to reflect the change in labels\n // NOTE: The input is updated only if the previous logicString was simple enough\n const updateLogicString = (actionType: string): void => {\n const numNewRows =\n actionType === INSERT_ROW ? conditionRows.length + 1 : conditionRows.length - 1;\n\n // If only one row left after the action, simply use its label as logicString\n // NOTE: If none left, the rowsReducer adds a new empty row\n if (numNewRows <= 1) {\n setLogicString('1');\n return;\n }\n\n // If the previous string was a simple AND/OR between all the rows, update the logicString to follow the same for the new list of rows.\n // If the previous string was a single token like `1` and a new row is inserted, do an AND between the new rows, i.e. `1 AND 2`\n // For all other complex cases, skip automatically updating the string and wait for the user to change it\n // To check this, split the previous string by `OR/AND` and check if each of the resultant token is a simple numeric token\n const splitter = logicString.includes('OR') ? 'OR' : 'AND';\n const tokens = logicString.split(splitter);\n const isEveryTokenInteger = tokens.every(w => /^\\d+$/.test(w.trim()));\n if (isEveryTokenInteger) {\n setLogicString(\n new Array(numNewRows)\n .fill(0)\n .map((w, i) => i + 1)\n .join(` ${splitter} `)\n );\n }\n };\n\n // Manages the focus behavior when inserting/removing a row\n useEffect(() => {\n if (focusRowIndex === null) return;\n\n if (newOperatorButtonRef.current) {\n newOperatorButtonRef.current.focus();\n newOperatorButtonRef.current = null;\n } else if (focusRowIndex !== null) {\n getFocusables(focusRowRef)[0]?.focus();\n }\n\n setFocusRowIndex(null);\n }, [focusRowIndex]);\n\n // Insert a new row at the given index\n const insertRow = (insertAt: number): void => {\n dispatch({ type: INSERT_ROW, payload: { insertAt } }); // Insert an entry in conditionRows\n if (isBasicMode) {\n // Set up a new AND/OR selector\n const insertOpAt = insertAt - 1; // Using `insertAt-1` since the operatorsList has one less entry compared to the conditionRows\n setOperatorsList([\n ...operatorsList.slice(0, insertOpAt),\n 'AND',\n ...operatorsList.slice(insertOpAt)\n ]);\n } else {\n updateLogicString(INSERT_ROW); // Update the logicString input to reflect the insertion\n }\n setFocusRowIndex(insertAt);\n };\n\n // Remove the row at the given index\n const removeRow = (removeAt: number): void => {\n dispatch({ type: REMOVE_ROW, payload: { removeAt } }); // Remove an entry in conditionRows\n if (isBasicMode) {\n // Remove an AND/OR selector\n if (removeAt === 0) {\n // If removing the first of the condition rows, remove the extraneous operator\n setOperatorsList(operatorsList.slice(1));\n } else {\n let removeOpAt = removeAt - 1; // Using `removeAt-1` since the operatorsList has one less entry compared to the conditionRows\n if (operatorsList[removeOpAt] === 'OR' && operatorsList[removeOpAt + 1] === 'AND') {\n // If removing a condition at the start of a nested group, remove the first operator from that group. e.g. Take `(1 AND 2) OR (3 AND 4 AND 5)`. If `3` is being deleted, it should become `(1 AND 2) OR (4 AND 5)` instead of `1 AND 2 AND 4 AND 5`\n removeOpAt += 1;\n }\n setOperatorsList([\n ...operatorsList.slice(0, removeOpAt),\n ...operatorsList.slice(removeOpAt + 1)\n ]);\n }\n } else {\n updateLogicString(REMOVE_ROW); // Update the logicString input to reflect the removal\n }\n setFocusRowIndex(() => {\n if (removeAt !== 0 && removeAt === conditionRows.length - 1) {\n return removeAt - 1;\n }\n\n return removeAt;\n });\n };\n\n // Update a Basic-mode operator at the given index\n const updateOperator = (updateAt: number, newValue: 'AND' | 'OR'): void => {\n setOperatorsList([\n ...operatorsList.slice(0, updateAt),\n newValue,\n ...operatorsList.slice(updateAt + 1)\n ]);\n };\n\n // Validate the logic input. Called upon clicking outside the textBox or upon submission.\n // If the expression is invalid, shows appropriate feedback and returns null.\n // If the expression is valid, formats it by setting up brackets at necessary places (to clear any ambiguities e.g. `1 AND 2 OR 3` is formatted as `(1 AND 2) OR 3` ). Returns a save-ready condition\n const validateLogicString = (logicToUse: string): Condition | null => {\n // Set up a lookup with row-labels as keys and rows as values\n const conditionLookup: { [label: string]: LeafCondition } = {};\n conditionRows.forEach(row => {\n const { id, label, ...leaf } = row; // Discard the extra properties added by ConditionRow to the LeafCondition interface\n conditionLookup[row.label] = leaf;\n });\n\n // Convert the logic string into a condition tree\n const parseResult = parseLogicString(logicToUse, conditionLookup, disallowNOT);\n\n // Indicate any parse error\n if (hasProp(parseResult, 'error')) {\n setLogicError(parseResult.error);\n return null;\n }\n\n // If no errors\n setLogicError(null); // Clear any previous error\n setLogicString(disambiguateLogic(logicToUse)); // Disambiguating the logic string by placing parentheses at appropriate places\n return parseResult.condition;\n };\n\n // Toggle between the Basic and Advanced modes\n // `forceToggle:true` is passed when switching from Advanced to Basic mode despite a loss of information\n const toggleMode = (forceToggle?: boolean): void => {\n setModeWarning(false); // Clear any previous warning\n if (isBasicMode) {\n // Update the logicString to match the operatorsList before switching the mode\n setLogicString(getLogicFromBasicMode(operatorsList));\n setBasicMode(false);\n } else if (forceToggle) {\n // If forcibly toggling from Advanced to Basic despite a loss of operators\n // Set up the default `AND` operator between all rows before switching to Basic mode\n setOperatorsList(new Array(conditionRows.length - 1).fill('AND'));\n setBasicMode(true);\n } else {\n // If switching from Advanced mode\n const condition = validateLogicString(logicString); // Validate the logicString. If it is an invalid, an appropriate error is shown for the user to act on\n if (condition !== null) {\n // If it's a valid condition, check if it's simple enough to be shown in Basic mode without any loss of information\n if (isBasicModeApplicable(condition)) {\n // If the logic is simple enough, identify the new set of operators before switching to Basic mode\n setOperatorsList(getBasicModeOperators(logicString));\n setBasicMode(true);\n } else {\n // If the logic is too complex show a warning for the user to act on\n setModeWarning(true);\n }\n }\n }\n };\n\n const getCondition: HandleValue['getCondition'] = () => {\n setErrorIndicators(false); // Reset any previous flag\n setLogicError(null); // Clear any previous error\n\n // If there's a single empty condition, submit with an `undefined` value (useful for clearing a previous condition)\n if (conditionRows.length === 1 && conditionRows[0].lhs.field === '') {\n return [true, undefined];\n }\n\n // Identify and indicate any invalid values in the condition rows\n const hasInvalidRows = conditionRows.some(row => !isValidCondition(row, fields, true));\n if (hasInvalidRows) {\n setErrorIndicators(true); // Enable inline error indications\n return [false];\n }\n\n // Validate the Logic string\n const logicToUse = isBasicMode ? getLogicFromBasicMode(operatorsList) : logicString; // If in Basic-mode, construct a different logicString based on the operatorsList\n const condition = validateLogicString(logicToUse); // This also takes care of showing an appropriate error feedback as needed\n if (condition !== null) {\n // Can be null when the logic string has errors\n return [true, condition];\n }\n\n return [false];\n };\n\n useImperativeHandle(\n handle,\n () => ({\n getCondition\n }),\n [getCondition]\n );\n\n const t = useI18n();\n\n useEffect(() => {\n if (showModeWarning) bannerHandleRef.current?.focus();\n }, [showModeWarning]);\n\n const { announceAssertive } = useLiveLog();\n\n useEffect(() => {\n announceAssertive({ message: t('condition_builder_mode_switch') });\n }, [isBasicMode]);\n\n return (\n <StyledConditionBuilder container={{ direction: 'column', gap: 4 }}>\n {/* Condition Rows */}\n <div>\n {conditionRows.map(({ id, label, ...leaf }, index) => {\n const deleteAriaLabel = `${t('condition_builder_field_label')} ${leaf.lhs.field\n .split('.')\n .pop()}`;\n\n let alignItems = 'end';\n if (showErrorIndicators && !isValidCondition(leaf, fields, false)) {\n alignItems = 'center';\n }\n\n return (\n <Fragment key={id}>\n {/* Row with the operator dropdown in Basic mode */}\n {isBasicMode && index > 0 && (\n <StyledRowWithSeparator\n container\n shaded={enableShading && operatorsList[index - 1] === 'AND'}\n >\n <MenuButton\n popover={{ hideOnTargetHidden: false }}\n text={operatorsList[index - 1].toLowerCase()}\n variant='simple'\n menu={{\n items: [\n {\n id: 'AND',\n primary: 'and',\n onClick: () => updateOperator(index - 1, 'AND')\n },\n {\n id: 'OR',\n primary: 'or',\n onClick: () => updateOperator(index - 1, 'OR')\n }\n ]\n }}\n ref={index === focusRowIndex ? newOperatorButtonRef : null}\n />\n </StyledRowWithSeparator>\n )}\n\n {/* Row with the AtomicCondition */}\n <StyledRow\n container={{ gap: 0.5, alignItems }}\n shaded={isBasicMode && enableShading}\n ref={index === focusRowIndex ? focusRowRef : null}\n >\n {/* Label */}\n {!isBasicMode && <StyledLabel>{label}</StyledLabel>}\n\n {/* Condition controls */}\n <Flex item={{ grow: 1 }}>\n <AtomicCondition\n condition={leaf}\n fields={fields}\n indicateErrors={showErrorIndicators}\n validComparators={validComparators}\n dateFunctions={dateFunctions}\n onChange={(newCondition: LeafCondition) => {\n const newRow = { id, label, ...newCondition };\n dispatch({ type: UPDATE_ROW, payload: { updateAt: index, newRow } });\n }}\n validRhsTypes={validRhsTypes}\n />\n </Flex>\n\n {/* Row actions */}\n <Button\n icon\n variant='simple'\n onClick={() => insertRow(index + 1)}\n label={t('add_condition')}\n >\n <Icon name='plus' />\n </Button>\n <Button\n icon\n variant='simple'\n onClick={() => removeRow(index)}\n label={t('delete')}\n aria-label={deleteAriaLabel ? t('delete_noun', [deleteAriaLabel]) : undefined}\n >\n <Icon name='trash' />\n </Button>\n </StyledRow>\n </Fragment>\n );\n })}\n </div>\n\n {/* LogicString input */}\n {!isBasicMode && (\n <div>\n <Flex container={{ gap: 0.25, direction: 'column' }}>\n <Input\n label={t('condition_builder_advanced_condition_label')}\n additionalInfo={{\n heading: t('condition_builder_advanced_condition_label'),\n content: (\n <div>\n {t('condition_builder_advanced_condition_tooltip', [\n disallowNOT ? 'AND/OR' : 'AND/OR/NOT',\n disallowNOT ? '(1 OR 2) AND (3 OR 4 OR 5)' : '(1 AND 2) OR (3 AND NOT 4)'\n ])}\n </div>\n )\n }}\n type='text'\n placeholder={t('condition_builder_advanced_condition_placeholder')}\n value={logicString}\n onChange={(e: ChangeEvent<HTMLInputElement>) => setLogicString(e.target.value)}\n onBlur={() => validateLogicString(logicString)}\n status={logicError !== null ? 'error' : undefined}\n info={logicError}\n />\n </Flex>\n </div>\n )}\n\n {/* Submit block */}\n <Flex container={{ direction: 'column', gap: 2 }}>\n {/* Banner to show a warning when switching from Advanced to Basic mode */}\n {showModeWarning && (\n <Banner\n variant='warning'\n messages={[\n {\n label: t('condition_builder_switch_banner_text'),\n action: {\n text: t('condition_builder_confirm_button_label'),\n onClick: () => {\n toggleMode(true);\n buttonRef.current?.focus();\n }\n }\n }\n ]}\n onDismiss={() => {\n setModeWarning(false);\n buttonRef.current?.focus();\n }}\n handle={bannerHandleRef}\n />\n )}\n\n {/* Footer buttons */}\n <Flex container={{ justify: 'between' }}>\n <Button\n name='mode-switch'\n variant='simple'\n onClick={() => {\n toggleMode(false);\n }}\n aria-label={\n isBasicMode\n ? t('condition_builder_advanced_mode_button_aria_label')\n : t('condition_builder_basic_mode_button_aria_label')\n }\n ref={buttonRef}\n >\n {isBasicMode\n ? t('condition_builder_advanced_mode_button_label')\n : t('condition_builder_basic_mode_button_label')}\n </Button>\n </Flex>\n </Flex>\n </StyledConditionBuilder>\n );\n};\nConditionBuilder.defaultProps = defaultProps;\n\nexport default ConditionBuilder;\n"]}
|
|
1
|
+
{"version":3,"file":"ConditionBuilder.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Fragment, useState, useReducer, useImperativeHandle, useRef, useEffect } from 'react';\nimport type { FunctionComponent, ChangeEvent } from 'react';\n\nimport {\n Button,\n Flex,\n Icon,\n Input,\n MenuButton,\n hasProp,\n useI18n,\n getFocusables,\n useLiveLog,\n Switch\n} from '@pega/cosmos-react-core';\nimport type { ForwardProps } from '@pega/cosmos-react-core';\n\nimport AtomicCondition, { isValidCondition } from './AtomicCondition';\nimport type ConditionBuilderProps from './ConditionBuilder.types';\nimport type { Condition, HandleValue, LeafCondition } from './ConditionBuilder.types';\nimport {\n splitConditionForBuilder,\n parseLogicString,\n disambiguateLogic,\n isBasicModeApplicable,\n getBasicModeOperators,\n getLogicFromBasicMode\n} from './core/utils';\nimport rowsReducer, { INSERT_ROW, UPDATE_ROW, REMOVE_ROW } from './core/rows-reducer';\nimport type { RHSType } from './core/types';\nimport {\n StyledRowWithSeparator,\n StyledRow,\n StyledLabel,\n StyledConditionBuilder\n} from './ConditionBuilder.styles';\n\n// Default props for the builder\nconst defaultProps: Partial<ConditionBuilderProps> = {\n condition: {\n condition: {\n comparator: 'IS_NOT_NULL',\n lhs: { field: '' }\n }\n }\n};\n\n// Component for the builder\nconst ConditionBuilder: FunctionComponent<ConditionBuilderProps & ForwardProps> = (\n props: ConditionBuilderProps\n) => {\n const {\n fields,\n condition: seedCondition,\n validComparators,\n validRhsTypes = new Set<RHSType>(['LITERAL', 'FIELD']),\n dateFunctions,\n disallowNOT,\n handle\n } = props;\n\n // Split the condition tree into a logic-string and a list of condition-rows.\n const clonedCondition: Condition = JSON.parse(JSON.stringify(seedCondition)); // Cloning to avoid modifying the original\n const { logic: seedLogic, rows: seedRows } = splitConditionForBuilder(clonedCondition);\n\n // On load, look to use the Basic-mode if the seed-condition is simple enough\n const [isBasicMode, setBasicMode] = useState(() => isBasicModeApplicable(clonedCondition));\n const [operatorsList, setOperatorsList] = useState(() => getBasicModeOperators(seedLogic)); // Operators-list used in Basic-mode to render dropdowns between the rows. NOTE: When in Advanced-mode, this can contain stale values.\n const [logicString, setLogicString] = useState(seedLogic); // Logic-string used in Advanced-mode. NOTE: When in Basic-mode, this can contain stale values.\n const [cachedLogicString, setCachedLogicString] = useState(seedLogic); // Logic-string used to store the last valid logic-string in Advanced-mode. This is used to restore the logic-string when switching back from Basic-mode to Advanced-mode.\n const [conditionRows, dispatch] = useReducer(rowsReducer, seedRows); // Conditions-rows\n const [logicError, setLogicError] = useState<string | null>(null); // Used to indicate errors in the logic string\n const [showErrorIndicators, setErrorIndicators] = useState(false); // Used to enable inline error indicators in the condition rows\n const enableShading =\n isBasicMode && operatorsList.includes('AND') && operatorsList.includes('OR'); // In Basic mode, enable shading to indicate grouping only when both operators are present\n\n const newOperatorButtonRef = useRef<HTMLButtonElement | null>(null);\n const focusRowRef = useRef<HTMLElement | null>(null);\n const [focusRowIndex, setFocusRowIndex] = useState<number | null>(null);\n\n // Upon adding/removing rows in Advanced mode, update the logic string to reflect the change in labels\n // NOTE: The input is updated only if the previous logicString was simple enough\n const updateLogicString = (actionType: string): void => {\n const numNewRows =\n actionType === INSERT_ROW ? conditionRows.length + 1 : conditionRows.length - 1;\n\n // If only one row left after the action, simply use its label as logicString\n // NOTE: If none left, the rowsReducer adds a new empty row\n if (numNewRows <= 1) {\n setLogicString('1');\n return;\n }\n\n // If the previous string was a simple AND/OR between all the rows, update the logicString to follow the same for the new list of rows.\n // If the previous string was a single token like `1` and a new row is inserted, do an AND between the new rows, i.e. `1 AND 2`\n // For all other complex cases, skip automatically updating the string and wait for the user to change it\n // To check this, split the previous string by `OR/AND` and check if each of the resultant token is a simple numeric token\n const splitter = logicString.includes('OR') ? 'OR' : 'AND';\n const tokens = logicString.split(splitter);\n const isEveryTokenInteger = tokens.every(w => /^\\d+$/.test(w.trim()));\n if (isEveryTokenInteger) {\n setLogicString(\n new Array(numNewRows)\n .fill(0)\n .map((w, i) => i + 1)\n .join(` ${splitter} `)\n );\n }\n };\n\n // Manages the focus behavior when inserting/removing a row\n useEffect(() => {\n if (focusRowIndex === null) return;\n\n if (newOperatorButtonRef.current) {\n newOperatorButtonRef.current.focus();\n newOperatorButtonRef.current = null;\n } else if (focusRowIndex !== null) {\n getFocusables(focusRowRef)[0]?.focus();\n }\n\n setFocusRowIndex(null);\n }, [focusRowIndex]);\n\n // Insert a new row at the given index\n const insertRow = (insertAt: number): void => {\n dispatch({ type: INSERT_ROW, payload: { insertAt } }); // Insert an entry in conditionRows\n if (isBasicMode) {\n // Set up a new AND/OR selector\n const insertOpAt = insertAt - 1; // Using `insertAt-1` since the operatorsList has one less entry compared to the conditionRows\n setOperatorsList([\n ...operatorsList.slice(0, insertOpAt),\n 'AND',\n ...operatorsList.slice(insertOpAt)\n ]);\n } else {\n updateLogicString(INSERT_ROW); // Update the logicString input to reflect the insertion\n }\n setFocusRowIndex(insertAt);\n };\n\n // Remove the row at the given index\n const removeRow = (removeAt: number): void => {\n dispatch({ type: REMOVE_ROW, payload: { removeAt } }); // Remove an entry in conditionRows\n if (isBasicMode) {\n // Remove an AND/OR selector\n if (removeAt === 0) {\n // If removing the first of the condition rows, remove the extraneous operator\n setOperatorsList(operatorsList.slice(1));\n } else {\n let removeOpAt = removeAt - 1; // Using `removeAt-1` since the operatorsList has one less entry compared to the conditionRows\n if (operatorsList[removeOpAt] === 'OR' && operatorsList[removeOpAt + 1] === 'AND') {\n // If removing a condition at the start of a nested group, remove the first operator from that group. e.g. Take `(1 AND 2) OR (3 AND 4 AND 5)`. If `3` is being deleted, it should become `(1 AND 2) OR (4 AND 5)` instead of `1 AND 2 AND 4 AND 5`\n removeOpAt += 1;\n }\n setOperatorsList([\n ...operatorsList.slice(0, removeOpAt),\n ...operatorsList.slice(removeOpAt + 1)\n ]);\n }\n } else {\n updateLogicString(REMOVE_ROW); // Update the logicString input to reflect the removal\n }\n setFocusRowIndex(() => {\n if (removeAt !== 0 && removeAt === conditionRows.length - 1) {\n return removeAt - 1;\n }\n\n return removeAt;\n });\n };\n\n // Update a Basic-mode operator at the given index\n const updateOperator = (updateAt: number, newValue: 'AND' | 'OR'): void => {\n setCachedLogicString('');\n setOperatorsList([\n ...operatorsList.slice(0, updateAt),\n newValue,\n ...operatorsList.slice(updateAt + 1)\n ]);\n };\n\n // Validate the logic input. Called upon clicking outside the textBox or upon submission.\n // If the expression is invalid, shows appropriate feedback and returns null.\n // If the expression is valid, formats it by setting up brackets at necessary places (to clear any ambiguities e.g. `1 AND 2 OR 3` is formatted as `(1 AND 2) OR 3` ). Returns a save-ready condition\n const validateLogicString = (logicToUse: string): Condition | null => {\n // Set up a lookup with row-labels as keys and rows as values\n const conditionLookup: { [label: string]: LeafCondition } = {};\n conditionRows.forEach(row => {\n const { id, label, ...leaf } = row; // Discard the extra properties added by ConditionRow to the LeafCondition interface\n conditionLookup[row.label] = leaf;\n });\n\n // Convert the logic string into a condition tree\n const parseResult = parseLogicString(logicToUse, conditionLookup, disallowNOT);\n\n // Indicate any parse error\n if (hasProp(parseResult, 'error')) {\n setLogicError(parseResult.error);\n return null;\n }\n\n // If no errors\n setLogicError(null); // Clear any previous error\n setLogicString(disambiguateLogic(logicToUse)); // Disambiguating the logic string by placing parentheses at appropriate places\n setCachedLogicString(disambiguateLogic(logicToUse));\n return parseResult.condition;\n };\n\n // Toggle between the Basic and Advanced modes\n const toggleMode = (): void => {\n if (isBasicMode) {\n // Update the logicString to match the operatorsList before switching the mode\n setLogicString(cachedLogicString || getLogicFromBasicMode(operatorsList));\n setBasicMode(false);\n } else {\n // If switched from advanced to basic mode the condition will be stored until another action takes place\n setCachedLogicString(logicString);\n const condition = validateLogicString(logicString); // Validate the logicString. If it is an invalid, an appropriate error is shown for the user to act on\n if (condition !== null) {\n // If the logic is simple enough, identify the new set of operators before switching to Basic mode.\n // If the logic is too complex fallback to using 'AND' between all rows\n setOperatorsList(\n isBasicModeApplicable(condition)\n ? getBasicModeOperators(logicString)\n : new Array(conditionRows.length - 1).fill('AND')\n );\n setBasicMode(true);\n }\n }\n };\n\n const getCondition: HandleValue['getCondition'] = () => {\n setErrorIndicators(false); // Reset any previous flag\n setLogicError(null); // Clear any previous error\n\n // If there's a single empty condition, submit with an `undefined` value (useful for clearing a previous condition)\n if (conditionRows.length === 1 && conditionRows[0].lhs.field === '') {\n return [true, undefined];\n }\n\n // Identify and indicate any invalid values in the condition rows\n const hasInvalidRows = conditionRows.some(row => !isValidCondition(row, fields, true));\n if (hasInvalidRows) {\n setErrorIndicators(true); // Enable inline error indications\n return [false];\n }\n\n // Validate the Logic string\n const logicToUse = isBasicMode ? getLogicFromBasicMode(operatorsList) : logicString; // If in Basic-mode, construct a different logicString based on the operatorsList\n const condition = validateLogicString(logicToUse); // This also takes care of showing an appropriate error feedback as needed\n if (condition !== null) {\n // Can be null when the logic string has errors\n return [true, condition];\n }\n\n return [false];\n };\n\n useImperativeHandle(\n handle,\n () => ({\n getCondition\n }),\n [getCondition]\n );\n\n const t = useI18n();\n\n const { announceAssertive } = useLiveLog();\n\n useEffect(() => {\n announceAssertive({ message: t('condition_builder_mode_switch') });\n }, [isBasicMode]);\n\n return (\n <StyledConditionBuilder container={{ direction: 'column', gap: 1 }}>\n <Flex container>\n <Switch\n label={t('condition_builder_advanced_mode_button_label')}\n aria-label={t('condition_builder_advanced_mode_button_label')}\n on={!isBasicMode}\n onChange={() => {\n toggleMode();\n }}\n />\n </Flex>\n {/* Condition Rows */}\n <div role='group'>\n {conditionRows.map(({ id, label, ...leaf }, index) => {\n const rowIndexAriaLabel = `${t('condition_builder_row', [index + 1])}`;\n const deleteAriaLabel = `${t('condition_builder_field_label')} ${leaf.lhs.field\n .split('.')\n .pop()}`;\n\n let alignItems = 'end';\n if (showErrorIndicators && !isValidCondition(leaf, fields, false)) {\n alignItems = 'center';\n }\n\n return (\n <Fragment key={id}>\n {/* Row with the operator dropdown in Basic mode */}\n {isBasicMode && index > 0 && (\n <StyledRowWithSeparator\n container\n shaded={enableShading && operatorsList[index - 1] === 'AND'}\n >\n <MenuButton\n popover={{ hideOnTargetHidden: false }}\n text={operatorsList[index - 1] === 'AND' ? 'And' : 'Or'}\n variant='simple'\n menu={{\n items: [\n {\n id: 'AND',\n primary: 'And',\n onClick: () => updateOperator(index - 1, 'AND')\n },\n {\n id: 'OR',\n primary: 'Or',\n onClick: () => updateOperator(index - 1, 'OR')\n }\n ]\n }}\n ref={index === focusRowIndex ? newOperatorButtonRef : null}\n />\n </StyledRowWithSeparator>\n )}\n\n {/* Row with the AtomicCondition */}\n <StyledRow\n aria-label={rowIndexAriaLabel}\n container={{ gap: 0.5, alignItems }}\n shaded={isBasicMode && enableShading}\n ref={index === focusRowIndex ? focusRowRef : null}\n >\n {/* Label */}\n {!isBasicMode && <StyledLabel>{label}</StyledLabel>}\n\n {/* Condition controls */}\n <Flex item={{ grow: 1 }}>\n <AtomicCondition\n condition={leaf}\n fields={fields}\n indicateErrors={showErrorIndicators}\n validComparators={validComparators}\n dateFunctions={dateFunctions}\n onChange={(newCondition: LeafCondition) => {\n const newRow = { id, label, ...newCondition };\n dispatch({ type: UPDATE_ROW, payload: { updateAt: index, newRow } });\n }}\n validRhsTypes={validRhsTypes}\n />\n </Flex>\n\n {/* Row actions */}\n <Button\n icon\n variant='simple'\n onClick={() => {\n insertRow(index + 1);\n setCachedLogicString('');\n }}\n label={t('add_condition')}\n >\n <Icon name='plus' />\n </Button>\n <Button\n icon\n variant='simple'\n onClick={() => {\n removeRow(index);\n setCachedLogicString('');\n }}\n label={t('delete')}\n aria-label={deleteAriaLabel ? t('delete_noun', [deleteAriaLabel]) : undefined}\n >\n <Icon name='trash' />\n </Button>\n </StyledRow>\n </Fragment>\n );\n })}\n </div>\n\n {/* LogicString input */}\n {!isBasicMode && (\n <div>\n <Flex container={{ gap: 0.25, direction: 'column' }}>\n <Input\n label={t('condition_builder_advanced_condition_label')}\n additionalInfo={{\n heading: t('condition_builder_advanced_condition_label'),\n content: (\n <div>\n {t('condition_builder_advanced_condition_tooltip', [\n disallowNOT ? 'AND/OR' : 'AND/OR/NOT',\n disallowNOT ? '(1 OR 2) AND (3 OR 4 OR 5)' : '(1 AND 2) OR (3 AND NOT 4)'\n ])}\n </div>\n )\n }}\n type='text'\n placeholder={t('condition_builder_advanced_condition_placeholder')}\n value={logicString\n .replace(/\\bAND\\b/g, 'and')\n .replace(/\\bOR\\b/g, 'or')\n .replace(/\\bNOT\\b/g, 'not')}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n setLogicString(e.target.value);\n setCachedLogicString(e.target.value);\n }}\n onBlur={() => validateLogicString(logicString)}\n status={logicError !== null ? 'error' : undefined}\n info={logicError}\n required\n />\n </Flex>\n </div>\n )}\n </StyledConditionBuilder>\n );\n};\nConditionBuilder.defaultProps = defaultProps;\n\nexport default ConditionBuilder;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionBuilder.styles.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.styles.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,sBAAsB,kNAWjC,CAAC;AAKH,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"ConditionBuilder.styles.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.styles.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,sBAAsB,kNAWjC,CAAC;AAKH,eAAO,MAAM,SAAS,kNAOrB,CAAC;AAIF,eAAO,MAAM,yBAAyB,yGAIpC,CAAC;AAKH,eAAO,MAAM,sBAAsB,kNAgBlC,CAAC;AAKF,eAAO,MAAM,WAAW,yGASvB,CAAC;AAIF,eAAO,MAAM,qBAAqB,wNAkBhC,CAAC"}
|
|
@@ -13,6 +13,10 @@ StyledConditionBuilder.defaultProps = defaultThemeProp;
|
|
|
13
13
|
export const StyledRow = styled(Flex) `
|
|
14
14
|
padding: 0.25rem;
|
|
15
15
|
background: ${props => (props.shaded ? 'rgba(0, 0, 0, 0.05)' : 'transparent')};
|
|
16
|
+
|
|
17
|
+
&:first-of-type {
|
|
18
|
+
padding-top: 0;
|
|
19
|
+
}
|
|
16
20
|
`;
|
|
17
21
|
StyledRow.defaultProps = defaultThemeProp;
|
|
18
22
|
export const StyledTimePeriodContainer = styled.div(({ theme }) => {
|
|
@@ -24,22 +28,30 @@ StyledTimePeriodContainer.defaultProps = defaultThemeProp;
|
|
|
24
28
|
// Styled row-separators for Basic-mode
|
|
25
29
|
export const StyledRowWithSeparator = styled(StyledRow) `
|
|
26
30
|
padding: 0 0.25rem;
|
|
27
|
-
&::after
|
|
31
|
+
&::after,
|
|
32
|
+
&::before {
|
|
28
33
|
content: '';
|
|
29
34
|
flex-grow: 1;
|
|
30
|
-
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.
|
|
35
|
+
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.4) 60%, rgba(0, 0, 0, 0) 0%);
|
|
31
36
|
background-position: left center;
|
|
32
|
-
background-size:
|
|
37
|
+
background-size: 0.5rem 0.0625rem;
|
|
33
38
|
background-repeat: repeat-x;
|
|
34
39
|
}
|
|
40
|
+
|
|
41
|
+
&::before {
|
|
42
|
+
width: 1rem;
|
|
43
|
+
flex-grow: 0;
|
|
44
|
+
}
|
|
35
45
|
`;
|
|
36
46
|
StyledRowWithSeparator.defaultProps = defaultThemeProp;
|
|
37
47
|
// Styled label for the rows in Advanced-mode
|
|
38
48
|
export const StyledLabel = styled.div `
|
|
49
|
+
font-weight: bold;
|
|
39
50
|
line-height: 2rem;
|
|
40
51
|
height: 2rem;
|
|
41
52
|
width: 2rem;
|
|
42
53
|
min-width: 2rem;
|
|
54
|
+
margin-bottom: calc(0.125rem);
|
|
43
55
|
text-align: center;
|
|
44
56
|
background: rgba(0, 0, 0, 0.04);
|
|
45
57
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionBuilder.styles.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.styles.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,IAAI,EACJ,sBAAsB,EACtB,aAAa,EACd,MAAM,yBAAyB,CAAC;AAGjC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAClD,KAAK,EAAE,EACL,IAAI,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EACjD,EACF,EAAE,EAAE;IACH,OAAO,GAAG,CAAA;MACN,aAAa;6BACU,YAAY,CAAC,EAAE,sBAAsB,OAAO;0CAC/B,OAAO;;GAE9C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,sBAAsB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEvD,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;;gBAErB,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"ConditionBuilder.styles.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.styles.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,IAAI,EACJ,sBAAsB,EACtB,aAAa,EACd,MAAM,yBAAyB,CAAC;AAGjC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAClD,KAAK,EAAE,EACL,IAAI,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EACjD,EACF,EAAE,EAAE;IACH,OAAO,GAAG,CAAA;MACN,aAAa;6BACU,YAAY,CAAC,EAAE,sBAAsB,OAAO;0CAC/B,OAAO;;GAE9C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,sBAAsB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEvD,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;;gBAErB,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,aAAa,CAAC;;;;;CAK9E,CAAC;AAEF,SAAS,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IAChE,OAAO,GAAG,CAAA;aACC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE;GACxC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,yBAAyB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE1D,uCAAuC;AACvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;;;;;;;;;;;;;;;;CAgBtD,CAAC;AAEF,sBAAsB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEvD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;CASpC,CAAC;AAEF,WAAW,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE5C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EACvD,KAAK,EAAE,EACL,IAAI,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,EACjE,UAAU,EAAE,EAAE,IAAI,EAAE,EACrB,EACD,SAAS,EACV,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzD,OAAO,CACL,CAAC,SAAS;QACV,GAAG,CAAA;QACC,sBAAsB;qBACT,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAa,CAAC;uBAChD,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;uCACb,OAAO;;KAEzC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,qBAAqB,CAAC,YAAY,GAAG,gBAAgB,CAAC","sourcesContent":["import styled, { css } from 'styled-components';\n\nimport {\n calculateFontSize,\n defaultThemeProp,\n FieldGroup,\n Flex,\n StyledFieldGroupLegend,\n StyledPopover\n} from '@pega/cosmos-react-core';\nimport type { FontSize } from '@pega/cosmos-react-core';\n\nexport const StyledConditionBuilder = styled(Flex)(({\n theme: {\n base: { 'content-width': contentWidth, spacing }\n }\n}) => {\n return css`\n ${StyledPopover}:has(&) {\n min-inline-size: min(${contentWidth.lg}, calc(100vw - 4 * ${spacing}));\n max-inline-size: calc(100vw - 4 * ${spacing});\n }\n `;\n});\n\nStyledConditionBuilder.defaultProps = defaultThemeProp;\n\n// Styled wrapper for each Condition row\nexport const StyledRow = styled(Flex)`\n padding: 0.25rem;\n background: ${props => (props.shaded ? 'rgba(0, 0, 0, 0.05)' : 'transparent')};\n\n &:first-of-type {\n padding-top: 0;\n }\n`;\n\nStyledRow.defaultProps = defaultThemeProp;\n\nexport const StyledTimePeriodContainer = styled.div(({ theme }) => {\n return css`\n width: ${theme.base['content-width'].sm};\n `;\n});\n\nStyledTimePeriodContainer.defaultProps = defaultThemeProp;\n\n// Styled row-separators for Basic-mode\nexport const StyledRowWithSeparator = styled(StyledRow)`\n padding: 0 0.25rem;\n &::after,\n &::before {\n content: '';\n flex-grow: 1;\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.4) 60%, rgba(0, 0, 0, 0) 0%);\n background-position: left center;\n background-size: 0.5rem 0.0625rem;\n background-repeat: repeat-x;\n }\n\n &::before {\n width: 1rem;\n flex-grow: 0;\n }\n`;\n\nStyledRowWithSeparator.defaultProps = defaultThemeProp;\n\n// Styled label for the rows in Advanced-mode\nexport const StyledLabel = styled.div`\n font-weight: bold;\n line-height: 2rem;\n height: 2rem;\n width: 2rem;\n min-width: 2rem;\n margin-bottom: calc(0.125rem);\n text-align: center;\n background: rgba(0, 0, 0, 0.04);\n`;\n\nStyledLabel.defaultProps = defaultThemeProp;\n\nexport const StyledAtomicCondition = styled(FieldGroup)(({\n theme: {\n base: { 'font-size': fontSize, 'font-scale': fontScale, spacing },\n components: { text }\n },\n collapsed\n}) => {\n const fontSizes = calculateFontSize(fontSize, fontScale);\n return (\n !collapsed &&\n css`\n ${StyledFieldGroupLegend} {\n font-size: ${fontSizes[text.secondary['font-size'] as FontSize]};\n font-weight: ${text.secondary['font-weight']};\n margin-block-end: calc(0.5 * ${spacing});\n }\n `\n );\n});\n\nStyledAtomicCondition.defaultProps = defaultThemeProp;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pega/cosmos-react-condition-builder",
|
|
3
|
-
"version": "8.0.0-build.
|
|
3
|
+
"version": "8.0.0-build.55.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/pegasystems/cosmos-react.git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"build": "tsc -b tsconfig.build.json"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@pega/cosmos-react-core": "8.0.0-build.
|
|
25
|
+
"@pega/cosmos-react-core": "8.0.0-build.55.1",
|
|
26
26
|
"@types/react": "^17.0.62 || ^18.3.3",
|
|
27
27
|
"@types/react-dom": "^17.0.20 || ^18.3.0",
|
|
28
28
|
"@types/styled-components": "^5.1.26",
|