@servicetitan/dte-unlayer 0.96.0 → 0.97.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,0BAA0B;IACvC,MAAM,CAAC,EAAE,OAAO,kBAAkB,EAAE,YAAY,CAAC;CACpD;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,uCAgNtE,CAAC"}
|
|
@@ -41,15 +41,9 @@ export const DisplayConditionModal = (props)=>{
|
|
|
41
41
|
});
|
|
42
42
|
}, []);
|
|
43
43
|
const handleClose = useCallback(()=>{
|
|
44
|
-
|
|
45
|
-
var _request_data;
|
|
46
|
-
request.done((_request_data = request.data) !== null && _request_data !== void 0 ? _request_data : null);
|
|
47
|
-
setRequest(null);
|
|
48
|
-
}
|
|
44
|
+
setRequest(null);
|
|
49
45
|
setIsOpen(false);
|
|
50
|
-
}, [
|
|
51
|
-
request
|
|
52
|
-
]);
|
|
46
|
+
}, []);
|
|
53
47
|
const handleSave = useCallback(()=>{
|
|
54
48
|
if (!request) {
|
|
55
49
|
return;
|
|
@@ -169,6 +163,7 @@ export const DisplayConditionModal = (props)=>{
|
|
|
169
163
|
style: {
|
|
170
164
|
maxHeight: MODAL_CONTENT_MAX_HEIGHT,
|
|
171
165
|
overflowY: 'auto',
|
|
166
|
+
paddingRight: 8,
|
|
172
167
|
width: '100%'
|
|
173
168
|
},
|
|
174
169
|
children: [
|
|
@@ -190,7 +185,7 @@ export const DisplayConditionModal = (props)=>{
|
|
|
190
185
|
}),
|
|
191
186
|
/*#__PURE__*/ _jsxs(Flex, {
|
|
192
187
|
direction: "row",
|
|
193
|
-
alignItems: "
|
|
188
|
+
alignItems: "flex-end",
|
|
194
189
|
gap: "3",
|
|
195
190
|
style: {
|
|
196
191
|
flexWrap: 'wrap'
|
|
@@ -200,13 +195,16 @@ export const DisplayConditionModal = (props)=>{
|
|
|
200
195
|
size: "small",
|
|
201
196
|
subdued: true,
|
|
202
197
|
variant: "body",
|
|
198
|
+
style: {
|
|
199
|
+
paddingBottom: 10
|
|
200
|
+
},
|
|
203
201
|
children: "Select to show or hide selected component."
|
|
204
202
|
}),
|
|
205
203
|
/*#__PURE__*/ _jsx("div", {
|
|
206
204
|
style: {
|
|
207
205
|
width: 160
|
|
208
206
|
},
|
|
209
|
-
children: /*#__PURE__*/ _jsxs(Combobox, {
|
|
207
|
+
children: /*#__PURE__*/ _jsxs(Combobox.Select, {
|
|
210
208
|
...{
|
|
211
209
|
disableClearSelection: true
|
|
212
210
|
},
|
|
@@ -225,7 +223,7 @@ export const DisplayConditionModal = (props)=>{
|
|
|
225
223
|
onChange: handleBehaviorChange,
|
|
226
224
|
children: [
|
|
227
225
|
/*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
|
|
228
|
-
label: "
|
|
226
|
+
label: "",
|
|
229
227
|
placeholder: "Select..."
|
|
230
228
|
}),
|
|
231
229
|
/*#__PURE__*/ _jsx(Combobox.Content, {
|
|
@@ -244,36 +242,44 @@ export const DisplayConditionModal = (props)=>{
|
|
|
244
242
|
})
|
|
245
243
|
]
|
|
246
244
|
}),
|
|
247
|
-
/*#__PURE__*/ _jsx(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
children: "Complete each condition before saving. Data point and value are required, and numeric fields must contain a valid number."
|
|
245
|
+
/*#__PURE__*/ _jsx("div", {
|
|
246
|
+
style: {
|
|
247
|
+
padding: 8
|
|
248
|
+
},
|
|
249
|
+
children: /*#__PURE__*/ _jsx(ConditionGroupsSection, {
|
|
250
|
+
dataPointOptions: dataPointOptions,
|
|
251
|
+
groups: state.groups,
|
|
252
|
+
onAddGroup: addGroup,
|
|
253
|
+
onRemoveGroup: removeGroup,
|
|
254
|
+
onUpdateGroup: updateGroup
|
|
255
|
+
})
|
|
259
256
|
})
|
|
260
257
|
]
|
|
261
258
|
})
|
|
262
259
|
}),
|
|
263
|
-
/*#__PURE__*/
|
|
260
|
+
/*#__PURE__*/ _jsx(Dialog.Footer, {
|
|
264
261
|
sticky: true,
|
|
265
|
-
children:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
262
|
+
children: /*#__PURE__*/ _jsxs(Flex, {
|
|
263
|
+
justifyContent: "flex-end",
|
|
264
|
+
alignItems: "center",
|
|
265
|
+
gap: "3",
|
|
266
|
+
style: {
|
|
267
|
+
width: '100%'
|
|
268
|
+
},
|
|
269
|
+
children: [
|
|
270
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
271
|
+
appearance: "secondary",
|
|
272
|
+
onClick: handleClose,
|
|
273
|
+
children: "Cancel"
|
|
274
|
+
}),
|
|
275
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
276
|
+
appearance: "primary",
|
|
277
|
+
disabled: !canSave,
|
|
278
|
+
onClick: handleSave,
|
|
279
|
+
children: "Save Changes"
|
|
280
|
+
})
|
|
281
|
+
]
|
|
282
|
+
})
|
|
277
283
|
})
|
|
278
284
|
]
|
|
279
285
|
}), portalTarget);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ConditionGroupsSection } from './ConditionGroupsSection';\nimport { defaultGroup, defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport { ConditionGroup as ConditionGroupType, DisplayBehavior } from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\n\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\nexport interface DisplayConditionModalProps {\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(props.schema), [props.schema]);\n\n const portalTarget = useMemo(() => {\n if (typeof document === 'undefined') {\n return null;\n }\n return document.body;\n }, []);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n setState(parsed ?? defaultState());\n setIsOpen(true);\n });\n }, []);\n\n const handleClose = useCallback(() => {\n if (request) {\n request.done(request.data ?? null);\n setRequest(null);\n }\n setIsOpen(false);\n }, [request]);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const condition = buildUnlayerDisplayCondition(state);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const removeGroup = useCallback((index: number) => {\n setState(prev => ({\n ...prev,\n groups: (() => {\n const nextGroups = prev.groups.filter((_, i) => i !== index);\n if (nextGroups.length === 0) {\n return [defaultGroup()];\n }\n if (index === 0) {\n const { logicalOperator: unusedOp, ...firstGroup } = nextGroups[0];\n return [firstGroup, ...nextGroups.slice(1)];\n }\n return nextGroups;\n })(),\n }));\n }, []);\n\n const addGroup = useCallback(() => {\n setState(prev => ({\n ...prev,\n groups: [...prev.groups, { ...defaultGroup(), logicalOperator: 'and' }],\n }));\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const canSave = useMemo(() => {\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [dataPointOptions, state.groups]);\n\n if (!portalTarget || !isOpen) {\n return null;\n }\n\n return createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Rules and Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"6\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n width: '100%',\n }}\n >\n <Flex\n direction=\"column\"\n gap=\"3\"\n style={{\n borderBottom: '1px solid #e0e0e0',\n paddingBottom: 16,\n }}\n >\n <Text size=\"medium\" variant=\"body\" style={{ fontWeight: 'bold' }}>\n When conditions are met:\n </Text>\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to show or hide selected component.\n </Text>\n <div style={{ width: 160 }}>\n <Combobox\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: BehaviorOption | null) => item?.value ?? ''}\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger\n label=\"Behavior\"\n placeholder=\"Select...\"\n />\n <Combobox.Content>\n {({ items }: { items: BehaviorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox>\n </div>\n </Flex>\n </Flex>\n <ConditionGroupsSection\n dataPointOptions={dataPointOptions}\n groups={state.groups}\n onAddGroup={addGroup}\n onRemoveGroup={removeGroup}\n onUpdateGroup={updateGroup}\n />\n {!canSave && (\n <Text size=\"small\" subdued variant=\"body\">\n Complete each condition before saving. Data point and value are\n required, and numeric fields must contain a valid number.\n </Text>\n )}\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Dialog.CancelButton onClick={handleClose}>Cancel</Dialog.CancelButton>\n <Button appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","useCallback","useEffect","useMemo","useState","createPortal","ConditionGroupsSection","defaultGroup","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","DisplayConditionModal","props","request","setRequest","isOpen","setIsOpen","state","setState","dataPointOptions","schema","portalTarget","document","body","nextRequest","existing","data","parsed","handleClose","done","handleSave","condition","updateGroup","index","group","prev","next","groups","removeGroup","nextGroups","filter","_","i","length","logicalOperator","unusedOp","firstGroup","slice","addGroup","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","canSave","conditions","dataPointKey","operator","trimmedValue","trim","fieldType","fullKey","test","open","onClose","size","Header","Content","direction","gap","style","maxHeight","overflowY","width","borderBottom","paddingBottom","variant","fontWeight","alignItems","flexWrap","subdued","div","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","map","Item","onAddGroup","onRemoveGroup","onUpdateGroup","Footer","sticky","CancelButton","onClick","appearance","disabled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ConditionGroupsSection } from './ConditionGroupsSection';\nimport { defaultGroup, defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport { ConditionGroup as ConditionGroupType, DisplayBehavior } from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\nexport interface DisplayConditionModalProps {\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(props.schema), [props.schema]);\n\n const portalTarget = useMemo(() => {\n if (typeof document === 'undefined') {\n return null;\n }\n return document.body;\n }, []);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n setState(parsed ?? defaultState());\n setIsOpen(true);\n });\n }, []);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const condition = buildUnlayerDisplayCondition(state);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const removeGroup = useCallback((index: number) => {\n setState(prev => ({\n ...prev,\n groups: (() => {\n const nextGroups = prev.groups.filter((_, i) => i !== index);\n if (nextGroups.length === 0) {\n return [defaultGroup()];\n }\n if (index === 0) {\n const { logicalOperator: unusedOp, ...firstGroup } = nextGroups[0];\n return [firstGroup, ...nextGroups.slice(1)];\n }\n return nextGroups;\n })(),\n }));\n }, []);\n\n const addGroup = useCallback(() => {\n setState(prev => ({\n ...prev,\n groups: [...prev.groups, { ...defaultGroup(), logicalOperator: 'and' }],\n }));\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const canSave = useMemo(() => {\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [dataPointOptions, state.groups]);\n\n if (!portalTarget || !isOpen) {\n return null;\n }\n\n return createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Rules and Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"6\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <Flex\n direction=\"column\"\n gap=\"3\"\n style={{\n borderBottom: '1px solid #e0e0e0',\n paddingBottom: 16,\n }}\n >\n <Text size=\"medium\" variant=\"body\" style={{ fontWeight: 'bold' }}>\n When conditions are met:\n </Text>\n <Flex\n direction=\"row\"\n alignItems=\"flex-end\"\n gap=\"3\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\" style={{ paddingBottom: 10 }}>\n Select to show or hide selected component.\n </Text>\n <div style={{ width: 160 }}>\n <Combobox.Select\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: BehaviorOption | null) => item?.value ?? ''}\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger label=\"\" placeholder=\"Select...\" />\n <Combobox.Content>\n {({ items }: { items: BehaviorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n </Flex>\n </Flex>\n <div style={{ padding: 8 }}>\n <ConditionGroupsSection\n dataPointOptions={dataPointOptions}\n groups={state.groups}\n onAddGroup={addGroup}\n onRemoveGroup={removeGroup}\n onUpdateGroup={updateGroup}\n />\n </div>\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Flex\n justifyContent=\"flex-end\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ width: '100%' }}\n >\n <Button appearance=\"secondary\" onClick={handleClose}>\n Cancel\n </Button>\n <Button appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","useCallback","useEffect","useMemo","useState","createPortal","ConditionGroupsSection","defaultGroup","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","DisplayConditionModal","props","request","setRequest","isOpen","setIsOpen","state","setState","dataPointOptions","schema","portalTarget","document","body","nextRequest","existing","data","parsed","handleClose","handleSave","condition","done","updateGroup","index","group","prev","next","groups","removeGroup","nextGroups","filter","_","i","length","logicalOperator","unusedOp","firstGroup","slice","addGroup","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","canSave","conditions","dataPointKey","operator","trimmedValue","trim","fieldType","fullKey","test","open","onClose","size","Header","Content","direction","gap","style","maxHeight","overflowY","paddingRight","width","borderBottom","paddingBottom","variant","fontWeight","alignItems","flexWrap","subdued","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","map","Item","padding","onAddGroup","onRemoveGroup","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -13,7 +13,6 @@ const BEHAVIOR_OPTIONS = [
|
|
|
13
13
|
{ label: 'Hide', value: 'hide' },
|
|
14
14
|
] as const;
|
|
15
15
|
const NUMERIC_VALUE_RE = /^-?(?:\d+\.?\d*|\.\d+)$/;
|
|
16
|
-
|
|
17
16
|
type BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];
|
|
18
17
|
|
|
19
18
|
export interface DisplayConditionModalProps {
|
|
@@ -45,12 +44,9 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
45
44
|
}, []);
|
|
46
45
|
|
|
47
46
|
const handleClose = useCallback(() => {
|
|
48
|
-
|
|
49
|
-
request.done(request.data ?? null);
|
|
50
|
-
setRequest(null);
|
|
51
|
-
}
|
|
47
|
+
setRequest(null);
|
|
52
48
|
setIsOpen(false);
|
|
53
|
-
}, [
|
|
49
|
+
}, []);
|
|
54
50
|
|
|
55
51
|
const handleSave = useCallback(() => {
|
|
56
52
|
if (!request) {
|
|
@@ -147,6 +143,7 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
147
143
|
style={{
|
|
148
144
|
maxHeight: MODAL_CONTENT_MAX_HEIGHT,
|
|
149
145
|
overflowY: 'auto',
|
|
146
|
+
paddingRight: 8,
|
|
150
147
|
width: '100%',
|
|
151
148
|
}}
|
|
152
149
|
>
|
|
@@ -163,15 +160,15 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
163
160
|
</Text>
|
|
164
161
|
<Flex
|
|
165
162
|
direction="row"
|
|
166
|
-
alignItems="
|
|
163
|
+
alignItems="flex-end"
|
|
167
164
|
gap="3"
|
|
168
165
|
style={{ flexWrap: 'wrap' }}
|
|
169
166
|
>
|
|
170
|
-
<Text size="small" subdued variant="body">
|
|
167
|
+
<Text size="small" subdued variant="body" style={{ paddingBottom: 10 }}>
|
|
171
168
|
Select to show or hide selected component.
|
|
172
169
|
</Text>
|
|
173
170
|
<div style={{ width: 160 }}>
|
|
174
|
-
<Combobox
|
|
171
|
+
<Combobox.Select
|
|
175
172
|
{...({ disableClearSelection: true } as object)}
|
|
176
173
|
itemToKey={(item: BehaviorOption | null) => item?.value ?? ''}
|
|
177
174
|
itemToString={(item: BehaviorOption | null) =>
|
|
@@ -181,10 +178,7 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
181
178
|
selectedItem={selectedBehavior}
|
|
182
179
|
onChange={handleBehaviorChange}
|
|
183
180
|
>
|
|
184
|
-
<Combobox.SelectTrigger
|
|
185
|
-
label="Behavior"
|
|
186
|
-
placeholder="Select..."
|
|
187
|
-
/>
|
|
181
|
+
<Combobox.SelectTrigger label="" placeholder="Select..." />
|
|
188
182
|
<Combobox.Content>
|
|
189
183
|
{({ items }: { items: BehaviorOption[] }) => (
|
|
190
184
|
<Combobox.List>
|
|
@@ -200,30 +194,35 @@ export const DisplayConditionModal = (props: DisplayConditionModalProps) => {
|
|
|
200
194
|
</Combobox.List>
|
|
201
195
|
)}
|
|
202
196
|
</Combobox.Content>
|
|
203
|
-
</Combobox>
|
|
197
|
+
</Combobox.Select>
|
|
204
198
|
</div>
|
|
205
199
|
</Flex>
|
|
206
200
|
</Flex>
|
|
207
|
-
<
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Complete each condition before saving. Data point and value are
|
|
217
|
-
required, and numeric fields must contain a valid number.
|
|
218
|
-
</Text>
|
|
219
|
-
)}
|
|
201
|
+
<div style={{ padding: 8 }}>
|
|
202
|
+
<ConditionGroupsSection
|
|
203
|
+
dataPointOptions={dataPointOptions}
|
|
204
|
+
groups={state.groups}
|
|
205
|
+
onAddGroup={addGroup}
|
|
206
|
+
onRemoveGroup={removeGroup}
|
|
207
|
+
onUpdateGroup={updateGroup}
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
220
210
|
</Flex>
|
|
221
211
|
</Dialog.Content>
|
|
222
212
|
<Dialog.Footer sticky>
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
213
|
+
<Flex
|
|
214
|
+
justifyContent="flex-end"
|
|
215
|
+
alignItems="center"
|
|
216
|
+
gap="3"
|
|
217
|
+
style={{ width: '100%' }}
|
|
218
|
+
>
|
|
219
|
+
<Button appearance="secondary" onClick={handleClose}>
|
|
220
|
+
Cancel
|
|
221
|
+
</Button>
|
|
222
|
+
<Button appearance="primary" disabled={!canSave} onClick={handleSave}>
|
|
223
|
+
Save Changes
|
|
224
|
+
</Button>
|
|
225
|
+
</Flex>
|
|
227
226
|
</Dialog.Footer>
|
|
228
227
|
</Dialog>,
|
|
229
228
|
portalTarget,
|