@syncfusion/ej2-react-form-builder 0.1.0-beta → 35.1.42

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 (160) hide show
  1. package/README.md +81 -36
  2. package/diConfig.json +148 -0
  3. package/dist/ej2-react-form-builder.min.js +10 -0
  4. package/dist/ej2-react-form-builder.umd.min.js +11 -0
  5. package/dist/ej2-react-form-builder.umd.min.js.map +1 -0
  6. package/dist/es6/ej2-react-form-builder.es2015.js +60 -0
  7. package/dist/es6/ej2-react-form-builder.es2015.js.map +1 -0
  8. package/form-builder.d.ts +4 -0
  9. package/form-builder.js +4 -0
  10. package/index.d.ts +2 -4
  11. package/index.js +2 -4
  12. package/license +6 -13
  13. package/package.json +19 -43
  14. package/src/form-builder/formbuilder.component.d.ts +37 -0
  15. package/src/form-builder/formbuilder.component.js +50 -0
  16. package/src/form-builder/index.d.ts +2 -0
  17. package/src/form-builder/index.js +2 -0
  18. package/src/form-builder/toolboxitems-directive.d.ts +28 -0
  19. package/src/form-builder/toolboxitems-directive.js +47 -0
  20. package/src/global.js +1 -0
  21. package/src/index.d.ts +2 -16
  22. package/src/index.js +2 -6
  23. package/Common/CheckboxGroup.d.ts +0 -13
  24. package/Common/CheckboxGroup.js +0 -50
  25. package/Common/ConditionalRuleEngine.d.ts +0 -296
  26. package/Common/ConditionalRuleEngine.js +0 -566
  27. package/Common/CustomTabComponent.d.ts +0 -17
  28. package/Common/CustomTabComponent.js +0 -30
  29. package/Common/CustomValidationEngine.d.ts +0 -58
  30. package/Common/CustomValidationEngine.js +0 -146
  31. package/Common/DataGridComponent.d.ts +0 -20
  32. package/Common/DataGridComponent.js +0 -273
  33. package/Common/FormValidator.d.ts +0 -485
  34. package/Common/FormValidator.js +0 -575
  35. package/Common/MinMaxRuleEngine.d.ts +0 -105
  36. package/Common/MinMaxRuleEngine.js +0 -365
  37. package/Common/StaticHtmlRenderer.d.ts +0 -14
  38. package/Common/StaticHtmlRenderer.js +0 -24
  39. package/Common/expressions/DependencyTracker.d.ts +0 -30
  40. package/Common/expressions/DependencyTracker.js +0 -128
  41. package/Common/expressions/ExpressionEngine.d.ts +0 -95
  42. package/Common/expressions/ExpressionEngine.js +0 -506
  43. package/Common/expressions/ExpressionParser.d.ts +0 -41
  44. package/Common/expressions/ExpressionParser.js +0 -269
  45. package/Common/expressions/useGridExpressions.d.ts +0 -12
  46. package/Common/expressions/useGridExpressions.js +0 -71
  47. package/Common/globalFormId.d.ts +0 -26
  48. package/Common/globalFormId.js +0 -45
  49. package/Common/json-converter.d.ts +0 -444
  50. package/Common/json-converter.js +0 -1184
  51. package/Common/parser.d.ts +0 -98
  52. package/Common/parser.js +0 -753
  53. package/Common/utils.d.ts +0 -130
  54. package/Common/utils.js +0 -574
  55. package/src/FormBuilder.d.ts +0 -211
  56. package/src/FormBuilder.js +0 -1299
  57. package/src/components/Database/ConnectionForm.d.ts +0 -8
  58. package/src/components/Database/ConnectionForm.js +0 -28
  59. package/src/components/TopBar.d.ts +0 -10
  60. package/src/components/TopBar.js +0 -7
  61. package/src/components/icons/ComponentIcons.d.ts +0 -44
  62. package/src/components/icons/ComponentIcons.js +0 -40
  63. package/src/components/layout/FormFieldWrapper.d.ts +0 -41
  64. package/src/components/layout/FormFieldWrapper.js +0 -112
  65. package/src/components/layout/LeftPane.d.ts +0 -23
  66. package/src/components/layout/LeftPane.js +0 -310
  67. package/src/components/layout/ListBoxPane.d.ts +0 -24
  68. package/src/components/layout/ListBoxPane.js +0 -94
  69. package/src/components/layout/MainSection.d.ts +0 -39
  70. package/src/components/layout/MainSection.js +0 -1766
  71. package/src/components/layout/Preview.d.ts +0 -12
  72. package/src/components/layout/Preview.js +0 -337
  73. package/src/components/layout/RightPane.d.ts +0 -22
  74. package/src/components/layout/RightPane.js +0 -370
  75. package/src/components/theme/ThemeSwitcher.d.ts +0 -14
  76. package/src/components/theme/ThemeSwitcher.js +0 -24
  77. package/src/components/theme/theme-constant.d.ts +0 -37
  78. package/src/components/theme/theme-constant.js +0 -23
  79. package/src/config/component-properties.json +0 -4929
  80. package/src/config/form-setting.json +0 -56
  81. package/src/config/locale.d.ts +0 -449
  82. package/src/config/locale.js +0 -449
  83. package/src/context/FormSchemaContext.d.ts +0 -32
  84. package/src/context/FormSchemaContext.js +0 -155
  85. package/src/context/LocalizationContext.d.ts +0 -27
  86. package/src/context/LocalizationContext.js +0 -43
  87. package/src/context/ThemeContext.d.ts +0 -23
  88. package/src/context/ThemeContext.js +0 -161
  89. package/src/context/contexts.d.ts +0 -6
  90. package/src/context/contexts.js +0 -6
  91. package/src/context/defaultFormSchema.d.ts +0 -6
  92. package/src/context/defaultFormSchema.js +0 -20
  93. package/src/defaultPalette.d.ts +0 -9
  94. package/src/defaultPalette.js +0 -45
  95. package/src/defaultTemplate.d.ts +0 -3
  96. package/src/defaultTemplate.js +0 -185
  97. package/src/import/schemaImportUtils.d.ts +0 -24
  98. package/src/import/schemaImportUtils.js +0 -121
  99. package/src/types/ActionButtons.d.ts +0 -44
  100. package/src/types/ActionButtons.js +0 -27
  101. package/src/types/ComponentProperties.d.ts +0 -33
  102. package/src/types/ComponentProperties.js +0 -2
  103. package/src/types/FormSchema.d.ts +0 -585
  104. package/src/types/FormSchema.js +0 -147
  105. package/src/types/connection.d.ts +0 -19
  106. package/src/types/connection.js +0 -9
  107. package/src/utils/AttributesEditor.d.ts +0 -13
  108. package/src/utils/AttributesEditor.js +0 -117
  109. package/src/utils/ButtonGroupEditor.d.ts +0 -15
  110. package/src/utils/ButtonGroupEditor.js +0 -141
  111. package/src/utils/ChoiceBasedFieldEditor.d.ts +0 -16
  112. package/src/utils/ChoiceBasedFieldEditor.js +0 -87
  113. package/src/utils/ClipboardHelper.d.ts +0 -26
  114. package/src/utils/ClipboardHelper.js +0 -83
  115. package/src/utils/ColumnBuilder.d.ts +0 -11
  116. package/src/utils/ColumnBuilder.js +0 -153
  117. package/src/utils/ColumnSpanEditor.d.ts +0 -8
  118. package/src/utils/ColumnSpanEditor.js +0 -98
  119. package/src/utils/ConditionDataEditor.d.ts +0 -29
  120. package/src/utils/ConditionDataEditor.js +0 -177
  121. package/src/utils/ConditionalEditorUtils.d.ts +0 -27
  122. package/src/utils/ConditionalEditorUtils.js +0 -310
  123. package/src/utils/ConditionsEditor.d.ts +0 -20
  124. package/src/utils/ConditionsEditor.js +0 -571
  125. package/src/utils/CustomAccordion.d.ts +0 -13
  126. package/src/utils/CustomAccordion.js +0 -38
  127. package/src/utils/CustomValidationEditor.d.ts +0 -11
  128. package/src/utils/CustomValidationEditor.js +0 -208
  129. package/src/utils/DataSourceCollector.d.ts +0 -3
  130. package/src/utils/DataSourceCollector.js +0 -252
  131. package/src/utils/ExpressionEditor.d.ts +0 -13
  132. package/src/utils/ExpressionEditor.js +0 -99
  133. package/src/utils/FormSettingsPanel.d.ts +0 -9
  134. package/src/utils/FormSettingsPanel.js +0 -60
  135. package/src/utils/LookupConfig.d.ts +0 -11
  136. package/src/utils/LookupConfig.js +0 -159
  137. package/src/utils/MinMaxValueEditor.d.ts +0 -25
  138. package/src/utils/MinMaxValueEditor.js +0 -188
  139. package/src/utils/OptionsEditor.d.ts +0 -8
  140. package/src/utils/OptionsEditor.js +0 -79
  141. package/src/utils/PropertyRenderer.d.ts +0 -22
  142. package/src/utils/PropertyRenderer.js +0 -210
  143. package/src/utils/ValueRenderer.d.ts +0 -2
  144. package/src/utils/ValueRenderer.js +0 -91
  145. package/src/utils/ej2DbAdaptor.d.ts +0 -6
  146. package/src/utils/ej2DbAdaptor.js +0 -38
  147. package/src/utils/mappingHeuristics.d.ts +0 -10
  148. package/src/utils/mappingHeuristics.js +0 -33
  149. package/src/utils/renderComponent.d.ts +0 -18
  150. package/src/utils/renderComponent.js +0 -300
  151. package/styles/tailwind3.css +0 -67
  152. package/styles/themes/action-buttons.css +0 -110
  153. package/styles/themes/datagrid.css +0 -380
  154. package/styles/themes/drag-reorder.css +0 -248
  155. package/styles/themes/import-dialog.css +0 -292
  156. package/styles/themes/index.css +0 -658
  157. package/styles/themes/left-pane.css +0 -253
  158. package/styles/themes/options-editor.css +0 -63
  159. package/styles/themes/preview.css +0 -702
  160. package/styles/themes/property-dialog.css +0 -371
@@ -1,269 +0,0 @@
1
- /**
2
- * ExpressionParser - Parse and compile expressions
3
- *
4
- * Converts string expressions into safe, compiled functions
5
- * Supports field references, operators, functions, and conditionals
6
- * @private
7
- * @spec Expression_Engine.md
8
- */
9
- export class ExpressionParser {
10
- supportedFunctions = [
11
- 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
12
- 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
13
- 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
14
- 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS', 'INCLUDES', 'CONTAINS', 'ISNAN', 'SUPPORTEDVALUESOF', 'TOSTRING', 'DATE', 'GETTIME',
15
- 'EVERY', 'SOME'
16
- ];
17
- availableFields = new Map();
18
- /**
19
- * Initialize parser with available fields for type validation
20
- */
21
- setAvailableFields(fields) {
22
- this.availableFields.clear();
23
- fields.forEach(field => {
24
- this.availableFields.set(field.name, field);
25
- });
26
- }
27
- validateFieldOperations(expression) {
28
- const errors = [];
29
- // Skip if no fields available
30
- if (this.availableFields.size === 0) {
31
- return errors;
32
- }
33
- // Invalid operators for string fields (allow only + for concatenation)
34
- const stringInvalidOps = ['-', '*', '/', '%', '^'];
35
- // All operators invalid for date fields
36
- const dateInvalidOps = ['-', '*', '/', '%', '^', '+'];
37
- // Track reported operator positions to avoid duplicates
38
- const reportedOperators = new Set();
39
- // Extract all field references and their surrounding operators
40
- const fieldRefPattern = /(\{[^}]+\})/g;
41
- let match;
42
- while ((match = fieldRefPattern.exec(expression)) !== null) {
43
- const fieldRef = match[0];
44
- const fieldName = fieldRef.slice(1, -1); // Remove { }
45
- const field = this.availableFields.get(fieldName);
46
- if (!field)
47
- continue; // Field not found in available fields, skip validation
48
- const fieldIndex = match.index;
49
- const fieldEndIndex = fieldIndex + fieldRef.length;
50
- // Get context around field reference (including spaces)
51
- const textBefore = expression.substring(Math.max(0, fieldIndex - 10), fieldIndex);
52
- const textAfter = expression.substring(fieldEndIndex, Math.min(expression.length, fieldEndIndex + 10));
53
- // Extract the operator if present (skip spaces)
54
- const operatorBefore = textBefore.trimEnd().slice(-1);
55
- const operatorAfter = textAfter.trimStart().charAt(0);
56
- // Calculate actual position of operators in the original expression
57
- const operatorBeforePos = fieldIndex - (textBefore.length - textBefore.trimEnd().length) - 1;
58
- const operatorAfterPos = fieldEndIndex + (textAfter.length - textAfter.trimStart().length);
59
- // For STRING fields: reject all operators except +
60
- if (field.type === 'string' && !field.format) {
61
- if (operatorBefore && stringInvalidOps.includes(operatorBefore)) {
62
- const key = `${operatorBeforePos}:${operatorBefore}`;
63
- if (!reportedOperators.has(key)) {
64
- errors.push(`Cannot perform '${operatorBefore}' operation on string field '{${fieldName}}'`);
65
- reportedOperators.add(key);
66
- }
67
- }
68
- if (operatorAfter && stringInvalidOps.includes(operatorAfter)) {
69
- const key = `${operatorAfterPos}:${operatorAfter}`;
70
- if (!reportedOperators.has(key)) {
71
- errors.push(`Cannot perform '${operatorAfter}' operation on string field '{${fieldName}}'`);
72
- reportedOperators.add(key);
73
- }
74
- }
75
- }
76
- // For DATE fields: reject ALL operators including +
77
- if (field.format === 'date' || field.format === 'date-time' || field.format === 'time') {
78
- if (operatorBefore && dateInvalidOps.includes(operatorBefore)) {
79
- const key = `${operatorBeforePos}:${operatorBefore}`;
80
- if (!reportedOperators.has(key)) {
81
- errors.push(`Cannot perform '${operatorBefore}' operation on date field '{${fieldName}}'`);
82
- reportedOperators.add(key);
83
- }
84
- }
85
- if (operatorAfter && dateInvalidOps.includes(operatorAfter)) {
86
- const key = `${operatorAfterPos}:${operatorAfter}`;
87
- if (!reportedOperators.has(key)) {
88
- errors.push(`Cannot perform '${operatorAfter}' operation on date field '{${fieldName}}'`);
89
- reportedOperators.add(key);
90
- }
91
- }
92
- }
93
- }
94
- return errors;
95
- }
96
- /**
97
- * Validate expression syntax
98
- */
99
- validate(expression) {
100
- const errors = [];
101
- if (!expression || expression.trim() === '') {
102
- return { valid: true, errors: [] };
103
- }
104
- // Check for unbalanced braces
105
- const openBraces = (expression.match(/\{/g) || []).length;
106
- const closeBraces = (expression.match(/\}/g) || []).length;
107
- if (openBraces !== closeBraces) {
108
- errors.push('Unbalanced braces in expression');
109
- }
110
- // Check for unbalanced parentheses
111
- const openParens = (expression.match(/\(/g) || []).length;
112
- const closeParens = (expression.match(/\)/g) || []).length;
113
- if (openParens !== closeParens) {
114
- errors.push('Unbalanced parentheses in expression');
115
- }
116
- // Check for invalid function calls
117
- const funcPattern = /(\w+)\s*\(/g;
118
- let match;
119
- while ((match = funcPattern.exec(expression)) !== null) {
120
- const funcName = match[1].toUpperCase();
121
- // Only validate uppercase-named functions
122
- if (funcName === funcName.toUpperCase() && !this.supportedFunctions.includes(funcName)) {
123
- errors.push(`Unknown function: ${funcName}`);
124
- }
125
- }
126
- // Validate field operations based on field types
127
- const fieldOpErrors = this.validateFieldOperations(expression);
128
- errors.push(...fieldOpErrors);
129
- return {
130
- valid: errors.length === 0,
131
- errors
132
- };
133
- }
134
- /**
135
- * Compile expression to executable function
136
- */
137
- compile(expression, options = {}) {
138
- try {
139
- // Set available fields for validation if provided
140
- if (options.availableFields && Array.isArray(options.availableFields)) {
141
- this.setAvailableFields(options.availableFields);
142
- }
143
- // Validate expression before compiling
144
- const validation = this.validate(expression);
145
- if (!validation.valid) {
146
- console.error('Expression validation errors:', validation.errors, { expression });
147
- return () => null;
148
- }
149
- // Replace field references with context lookups
150
- let compiled = expression;
151
- // Handle field references FIRST (this includes refs inside ${...})
152
- compiled = this.compileFieldReferences(compiled);
153
- compiled = options.isCustomValidation ? this.compileInputReferences(compiled) : compiled;
154
- // Handle bare function calls SECOND (e.g., SUM([...]) without braces)
155
- compiled = this.compileBareFunctionCalls(compiled);
156
- // Handle math expressions THIRD (now ${} and {} contain already-replaced refs)
157
- compiled = this.compileMatrixExpressions(compiled);
158
- // Create function that safely evaluates the expression
159
- return (context) => {
160
- try {
161
- // This uses Function constructor with controlled context binding
162
- // which is safer than eval() but still allows expressions
163
- // Note: compiled expression already uses context['field'] syntax
164
- const func = new Function('context', `
165
- try {
166
- return ${compiled};
167
- } catch (e) {
168
- return null;
169
- }
170
- `);
171
- return func(context);
172
- }
173
- catch (e) {
174
- console.error('Expression execution error:', e, { expression, compiled });
175
- return null;
176
- }
177
- };
178
- }
179
- catch (error) {
180
- console.error('Expression compilation error:', error, { expression });
181
- return () => null;
182
- }
183
- }
184
- // Private helpers
185
- compileMatrixExpressions(expression) {
186
- let compiled = expression;
187
- const constants = ['PI', 'TRUE', 'FALSE', 'NULL', 'UNDEFINED', 'Math'];
188
- const functions = [
189
- 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
190
- 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
191
- 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
192
- 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS'
193
- ];
194
- // Create fresh regex each time to avoid lastIndex issues with g flag
195
- const mathExprPattern = /\$?\{([^}]+)\}/g;
196
- // Process ${...} and {...} blocks: replace bare identifiers with context lookups
197
- compiled = compiled.replace(mathExprPattern, (_match, content) => {
198
- let transformed = content;
199
- // STEP 1: Handle function calls first
200
- // Match function names followed by ( and prefix with context.
201
- // Use negative lookbehind to avoid double-replacing (e.g., context.SUM)
202
- functions.forEach(fn => {
203
- const funcCallRegex = new RegExp(`(?<!context\\.)\\b${fn}\\b(?=\\s*\\()`, 'g');
204
- transformed = transformed.replace(funcCallRegex, `context.${fn}`);
205
- });
206
- constants.forEach(constant => {
207
- const constantRegex = new RegExp(`\\b${constant}\\b`, 'g');
208
- transformed = transformed.replace(constantRegex, `context.${constant}`);
209
- });
210
- // Return as parenthesized expression
211
- return `(${transformed})`;
212
- });
213
- return compiled;
214
- }
215
- compileBareFunctionCalls(expression) {
216
- let compiled = expression;
217
- const functions = [
218
- 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
219
- 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
220
- 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
221
- 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS'
222
- ];
223
- // Handle bare function calls like SUM([...]) that are not inside ${...} or {...}
224
- // Use negative lookbehind to avoid matching if already preceded by context.
225
- functions.forEach(fn => {
226
- const funcCallRegex = new RegExp(`(?<!context\\.)\\b${fn}\\b(?=\\s*\\()`, 'g');
227
- compiled = compiled.replace(funcCallRegex, `context.${fn}`);
228
- });
229
- return compiled;
230
- }
231
- compileFieldReferences(expression) {
232
- let compiled = expression;
233
- // Create fresh regex each time to avoid lastIndex issues with g flag
234
- const fieldRefPattern = /\{([^{}]+)\}/g;
235
- // Replace {fieldName} with context['fieldName'] or field access
236
- compiled = compiled.replace(fieldRefPattern, (match, ref) => {
237
- // Handle escaped braces
238
- if (ref.startsWith('\\') && ref.endsWith('\\')) {
239
- return match; // Keep as is
240
- }
241
- // Handle nested paths like {customer.name}
242
- return `context['${ref.replace(/\./g, '\'].[')}']`;
243
- });
244
- return compiled;
245
- }
246
- compileInputReferences(expression) {
247
- const compiled = expression;
248
- // First, protect string literals to avoid replacing 'input' inside strings
249
- const strings = [];
250
- let stringProtected = compiled;
251
- stringProtected = stringProtected.replace(/(['"`])(?:(?=(\\?))\2.)*?\1/g, (match) => {
252
- strings.push(match);
253
- return `__STRING_${strings.length - 1}__`;
254
- });
255
- // Case 1: Replace input.property with context['input'].property
256
- const inputPropertyPattern = /(?<!context\[')\binput\./g;
257
- stringProtected = stringProtected.replace(inputPropertyPattern, 'context[\'input\'].');
258
- // Case 2: Replace bare 'input' with context['input']
259
- // Use negative lookbehind to avoid replacing if already preceded by context.'
260
- const inputPattern = /(?<!context\[')\binput\b(?!\s*[(\.])/g;
261
- stringProtected = stringProtected.replace(inputPattern, 'context[\'input\']');
262
- // Restore string literals
263
- let result = stringProtected;
264
- strings.forEach((str, idx) => {
265
- result = result.replace(`__STRING_${idx}__`, str);
266
- });
267
- return result;
268
- }
269
- }
@@ -1,12 +0,0 @@
1
- import { ExpressionEngine } from './ExpressionEngine';
2
- /**
3
- * Hook to evaluate expressions for grid rows
4
- * Returns a function that calculates all expression columns for a given row
5
- * @private
6
- */
7
- export declare const useGridExpressions: () => {
8
- evaluateRowExpressions: (row: Record<string, any>, columns: any[]) => Record<string, any>;
9
- extractCalculatedColumns: (columns: any[]) => any[];
10
- engine: ExpressionEngine;
11
- parseColumnValue: (value: any, columnType?: string) => any;
12
- };
@@ -1,71 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { ExpressionEngine } from './ExpressionEngine';
3
- /**
4
- * Hook to evaluate expressions for grid rows
5
- * Returns a function that calculates all expression columns for a given row
6
- * @private
7
- */
8
- export const useGridExpressions = () => {
9
- const engine = new ExpressionEngine();
10
- /**
11
- * Convert column values to proper types (especially numbers)
12
- * Form inputs return strings, so we need to parse numeric values
13
- */
14
- const parseColumnValue = useCallback((value, columnType) => {
15
- // Handle null/undefined
16
- if (value === null || value === undefined || value === '') {
17
- return value;
18
- }
19
- // Parse number types
20
- if (columnType === 'number') {
21
- const parsed = parseFloat(String(value));
22
- return isNaN(parsed) ? 0 : parsed;
23
- }
24
- // Parse boolean types
25
- if (columnType === 'boolean') {
26
- if (typeof value === 'boolean')
27
- return value;
28
- return value === 'true' || value === '1' || value === 1 || value === true;
29
- }
30
- // Return as-is for string and other types
31
- return value;
32
- }, []);
33
- const evaluateRowExpressions = useCallback((row, columns) => {
34
- const calculatedRow = { ...row };
35
- // Find all columns with expressions
36
- const calculatedColumns = columns.filter(col => col.expression && col.expression.trim());
37
- for (const column of calculatedColumns) {
38
- if (!column.expression)
39
- continue;
40
- try {
41
- // Prepare row values with proper type conversion
42
- const typedRow = {};
43
- columns.forEach((col) => {
44
- const value = calculatedRow[col.field];
45
- typedRow[col.field] = parseColumnValue(value, col.type);
46
- });
47
- // Evaluate expression with current row as context
48
- const result = engine.evaluate(column.expression, typedRow, {
49
- throwOnError: false
50
- });
51
- // Update row with calculated value
52
- calculatedRow[column.field] = result;
53
- }
54
- catch (error) {
55
- console.error(`Failed to evaluate expression for column "${column.field}":`, error);
56
- // Keep original value or set to null on error
57
- calculatedRow[column.field] = null;
58
- }
59
- }
60
- return calculatedRow;
61
- }, [parseColumnValue]);
62
- const extractCalculatedColumns = useCallback((columns) => {
63
- return columns.filter(col => col.expression && col.expression.trim());
64
- }, []);
65
- return {
66
- evaluateRowExpressions,
67
- extractCalculatedColumns,
68
- engine,
69
- parseColumnValue
70
- };
71
- };
@@ -1,26 +0,0 @@
1
- /**
2
- * @private
3
- */
4
- export declare const setFormId: (id: string | null) => void;
5
- /**
6
- * @private
7
- */
8
- export declare const getFormId: () => string | null;
9
- /**
10
- * @private
11
- */
12
- export declare const subscribeFormId: (cb: (id: string | null) => void) => () => boolean;
13
- /**
14
- * @private
15
- */
16
- export declare const useFormId: () => string;
17
- /**
18
- * @private
19
- */
20
- declare const _default: {
21
- setFormId: (id: string | null) => void;
22
- getFormId: () => string | null;
23
- subscribeFormId: (cb: (id: string | null) => void) => () => boolean;
24
- useFormId: () => string;
25
- };
26
- export default _default;
@@ -1,45 +0,0 @@
1
- import React from 'react';
2
- let formId = null;
3
- const listeners = new Set();
4
- /**
5
- * @private
6
- */
7
- export const setFormId = (id) => {
8
- formId = id;
9
- listeners.forEach((cb) => cb(id));
10
- };
11
- /**
12
- * @private
13
- */
14
- export const getFormId = () => formId;
15
- /**
16
- * @private
17
- */
18
- export const subscribeFormId = (cb) => {
19
- listeners.add(cb);
20
- return () => listeners.delete(cb);
21
- };
22
- /**
23
- * @private
24
- */
25
- export const useFormId = () => {
26
- const [, setTick] = React.useState(0);
27
- const [id, setId] = React.useState(formId);
28
- React.useEffect(() => {
29
- const unsub = subscribeFormId((newId) => {
30
- setId(newId);
31
- setTick((t) => t + 1);
32
- });
33
- return unsub;
34
- }, []);
35
- return id;
36
- };
37
- /**
38
- * @private
39
- */
40
- export default {
41
- setFormId,
42
- getFormId,
43
- subscribeFormId,
44
- useFormId,
45
- };