@pega/cosmos-react-condition-builder 2.2.1 → 2.2.4

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 (105) hide show
  1. package/lib/components/ConditionBuilder/AtomicCondition.d.ts +51 -0
  2. package/lib/components/ConditionBuilder/AtomicCondition.d.ts.map +1 -0
  3. package/lib/components/ConditionBuilder/AtomicCondition.js +119 -0
  4. package/lib/components/ConditionBuilder/AtomicCondition.js.map +1 -0
  5. package/lib/components/ConditionBuilder/ConditionBuilder.d.ts +6 -0
  6. package/lib/components/ConditionBuilder/ConditionBuilder.d.ts.map +1 -0
  7. package/lib/components/ConditionBuilder/ConditionBuilder.js +234 -0
  8. package/lib/components/ConditionBuilder/ConditionBuilder.js.map +1 -0
  9. package/lib/components/ConditionBuilder/ConditionBuilder.types.d.ts +112 -0
  10. package/lib/components/ConditionBuilder/ConditionBuilder.types.d.ts.map +1 -0
  11. package/lib/components/ConditionBuilder/ConditionBuilder.types.js +2 -0
  12. package/lib/components/ConditionBuilder/ConditionBuilder.types.js.map +1 -0
  13. package/lib/components/ConditionBuilder/FieldCondition.d.ts +7 -0
  14. package/lib/components/ConditionBuilder/FieldCondition.d.ts.map +1 -0
  15. package/lib/components/ConditionBuilder/FieldCondition.js +26 -0
  16. package/lib/components/ConditionBuilder/FieldCondition.js.map +1 -0
  17. package/lib/components/ConditionBuilder/FieldCondition.types.d.ts +25 -0
  18. package/lib/components/ConditionBuilder/FieldCondition.types.d.ts.map +1 -0
  19. package/lib/components/ConditionBuilder/FieldCondition.types.js +2 -0
  20. package/lib/components/ConditionBuilder/FieldCondition.types.js.map +1 -0
  21. package/lib/components/ConditionBuilder/HelpButton.d.ts +10 -0
  22. package/lib/components/ConditionBuilder/HelpButton.d.ts.map +1 -0
  23. package/lib/components/ConditionBuilder/HelpButton.js +11 -0
  24. package/lib/components/ConditionBuilder/HelpButton.js.map +1 -0
  25. package/lib/components/ConditionBuilder/RhsControls/DateFunctionMenu.d.ts +18 -0
  26. package/lib/components/ConditionBuilder/RhsControls/DateFunctionMenu.d.ts.map +1 -0
  27. package/lib/components/ConditionBuilder/RhsControls/DateFunctionMenu.js +115 -0
  28. package/lib/components/ConditionBuilder/RhsControls/DateFunctionMenu.js.map +1 -0
  29. package/lib/components/ConditionBuilder/RhsControls/FieldSelector.d.ts +19 -0
  30. package/lib/components/ConditionBuilder/RhsControls/FieldSelector.d.ts.map +1 -0
  31. package/lib/components/ConditionBuilder/RhsControls/FieldSelector.js +67 -0
  32. package/lib/components/ConditionBuilder/RhsControls/FieldSelector.js.map +1 -0
  33. package/lib/components/ConditionBuilder/RhsControls/MultiValueSelector.d.ts +16 -0
  34. package/lib/components/ConditionBuilder/RhsControls/MultiValueSelector.d.ts.map +1 -0
  35. package/lib/components/ConditionBuilder/RhsControls/MultiValueSelector.js +43 -0
  36. package/lib/components/ConditionBuilder/RhsControls/MultiValueSelector.js.map +1 -0
  37. package/lib/components/ConditionBuilder/RhsControls/NumericInput.d.ts +18 -0
  38. package/lib/components/ConditionBuilder/RhsControls/NumericInput.d.ts.map +1 -0
  39. package/lib/components/ConditionBuilder/RhsControls/NumericInput.js +19 -0
  40. package/lib/components/ConditionBuilder/RhsControls/NumericInput.js.map +1 -0
  41. package/lib/components/ConditionBuilder/RhsControls/RelativeDateMenu.d.ts +18 -0
  42. package/lib/components/ConditionBuilder/RhsControls/RelativeDateMenu.d.ts.map +1 -0
  43. package/lib/components/ConditionBuilder/RhsControls/RelativeDateMenu.js +109 -0
  44. package/lib/components/ConditionBuilder/RhsControls/RelativeDateMenu.js.map +1 -0
  45. package/lib/components/ConditionBuilder/RhsControls/RhsModeSwitch.d.ts +24 -0
  46. package/lib/components/ConditionBuilder/RhsControls/RhsModeSwitch.d.ts.map +1 -0
  47. package/lib/components/ConditionBuilder/RhsControls/RhsModeSwitch.js +122 -0
  48. package/lib/components/ConditionBuilder/RhsControls/RhsModeSwitch.js.map +1 -0
  49. package/lib/components/ConditionBuilder/RhsControls/TimePeriodInput.d.ts +8 -0
  50. package/lib/components/ConditionBuilder/RhsControls/TimePeriodInput.d.ts.map +1 -0
  51. package/lib/components/ConditionBuilder/RhsControls/TimePeriodInput.js +89 -0
  52. package/lib/components/ConditionBuilder/RhsControls/TimePeriodInput.js.map +1 -0
  53. package/lib/components/ConditionBuilder/RhsControls/TimePeriodMenu.d.ts +20 -0
  54. package/lib/components/ConditionBuilder/RhsControls/TimePeriodMenu.d.ts.map +1 -0
  55. package/lib/components/ConditionBuilder/RhsControls/TimePeriodMenu.js +11 -0
  56. package/lib/components/ConditionBuilder/RhsControls/TimePeriodMenu.js.map +1 -0
  57. package/lib/components/ConditionBuilder/RhsControls/index.d.ts +39 -0
  58. package/lib/components/ConditionBuilder/RhsControls/index.d.ts.map +1 -0
  59. package/lib/components/ConditionBuilder/RhsControls/index.js +219 -0
  60. package/lib/components/ConditionBuilder/RhsControls/index.js.map +1 -0
  61. package/lib/components/ConditionBuilder/core/comparators.d.ts +12 -0
  62. package/lib/components/ConditionBuilder/core/comparators.d.ts.map +1 -0
  63. package/lib/components/ConditionBuilder/core/comparators.js +74 -0
  64. package/lib/components/ConditionBuilder/core/comparators.js.map +1 -0
  65. package/lib/components/ConditionBuilder/core/evaluator.d.ts +14 -0
  66. package/lib/components/ConditionBuilder/core/evaluator.d.ts.map +1 -0
  67. package/lib/components/ConditionBuilder/core/evaluator.js +257 -0
  68. package/lib/components/ConditionBuilder/core/evaluator.js.map +1 -0
  69. package/lib/components/ConditionBuilder/core/extendDayJs.d.ts +2 -0
  70. package/lib/components/ConditionBuilder/core/extendDayJs.d.ts.map +1 -0
  71. package/lib/components/ConditionBuilder/core/extendDayJs.js +4 -0
  72. package/lib/components/ConditionBuilder/core/extendDayJs.js.map +1 -0
  73. package/lib/components/ConditionBuilder/core/formatter.d.ts +16 -0
  74. package/lib/components/ConditionBuilder/core/formatter.d.ts.map +1 -0
  75. package/lib/components/ConditionBuilder/core/formatter.js +190 -0
  76. package/lib/components/ConditionBuilder/core/formatter.js.map +1 -0
  77. package/lib/components/ConditionBuilder/core/rows-reducer.d.ts +27 -0
  78. package/lib/components/ConditionBuilder/core/rows-reducer.d.ts.map +1 -0
  79. package/lib/components/ConditionBuilder/core/rows-reducer.js +50 -0
  80. package/lib/components/ConditionBuilder/core/rows-reducer.js.map +1 -0
  81. package/lib/components/ConditionBuilder/core/time-utils.d.ts +5 -0
  82. package/lib/components/ConditionBuilder/core/time-utils.d.ts.map +1 -0
  83. package/lib/components/ConditionBuilder/core/time-utils.js +23 -0
  84. package/lib/components/ConditionBuilder/core/time-utils.js.map +1 -0
  85. package/lib/components/ConditionBuilder/core/transformer.d.ts +7 -0
  86. package/lib/components/ConditionBuilder/core/transformer.d.ts.map +1 -0
  87. package/lib/components/ConditionBuilder/core/transformer.js +154 -0
  88. package/lib/components/ConditionBuilder/core/transformer.js.map +1 -0
  89. package/lib/components/ConditionBuilder/core/types.d.ts +47 -0
  90. package/lib/components/ConditionBuilder/core/types.d.ts.map +1 -0
  91. package/lib/components/ConditionBuilder/core/types.js +2 -0
  92. package/lib/components/ConditionBuilder/core/types.js.map +1 -0
  93. package/lib/components/ConditionBuilder/core/utils.d.ts +37 -0
  94. package/lib/components/ConditionBuilder/core/utils.d.ts.map +1 -0
  95. package/lib/components/ConditionBuilder/core/utils.js +439 -0
  96. package/lib/components/ConditionBuilder/core/utils.js.map +1 -0
  97. package/lib/components/ConditionBuilder/index.d.ts +11 -0
  98. package/lib/components/ConditionBuilder/index.d.ts.map +1 -0
  99. package/lib/components/ConditionBuilder/index.js +8 -0
  100. package/lib/components/ConditionBuilder/index.js.map +1 -0
  101. package/lib/index.d.ts +3 -0
  102. package/lib/index.d.ts.map +1 -0
  103. package/lib/index.js +4 -0
  104. package/lib/index.js.map +1 -0
  105. package/package.json +2 -2
@@ -0,0 +1,257 @@
1
+ // cspell:ignore words YYYYQQ, YYYYMM, YYYYMMDD, YYYYMMDDHH
2
+ import { hasProp } from '@pega/cosmos-react-core';
3
+ import transformComplexCondition from './transformer';
4
+ const QUOTE = '"';
5
+ /** Evaluates leaf conditions with BOOLEAN fields */
6
+ function evaluateBoolCondition(lhsValue, comparator, rhsValue // undefined for IS_TRUE/IS_FALSE comparators
7
+ ) {
8
+ switch (comparator) {
9
+ case 'IS_TRUE':
10
+ return lhsValue === true;
11
+ case 'IS_FALSE':
12
+ return lhsValue === false;
13
+ case 'EQ':
14
+ return lhsValue === rhsValue;
15
+ case 'NEQ':
16
+ return lhsValue !== rhsValue;
17
+ default:
18
+ return false; // Not needed
19
+ }
20
+ }
21
+ /** Evaluates leaf conditions with TEXT fields */
22
+ function evaluateTextCondition(lhsValue, comparator, rhsValue) {
23
+ lhsValue = lhsValue.toLowerCase(); // Converting to lowerCase to perform case-insensitive comparisons
24
+ // For IN/NOT_IN comparators, the rhsValue is of type `string[]`
25
+ if (Array.isArray(rhsValue)) {
26
+ const lhsInRhs = rhsValue
27
+ .map(v => {
28
+ v = v.toLowerCase().trim();
29
+ // Handle text in quotes
30
+ if (v.startsWith(QUOTE) && v.endsWith(QUOTE)) {
31
+ v = v.slice(1, -1);
32
+ }
33
+ return v;
34
+ })
35
+ .includes(lhsValue); // Converting to lowerCase to perform case-insensitive comparisons
36
+ return comparator === 'IN' ? lhsInRhs : !lhsInRhs; // Handling IN/NOT_IN comparators
37
+ }
38
+ // Converting to lowerCase to perform case-insensitive comparisons
39
+ rhsValue = rhsValue.toLowerCase().trim();
40
+ // Handle if rhs is in quotes
41
+ if (rhsValue.startsWith(QUOTE) && rhsValue.endsWith(QUOTE)) {
42
+ rhsValue = rhsValue.slice(1, -1);
43
+ }
44
+ switch (comparator) {
45
+ case 'EQ':
46
+ return lhsValue === rhsValue;
47
+ case 'NEQ':
48
+ return lhsValue !== rhsValue;
49
+ case 'STARTS_WITH':
50
+ return lhsValue.startsWith(rhsValue);
51
+ case 'NOT_STARTS_WITH':
52
+ return !lhsValue.startsWith(rhsValue);
53
+ case 'ENDS_WITH':
54
+ return lhsValue.endsWith(rhsValue);
55
+ case 'NOT_ENDS_WITH':
56
+ return !lhsValue.endsWith(rhsValue);
57
+ case 'CONTAINS':
58
+ return lhsValue.includes(rhsValue);
59
+ case 'NOT_CONTAINS':
60
+ return !lhsValue.includes(rhsValue);
61
+ default:
62
+ return false; // Not needed
63
+ }
64
+ }
65
+ /** Evaluates leaf conditions with NUMBER fields */
66
+ function evaluateNumericCondition(lhsValue, comparator, rhsValue) {
67
+ // For IN/NOT_IN comparators, the rhsValue is of type `number[]`
68
+ if (Array.isArray(rhsValue)) {
69
+ const lhsInRhs = rhsValue.includes(lhsValue);
70
+ return comparator === 'IN' ? lhsInRhs : !lhsInRhs; // Handling IN/NOT_IN comparators
71
+ }
72
+ switch (comparator) {
73
+ case 'EQ':
74
+ return lhsValue === rhsValue;
75
+ case 'NEQ':
76
+ return lhsValue !== rhsValue;
77
+ case 'GT':
78
+ return lhsValue > rhsValue;
79
+ case 'GTE':
80
+ return lhsValue >= rhsValue;
81
+ case 'LT':
82
+ return lhsValue < rhsValue;
83
+ case 'LTE':
84
+ return lhsValue <= rhsValue;
85
+ default:
86
+ return false; // Not needed
87
+ }
88
+ }
89
+ /** Returns different date parts in local time from the given date object */
90
+ function getDateParts(date) {
91
+ return {
92
+ YYYY: date.getFullYear().toString().padStart(4, '0'),
93
+ QQ: (3 * Math.floor(date.getMonth() / 3) + 1).toString().padStart(2, '0'),
94
+ MM: (date.getMonth() + 1).toString().padStart(2, '0'),
95
+ DD: date.getDate().toString().padStart(2, '0'),
96
+ HH: date.getHours().toString().padStart(2, '0')
97
+ };
98
+ }
99
+ /** Evaluates leaf conditions with Date-functions */
100
+ function evaluateDateFuncCondition(lhsValue, fieldType, comparator, rhs) {
101
+ if (fieldType === 'DATE_ONLY')
102
+ lhsValue += 'T00:00:00'; // `T00:00:00` is needed for the `Date()` constructor to treat it as local (not UTC)
103
+ const lhsDateObj = new Date(lhsValue);
104
+ const { YYYY: lhsYYYY, QQ: lhsQQ, MM: lhsMM, DD: lhsDD, HH: lhsHH } = getDateParts(lhsDateObj);
105
+ // Determine a numeric representation of the values for the given date function
106
+ let lhsNumVal = 0;
107
+ let rhsNumVal = 0;
108
+ switch (rhs.dateFunction) {
109
+ case 'YEARS':
110
+ // Using YYYY as a number
111
+ lhsNumVal = Number(lhsYYYY);
112
+ rhsNumVal = Number(rhs.value.slice(0, 4));
113
+ break;
114
+ case 'QUARTERS':
115
+ // Using YYYYQQ as a number
116
+ lhsNumVal = Number(`${lhsYYYY}${lhsQQ}`);
117
+ rhsNumVal = Number(rhs.value.replace(/-/g, '').slice(0, 6));
118
+ break;
119
+ case 'MONTHS':
120
+ // Using YYYYMM as a number
121
+ lhsNumVal = Number(`${lhsYYYY}${lhsMM}`);
122
+ rhsNumVal = Number(rhs.value.replace(/-/g, '').slice(0, 6));
123
+ break;
124
+ case 'WEEKS': {
125
+ // Identify the start of week for the given LHS
126
+ const lhsDayStart = new Date(`${lhsYYYY}-${lhsMM}-${lhsDD}T00:00:00`); // `T00:00:00` is needed for the `Date()` constructor to treat it as local (not UTC)
127
+ const lhsDay = lhsDayStart.getDay() || 7; // 'getDay()' returns 0 for Sundays
128
+ const lhsWeekStart = new Date(lhsDayStart.getTime() - (lhsDay - 1) * 24 * 60 * 60 * 1000);
129
+ const { YYYY: weekStartYYYY, MM: weekStartMM, DD: weekStartDD } = getDateParts(lhsWeekStart);
130
+ // Using YYYYMMDD of the week-start-day as a number
131
+ lhsNumVal = Number(`${weekStartYYYY}${weekStartMM}${weekStartDD}`);
132
+ rhsNumVal = Number(rhs.value.replace(/-/g, ''));
133
+ break;
134
+ }
135
+ case 'DAYS':
136
+ // Using YYYYMMDD as a number
137
+ lhsNumVal = Number(`${lhsYYYY}${lhsMM}${lhsDD}`);
138
+ rhsNumVal = Number(rhs.value.replace(/-/g, ''));
139
+ break;
140
+ case 'HOURS':
141
+ // Using YYYYMMDDHH as a number
142
+ lhsNumVal = Number(`${lhsYYYY}${lhsMM}${lhsDD}${lhsHH}`);
143
+ rhsNumVal = Number(rhs.value.replace(/-|T/g, '').slice(0, 10));
144
+ break;
145
+ case 'MONTHS_OF_YEAR':
146
+ lhsNumVal = Number(lhsMM);
147
+ rhsNumVal = rhs.value;
148
+ break;
149
+ case 'DAYS_OF_MONTH':
150
+ lhsNumVal = Number(lhsDD);
151
+ rhsNumVal = rhs.value;
152
+ break;
153
+ case 'DAYS_OF_WEEK':
154
+ lhsNumVal = lhsDateObj.getDay() || 7; // 'getDay()' returns 0 for Sundays
155
+ rhsNumVal = rhs.value;
156
+ break;
157
+ default: // Not needed
158
+ }
159
+ // Compare the numeric representations
160
+ return evaluateNumericCondition(lhsNumVal, comparator, rhsNumVal);
161
+ }
162
+ /** Evaluates a leaf node in a condition tree for the given data document */
163
+ function evaluateLeafCondition(leaf, data, fields) {
164
+ // For safety against any malformed nodes or unexpected types/formats in data-values
165
+ try {
166
+ const { lhs, comparator, rhs } = leaf;
167
+ // Determine LHS and RHS values
168
+ const lhsValue = data[lhs.field];
169
+ let rhsValue;
170
+ if (rhs) {
171
+ if (hasProp(rhs, 'field')) {
172
+ rhsValue = data[rhs.field]; // If RHS is another field
173
+ }
174
+ else if (hasProp(rhs, 'value')) {
175
+ rhsValue = rhs.value; // If RHS is a single value
176
+ }
177
+ else if (hasProp(rhs, 'relativeDate')) {
178
+ rhsValue = true; // TODO: When we transform relative dates to LT/GT statements, we won't need this.
179
+ }
180
+ else {
181
+ rhsValue = rhs.values; // If RHS is a list of values
182
+ }
183
+ }
184
+ // Handle NULL comparators common to all field-types
185
+ const isNullValue = lhsValue === null || lhsValue === undefined;
186
+ if (comparator === 'IS_NULL') {
187
+ return isNullValue;
188
+ }
189
+ if (comparator === 'IS_NOT_NULL') {
190
+ return !isNullValue;
191
+ }
192
+ // For all other comparators, evaluate separately by field-type
193
+ const field = fields.find(f => f.name === lhs.field);
194
+ if (field === undefined) {
195
+ return false; // If the corresponding field is not found in the input fields
196
+ }
197
+ switch (field.type) {
198
+ case 'BOOLEAN':
199
+ return evaluateBoolCondition(lhsValue, comparator, rhsValue);
200
+ case 'TEXT':
201
+ return evaluateTextCondition(lhsValue, comparator, rhsValue);
202
+ case 'NUMBER':
203
+ case 'TIME_ONLY':
204
+ return evaluateNumericCondition(lhsValue, comparator, rhsValue);
205
+ case 'DATE_TIME':
206
+ case 'DATE_ONLY': {
207
+ if (rhs && hasProp(rhs, 'dateFunction')) {
208
+ return evaluateDateFuncCondition(lhsValue, field.type, comparator, rhs);
209
+ }
210
+ if (rhs && hasProp(rhs, 'relativeDate')) {
211
+ return true; // TODO: When we transform relative dates to LT/GT statements, we won't need this.
212
+ }
213
+ // Both the values are expected to be in an ISO-8601 format
214
+ const lhsAsTicks = new Date(lhsValue).getTime();
215
+ const rhsAsTicks = new Date(rhsValue).getTime();
216
+ return evaluateNumericCondition(lhsAsTicks, comparator, rhsAsTicks);
217
+ }
218
+ default:
219
+ return false; // Not needed
220
+ }
221
+ }
222
+ catch {
223
+ return false;
224
+ }
225
+ }
226
+ /**
227
+ * Evaluates a condition tree for the given data document
228
+ * NOTE: The output is nondeterministic if:
229
+ * - any of the nodes in the input Condition are in an unexpected format (invalid keys, comparators etc.)
230
+ * - any null/undefined values are encountered in the input data, unless they are used with an IS_NULL/IS_NOT_NULL comparator
231
+ * - stringified values are encountered for BOOLEAN/NUMBER fields
232
+ * - non-ISO strings are passed for DATE_TIME/DATE_ONLY fields
233
+ * - TIME_ONLY data values are not passed as `number of milliseconds since the start of day`
234
+ */
235
+ export default function evaluateCondition(condition, data, fields) {
236
+ // For safety against any malformed trees
237
+ try {
238
+ // Update relative date conditions to be LT/GT date range conditions
239
+ const updatedCondition = transformComplexCondition(condition, fields);
240
+ if (hasProp(updatedCondition, 'AND')) {
241
+ // Return true if all the child nodes are true
242
+ return updatedCondition.AND.every(child => evaluateCondition(child, data, fields));
243
+ }
244
+ if (hasProp(updatedCondition, 'OR')) {
245
+ // Return true if any one of the child nodes is true
246
+ return updatedCondition.OR.some(child => evaluateCondition(child, data, fields));
247
+ }
248
+ if (hasProp(updatedCondition, 'NOT')) {
249
+ return !evaluateCondition(updatedCondition.NOT, data, fields);
250
+ }
251
+ return evaluateLeafCondition(updatedCondition.condition, data, fields);
252
+ }
253
+ catch {
254
+ return false;
255
+ }
256
+ }
257
+ //# sourceMappingURL=evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/evaluator.ts"],"names":[],"mappings":"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","sourcesContent":["// cspell:ignore words YYYYQQ, YYYYMM, YYYYMMDD, YYYYMMDDHH\nimport { hasProp } from '@pega/cosmos-react-core';\n\nimport { Condition, LeafCondition, Field, RhsWithDateFunction } from '../ConditionBuilder.types';\n\nimport { Comparator, FieldType } from './types';\nimport transformComplexCondition from './transformer';\n\nconst QUOTE = '\"';\n/** Evaluates leaf conditions with BOOLEAN fields */\nfunction evaluateBoolCondition(\n lhsValue: boolean,\n comparator: Comparator,\n rhsValue?: boolean // undefined for IS_TRUE/IS_FALSE comparators\n): boolean {\n switch (comparator) {\n case 'IS_TRUE':\n return lhsValue === true;\n case 'IS_FALSE':\n return lhsValue === false;\n case 'EQ':\n return lhsValue === rhsValue;\n case 'NEQ':\n return lhsValue !== rhsValue;\n default:\n return false; // Not needed\n }\n}\n\n/** Evaluates leaf conditions with TEXT fields */\nfunction evaluateTextCondition(\n lhsValue: string,\n comparator: Comparator,\n rhsValue: string | string[]\n): boolean {\n lhsValue = lhsValue.toLowerCase(); // Converting to lowerCase to perform case-insensitive comparisons\n\n // For IN/NOT_IN comparators, the rhsValue is of type `string[]`\n if (Array.isArray(rhsValue)) {\n const lhsInRhs = rhsValue\n .map(v => {\n v = v.toLowerCase().trim();\n // Handle text in quotes\n if (v.startsWith(QUOTE) && v.endsWith(QUOTE)) {\n v = v.slice(1, -1);\n }\n return v;\n })\n .includes(lhsValue); // Converting to lowerCase to perform case-insensitive comparisons\n return comparator === 'IN' ? lhsInRhs : !lhsInRhs; // Handling IN/NOT_IN comparators\n }\n // Converting to lowerCase to perform case-insensitive comparisons\n rhsValue = rhsValue.toLowerCase().trim();\n\n // Handle if rhs is in quotes\n if (rhsValue.startsWith(QUOTE) && rhsValue.endsWith(QUOTE)) {\n rhsValue = rhsValue.slice(1, -1);\n }\n switch (comparator) {\n case 'EQ':\n return lhsValue === rhsValue;\n case 'NEQ':\n return lhsValue !== rhsValue;\n case 'STARTS_WITH':\n return lhsValue.startsWith(rhsValue);\n case 'NOT_STARTS_WITH':\n return !lhsValue.startsWith(rhsValue);\n case 'ENDS_WITH':\n return lhsValue.endsWith(rhsValue);\n case 'NOT_ENDS_WITH':\n return !lhsValue.endsWith(rhsValue);\n case 'CONTAINS':\n return lhsValue.includes(rhsValue);\n case 'NOT_CONTAINS':\n return !lhsValue.includes(rhsValue);\n default:\n return false; // Not needed\n }\n}\n\n/** Evaluates leaf conditions with NUMBER fields */\nfunction evaluateNumericCondition(\n lhsValue: number,\n comparator: Comparator,\n rhsValue: number | number[]\n): boolean {\n // For IN/NOT_IN comparators, the rhsValue is of type `number[]`\n if (Array.isArray(rhsValue)) {\n const lhsInRhs: boolean = rhsValue.includes(lhsValue);\n return comparator === 'IN' ? lhsInRhs : !lhsInRhs; // Handling IN/NOT_IN comparators\n }\n\n switch (comparator) {\n case 'EQ':\n return lhsValue === rhsValue;\n case 'NEQ':\n return lhsValue !== rhsValue;\n case 'GT':\n return lhsValue > rhsValue;\n case 'GTE':\n return lhsValue >= rhsValue;\n case 'LT':\n return lhsValue < rhsValue;\n case 'LTE':\n return lhsValue <= rhsValue;\n default:\n return false; // Not needed\n }\n}\n\n/** Returns different date parts in local time from the given date object */\nfunction getDateParts(date: Date): {\n YYYY: string;\n QQ: string;\n MM: string;\n DD: string;\n HH: string;\n} {\n return {\n YYYY: date.getFullYear().toString().padStart(4, '0'),\n QQ: (3 * Math.floor(date.getMonth() / 3) + 1).toString().padStart(2, '0'), // MM value for the quarter's starting month\n MM: (date.getMonth() + 1).toString().padStart(2, '0'),\n DD: date.getDate().toString().padStart(2, '0'),\n HH: date.getHours().toString().padStart(2, '0')\n };\n}\n\n/** Evaluates leaf conditions with Date-functions */\nfunction evaluateDateFuncCondition(\n lhsValue: string,\n fieldType: FieldType,\n comparator: Comparator,\n rhs: RhsWithDateFunction\n): boolean {\n if (fieldType === 'DATE_ONLY') lhsValue += 'T00:00:00'; // `T00:00:00` is needed for the `Date()` constructor to treat it as local (not UTC)\n const lhsDateObj = new Date(lhsValue);\n const { YYYY: lhsYYYY, QQ: lhsQQ, MM: lhsMM, DD: lhsDD, HH: lhsHH } = getDateParts(lhsDateObj);\n\n // Determine a numeric representation of the values for the given date function\n let lhsNumVal = 0;\n let rhsNumVal = 0;\n switch (rhs.dateFunction) {\n case 'YEARS':\n // Using YYYY as a number\n lhsNumVal = Number(lhsYYYY);\n rhsNumVal = Number((rhs.value as string).slice(0, 4));\n break;\n case 'QUARTERS':\n // Using YYYYQQ as a number\n lhsNumVal = Number(`${lhsYYYY}${lhsQQ}`);\n rhsNumVal = Number((rhs.value as string).replace(/-/g, '').slice(0, 6));\n break;\n case 'MONTHS':\n // Using YYYYMM as a number\n lhsNumVal = Number(`${lhsYYYY}${lhsMM}`);\n rhsNumVal = Number((rhs.value as string).replace(/-/g, '').slice(0, 6));\n break;\n case 'WEEKS': {\n // Identify the start of week for the given LHS\n const lhsDayStart = new Date(`${lhsYYYY}-${lhsMM}-${lhsDD}T00:00:00`); // `T00:00:00` is needed for the `Date()` constructor to treat it as local (not UTC)\n const lhsDay = lhsDayStart.getDay() || 7; // 'getDay()' returns 0 for Sundays\n const lhsWeekStart = new Date(lhsDayStart.getTime() - (lhsDay - 1) * 24 * 60 * 60 * 1000);\n const { YYYY: weekStartYYYY, MM: weekStartMM, DD: weekStartDD } = getDateParts(lhsWeekStart);\n\n // Using YYYYMMDD of the week-start-day as a number\n lhsNumVal = Number(`${weekStartYYYY}${weekStartMM}${weekStartDD}`);\n rhsNumVal = Number((rhs.value as string).replace(/-/g, ''));\n break;\n }\n case 'DAYS':\n // Using YYYYMMDD as a number\n lhsNumVal = Number(`${lhsYYYY}${lhsMM}${lhsDD}`);\n rhsNumVal = Number((rhs.value as string).replace(/-/g, ''));\n break;\n case 'HOURS':\n // Using YYYYMMDDHH as a number\n lhsNumVal = Number(`${lhsYYYY}${lhsMM}${lhsDD}${lhsHH}`);\n rhsNumVal = Number((rhs.value as string).replace(/-|T/g, '').slice(0, 10));\n break;\n case 'MONTHS_OF_YEAR':\n lhsNumVal = Number(lhsMM);\n rhsNumVal = rhs.value as number;\n break;\n case 'DAYS_OF_MONTH':\n lhsNumVal = Number(lhsDD);\n rhsNumVal = rhs.value as number;\n break;\n case 'DAYS_OF_WEEK':\n lhsNumVal = lhsDateObj.getDay() || 7; // 'getDay()' returns 0 for Sundays\n rhsNumVal = rhs.value as number;\n break;\n default: // Not needed\n }\n\n // Compare the numeric representations\n return evaluateNumericCondition(lhsNumVal, comparator, rhsNumVal);\n}\n\n/** Evaluates a leaf node in a condition tree for the given data document */\nfunction evaluateLeafCondition(\n leaf: LeafCondition,\n data: { [fieldName: string]: any },\n fields: Field[]\n): boolean {\n // For safety against any malformed nodes or unexpected types/formats in data-values\n try {\n const { lhs, comparator, rhs } = leaf;\n\n // Determine LHS and RHS values\n const lhsValue: any = data[lhs.field];\n let rhsValue: any;\n if (rhs) {\n if (hasProp(rhs, 'field')) {\n rhsValue = data[rhs.field]; // If RHS is another field\n } else if (hasProp(rhs, 'value')) {\n rhsValue = rhs.value; // If RHS is a single value\n } else if (hasProp(rhs, 'relativeDate')) {\n rhsValue = true; // TODO: When we transform relative dates to LT/GT statements, we won't need this.\n } else {\n rhsValue = rhs.values; // If RHS is a list of values\n }\n }\n\n // Handle NULL comparators common to all field-types\n const isNullValue = lhsValue === null || lhsValue === undefined;\n if (comparator === 'IS_NULL') {\n return isNullValue;\n }\n if (comparator === 'IS_NOT_NULL') {\n return !isNullValue;\n }\n\n // For all other comparators, evaluate separately by field-type\n const field = fields.find(f => f.name === lhs.field);\n if (field === undefined) {\n return false; // If the corresponding field is not found in the input fields\n }\n switch (field.type) {\n case 'BOOLEAN':\n return evaluateBoolCondition(lhsValue, comparator, rhsValue);\n case 'TEXT':\n return evaluateTextCondition(lhsValue, comparator, rhsValue);\n case 'NUMBER':\n case 'TIME_ONLY':\n return evaluateNumericCondition(lhsValue, comparator, rhsValue);\n case 'DATE_TIME':\n case 'DATE_ONLY': {\n if (rhs && hasProp(rhs, 'dateFunction')) {\n return evaluateDateFuncCondition(lhsValue, field.type, comparator, rhs);\n }\n\n if (rhs && hasProp(rhs, 'relativeDate')) {\n return true; // TODO: When we transform relative dates to LT/GT statements, we won't need this.\n }\n\n // Both the values are expected to be in an ISO-8601 format\n const lhsAsTicks = new Date(lhsValue).getTime();\n const rhsAsTicks = new Date(rhsValue).getTime();\n return evaluateNumericCondition(lhsAsTicks, comparator, rhsAsTicks);\n }\n default:\n return false; // Not needed\n }\n } catch {\n return false;\n }\n}\n\n/**\n * Evaluates a condition tree for the given data document\n * NOTE: The output is nondeterministic if:\n * - any of the nodes in the input Condition are in an unexpected format (invalid keys, comparators etc.)\n * - any null/undefined values are encountered in the input data, unless they are used with an IS_NULL/IS_NOT_NULL comparator\n * - stringified values are encountered for BOOLEAN/NUMBER fields\n * - non-ISO strings are passed for DATE_TIME/DATE_ONLY fields\n * - TIME_ONLY data values are not passed as `number of milliseconds since the start of day`\n */\nexport default function evaluateCondition(\n condition: Condition,\n data: { [fieldName: string]: any },\n fields: Field[]\n): boolean {\n // For safety against any malformed trees\n try {\n // Update relative date conditions to be LT/GT date range conditions\n const updatedCondition: Condition = transformComplexCondition(condition, fields);\n if (hasProp(updatedCondition, 'AND')) {\n // Return true if all the child nodes are true\n return updatedCondition.AND.every(child => evaluateCondition(child, data, fields));\n }\n if (hasProp(updatedCondition, 'OR')) {\n // Return true if any one of the child nodes is true\n return updatedCondition.OR.some(child => evaluateCondition(child, data, fields));\n }\n if (hasProp(updatedCondition, 'NOT')) {\n return !evaluateCondition(updatedCondition.NOT, data, fields);\n }\n return evaluateLeafCondition(updatedCondition.condition, data, fields);\n } catch {\n return false;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=extendDayJs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extendDayJs.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/extendDayJs.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import dayjs from 'dayjs';
2
+ import quarterOfYear from 'dayjs/plugin/quarterOfYear';
3
+ dayjs.extend(quarterOfYear);
4
+ //# sourceMappingURL=extendDayJs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extendDayJs.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/extendDayJs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAEvD,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC","sourcesContent":["import dayjs from 'dayjs';\nimport quarterOfYear from 'dayjs/plugin/quarterOfYear';\n\ndayjs.extend(quarterOfYear);\n"]}
@@ -0,0 +1,16 @@
1
+ import { TranslationPack } from '@pega/cosmos-react-core';
2
+ import { TranslationFunction } from '@pega/cosmos-react-core/lib/i18n/translate';
3
+ import { Condition, Field } from '../ConditionBuilder.types';
4
+ import { DatePart, TimePeriod } from './types';
5
+ /** Options object optionally passed to formatCondition method. */
6
+ interface ConditionFormatOptions {
7
+ locale?: string;
8
+ }
9
+ export declare function formatRelativeDate(translate: TranslationFunction<TranslationPack>, timePeriod: TimePeriod, datePart: DatePart, interval?: number): string;
10
+ /**
11
+ * Returns a user-friendly text representation of a given complex condition
12
+ * The input `fields` are used to look up display labels for the fields
13
+ */
14
+ export default function formatCondition(condition: Condition, fields: Field[], translate: TranslationFunction<TranslationPack>, options?: ConditionFormatOptions): string;
15
+ export {};
16
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/formatter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAGjF,OAAO,EAAE,SAAS,EAAiB,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM/C,kEAAkE;AAClE,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,mBAAmB,CAAC,eAAe,CAAC,EAC/C,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAQR;AAiLD;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,KAAK,EAAE,EACf,SAAS,EAAE,mBAAmB,CAAC,eAAe,CAAC,EAC/C,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM,CAUR"}
@@ -0,0 +1,190 @@
1
+ // cSpell:words LPAREN RPAREN
2
+ // FIXME: TR (Several constructs in this file need to be localized)
3
+ import { hasProp } from '@pega/cosmos-react-core';
4
+ import { getFormattedValue } from '@pega/cosmos-react-core/lib/components/Number/utils';
5
+ import { getQuarter } from '@pega/cosmos-react-core/lib/components/DateTime/Input/utils';
6
+ import { convertMsToTimeValue } from './time-utils';
7
+ const LPAREN = '(';
8
+ const RPAREN = ')';
9
+ export function formatRelativeDate(translate, timePeriod, datePart, interval) {
10
+ const translationKey = timePeriod === 'CURRENT'
11
+ ? `condition_builder_current_${datePart.toLowerCase().slice(0, -1)}`
12
+ : `condition_builder_${timePeriod.toLowerCase()}_X_${datePart.toLowerCase()}`;
13
+ return translate(translationKey, [interval ?? 0], {
14
+ count: interval ?? 0
15
+ });
16
+ }
17
+ /** Returns a user-friendly text representation of a given leaf condition */
18
+ function formatLeafCondition(leaf, fields, translate, { locale = 'en-US' } = {}) {
19
+ const { lhs, comparator, rhs } = leaf;
20
+ // Determine texts for LHS and RHS
21
+ const lhsField = fields.find(f => f.name === lhs.field); // Expecting valid inputs
22
+ const lhsText = lhsField.label || lhsField.name; // label is optional
23
+ let rhsText = '';
24
+ if (rhs) {
25
+ if (hasProp(rhs, 'field')) {
26
+ // If RHS is another field
27
+ const rhsField = fields.find(f => f.name === rhs.field); // Expecting valid inputs
28
+ rhsText = rhsField.label || rhsField.name; // label is optional
29
+ }
30
+ else if (hasProp(rhs, 'value')) {
31
+ if (hasProp(rhs, 'dateFunction')) {
32
+ // If RHS is a date function value
33
+ switch (rhs.dateFunction) {
34
+ case 'YEARS':
35
+ rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {
36
+ year: 'numeric'
37
+ });
38
+ break;
39
+ case 'QUARTERS': {
40
+ const formattedYear = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {
41
+ year: 'numeric'
42
+ });
43
+ const quarterNumber = getQuarter(rhs.value);
44
+ rhsText = `${translate(`date_quarter_q${quarterNumber}`, [formattedYear])}`;
45
+ break;
46
+ }
47
+ case 'MONTHS':
48
+ rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {
49
+ year: 'numeric',
50
+ month: 'short'
51
+ });
52
+ break;
53
+ case 'WEEKS':
54
+ rhsText = `Week of ${new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {
55
+ year: 'numeric',
56
+ month: 'short',
57
+ day: 'numeric'
58
+ })}`;
59
+ break;
60
+ case 'DAYS':
61
+ rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {
62
+ year: 'numeric',
63
+ month: 'short',
64
+ day: 'numeric'
65
+ });
66
+ break;
67
+ case 'HOURS':
68
+ rhsText = new Date(rhs.value).toLocaleString(locale, {
69
+ year: 'numeric',
70
+ month: 'short',
71
+ day: 'numeric',
72
+ hour: 'numeric',
73
+ hour12: true
74
+ });
75
+ break;
76
+ case 'MONTHS_OF_YEAR':
77
+ rhsText = new Date(2021, rhs.value - 1, 1).toLocaleString(locale, {
78
+ month: 'long'
79
+ });
80
+ break;
81
+ case 'DAYS_OF_MONTH':
82
+ rhsText = `Day ${rhs.value} of month`;
83
+ break;
84
+ case 'DAYS_OF_WEEK':
85
+ // Choosing Feb-2021 as it starts on a Monday
86
+ rhsText = new Date(2021, 1, rhs.value).toLocaleString(locale, {
87
+ weekday: 'long'
88
+ });
89
+ break;
90
+ default: // Not needed
91
+ }
92
+ }
93
+ else {
94
+ // If RHS is a single literal value
95
+ switch (lhsField.type) {
96
+ case 'TIME_ONLY':
97
+ // For these cases, rhs.value is stored as # of milliseconds since day-start
98
+ rhsText = convertMsToTimeValue(rhs.value);
99
+ break;
100
+ case 'NUMBER':
101
+ rhsText = getFormattedValue(rhs.value.toString(), locale, true, 4);
102
+ break;
103
+ default:
104
+ rhsText = rhs.value;
105
+ }
106
+ }
107
+ }
108
+ else if (hasProp(rhs, 'relativeDate')) {
109
+ const { relativeDate: { timePeriod, interval, datePart } } = rhs;
110
+ rhsText = formatRelativeDate(translate, timePeriod, datePart, interval);
111
+ }
112
+ else {
113
+ rhsText = rhs.values.join(', '); // If RHS is a list of values
114
+ }
115
+ }
116
+ switch (comparator) {
117
+ case 'IS_NULL':
118
+ return `${lhsText} is null`;
119
+ case 'IS_NOT_NULL':
120
+ return `${lhsText} is not null`;
121
+ case 'IS_TRUE':
122
+ return `${lhsText} is true`;
123
+ case 'IS_FALSE':
124
+ return `${lhsText} is false`;
125
+ case 'EQ':
126
+ return `${lhsText} is ${rhsText}`;
127
+ case 'NEQ':
128
+ return `${lhsText} isn't ${rhsText}`;
129
+ case 'IN':
130
+ return `${lhsText} is among ${rhsText}`;
131
+ case 'NOT_IN':
132
+ return `${lhsText} is not among ${rhsText}`;
133
+ case 'GT':
134
+ return `${lhsText} > ${rhsText}`;
135
+ case 'GTE':
136
+ return `${lhsText} >= ${rhsText}`;
137
+ case 'LT':
138
+ return `${lhsText} < ${rhsText}`;
139
+ case 'LTE':
140
+ return `${lhsText} <= ${rhsText}`;
141
+ case 'STARTS_WITH':
142
+ return `${lhsText} starts with ${rhsText}`;
143
+ case 'NOT_STARTS_WITH':
144
+ return `${lhsText} doesn't start with ${rhsText}`;
145
+ case 'ENDS_WITH':
146
+ return `${lhsText} ends with ${rhsText}`;
147
+ case 'NOT_ENDS_WITH':
148
+ return `${lhsText} doesn't end with ${rhsText}`;
149
+ case 'CONTAINS':
150
+ return `${lhsText} contains ${rhsText}`;
151
+ case 'NOT_CONTAINS':
152
+ return `${lhsText} doesn't contain ${rhsText}`;
153
+ default:
154
+ return ''; // Not needed
155
+ }
156
+ }
157
+ /** Returns a user-friendly text representation of the given node in a condition */
158
+ function formatConditionNode(node, fields, translate, options) {
159
+ if (hasProp(node, 'AND')) {
160
+ const childStrings = node.AND.map(n => formatConditionNode(n, fields, translate, options));
161
+ return `(${childStrings.join(' AND ')})`;
162
+ }
163
+ if (hasProp(node, 'OR')) {
164
+ const childStrings = node.OR.map(n => formatConditionNode(n, fields, translate, options));
165
+ return `(${childStrings.join(' OR ')})`;
166
+ }
167
+ if (hasProp(node, 'NOT')) {
168
+ const childString = formatConditionNode(node.NOT, fields, translate, options);
169
+ if (childString.startsWith(LPAREN) && childString.endsWith(RPAREN)) {
170
+ // Avoid double brackets when the child node is an AND/OR node
171
+ return `NOT ${childString}`;
172
+ }
173
+ return `NOT (${childString})`;
174
+ }
175
+ return formatLeafCondition(node.condition, fields, translate, options); // If leaf-level is reached
176
+ }
177
+ /**
178
+ * Returns a user-friendly text representation of a given complex condition
179
+ * The input `fields` are used to look up display labels for the fields
180
+ */
181
+ export default function formatCondition(condition, fields, translate, options) {
182
+ // Recursively format the tree, starting at the root node
183
+ let text = formatConditionNode(condition, fields, translate, options);
184
+ // If the root node is AND/OR, there will be extra parentheses. Remove them
185
+ if (text.startsWith(LPAREN) && text.endsWith(RPAREN)) {
186
+ text = text.slice(1, -1);
187
+ }
188
+ return text;
189
+ }
190
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/formatter.ts"],"names":[],"mappings":"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","sourcesContent":["// cSpell:words LPAREN RPAREN\n// FIXME: TR (Several constructs in this file need to be localized)\nimport { hasProp, TranslationPack } from '@pega/cosmos-react-core';\nimport { getFormattedValue } from '@pega/cosmos-react-core/lib/components/Number/utils';\nimport { TranslationFunction } from '@pega/cosmos-react-core/lib/i18n/translate';\nimport { getQuarter } from '@pega/cosmos-react-core/lib/components/DateTime/Input/utils';\n\nimport { Condition, LeafCondition, Field } from '../ConditionBuilder.types';\n\nimport { DatePart, TimePeriod } from './types';\nimport { convertMsToTimeValue } from './time-utils';\n\nconst LPAREN = '(';\nconst RPAREN = ')';\n\n/** Options object optionally passed to formatCondition method. */\ninterface ConditionFormatOptions {\n locale?: string;\n}\n\nexport function formatRelativeDate(\n translate: TranslationFunction<TranslationPack>,\n timePeriod: TimePeriod,\n datePart: DatePart,\n interval?: number\n): string {\n const translationKey =\n timePeriod === 'CURRENT'\n ? `condition_builder_current_${datePart.toLowerCase().slice(0, -1)}`\n : `condition_builder_${timePeriod.toLowerCase()}_X_${datePart.toLowerCase()}`;\n return translate(translationKey as keyof TranslationPack, [interval ?? 0], {\n count: interval ?? 0\n });\n}\n\n/** Returns a user-friendly text representation of a given leaf condition */\nfunction formatLeafCondition(\n leaf: LeafCondition,\n fields: Field[],\n translate: TranslationFunction<TranslationPack>,\n { locale = 'en-US' }: ConditionFormatOptions = {}\n): string {\n const { lhs, comparator, rhs } = leaf;\n\n // Determine texts for LHS and RHS\n const lhsField = fields.find(f => f.name === lhs.field) as Field; // Expecting valid inputs\n const lhsText = lhsField.label || lhsField.name; // label is optional\n let rhsText = '';\n if (rhs) {\n if (hasProp(rhs, 'field')) {\n // If RHS is another field\n const rhsField = fields.find(f => f.name === rhs.field) as Field; // Expecting valid inputs\n rhsText = rhsField.label || rhsField.name; // label is optional\n } else if (hasProp(rhs, 'value')) {\n if (hasProp(rhs, 'dateFunction')) {\n // If RHS is a date function value\n switch (rhs.dateFunction) {\n case 'YEARS':\n rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {\n year: 'numeric'\n });\n break;\n case 'QUARTERS': {\n const formattedYear = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {\n year: 'numeric'\n });\n const quarterNumber = getQuarter(rhs.value);\n rhsText = `${translate(`date_quarter_q${quarterNumber}`, [formattedYear])}`;\n break;\n }\n case 'MONTHS':\n rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {\n year: 'numeric',\n month: 'short'\n });\n break;\n case 'WEEKS':\n rhsText = `Week of ${new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n })}`;\n break;\n case 'DAYS':\n rhsText = new Date(`${rhs.value}T00:00:00`).toLocaleString(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n break;\n case 'HOURS':\n rhsText = new Date(rhs.value).toLocaleString(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n hour12: true\n });\n break;\n case 'MONTHS_OF_YEAR':\n rhsText = new Date(2021, (rhs.value as number) - 1, 1).toLocaleString(locale, {\n month: 'long'\n });\n break;\n case 'DAYS_OF_MONTH':\n rhsText = `Day ${rhs.value} of month`;\n break;\n case 'DAYS_OF_WEEK':\n // Choosing Feb-2021 as it starts on a Monday\n rhsText = new Date(2021, 1, rhs.value as number).toLocaleString(locale, {\n weekday: 'long'\n });\n break;\n default: // Not needed\n }\n } else {\n // If RHS is a single literal value\n switch (lhsField.type) {\n case 'TIME_ONLY':\n // For these cases, rhs.value is stored as # of milliseconds since day-start\n rhsText = convertMsToTimeValue(rhs.value as number);\n break;\n case 'NUMBER':\n rhsText = getFormattedValue(rhs.value.toString(), locale, true, 4);\n break;\n default:\n rhsText = rhs.value as string;\n }\n }\n } else if (hasProp(rhs, 'relativeDate')) {\n const {\n relativeDate: { timePeriod, interval, datePart }\n } = rhs;\n rhsText = formatRelativeDate(translate, timePeriod, datePart, interval);\n } else {\n rhsText = rhs.values.join(', '); // If RHS is a list of values\n }\n }\n\n switch (comparator) {\n case 'IS_NULL':\n return `${lhsText} is null`;\n case 'IS_NOT_NULL':\n return `${lhsText} is not null`;\n case 'IS_TRUE':\n return `${lhsText} is true`;\n case 'IS_FALSE':\n return `${lhsText} is false`;\n case 'EQ':\n return `${lhsText} is ${rhsText}`;\n case 'NEQ':\n return `${lhsText} isn't ${rhsText}`;\n case 'IN':\n return `${lhsText} is among ${rhsText}`;\n case 'NOT_IN':\n return `${lhsText} is not among ${rhsText}`;\n case 'GT':\n return `${lhsText} > ${rhsText}`;\n case 'GTE':\n return `${lhsText} >= ${rhsText}`;\n case 'LT':\n return `${lhsText} < ${rhsText}`;\n case 'LTE':\n return `${lhsText} <= ${rhsText}`;\n case 'STARTS_WITH':\n return `${lhsText} starts with ${rhsText}`;\n case 'NOT_STARTS_WITH':\n return `${lhsText} doesn't start with ${rhsText}`;\n case 'ENDS_WITH':\n return `${lhsText} ends with ${rhsText}`;\n case 'NOT_ENDS_WITH':\n return `${lhsText} doesn't end with ${rhsText}`;\n case 'CONTAINS':\n return `${lhsText} contains ${rhsText}`;\n case 'NOT_CONTAINS':\n return `${lhsText} doesn't contain ${rhsText}`;\n default:\n return ''; // Not needed\n }\n}\n\n/** Returns a user-friendly text representation of the given node in a condition */\nfunction formatConditionNode(\n node: Condition,\n fields: Field[],\n translate: TranslationFunction<TranslationPack>,\n options?: ConditionFormatOptions\n): string {\n if (hasProp(node, 'AND')) {\n const childStrings = node.AND.map(n => formatConditionNode(n, fields, translate, options));\n return `(${childStrings.join(' AND ')})`;\n }\n\n if (hasProp(node, 'OR')) {\n const childStrings = node.OR.map(n => formatConditionNode(n, fields, translate, options));\n return `(${childStrings.join(' OR ')})`;\n }\n\n if (hasProp(node, 'NOT')) {\n const childString = formatConditionNode(node.NOT, fields, translate, options);\n if (childString.startsWith(LPAREN) && childString.endsWith(RPAREN)) {\n // Avoid double brackets when the child node is an AND/OR node\n return `NOT ${childString}`;\n }\n return `NOT (${childString})`;\n }\n\n return formatLeafCondition(node.condition, fields, translate, options); // If leaf-level is reached\n}\n\n/**\n * Returns a user-friendly text representation of a given complex condition\n * The input `fields` are used to look up display labels for the fields\n */\nexport default function formatCondition(\n condition: Condition,\n fields: Field[],\n translate: TranslationFunction<TranslationPack>,\n options?: ConditionFormatOptions\n): string {\n // Recursively format the tree, starting at the root node\n let text = formatConditionNode(condition, fields, translate, options);\n\n // If the root node is AND/OR, there will be extra parentheses. Remove them\n if (text.startsWith(LPAREN) && text.endsWith(RPAREN)) {\n text = text.slice(1, -1);\n }\n\n return text;\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import { ConditionRow } from '../ConditionBuilder.types';
2
+ export declare const INSERT_ROW = "INSERT_ROW";
3
+ export declare const UPDATE_ROW = "UPDATE_ROW";
4
+ export declare const REMOVE_ROW = "REMOVE_ROW";
5
+ interface InsertAction {
6
+ type: 'INSERT_ROW';
7
+ payload: {
8
+ insertAt: number;
9
+ };
10
+ }
11
+ interface UpdateAction {
12
+ type: 'UPDATE_ROW';
13
+ payload: {
14
+ updateAt: number;
15
+ newRow: ConditionRow;
16
+ };
17
+ }
18
+ interface RemoveAction {
19
+ type: 'REMOVE_ROW';
20
+ payload: {
21
+ removeAt: number;
22
+ };
23
+ }
24
+ declare type RowAction = InsertAction | UpdateAction | RemoveAction;
25
+ export default function rowsReducer(rows: ConditionRow[], action: RowAction): ConditionRow[];
26
+ export {};
27
+ //# sourceMappingURL=rows-reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows-reducer.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/core/rows-reducer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAazD,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,UAAU,eAAe,CAAC;AAGvC,UAAU,YAAY;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B;AACD,UAAU,YAAY;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,YAAY,CAAC;KACtB,CAAC;CACH;AACD,UAAU,YAAY;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B;AACD,aAAK,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAG5D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,SAAS,GAAG,YAAY,EAAE,CAoC3F"}
@@ -0,0 +1,50 @@
1
+ import { createUID } from '@pega/cosmos-react-core';
2
+ // Returns a new empty condition row
3
+ const getNewRow = () => {
4
+ return {
5
+ id: createUID(),
6
+ label: '',
7
+ comparator: 'IS_NOT_NULL',
8
+ lhs: { field: '' }
9
+ };
10
+ };
11
+ // Action types as variables. Helps avoid errors due to typos
12
+ export const INSERT_ROW = 'INSERT_ROW';
13
+ export const UPDATE_ROW = 'UPDATE_ROW';
14
+ export const REMOVE_ROW = 'REMOVE_ROW';
15
+ // Reducer for the condition rows
16
+ export default function rowsReducer(rows, action) {
17
+ switch (action.type) {
18
+ // Insert an empty condition at the given index
19
+ case INSERT_ROW: {
20
+ const { insertAt } = action.payload;
21
+ const newRows = [...rows.slice(0, insertAt), getNewRow(), ...rows.slice(insertAt)];
22
+ newRows.forEach((row, index) => {
23
+ // Update `label`s to have intuitive row-labels. NOTE: The logicString is updated separately for the label-change
24
+ row.label = `${index + 1}`;
25
+ });
26
+ return newRows;
27
+ }
28
+ // Update existing condition at the given index
29
+ case UPDATE_ROW: {
30
+ const { updateAt, newRow } = action.payload;
31
+ return [...rows.slice(0, updateAt), newRow, ...rows.slice(updateAt + 1)];
32
+ }
33
+ // Remove existing condition at the given index
34
+ case REMOVE_ROW: {
35
+ const { removeAt } = action.payload;
36
+ const newRows = [...rows.slice(0, removeAt), ...rows.slice(removeAt + 1)];
37
+ if (newRows.length === 0) {
38
+ newRows.push(getNewRow()); // Ensure that there is always at least one row
39
+ }
40
+ newRows.forEach((row, index) => {
41
+ // Update `label`s to have intuitive row-labels. NOTE: The logicString is updated separately for the label-change
42
+ row.label = `${index + 1}`;
43
+ });
44
+ return newRows;
45
+ }
46
+ default:
47
+ return rows;
48
+ }
49
+ }
50
+ //# sourceMappingURL=rows-reducer.js.map