@servicetitan/dte-unlayer 0.94.0 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/display-conditions/ConditionGroup.d.ts +12 -0
  2. package/dist/display-conditions/ConditionGroup.d.ts.map +1 -0
  3. package/dist/display-conditions/ConditionGroup.js +181 -0
  4. package/dist/display-conditions/ConditionGroup.js.map +1 -0
  5. package/dist/display-conditions/ConditionGroupsSection.d.ts +11 -0
  6. package/dist/display-conditions/ConditionGroupsSection.d.ts.map +1 -0
  7. package/dist/display-conditions/ConditionGroupsSection.js +71 -0
  8. package/dist/display-conditions/ConditionGroupsSection.js.map +1 -0
  9. package/dist/display-conditions/ConditionRow.d.ts +11 -0
  10. package/dist/display-conditions/ConditionRow.d.ts.map +1 -0
  11. package/dist/display-conditions/ConditionRow.js +206 -0
  12. package/dist/display-conditions/ConditionRow.js.map +1 -0
  13. package/dist/display-conditions/DisplayConditionModal.d.ts +5 -0
  14. package/dist/display-conditions/DisplayConditionModal.d.ts.map +1 -0
  15. package/dist/display-conditions/DisplayConditionModal.js +282 -0
  16. package/dist/display-conditions/DisplayConditionModal.js.map +1 -0
  17. package/dist/display-conditions/SeparatorWithChip.d.ts +6 -0
  18. package/dist/display-conditions/SeparatorWithChip.d.ts.map +1 -0
  19. package/dist/display-conditions/SeparatorWithChip.js +15 -0
  20. package/dist/display-conditions/SeparatorWithChip.js.map +1 -0
  21. package/dist/display-conditions/constants.d.ts +7 -0
  22. package/dist/display-conditions/constants.d.ts.map +1 -0
  23. package/dist/display-conditions/constants.js +22 -0
  24. package/dist/display-conditions/constants.js.map +1 -0
  25. package/dist/display-conditions/displayConditionController.d.ts +9 -0
  26. package/dist/display-conditions/displayConditionController.d.ts.map +1 -0
  27. package/dist/display-conditions/displayConditionController.js +29 -0
  28. package/dist/display-conditions/displayConditionController.js.map +1 -0
  29. package/dist/display-conditions/nunjucks.d.ts +8 -0
  30. package/dist/display-conditions/nunjucks.d.ts.map +1 -0
  31. package/dist/display-conditions/nunjucks.js +448 -0
  32. package/dist/display-conditions/nunjucks.js.map +1 -0
  33. package/dist/display-conditions/schemaDataPoints.d.ts +4 -0
  34. package/dist/display-conditions/schemaDataPoints.d.ts.map +1 -0
  35. package/dist/display-conditions/schemaDataPoints.js +18 -0
  36. package/dist/display-conditions/schemaDataPoints.js.map +1 -0
  37. package/dist/display-conditions/types.d.ts +130 -0
  38. package/dist/display-conditions/types.d.ts.map +1 -0
  39. package/dist/display-conditions/types.js +72 -0
  40. package/dist/display-conditions/types.js.map +1 -0
  41. package/dist/editor-core-source.d.ts +1 -1
  42. package/dist/editor-core-source.d.ts.map +1 -1
  43. package/dist/editor-core-source.js +1 -1
  44. package/dist/editor-core-source.js.map +1 -1
  45. package/dist/editor.d.ts.map +1 -1
  46. package/dist/editor.js +4 -0
  47. package/dist/editor.js.map +1 -1
  48. package/dist/shared/schema.d.ts +2 -0
  49. package/dist/shared/schema.d.ts.map +1 -1
  50. package/dist/shared/schema.js.map +1 -1
  51. package/dist/unlayer.d.ts.map +1 -1
  52. package/dist/unlayer.js +7 -0
  53. package/dist/unlayer.js.map +1 -1
  54. package/package.json +4 -2
  55. package/src/display-conditions/ConditionGroup.tsx +145 -0
  56. package/src/display-conditions/ConditionGroupsSection.tsx +64 -0
  57. package/src/display-conditions/ConditionRow.tsx +185 -0
  58. package/src/display-conditions/DisplayConditionModal.tsx +231 -0
  59. package/src/display-conditions/SeparatorWithChip.tsx +14 -0
  60. package/src/display-conditions/constants.ts +22 -0
  61. package/src/display-conditions/displayConditionController.ts +42 -0
  62. package/src/display-conditions/nunjucks.ts +503 -0
  63. package/src/display-conditions/schemaDataPoints.ts +33 -0
  64. package/src/display-conditions/types.ts +75 -0
  65. package/src/editor-core-source.ts +1 -1
  66. package/src/editor.tsx +2 -0
  67. package/src/shared/schema.ts +2 -0
  68. package/src/unlayer.tsx +9 -0
@@ -0,0 +1,12 @@
1
+ import { ConditionGroup as ConditionGroupType } from './types';
2
+ import type { DataPointOption } from './types';
3
+ export interface ConditionGroupProps {
4
+ canDelete: boolean;
5
+ dataPointOptions: DataPointOption[];
6
+ group: ConditionGroupType;
7
+ onDelete: () => void;
8
+ onUpdate: (g: ConditionGroupType) => void;
9
+ ruleIndex: number;
10
+ }
11
+ export declare function ConditionGroup({ canDelete, dataPointOptions, group, onDelete, onUpdate, ruleIndex, }: Readonly<ConditionGroupProps>): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=ConditionGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionGroup.d.ts","sourceRoot":"","sources":["../../src/display-conditions/ConditionGroup.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,IAAI,kBAAkB,EAAoC,MAAM,SAAS,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAC3B,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,GACZ,EAAE,QAAQ,CAAC,mBAAmB,CAAC,2CAuH/B"}
@@ -0,0 +1,181 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Flex, SegmentedControl, Text } from '@servicetitan/anvil2';
3
+ import PlusIcon from '@servicetitan/anvil2/assets/icons/material/round/add.svg';
4
+ import TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';
5
+ import { useCallback } from 'react';
6
+ import { ConditionRow } from './ConditionRow';
7
+ import { defaultCondition } from './constants';
8
+ export function ConditionGroup({ canDelete, dataPointOptions, group, onDelete, onUpdate, ruleIndex }) {
9
+ const addCondition = useCallback(()=>{
10
+ const newCondition = {
11
+ ...defaultCondition(),
12
+ logicalOperator: 'and'
13
+ };
14
+ onUpdate({
15
+ ...group,
16
+ conditions: [
17
+ ...group.conditions,
18
+ newCondition
19
+ ]
20
+ });
21
+ }, [
22
+ group,
23
+ onUpdate
24
+ ]);
25
+ const updateCondition = useCallback((index, c)=>{
26
+ const next = [
27
+ ...group.conditions
28
+ ];
29
+ next[index] = c;
30
+ onUpdate({
31
+ ...group,
32
+ conditions: next
33
+ });
34
+ }, [
35
+ group,
36
+ onUpdate
37
+ ]);
38
+ const removeCondition = useCallback((index)=>{
39
+ let next = group.conditions.filter((_, i)=>i !== index);
40
+ // If we removed the first condition, clear logicalOperator on the new first
41
+ if (index === 0 && next.length > 0) {
42
+ const { logicalOperator: unusedOp, ...rest } = next[0];
43
+ next = [
44
+ rest,
45
+ ...next.slice(1)
46
+ ];
47
+ }
48
+ onUpdate({
49
+ ...group,
50
+ conditions: next.length ? next : [
51
+ defaultCondition()
52
+ ]
53
+ });
54
+ }, [
55
+ group,
56
+ onUpdate
57
+ ]);
58
+ const handleLogicalOperatorChange = useCallback((conditionIndex, value)=>{
59
+ const next = [
60
+ ...group.conditions
61
+ ];
62
+ next[conditionIndex] = {
63
+ ...next[conditionIndex],
64
+ logicalOperator: value
65
+ };
66
+ onUpdate({
67
+ ...group,
68
+ conditions: next
69
+ });
70
+ }, [
71
+ group,
72
+ onUpdate
73
+ ]);
74
+ return /*#__PURE__*/ _jsxs(Flex, {
75
+ direction: "column",
76
+ gap: "2",
77
+ style: {
78
+ width: '100%'
79
+ },
80
+ children: [
81
+ /*#__PURE__*/ _jsxs(Flex, {
82
+ direction: "row",
83
+ alignItems: "center",
84
+ justifyContent: "space-between",
85
+ style: {
86
+ width: '100%'
87
+ },
88
+ children: [
89
+ /*#__PURE__*/ _jsxs(Text, {
90
+ size: "medium",
91
+ variant: "body",
92
+ style: {
93
+ fontWeight: 'bold'
94
+ },
95
+ children: [
96
+ "Rule ",
97
+ ruleIndex + 1
98
+ ]
99
+ }),
100
+ canDelete && /*#__PURE__*/ _jsx(Button, {
101
+ appearance: "ghost",
102
+ "aria-label": "Delete rule",
103
+ icon: {
104
+ before: TrashIcon
105
+ },
106
+ size: "large",
107
+ onClick: onDelete
108
+ })
109
+ ]
110
+ }),
111
+ /*#__PURE__*/ _jsxs(Flex, {
112
+ direction: "column",
113
+ gap: "3",
114
+ style: {
115
+ backgroundColor: '#fff',
116
+ border: '1px solid #e0e0e0',
117
+ borderRadius: 8,
118
+ padding: 12,
119
+ width: '100%'
120
+ },
121
+ children: [
122
+ group.conditions.map((c, i)=>{
123
+ var _c_logicalOperator;
124
+ return /*#__PURE__*/ _jsxs(Flex, {
125
+ direction: "column",
126
+ gap: "3",
127
+ style: {
128
+ padding: '8px 0'
129
+ },
130
+ children: [
131
+ i > 0 && /*#__PURE__*/ _jsx(Flex, {
132
+ justifyContent: "center",
133
+ alignItems: "center",
134
+ gap: "2",
135
+ children: /*#__PURE__*/ _jsxs(SegmentedControl, {
136
+ selected: (_c_logicalOperator = c.logicalOperator) !== null && _c_logicalOperator !== void 0 ? _c_logicalOperator : 'and',
137
+ onChange: (v)=>handleLogicalOperatorChange(i, v),
138
+ children: [
139
+ /*#__PURE__*/ _jsx(SegmentedControl.Segment, {
140
+ value: "and",
141
+ children: "And"
142
+ }),
143
+ /*#__PURE__*/ _jsx(SegmentedControl.Segment, {
144
+ value: "or",
145
+ children: "Or"
146
+ })
147
+ ]
148
+ })
149
+ }),
150
+ /*#__PURE__*/ _jsx(ConditionRow, {
151
+ canRemove: true,
152
+ condition: c,
153
+ dataPointOptions: dataPointOptions,
154
+ onChange: (next)=>updateCondition(i, next),
155
+ onRemove: ()=>removeCondition(i)
156
+ })
157
+ ]
158
+ }, c.id);
159
+ }),
160
+ /*#__PURE__*/ _jsx(Flex, {
161
+ justifyContent: "center",
162
+ style: {
163
+ paddingTop: 8,
164
+ width: '100%'
165
+ },
166
+ children: /*#__PURE__*/ _jsx(Button, {
167
+ appearance: "secondary",
168
+ icon: {
169
+ before: PlusIcon
170
+ },
171
+ onClick: addCondition,
172
+ children: "Add Condition"
173
+ })
174
+ })
175
+ ]
176
+ })
177
+ ]
178
+ });
179
+ }
180
+
181
+ //# sourceMappingURL=ConditionGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/display-conditions/ConditionGroup.tsx"],"sourcesContent":["import { Button, Flex, SegmentedControl, Text } from '@servicetitan/anvil2';\nimport PlusIcon from '@servicetitan/anvil2/assets/icons/material/round/add.svg';\nimport TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';\nimport { useCallback } from 'react';\nimport { ConditionRow } from './ConditionRow';\nimport { defaultCondition } from './constants';\nimport { ConditionGroup as ConditionGroupType, LogicalOperator, SingleCondition } from './types';\nimport type { DataPointOption } from './types';\n\nexport interface ConditionGroupProps {\n canDelete: boolean;\n dataPointOptions: DataPointOption[];\n group: ConditionGroupType;\n onDelete: () => void;\n onUpdate: (g: ConditionGroupType) => void;\n ruleIndex: number;\n}\n\nexport function ConditionGroup({\n canDelete,\n dataPointOptions,\n group,\n onDelete,\n onUpdate,\n ruleIndex,\n}: Readonly<ConditionGroupProps>) {\n const addCondition = useCallback(() => {\n const newCondition: SingleCondition = {\n ...defaultCondition(),\n logicalOperator: 'and',\n };\n onUpdate({\n ...group,\n conditions: [...group.conditions, newCondition],\n });\n }, [group, onUpdate]);\n\n const updateCondition = useCallback(\n (index: number, c: SingleCondition) => {\n const next = [...group.conditions];\n next[index] = c;\n onUpdate({ ...group, conditions: next });\n },\n [group, onUpdate],\n );\n\n const removeCondition = useCallback(\n (index: number) => {\n let next = group.conditions.filter((_, i) => i !== index);\n // If we removed the first condition, clear logicalOperator on the new first\n if (index === 0 && next.length > 0) {\n const { logicalOperator: unusedOp, ...rest } = next[0];\n next = [rest as SingleCondition, ...next.slice(1)];\n }\n onUpdate({\n ...group,\n conditions: next.length ? next : [defaultCondition()],\n });\n },\n [group, onUpdate],\n );\n\n const handleLogicalOperatorChange = useCallback(\n (conditionIndex: number, value: string) => {\n const next = [...group.conditions];\n next[conditionIndex] = {\n ...next[conditionIndex],\n logicalOperator: value as LogicalOperator,\n };\n onUpdate({ ...group, conditions: next });\n },\n [group, onUpdate],\n );\n\n return (\n <Flex direction=\"column\" gap=\"2\" style={{ width: '100%' }}>\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n style={{ width: '100%' }}\n >\n <Text size=\"medium\" variant=\"body\" style={{ fontWeight: 'bold' }}>\n Rule {ruleIndex + 1}\n </Text>\n {canDelete && (\n <Button\n appearance=\"ghost\"\n aria-label=\"Delete rule\"\n icon={{ before: TrashIcon }}\n size=\"large\"\n onClick={onDelete}\n />\n )}\n </Flex>\n <Flex\n direction=\"column\"\n gap=\"3\"\n style={{\n backgroundColor: '#fff',\n border: '1px solid #e0e0e0',\n borderRadius: 8,\n padding: 12,\n width: '100%',\n }}\n >\n {group.conditions.map((c, i) => (\n <Flex key={c.id} direction=\"column\" gap=\"3\" style={{ padding: '8px 0' }}>\n {i > 0 && (\n <Flex justifyContent=\"center\" alignItems=\"center\" gap=\"2\">\n <SegmentedControl\n selected={c.logicalOperator ?? 'and'}\n onChange={(v: string) => handleLogicalOperatorChange(i, v)}\n >\n <SegmentedControl.Segment value=\"and\">\n And\n </SegmentedControl.Segment>\n <SegmentedControl.Segment value=\"or\">\n Or\n </SegmentedControl.Segment>\n </SegmentedControl>\n </Flex>\n )}\n <ConditionRow\n canRemove\n condition={c}\n dataPointOptions={dataPointOptions}\n onChange={next => updateCondition(i, next)}\n onRemove={() => removeCondition(i)}\n />\n </Flex>\n ))}\n <Flex justifyContent=\"center\" style={{ paddingTop: 8, width: '100%' }}>\n <Button\n appearance=\"secondary\"\n icon={{ before: PlusIcon }}\n onClick={addCondition}\n >\n Add Condition\n </Button>\n </Flex>\n </Flex>\n </Flex>\n );\n}\n"],"names":["Button","Flex","SegmentedControl","Text","PlusIcon","TrashIcon","useCallback","ConditionRow","defaultCondition","ConditionGroup","canDelete","dataPointOptions","group","onDelete","onUpdate","ruleIndex","addCondition","newCondition","logicalOperator","conditions","updateCondition","index","c","next","removeCondition","filter","_","i","length","unusedOp","rest","slice","handleLogicalOperatorChange","conditionIndex","value","direction","gap","style","width","alignItems","justifyContent","size","variant","fontWeight","appearance","aria-label","icon","before","onClick","backgroundColor","border","borderRadius","padding","map","selected","onChange","v","Segment","canRemove","condition","onRemove","id","paddingTop"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ConditionGroup as ConditionGroupType } from './types';
2
+ import type { DataPointOption } from './types';
3
+ export interface ConditionGroupsSectionProps {
4
+ dataPointOptions: DataPointOption[];
5
+ groups: ConditionGroupType[];
6
+ onAddGroup: () => void;
7
+ onRemoveGroup: (index: number) => void;
8
+ onUpdateGroup: (index: number, group: ConditionGroupType) => void;
9
+ }
10
+ export declare function ConditionGroupsSection({ dataPointOptions, groups, onAddGroup, onRemoveGroup, onUpdateGroup, }: Readonly<ConditionGroupsSectionProps>): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=ConditionGroupsSection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionGroupsSection.d.ts","sourceRoot":"","sources":["../../src/display-conditions/ConditionGroupsSection.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,IAAI,kBAAkB,EAAmB,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,2BAA2B;IACxC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrE;AAED,wBAAgB,sBAAsB,CAAC,EACnC,gBAAgB,EAChB,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,GAChB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,2CA2CvC"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Flex, SegmentedControl } from '@servicetitan/anvil2';
3
+ import PlusIcon from '@servicetitan/anvil2/assets/icons/material/round/add.svg';
4
+ import { ConditionGroup } from './ConditionGroup';
5
+ export function ConditionGroupsSection({ dataPointOptions, groups, onAddGroup, onRemoveGroup, onUpdateGroup }) {
6
+ return /*#__PURE__*/ _jsxs(Flex, {
7
+ direction: "column",
8
+ gap: "4",
9
+ children: [
10
+ groups.map((group, index)=>{
11
+ var _group_logicalOperator;
12
+ return /*#__PURE__*/ _jsxs(Flex, {
13
+ direction: "column",
14
+ gap: "3",
15
+ children: [
16
+ index > 0 && /*#__PURE__*/ _jsx(Flex, {
17
+ justifyContent: "center",
18
+ alignItems: "center",
19
+ gap: "2",
20
+ style: {
21
+ padding: '12px'
22
+ },
23
+ children: /*#__PURE__*/ _jsxs(SegmentedControl, {
24
+ selected: (_group_logicalOperator = group.logicalOperator) !== null && _group_logicalOperator !== void 0 ? _group_logicalOperator : 'and',
25
+ onChange: (value)=>onUpdateGroup(index, {
26
+ ...group,
27
+ logicalOperator: value
28
+ }),
29
+ children: [
30
+ /*#__PURE__*/ _jsx(SegmentedControl.Segment, {
31
+ value: "and",
32
+ children: "And"
33
+ }),
34
+ /*#__PURE__*/ _jsx(SegmentedControl.Segment, {
35
+ value: "or",
36
+ children: "Or"
37
+ })
38
+ ]
39
+ })
40
+ }),
41
+ /*#__PURE__*/ _jsx(ConditionGroup, {
42
+ canDelete: groups.length > 1,
43
+ dataPointOptions: dataPointOptions,
44
+ group: group,
45
+ onDelete: ()=>onRemoveGroup(index),
46
+ onUpdate: (g)=>onUpdateGroup(index, g),
47
+ ruleIndex: index
48
+ })
49
+ ]
50
+ }, group.id);
51
+ }),
52
+ /*#__PURE__*/ _jsx(Flex, {
53
+ justifyContent: "center",
54
+ style: {
55
+ paddingTop: 8,
56
+ width: '100%'
57
+ },
58
+ children: /*#__PURE__*/ _jsx(Button, {
59
+ appearance: "secondary",
60
+ icon: {
61
+ before: PlusIcon
62
+ },
63
+ onClick: onAddGroup,
64
+ children: "Add Rule"
65
+ })
66
+ })
67
+ ]
68
+ });
69
+ }
70
+
71
+ //# sourceMappingURL=ConditionGroupsSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/display-conditions/ConditionGroupsSection.tsx"],"sourcesContent":["import { Button, Flex, SegmentedControl } from '@servicetitan/anvil2';\nimport PlusIcon from '@servicetitan/anvil2/assets/icons/material/round/add.svg';\nimport { ConditionGroup } from './ConditionGroup';\nimport { ConditionGroup as ConditionGroupType, LogicalOperator } from './types';\nimport type { DataPointOption } from './types';\n\nexport interface ConditionGroupsSectionProps {\n dataPointOptions: DataPointOption[];\n groups: ConditionGroupType[];\n onAddGroup: () => void;\n onRemoveGroup: (index: number) => void;\n onUpdateGroup: (index: number, group: ConditionGroupType) => void;\n}\n\nexport function ConditionGroupsSection({\n dataPointOptions,\n groups,\n onAddGroup,\n onRemoveGroup,\n onUpdateGroup,\n}: Readonly<ConditionGroupsSectionProps>) {\n return (\n <Flex direction=\"column\" gap=\"4\">\n {groups.map((group, index) => (\n <Flex key={group.id} direction=\"column\" gap=\"3\">\n {index > 0 && (\n <Flex\n justifyContent=\"center\"\n alignItems=\"center\"\n gap=\"2\"\n style={{ padding: '12px' }}\n >\n <SegmentedControl\n selected={group.logicalOperator ?? 'and'}\n onChange={(value: string) =>\n onUpdateGroup(index, {\n ...group,\n logicalOperator: value as LogicalOperator,\n })\n }\n >\n <SegmentedControl.Segment value=\"and\">And</SegmentedControl.Segment>\n <SegmentedControl.Segment value=\"or\">Or</SegmentedControl.Segment>\n </SegmentedControl>\n </Flex>\n )}\n <ConditionGroup\n canDelete={groups.length > 1}\n dataPointOptions={dataPointOptions}\n group={group}\n onDelete={() => onRemoveGroup(index)}\n onUpdate={g => onUpdateGroup(index, g)}\n ruleIndex={index}\n />\n </Flex>\n ))}\n <Flex justifyContent=\"center\" style={{ paddingTop: 8, width: '100%' }}>\n <Button appearance=\"secondary\" icon={{ before: PlusIcon }} onClick={onAddGroup}>\n Add Rule\n </Button>\n </Flex>\n </Flex>\n );\n}\n"],"names":["Button","Flex","SegmentedControl","PlusIcon","ConditionGroup","ConditionGroupsSection","dataPointOptions","groups","onAddGroup","onRemoveGroup","onUpdateGroup","direction","gap","map","group","index","justifyContent","alignItems","style","padding","selected","logicalOperator","onChange","value","Segment","canDelete","length","onDelete","onUpdate","g","ruleIndex","id","paddingTop","width","appearance","icon","before","onClick"],"mappings":";AAAA,SAASA,MAAM,EAAEC,IAAI,EAAEC,gBAAgB,QAAQ,uBAAuB;AACtE,OAAOC,cAAc,2DAA2D;AAChF,SAASC,cAAc,QAAQ,mBAAmB;AAYlD,OAAO,SAASC,uBAAuB,EACnCC,gBAAgB,EAChBC,MAAM,EACNC,UAAU,EACVC,aAAa,EACbC,aAAa,EACuB;IACpC,qBACI,MAACT;QAAKU,WAAU;QAASC,KAAI;;YACxBL,OAAOM,GAAG,CAAC,CAACC,OAAOC;oBAUUD;qCAT1B,MAACb;oBAAoBU,WAAU;oBAASC,KAAI;;wBACvCG,QAAQ,mBACL,KAACd;4BACGe,gBAAe;4BACfC,YAAW;4BACXL,KAAI;4BACJM,OAAO;gCAAEC,SAAS;4BAAO;sCAEzB,cAAA,MAACjB;gCACGkB,UAAUN,CAAAA,yBAAAA,MAAMO,eAAe,cAArBP,oCAAAA,yBAAyB;gCACnCQ,UAAU,CAACC,QACPb,cAAcK,OAAO;wCACjB,GAAGD,KAAK;wCACRO,iBAAiBE;oCACrB;;kDAGJ,KAACrB,iBAAiBsB,OAAO;wCAACD,OAAM;kDAAM;;kDACtC,KAACrB,iBAAiBsB,OAAO;wCAACD,OAAM;kDAAK;;;;;sCAIjD,KAACnB;4BACGqB,WAAWlB,OAAOmB,MAAM,GAAG;4BAC3BpB,kBAAkBA;4BAClBQ,OAAOA;4BACPa,UAAU,IAAMlB,cAAcM;4BAC9Ba,UAAUC,CAAAA,IAAKnB,cAAcK,OAAOc;4BACpCC,WAAWf;;;mBA5BRD,MAAMiB,EAAE;;0BAgCvB,KAAC9B;gBAAKe,gBAAe;gBAASE,OAAO;oBAAEc,YAAY;oBAAGC,OAAO;gBAAO;0BAChE,cAAA,KAACjC;oBAAOkC,YAAW;oBAAYC,MAAM;wBAAEC,QAAQjC;oBAAS;oBAAGkC,SAAS7B;8BAAY;;;;;AAMhG"}
@@ -0,0 +1,11 @@
1
+ import { SingleCondition } from './types';
2
+ import type { DataPointOption } from './types';
3
+ export interface ConditionRowProps {
4
+ canRemove: boolean;
5
+ condition: SingleCondition;
6
+ dataPointOptions: DataPointOption[];
7
+ onChange: (c: SingleCondition) => void;
8
+ onRemove: () => void;
9
+ }
10
+ export declare function ConditionRow({ canRemove, condition, dataPointOptions, onChange, onRemove, }: Readonly<ConditionRowProps>): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=ConditionRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionRow.d.ts","sourceRoot":"","sources":["../../src/display-conditions/ConditionRow.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoB,eAAe,EAA0C,MAAM,SAAS,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,eAAe,CAAC;IAC3B,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB;AAsBD,wBAAgB,YAAY,CAAC,EACzB,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,QAAQ,EACR,QAAQ,GACX,EAAE,QAAQ,CAAC,iBAAiB,CAAC,2CAgJ7B"}
@@ -0,0 +1,206 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Chip, Combobox, Flex, TextField } from '@servicetitan/anvil2';
3
+ import TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';
4
+ import { useMemo } from 'react';
5
+ import { NUMBER_OPERATORS, STRING_OPERATORS, VALUE_LESS_OPERATORS } from './types';
6
+ function sanitizeNumericInput(raw) {
7
+ // Allow only a single leading minus and one decimal separator.
8
+ let value = raw.replaceAll(/[^0-9.-]/g, '');
9
+ const isNegative = value.startsWith('-');
10
+ value = value.replaceAll('-', '');
11
+ if (isNegative) {
12
+ value = `-${value}`;
13
+ }
14
+ const firstDot = value.indexOf('.');
15
+ if (firstDot >= 0) {
16
+ value = `${value.slice(0, firstDot + 1)}${value.slice(firstDot + 1).replaceAll('.', '')}`;
17
+ }
18
+ return value;
19
+ }
20
+ export function ConditionRow({ canRemove, condition, dataPointOptions, onChange, onRemove }) {
21
+ const selectedDataPoint = useMemo(()=>{
22
+ var _dataPointOptions_find;
23
+ return (_dataPointOptions_find = dataPointOptions.find((opt)=>opt.fullKey === condition.dataPointKey)) !== null && _dataPointOptions_find !== void 0 ? _dataPointOptions_find : null;
24
+ }, [
25
+ dataPointOptions,
26
+ condition.dataPointKey
27
+ ]);
28
+ var _selectedDataPoint_fieldType;
29
+ const fieldType = (_selectedDataPoint_fieldType = selectedDataPoint === null || selectedDataPoint === void 0 ? void 0 : selectedDataPoint.fieldType) !== null && _selectedDataPoint_fieldType !== void 0 ? _selectedDataPoint_fieldType : 'string';
30
+ const operatorItems = useMemo(()=>fieldType === 'number' ? [
31
+ ...NUMBER_OPERATORS
32
+ ] : [
33
+ ...STRING_OPERATORS
34
+ ], [
35
+ fieldType
36
+ ]);
37
+ const selectedOperator = useMemo(()=>{
38
+ var _operatorItems_find;
39
+ return (_operatorItems_find = operatorItems.find((op)=>op.value === condition.operator)) !== null && _operatorItems_find !== void 0 ? _operatorItems_find : null;
40
+ }, [
41
+ operatorItems,
42
+ condition.operator
43
+ ]);
44
+ const isValueLess = VALUE_LESS_OPERATORS.includes(condition.operator);
45
+ const handleValueChange = (raw)=>{
46
+ const value = fieldType === 'number' ? sanitizeNumericInput(raw) : raw;
47
+ onChange({
48
+ ...condition,
49
+ value
50
+ });
51
+ };
52
+ const handleDataPointChange = (item)=>{
53
+ var _item_fieldType;
54
+ const nextFieldType = (_item_fieldType = item === null || item === void 0 ? void 0 : item.fieldType) !== null && _item_fieldType !== void 0 ? _item_fieldType : 'string';
55
+ const nextIsNumber = nextFieldType === 'number';
56
+ const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;
57
+ const operatorReset = !nextOperatorItems.some((op)=>op.value === condition.operator);
58
+ var _item_fullKey;
59
+ onChange({
60
+ ...condition,
61
+ dataPointKey: (_item_fullKey = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _item_fullKey !== void 0 ? _item_fullKey : '',
62
+ operator: operatorReset ? nextIsNumber ? 'num_eq' : 'is_equal_to' : condition.operator
63
+ });
64
+ };
65
+ return /*#__PURE__*/ _jsxs(Flex, {
66
+ direction: "row",
67
+ alignItems: "flex-end",
68
+ gap: "2",
69
+ style: {
70
+ flexWrap: 'wrap',
71
+ rowGap: 8,
72
+ width: '100%'
73
+ },
74
+ children: [
75
+ /*#__PURE__*/ _jsx("div", {
76
+ style: {
77
+ display: 'flex',
78
+ alignItems: 'flex-end',
79
+ flexShrink: 0,
80
+ padding: '6px 12px'
81
+ },
82
+ children: /*#__PURE__*/ _jsx(Chip, {
83
+ label: "IF",
84
+ size: "medium"
85
+ })
86
+ }),
87
+ /*#__PURE__*/ _jsx("div", {
88
+ style: {
89
+ flex: '2 1 280px',
90
+ minWidth: 240
91
+ },
92
+ children: /*#__PURE__*/ _jsxs(Combobox, {
93
+ ...{
94
+ disableClearSelection: true
95
+ },
96
+ itemToKey: (item)=>{
97
+ var _item_fullKey;
98
+ return (_item_fullKey = item === null || item === void 0 ? void 0 : item.fullKey) !== null && _item_fullKey !== void 0 ? _item_fullKey : '';
99
+ },
100
+ itemToString: (item)=>{
101
+ var _item_title;
102
+ return (_item_title = item === null || item === void 0 ? void 0 : item.title) !== null && _item_title !== void 0 ? _item_title : '';
103
+ },
104
+ items: dataPointOptions,
105
+ selectedItem: selectedDataPoint,
106
+ onChange: handleDataPointChange,
107
+ children: [
108
+ /*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
109
+ label: "Data point",
110
+ placeholder: "Select data point..."
111
+ }),
112
+ /*#__PURE__*/ _jsx(Combobox.Content, {
113
+ children: ({ items })=>/*#__PURE__*/ _jsx(Combobox.List, {
114
+ children: items.map((item, i)=>/*#__PURE__*/ _jsx(Combobox.Item, {
115
+ index: i,
116
+ item: item,
117
+ children: item.title
118
+ }, item.fullKey))
119
+ })
120
+ })
121
+ ]
122
+ })
123
+ }),
124
+ /*#__PURE__*/ _jsx("div", {
125
+ style: {
126
+ flex: '1 1 220px',
127
+ minWidth: 180
128
+ },
129
+ children: /*#__PURE__*/ _jsxs(Combobox, {
130
+ ...{
131
+ disableClearSelection: true
132
+ },
133
+ itemToKey: (item)=>{
134
+ var _item_value;
135
+ return (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : '';
136
+ },
137
+ itemToString: (item)=>{
138
+ var _item_label;
139
+ return (_item_label = item === null || item === void 0 ? void 0 : item.label) !== null && _item_label !== void 0 ? _item_label : '';
140
+ },
141
+ items: operatorItems,
142
+ selectedItem: selectedOperator,
143
+ onChange: (item)=>{
144
+ var _item_value;
145
+ return onChange({
146
+ ...condition,
147
+ operator: (_item_value = item === null || item === void 0 ? void 0 : item.value) !== null && _item_value !== void 0 ? _item_value : 'is_equal_to'
148
+ });
149
+ },
150
+ children: [
151
+ /*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
152
+ label: "Condition",
153
+ placeholder: "Select..."
154
+ }),
155
+ /*#__PURE__*/ _jsx(Combobox.Content, {
156
+ children: ({ items })=>/*#__PURE__*/ _jsx(Combobox.List, {
157
+ children: items.map((item, i)=>/*#__PURE__*/ _jsx(Combobox.Item, {
158
+ index: i,
159
+ item: item,
160
+ children: item.label
161
+ }, item.value))
162
+ })
163
+ })
164
+ ]
165
+ })
166
+ }),
167
+ !isValueLess && /*#__PURE__*/ _jsx("div", {
168
+ style: {
169
+ flex: '1 1 220px',
170
+ minWidth: 180
171
+ },
172
+ children: /*#__PURE__*/ _jsx(TextField, {
173
+ label: "Value",
174
+ value: condition.value,
175
+ onChange: (e)=>handleValueChange(e.target.value),
176
+ placeholder: fieldType === 'number' ? 'e.g. 1.5' : 'Enter value...',
177
+ style: {
178
+ width: '100%'
179
+ },
180
+ "aria-label": "Value",
181
+ ...fieldType === 'number' && {
182
+ inputMode: 'decimal'
183
+ }
184
+ })
185
+ }),
186
+ canRemove && /*#__PURE__*/ _jsx("div", {
187
+ style: {
188
+ display: 'flex',
189
+ alignItems: 'flex-end',
190
+ flexShrink: 0,
191
+ padding: '6px 12px'
192
+ },
193
+ children: /*#__PURE__*/ _jsx(Button, {
194
+ appearance: "secondary",
195
+ "aria-label": "Remove condition",
196
+ icon: {
197
+ before: TrashIcon
198
+ },
199
+ onClick: onRemove
200
+ })
201
+ })
202
+ ]
203
+ });
204
+ }
205
+
206
+ //# sourceMappingURL=ConditionRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/display-conditions/ConditionRow.tsx"],"sourcesContent":["import { Button, Chip, Combobox, Flex, TextField } from '@servicetitan/anvil2';\nimport TrashIcon from '@servicetitan/anvil2/assets/icons/material/round/delete.svg';\nimport { useMemo } from 'react';\nimport { NUMBER_OPERATORS, SingleCondition, STRING_OPERATORS, VALUE_LESS_OPERATORS } from './types';\nimport type { DataPointOption } from './types';\n\nexport interface ConditionRowProps {\n canRemove: boolean;\n condition: SingleCondition;\n dataPointOptions: DataPointOption[];\n onChange: (c: SingleCondition) => void;\n onRemove: () => void;\n}\n\ninterface OperatorOption {\n label: string;\n value: string;\n}\n\nfunction sanitizeNumericInput(raw: string): string {\n // Allow only a single leading minus and one decimal separator.\n let value = raw.replaceAll(/[^0-9.-]/g, '');\n const isNegative = value.startsWith('-');\n value = value.replaceAll('-', '');\n if (isNegative) {\n value = `-${value}`;\n }\n const firstDot = value.indexOf('.');\n if (firstDot >= 0) {\n value = `${value.slice(0, firstDot + 1)}${value.slice(firstDot + 1).replaceAll('.', '')}`;\n }\n return value;\n}\n\nexport function ConditionRow({\n canRemove,\n condition,\n dataPointOptions,\n onChange,\n onRemove,\n}: Readonly<ConditionRowProps>) {\n const selectedDataPoint = useMemo(\n () => dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey) ?? null,\n [dataPointOptions, condition.dataPointKey],\n );\n\n const fieldType = selectedDataPoint?.fieldType ?? 'string';\n\n const operatorItems: OperatorOption[] = useMemo(\n () =>\n fieldType === 'number'\n ? ([...NUMBER_OPERATORS] as OperatorOption[])\n : ([...STRING_OPERATORS] as OperatorOption[]),\n [fieldType],\n );\n\n const selectedOperator = useMemo(\n () => operatorItems.find(op => op.value === condition.operator) ?? null,\n [operatorItems, condition.operator],\n );\n\n const isValueLess = VALUE_LESS_OPERATORS.includes(condition.operator);\n\n const handleValueChange = (raw: string) => {\n const value = fieldType === 'number' ? sanitizeNumericInput(raw) : raw;\n onChange({ ...condition, value });\n };\n\n const handleDataPointChange = (item: DataPointOption | null) => {\n const nextFieldType = item?.fieldType ?? 'string';\n const nextIsNumber = nextFieldType === 'number';\n const nextOperatorItems = nextIsNumber ? NUMBER_OPERATORS : STRING_OPERATORS;\n const operatorReset = !nextOperatorItems.some(op => op.value === condition.operator);\n onChange({\n ...condition,\n dataPointKey: item?.fullKey ?? '',\n operator: operatorReset\n ? nextIsNumber\n ? 'num_eq'\n : 'is_equal_to'\n : condition.operator,\n });\n };\n\n return (\n <Flex\n direction=\"row\"\n alignItems=\"flex-end\"\n gap=\"2\"\n style={{ flexWrap: 'wrap', rowGap: 8, width: '100%' }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '6px 12px',\n }}\n >\n <Chip label=\"IF\" size=\"medium\" />\n </div>\n <div style={{ flex: '2 1 280px', minWidth: 240 }}>\n <Combobox\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: DataPointOption | null) => item?.fullKey ?? ''}\n itemToString={(item: DataPointOption | null) => item?.title ?? ''}\n items={dataPointOptions}\n selectedItem={selectedDataPoint}\n onChange={handleDataPointChange}\n >\n <Combobox.SelectTrigger label=\"Data point\" placeholder=\"Select data point...\" />\n <Combobox.Content>\n {({ items }: { items: DataPointOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.fullKey}>\n {item.title}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox>\n </div>\n <div style={{ flex: '1 1 220px', minWidth: 180 }}>\n <Combobox\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: OperatorOption | null) => item?.value ?? ''}\n itemToString={(item: OperatorOption | null) => item?.label ?? ''}\n items={operatorItems}\n selectedItem={selectedOperator}\n onChange={(item: OperatorOption | null) =>\n onChange({\n ...condition,\n operator: (item?.value ?? 'is_equal_to') as SingleCondition['operator'],\n })\n }\n >\n <Combobox.SelectTrigger label=\"Condition\" placeholder=\"Select...\" />\n <Combobox.Content>\n {({ items }: { items: OperatorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item index={i} item={item} key={item.value}>\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox>\n </div>\n {!isValueLess && (\n <div style={{ flex: '1 1 220px', minWidth: 180 }}>\n <TextField\n label=\"Value\"\n value={condition.value}\n onChange={e => handleValueChange(e.target.value)}\n placeholder={fieldType === 'number' ? 'e.g. 1.5' : 'Enter value...'}\n style={{ width: '100%' }}\n aria-label=\"Value\"\n {...(fieldType === 'number' && { inputMode: 'decimal' })}\n />\n </div>\n )}\n {canRemove && (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n flexShrink: 0,\n padding: '6px 12px',\n }}\n >\n <Button\n appearance=\"secondary\"\n aria-label=\"Remove condition\"\n icon={{ before: TrashIcon }}\n onClick={onRemove}\n />\n </div>\n )}\n </Flex>\n );\n}\n"],"names":["Button","Chip","Combobox","Flex","TextField","TrashIcon","useMemo","NUMBER_OPERATORS","STRING_OPERATORS","VALUE_LESS_OPERATORS","sanitizeNumericInput","raw","value","replaceAll","isNegative","startsWith","firstDot","indexOf","slice","ConditionRow","canRemove","condition","dataPointOptions","onChange","onRemove","selectedDataPoint","find","opt","fullKey","dataPointKey","fieldType","operatorItems","selectedOperator","op","operator","isValueLess","includes","handleValueChange","handleDataPointChange","item","nextFieldType","nextIsNumber","nextOperatorItems","operatorReset","some","direction","alignItems","gap","style","flexWrap","rowGap","width","div","display","flexShrink","padding","label","size","flex","minWidth","disableClearSelection","itemToKey","itemToString","title","items","selectedItem","SelectTrigger","placeholder","Content","List","map","i","Item","index","e","target","aria-label","inputMode","appearance","icon","before","onClick"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface DisplayConditionModalProps {
2
+ schema?: import('../shared/schema').SchemaObject;
3
+ }
4
+ export declare const DisplayConditionModal: (props: DisplayConditionModalProps) => import("react").ReactPortal | null;
5
+ //# sourceMappingURL=DisplayConditionModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,0BAA0B;IACvC,MAAM,CAAC,EAAE,OAAO,kBAAkB,EAAE,YAAY,CAAC;CACpD;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,uCAgNtE,CAAC"}