@rettangoli/ui 1.0.0-rc13 → 1.0.0-rc14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rettangoli-iife-layout.min.js +3 -0
- package/dist/rettangoli-iife-ui.min.js +133 -61
- package/package.json +7 -3
- package/src/components/form/form.handlers.js +328 -152
- package/src/components/form/form.methods.js +199 -0
- package/src/components/form/form.schema.yaml +16 -271
- package/src/components/form/form.store.js +398 -95
- package/src/components/form/form.view.yaml +67 -52
- package/src/components/popoverInput/popoverInput.handlers.js +61 -50
- package/src/components/popoverInput/popoverInput.schema.yaml +0 -1
- package/src/components/popoverInput/popoverInput.store.js +7 -3
- package/src/components/popoverInput/popoverInput.view.yaml +2 -2
- package/src/components/select/select.handlers.js +15 -19
- package/src/components/select/select.schema.yaml +2 -0
- package/src/components/select/select.store.js +8 -6
- package/src/components/select/select.view.yaml +4 -4
- package/src/components/sliderInput/sliderInput.handlers.js +15 -1
- package/src/entry-iife-ui.js +2 -0
- package/src/index.js +2 -0
- package/src/primitives/checkbox.js +295 -0
- package/src/primitives/textarea.js +3 -0
|
@@ -15,35 +15,74 @@ const encode = (input) => {
|
|
|
15
15
|
return ""
|
|
16
16
|
}
|
|
17
17
|
return `"${escapeHtml(String(input))}"`;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const isObjectLike = (value) => value !== null && typeof value === "object";
|
|
21
|
+
const isPlainObject = (value) => isObjectLike(value) && !Array.isArray(value);
|
|
22
|
+
const isPathLike = (path) => typeof path === "string" && path.includes(".");
|
|
23
|
+
const hasBracketPathToken = (path) => typeof path === "string" && /[\[\]]/.test(path);
|
|
24
|
+
|
|
25
|
+
function pickByPaths(obj, paths) {
|
|
26
|
+
const result = {};
|
|
27
|
+
for (const path of paths) {
|
|
28
|
+
if (typeof path !== "string" || path.length === 0) continue;
|
|
29
|
+
const value = get(obj, path);
|
|
30
|
+
if (value !== undefined) {
|
|
31
|
+
set(result, path, value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
18
35
|
}
|
|
19
36
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
function normalizeWhenDirectives(form) {
|
|
38
|
+
if (!isPlainObject(form) || !Array.isArray(form.fields)) {
|
|
39
|
+
return form;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const normalizeFields = (fields = []) =>
|
|
43
|
+
fields.map((field) => {
|
|
44
|
+
if (!isPlainObject(field)) {
|
|
45
|
+
return field;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof field.$when === "string" && field.$when.trim().length > 0) {
|
|
49
|
+
const { $when, ...rest } = field;
|
|
50
|
+
const normalizedField = Array.isArray(rest.fields)
|
|
51
|
+
? { ...rest, fields: normalizeFields(rest.fields) }
|
|
52
|
+
: rest;
|
|
53
|
+
return {
|
|
54
|
+
[`$if ${$when}`]: normalizedField,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (Array.isArray(field.fields)) {
|
|
59
|
+
return {
|
|
60
|
+
...field,
|
|
61
|
+
fields: normalizeFields(field.fields),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return field;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
...form,
|
|
70
|
+
fields: normalizeFields(form.fields),
|
|
71
|
+
};
|
|
25
72
|
}
|
|
26
73
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
content: ''
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Lodash-like utility functions for nested property access
|
|
38
|
-
const get = (obj, path, defaultValue = undefined) => {
|
|
39
|
-
if (!path) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const keys = path.split(/[\[\].]/).filter((key) => key !== "");
|
|
74
|
+
// Nested property access utilities
|
|
75
|
+
export const get = (obj, path, defaultValue = undefined) => {
|
|
76
|
+
if (!path) return defaultValue;
|
|
77
|
+
if (!isObjectLike(obj)) return defaultValue;
|
|
78
|
+
if (hasBracketPathToken(path)) return defaultValue;
|
|
79
|
+
const keys = path.split(".").filter((key) => key !== "");
|
|
43
80
|
let current = obj;
|
|
44
|
-
|
|
45
81
|
for (const key of keys) {
|
|
46
82
|
if (current === null || current === undefined || !(key in current)) {
|
|
83
|
+
if (Object.prototype.hasOwnProperty.call(obj, path)) {
|
|
84
|
+
return obj[path];
|
|
85
|
+
}
|
|
47
86
|
return defaultValue;
|
|
48
87
|
}
|
|
49
88
|
current = current[key];
|
|
@@ -51,16 +90,21 @@ const get = (obj, path, defaultValue = undefined) => {
|
|
|
51
90
|
return current;
|
|
52
91
|
};
|
|
53
92
|
|
|
54
|
-
const set = (obj, path, value) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
93
|
+
export const set = (obj, path, value) => {
|
|
94
|
+
if (!isObjectLike(obj) || typeof path !== "string" || path.length === 0) {
|
|
95
|
+
return obj;
|
|
96
|
+
}
|
|
97
|
+
if (hasBracketPathToken(path)) {
|
|
98
|
+
return obj;
|
|
99
|
+
}
|
|
100
|
+
const keys = path.split(".").filter((key) => key !== "");
|
|
101
|
+
if (keys.length === 0) {
|
|
102
|
+
return obj;
|
|
103
|
+
}
|
|
104
|
+
if (isPathLike(path) && Object.prototype.hasOwnProperty.call(obj, path)) {
|
|
59
105
|
delete obj[path];
|
|
60
106
|
}
|
|
61
|
-
|
|
62
107
|
let current = obj;
|
|
63
|
-
|
|
64
108
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
65
109
|
const key = keys[i];
|
|
66
110
|
if (
|
|
@@ -68,19 +112,15 @@ const set = (obj, path, value) => {
|
|
|
68
112
|
typeof current[key] !== "object" ||
|
|
69
113
|
current[key] === null
|
|
70
114
|
) {
|
|
71
|
-
|
|
72
|
-
const nextKey = keys[i + 1];
|
|
73
|
-
const isArrayIndex = /^\d+$/.test(nextKey);
|
|
74
|
-
current[key] = isArrayIndex ? [] : {};
|
|
115
|
+
current[key] = {};
|
|
75
116
|
}
|
|
76
117
|
current = current[key];
|
|
77
118
|
}
|
|
78
|
-
|
|
79
119
|
current[keys[keys.length - 1]] = value;
|
|
80
120
|
return obj;
|
|
81
121
|
};
|
|
82
122
|
|
|
83
|
-
const blacklistedAttrs = ["id", "class", "style", "slot", "form", "defaultValues", "
|
|
123
|
+
const blacklistedAttrs = ["id", "class", "style", "slot", "form", "defaultValues", "disabled"];
|
|
84
124
|
|
|
85
125
|
const stringifyAttrs = (props = {}) => {
|
|
86
126
|
return Object.entries(props)
|
|
@@ -89,100 +129,363 @@ const stringifyAttrs = (props = {}) => {
|
|
|
89
129
|
.join(" ");
|
|
90
130
|
};
|
|
91
131
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
132
|
+
// --- Validation ---
|
|
133
|
+
|
|
134
|
+
const PATTERN_PRESETS = {
|
|
135
|
+
email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
136
|
+
url: /^https?:\/\/.+/,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const DEFAULT_MESSAGES = {
|
|
140
|
+
required: "This field is required",
|
|
141
|
+
minLength: (val) => `Must be at least ${val} characters`,
|
|
142
|
+
maxLength: (val) => `Must be at most ${val} characters`,
|
|
143
|
+
pattern: "Invalid format",
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const validateField = (field, value) => {
|
|
147
|
+
// Check required
|
|
148
|
+
if (field.required) {
|
|
149
|
+
const isEmpty =
|
|
150
|
+
value === undefined ||
|
|
151
|
+
value === null ||
|
|
152
|
+
value === "" ||
|
|
153
|
+
(typeof value === "boolean" && value === false);
|
|
154
|
+
// For numbers, 0 is a valid value
|
|
155
|
+
const isEmptyNumber = field.type === "input-number" && value === null;
|
|
156
|
+
const shouldFail = field.type === "input-number" ? isEmptyNumber : isEmpty;
|
|
157
|
+
|
|
158
|
+
if (shouldFail) {
|
|
159
|
+
if (typeof field.required === "object" && field.required.message) {
|
|
160
|
+
return field.required.message;
|
|
161
|
+
}
|
|
162
|
+
return DEFAULT_MESSAGES.required;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Check rules
|
|
167
|
+
if (Array.isArray(field.rules)) {
|
|
168
|
+
for (const rule of field.rules) {
|
|
169
|
+
const error = validateRule(rule, value);
|
|
170
|
+
if (error) return error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return null;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const validateRule = (rule, value) => {
|
|
178
|
+
// Skip validation on empty values (required handles that)
|
|
179
|
+
if (value === undefined || value === null || value === "") return null;
|
|
180
|
+
|
|
181
|
+
const strValue = String(value);
|
|
182
|
+
|
|
183
|
+
switch (rule.rule) {
|
|
184
|
+
case "minLength": {
|
|
185
|
+
if (strValue.length < rule.value) {
|
|
186
|
+
return rule.message || DEFAULT_MESSAGES.minLength(rule.value);
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
case "maxLength": {
|
|
191
|
+
if (strValue.length > rule.value) {
|
|
192
|
+
return rule.message || DEFAULT_MESSAGES.maxLength(rule.value);
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
case "pattern": {
|
|
197
|
+
const preset = PATTERN_PRESETS[rule.value];
|
|
198
|
+
let regex = preset;
|
|
199
|
+
if (!regex) {
|
|
200
|
+
try {
|
|
201
|
+
regex = new RegExp(rule.value);
|
|
202
|
+
} catch {
|
|
203
|
+
return rule.message || DEFAULT_MESSAGES.pattern;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!regex.test(strValue)) {
|
|
207
|
+
return rule.message || DEFAULT_MESSAGES.pattern;
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
default:
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const validateForm = (fields, formValues) => {
|
|
217
|
+
const errors = {};
|
|
218
|
+
const dataFields = collectAllDataFields(fields);
|
|
219
|
+
|
|
220
|
+
for (const field of dataFields) {
|
|
221
|
+
const value = get(formValues, field.name);
|
|
222
|
+
const error = validateField(field, value);
|
|
223
|
+
if (error) {
|
|
224
|
+
errors[field.name] = error;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
valid: Object.keys(errors).length === 0,
|
|
230
|
+
errors,
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
// --- Field helpers ---
|
|
235
|
+
|
|
236
|
+
const DISPLAY_TYPES = ["section", "read-only-text", "slot"];
|
|
237
|
+
|
|
238
|
+
export const isDataField = (field) => {
|
|
239
|
+
return !DISPLAY_TYPES.includes(field.type);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const collectAllDataFields = (fields) => {
|
|
243
|
+
const result = [];
|
|
244
|
+
for (const field of fields) {
|
|
245
|
+
if (field.type === "section" && Array.isArray(field.fields)) {
|
|
246
|
+
result.push(...collectAllDataFields(field.fields));
|
|
247
|
+
} else if (isDataField(field)) {
|
|
248
|
+
result.push(field);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export const getDefaultValue = (field) => {
|
|
255
|
+
switch (field.type) {
|
|
256
|
+
case "input-text":
|
|
257
|
+
case "input-textarea":
|
|
258
|
+
case "popover-input":
|
|
259
|
+
return "";
|
|
260
|
+
case "input-number":
|
|
261
|
+
return null;
|
|
262
|
+
case "select":
|
|
263
|
+
return null;
|
|
264
|
+
case "checkbox":
|
|
265
|
+
return false;
|
|
266
|
+
case "color-picker":
|
|
267
|
+
return "#000000";
|
|
268
|
+
case "slider":
|
|
269
|
+
case "slider-with-input":
|
|
270
|
+
return field.min !== undefined ? field.min : 0;
|
|
271
|
+
case "image":
|
|
272
|
+
return null;
|
|
273
|
+
default:
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export const flattenFields = (fields, startIdx = 0) => {
|
|
279
|
+
const result = [];
|
|
280
|
+
let idx = startIdx;
|
|
95
281
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
282
|
+
for (const field of fields) {
|
|
283
|
+
if (field.type === "section") {
|
|
284
|
+
result.push({
|
|
285
|
+
...field,
|
|
286
|
+
_isSection: true,
|
|
287
|
+
_idx: idx,
|
|
288
|
+
});
|
|
289
|
+
idx++;
|
|
290
|
+
if (Array.isArray(field.fields)) {
|
|
291
|
+
const nested = flattenFields(field.fields, idx);
|
|
292
|
+
result.push(...nested);
|
|
293
|
+
idx += nested.length;
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
result.push({
|
|
297
|
+
...field,
|
|
298
|
+
_isSection: false,
|
|
299
|
+
_idx: idx,
|
|
300
|
+
});
|
|
301
|
+
idx++;
|
|
302
|
+
}
|
|
99
303
|
}
|
|
100
304
|
|
|
101
|
-
return
|
|
305
|
+
return result;
|
|
102
306
|
};
|
|
103
307
|
|
|
308
|
+
// --- Store ---
|
|
309
|
+
|
|
310
|
+
export const createInitialState = () =>
|
|
311
|
+
Object.freeze({
|
|
312
|
+
formValues: {},
|
|
313
|
+
errors: {},
|
|
314
|
+
reactiveMode: false,
|
|
315
|
+
tooltipState: {
|
|
316
|
+
open: false,
|
|
317
|
+
x: 0,
|
|
318
|
+
y: 0,
|
|
319
|
+
content: "",
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
export const selectForm = ({ state, props }) => {
|
|
324
|
+
const { form = {} } = props || {};
|
|
325
|
+
const normalizedForm = normalizeWhenDirectives(form);
|
|
326
|
+
const context = isPlainObject(props?.context) ? props.context : {};
|
|
327
|
+
const stateFormValues = isPlainObject(state?.formValues)
|
|
328
|
+
? state.formValues
|
|
329
|
+
: {};
|
|
330
|
+
const mergedContext = {
|
|
331
|
+
...context,
|
|
332
|
+
...stateFormValues,
|
|
333
|
+
formValues: stateFormValues,
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
if (Object.keys(mergedContext).length > 0) {
|
|
337
|
+
return parseAndRender(normalizedForm, mergedContext);
|
|
338
|
+
}
|
|
339
|
+
return normalizedForm;
|
|
340
|
+
};
|
|
104
341
|
|
|
105
342
|
export const selectViewData = ({ state, props }) => {
|
|
106
343
|
const containerAttrString = stringifyAttrs(props);
|
|
107
|
-
|
|
108
344
|
const form = selectForm({ state, props });
|
|
109
|
-
const fields =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
345
|
+
const fields = form.fields || [];
|
|
346
|
+
const formDisabled = !!props?.disabled;
|
|
347
|
+
|
|
348
|
+
// Flatten fields for template iteration
|
|
349
|
+
const flatFields = flattenFields(fields);
|
|
350
|
+
|
|
351
|
+
// Enrich each field with computed properties
|
|
352
|
+
flatFields.forEach((field, arrIdx) => {
|
|
353
|
+
field._arrIdx = arrIdx;
|
|
354
|
+
|
|
355
|
+
if (field._isSection) return;
|
|
356
|
+
|
|
357
|
+
const isData = isDataField(field);
|
|
358
|
+
field._disabled = formDisabled || !!field.disabled;
|
|
359
|
+
|
|
360
|
+
if (isData && field.name) {
|
|
361
|
+
field._error = state.errors[field.name] || null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Type-specific computed props
|
|
365
|
+
if (field.type === "input-text") {
|
|
366
|
+
field._inputType = field.inputType || "text";
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (field.type === "select") {
|
|
370
|
+
const val = get(state.formValues, field.name);
|
|
371
|
+
field._selectedValue = val !== undefined ? val : null;
|
|
372
|
+
field.placeholder = field.placeholder || "";
|
|
373
|
+
// clearable defaults to true; noClear is the inverse
|
|
374
|
+
field.noClear = field.clearable === false;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (field.type === "image") {
|
|
378
|
+
const src = get(state.formValues, field.name);
|
|
379
|
+
field._imageSrc = src && String(src).trim() ? src : null;
|
|
380
|
+
field.placeholderText = field.placeholderText || "No Image";
|
|
121
381
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
field.imageSrc = src && src.trim() ? src : null;
|
|
126
|
-
// Set placeholder text
|
|
127
|
-
field.placeholderText = field.placeholder || "No Image";
|
|
382
|
+
|
|
383
|
+
if (field.type === "read-only-text") {
|
|
384
|
+
field.content = field.content || "";
|
|
128
385
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
field.
|
|
386
|
+
|
|
387
|
+
if (field.type === "checkbox") {
|
|
388
|
+
const inlineText = typeof field.content === "string"
|
|
389
|
+
? field.content
|
|
390
|
+
: (typeof field.checkboxLabel === "string" ? field.checkboxLabel : "");
|
|
391
|
+
field._checkboxText = inlineText;
|
|
135
392
|
}
|
|
136
393
|
});
|
|
137
394
|
|
|
395
|
+
// Actions
|
|
396
|
+
const actions = form.actions || { buttons: [] };
|
|
397
|
+
const layout = actions.layout || "split";
|
|
398
|
+
const buttons = (actions.buttons || []).map((btn, i) => ({
|
|
399
|
+
...btn,
|
|
400
|
+
_globalIdx: i,
|
|
401
|
+
variant: btn.variant || "se",
|
|
402
|
+
_disabled: formDisabled || !!btn.disabled,
|
|
403
|
+
pre: btn.pre || "",
|
|
404
|
+
suf: btn.suf || "",
|
|
405
|
+
}));
|
|
406
|
+
|
|
407
|
+
let actionsData;
|
|
408
|
+
if (layout === "split") {
|
|
409
|
+
actionsData = {
|
|
410
|
+
_layout: "split",
|
|
411
|
+
buttons,
|
|
412
|
+
_leftButtons: buttons.filter((b) => b.align === "left"),
|
|
413
|
+
_rightButtons: buttons.filter((b) => b.align !== "left"),
|
|
414
|
+
};
|
|
415
|
+
} else {
|
|
416
|
+
actionsData = {
|
|
417
|
+
_layout: layout,
|
|
418
|
+
buttons,
|
|
419
|
+
_allButtons: buttons,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
|
|
138
423
|
return {
|
|
139
|
-
key: props?.key,
|
|
140
424
|
containerAttrString,
|
|
141
425
|
title: form?.title || "",
|
|
142
426
|
description: form?.description || "",
|
|
143
|
-
|
|
144
|
-
actions:
|
|
145
|
-
buttons: [],
|
|
146
|
-
},
|
|
427
|
+
flatFields,
|
|
428
|
+
actions: actionsData,
|
|
147
429
|
formValues: state.formValues,
|
|
148
430
|
tooltipState: state.tooltipState,
|
|
149
431
|
};
|
|
150
432
|
};
|
|
151
433
|
|
|
152
|
-
export const selectState = ({ state }) => {
|
|
153
|
-
return state;
|
|
154
|
-
};
|
|
155
|
-
|
|
156
434
|
export const selectFormValues = ({ state, props }) => {
|
|
157
435
|
const form = selectForm({ state, props });
|
|
158
|
-
|
|
159
|
-
return
|
|
436
|
+
const dataFields = collectAllDataFields(form.fields || []);
|
|
437
|
+
return pickByPaths(
|
|
160
438
|
state.formValues,
|
|
161
|
-
|
|
439
|
+
dataFields.map((f) => f.name).filter((name) => typeof name === "string" && name.length > 0),
|
|
162
440
|
);
|
|
163
441
|
};
|
|
164
442
|
|
|
165
|
-
export const getFormFieldValue = ({ state }, name) => {
|
|
166
|
-
return get(state.formValues, name);
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
export const setFormValues = ({ state }, payload = {}) => {
|
|
170
|
-
state.formValues = payload.formValues || {};
|
|
171
|
-
};
|
|
172
|
-
|
|
173
443
|
export const setFormFieldValue = ({ state, props }, payload = {}) => {
|
|
174
444
|
const { name, value } = payload;
|
|
175
|
-
if (!name)
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
445
|
+
if (!name) return;
|
|
178
446
|
set(state.formValues, name, value);
|
|
179
|
-
|
|
447
|
+
pruneHiddenValues({ state, props });
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
export const pruneHiddenValues = ({ state, props }) => {
|
|
451
|
+
if (!props) return;
|
|
452
|
+
// Prune to only visible field names
|
|
180
453
|
const form = selectForm({ state, props });
|
|
181
|
-
const
|
|
454
|
+
const dataFields = collectAllDataFields(form.fields || []);
|
|
455
|
+
state.formValues = pickByPaths(
|
|
182
456
|
state.formValues,
|
|
183
|
-
|
|
457
|
+
dataFields.map((f) => f.name).filter((name) => typeof name === "string" && name.length > 0),
|
|
184
458
|
);
|
|
185
|
-
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
export const setFormValues = ({ state }, payload = {}) => {
|
|
462
|
+
const { values } = payload;
|
|
463
|
+
if (!values || typeof values !== "object") return;
|
|
464
|
+
Object.keys(values).forEach((key) => {
|
|
465
|
+
set(state.formValues, key, values[key]);
|
|
466
|
+
});
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
export const resetFormValues = ({ state }, payload = {}) => {
|
|
470
|
+
const { defaultValues = {} } = payload;
|
|
471
|
+
state.formValues = defaultValues ? structuredClone(defaultValues) : {};
|
|
472
|
+
state.errors = {};
|
|
473
|
+
state.reactiveMode = false;
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
export const setErrors = ({ state }, payload = {}) => {
|
|
477
|
+
state.errors = payload.errors || {};
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
export const clearFieldError = ({ state }, payload = {}) => {
|
|
481
|
+
const { name } = payload;
|
|
482
|
+
if (name && state.errors[name]) {
|
|
483
|
+
delete state.errors[name];
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
export const setReactiveMode = ({ state }) => {
|
|
488
|
+
state.reactiveMode = true;
|
|
186
489
|
};
|
|
187
490
|
|
|
188
491
|
export const showTooltip = ({ state }, payload = {}) => {
|
|
@@ -198,6 +501,6 @@ export const showTooltip = ({ state }, payload = {}) => {
|
|
|
198
501
|
export const hideTooltip = ({ state }) => {
|
|
199
502
|
state.tooltipState = {
|
|
200
503
|
...state.tooltipState,
|
|
201
|
-
open: false
|
|
504
|
+
open: false,
|
|
202
505
|
};
|
|
203
506
|
};
|