@flowerforce/flower-core 3.3.1-beta.1 → 4.0.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +241 -271
- package/dist/index.esm.js +231 -270
- package/dist/src/constants/index.d.ts +5 -0
- package/dist/src/event-emitter/index.d.ts +1 -0
- package/dist/src/index.d.ts +6 -8
- package/dist/src/interfaces/CoreInterface.d.ts +23 -17
- package/dist/src/interfaces/ReducerInterface.d.ts +117 -99
- package/dist/src/{rules-matcher/interface.d.ts → interfaces/RulesMatcherInterface.d.ts} +1 -1
- package/dist/src/interfaces/SelectorsInterface.d.ts +21 -12
- package/dist/src/interfaces/Store.d.ts +2 -10
- package/dist/src/interfaces/UtilsInterface.d.ts +1 -1
- package/dist/src/interfaces/index.d.ts +3 -0
- package/dist/src/rules-matcher/RulesMatcher.d.ts +2 -0
- package/dist/src/rules-matcher/index.d.ts +2 -0
- package/dist/src/rules-matcher/utils.d.ts +2 -3
- package/dist/src/state-manager/index.d.ts +2 -0
- package/dist/src/state-manager/state-functions/FlowerCoreMergedReducers.d.ts +2 -0
- package/dist/src/state-manager/state-functions/FlowerCoreStateFunctions.d.ts +5 -0
- package/dist/src/state-manager/state-functions/FlowerDataStateFunctions.d.ts +13 -0
- package/dist/src/state-manager/state-functions/index.d.ts +4 -0
- package/dist/src/state-manager/state-selectors/FlowerCoreStateSelectors.d.ts +2 -0
- package/dist/src/state-manager/state-selectors/FlowerFormStateSelectors.d.ts +2 -0
- package/dist/src/state-manager/state-selectors/FlowerSelectorsMerged.d.ts +2 -0
- package/dist/src/state-manager/state-selectors/index.d.ts +4 -0
- package/dist/src/{FlowerCoreStateUtils.d.ts → utils/FlowerCoreStateUtils.d.ts} +2 -2
- package/dist/src/{CoreUtils.d.ts → utils/FlowerCoreUtils.d.ts} +1 -2
- package/dist/src/utils/FlowerFlowUtils.d.ts +3 -0
- package/dist/src/utils/FlowerFormCoreUtils.d.ts +2 -0
- package/dist/src/utils/index.d.ts +4 -0
- package/package.json +1 -1
- package/dist/src/FlowerCoreStateFunctions.d.ts +0 -5
- package/dist/src/FlowerCoreStateSelectors.d.ts +0 -2
- package/dist/src/RulesMatcher.d.ts +0 -5
- package/dist/src/devtoolState.d.ts +0 -2
- /package/dist/src/{Emitter.d.ts → event-emitter/Emitter.d.ts} +0 -0
package/dist/index.cjs.js
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
3
|
var tinyEmitter = require('tiny-emitter');
|
4
|
-
var _set = require('lodash/set');
|
5
|
-
var _unset = require('lodash/unset');
|
6
4
|
var _get = require('lodash/get');
|
7
|
-
var _last = require('lodash/last');
|
8
|
-
var _slice = require('lodash/slice');
|
9
|
-
var _cloneDeep = require('lodash/cloneDeep');
|
10
|
-
var lastIndexOf = require('lodash/lastIndexOf');
|
11
5
|
var find = require('lodash/find');
|
12
6
|
var keyBy = require('lodash/keyBy');
|
13
7
|
var has = require('lodash/has');
|
@@ -18,10 +12,56 @@ var mapKeys = require('lodash/mapKeys');
|
|
18
12
|
var mapValues = require('lodash/mapValues');
|
19
13
|
var _trimStart = require('lodash/trimStart');
|
20
14
|
var _intersection = require('lodash/intersection');
|
15
|
+
var _set = require('lodash/set');
|
16
|
+
var _last = require('lodash/last');
|
17
|
+
var _slice = require('lodash/slice');
|
18
|
+
var _cloneDeep = require('lodash/cloneDeep');
|
19
|
+
var lastIndexOf = require('lodash/lastIndexOf');
|
20
|
+
var _unset = require('lodash/unset');
|
21
21
|
var flat = require('flat');
|
22
22
|
|
23
23
|
const Emitter = new tinyEmitter.TinyEmitter();
|
24
24
|
|
25
|
+
exports.REDUCER_NAME = void 0;
|
26
|
+
(function (REDUCER_NAME) {
|
27
|
+
REDUCER_NAME["FLOWER_FLOW"] = "FlowerFlow";
|
28
|
+
REDUCER_NAME["FLOWER_DATA"] = "FlowerData";
|
29
|
+
})(exports.REDUCER_NAME || (exports.REDUCER_NAME = {}));
|
30
|
+
const devtoolState = {};
|
31
|
+
|
32
|
+
const FlowerStateUtils = {
|
33
|
+
getAllData: (state) => state &&
|
34
|
+
Object.entries(state ?? {}).reduce((acc, [k, v]) => ({ ...acc, [k]: v?.data ?? v }), {}),
|
35
|
+
selectFlowerFormNode: (name) => (state) => _get(state, name),
|
36
|
+
makeSelectCurrentNextRules: (name) => (state) => {
|
37
|
+
const nextRules = _get(state, [name, 'nextRules']);
|
38
|
+
const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(name)(state);
|
39
|
+
return _get(nextRules, [currentNodeId]);
|
40
|
+
},
|
41
|
+
makeSelectCurrentNodeId: (name) => (state) => {
|
42
|
+
const subState = _get(state, [name]);
|
43
|
+
const startId = _get(state, ['startId']);
|
44
|
+
return _get(subState, ['current']) || startId;
|
45
|
+
},
|
46
|
+
makeSelectNodeErrors: (name) => (state) => {
|
47
|
+
const form = FlowerStateUtils.selectFlowerFormNode(name)(state);
|
48
|
+
return createFormData(form);
|
49
|
+
}
|
50
|
+
};
|
51
|
+
const createFormData = (form) => {
|
52
|
+
const validationErrors = form && form.errors;
|
53
|
+
const allErrors = Object.values(validationErrors || {});
|
54
|
+
return {
|
55
|
+
isSubmitted: form?.isSubmitted || false,
|
56
|
+
isDirty: Object.values(form?.dirty || {}).some(Boolean) || false,
|
57
|
+
hasFocus: form?.hasFocus,
|
58
|
+
errors: form?.errors,
|
59
|
+
customErrors: form?.customErrors,
|
60
|
+
isValidating: form?.isValidating,
|
61
|
+
isValid: allErrors.flat().length === 0
|
62
|
+
};
|
63
|
+
};
|
64
|
+
|
25
65
|
const EMPTY_STRING_REGEXP = /^\s*$/;
|
26
66
|
/**
|
27
67
|
* Defines a utility object named rulesMatcherUtils, which contains various helper functions used for processing rules and data in a rule-matching context.
|
@@ -242,10 +282,6 @@ const rulesMatcher = (rules, formValue = {}, apply = true, options) => {
|
|
242
282
|
const valid = rulesMatcherUtils.checkRule(conditions, formValue, options ?? {});
|
243
283
|
return [valid === apply];
|
244
284
|
};
|
245
|
-
const MatchRules = {
|
246
|
-
rulesMatcher,
|
247
|
-
utils: rulesMatcherUtils
|
248
|
-
};
|
249
285
|
|
250
286
|
/* eslint-disable no-useless-escape */
|
251
287
|
// TODO align this set of functions to selectors and reducers functions
|
@@ -268,36 +304,12 @@ const flattenRules = (ob) => {
|
|
268
304
|
}
|
269
305
|
return result;
|
270
306
|
};
|
271
|
-
// export const searchEmptyKeyRecursively = <T extends object>(
|
272
|
-
// _key: "$and" | "$or",
|
273
|
-
// obj: T
|
274
|
-
// ) => {
|
275
|
-
// if (
|
276
|
-
// isEmpty(obj) ||
|
277
|
-
// typeof obj !== "object" ||
|
278
|
-
// Object.keys(obj).length === 0
|
279
|
-
// ) {
|
280
|
-
// return true;
|
281
|
-
// }
|
282
|
-
// if (Object.keys(obj).includes(_key)) {
|
283
|
-
// if (obj[_key] && obj[_key].length === 0) return true;
|
284
|
-
// return Object.keys(obj).map((key) =>
|
285
|
-
// searchEmptyKeyRecursively(_key, obj[key])
|
286
|
-
// );
|
287
|
-
// }
|
288
|
-
// return Object.keys(obj)
|
289
|
-
// .map((key) => searchEmptyKeyRecursively(_key, obj[key]))
|
290
|
-
// .every((v) => v === true);
|
291
|
-
// };
|
292
307
|
const getRulesExists = (rules) => {
|
293
|
-
return Object.keys(rules).length ?
|
308
|
+
return Object.keys(rules).length ? FlowUtils.mapEdge(rules) : undefined;
|
294
309
|
};
|
295
|
-
|
296
|
-
* Defines a collection of utility functions for processing rules, nodes and graph-like structures
|
297
|
-
*/
|
298
|
-
const CoreUtils = {
|
310
|
+
const FlowUtils = {
|
299
311
|
generateRulesName: (nextRules) => {
|
300
|
-
|
312
|
+
return nextRules.reduce((acc, inc) => {
|
301
313
|
const n = typeof inc.rules === 'string'
|
302
314
|
? inc.rules || '__ERROR_NAME__'
|
303
315
|
: inc.rules?.name || '__ERROR_NAME__';
|
@@ -306,7 +318,6 @@ const CoreUtils = {
|
|
306
318
|
[n]: inc.nodeId
|
307
319
|
};
|
308
320
|
}, {});
|
309
|
-
return a;
|
310
321
|
},
|
311
322
|
mapKeysDeepLodash: (obj, cb, isRecursive) => {
|
312
323
|
/* istanbul ignore next */
|
@@ -322,13 +333,13 @@ const CoreUtils = {
|
|
322
333
|
}
|
323
334
|
}
|
324
335
|
if (Array.isArray(obj)) {
|
325
|
-
return obj.map((item) =>
|
336
|
+
return obj.map((item) => FlowUtils.mapKeysDeepLodash(item, cb, true));
|
326
337
|
}
|
327
338
|
if (!isPlainObject(obj)) {
|
328
339
|
return obj;
|
329
340
|
}
|
330
341
|
const result = mapKeys(obj, cb);
|
331
|
-
return mapValues(result, (value) =>
|
342
|
+
return mapValues(result, (value) => FlowUtils.mapKeysDeepLodash(value, cb, true));
|
332
343
|
},
|
333
344
|
generateNodes: (nodes) => keyBy(nodes.map((s) => omit(s, 'nextRules')), 'nodeId'),
|
334
345
|
makeObjectRules: (nodes) => nodes.reduce((acc, inc) => ({ ...acc, [inc.nodeId]: inc.nextRules }), {}),
|
@@ -345,17 +356,18 @@ const CoreUtils = {
|
|
345
356
|
},
|
346
357
|
mapEdge: (nextNode) => {
|
347
358
|
const res = nextNode.sort((a, b) => {
|
348
|
-
const x =
|
349
|
-
const y =
|
359
|
+
const x = FlowUtils.isEmptyRules(a.rules);
|
360
|
+
const y = FlowUtils.isEmptyRules(b.rules);
|
350
361
|
return Number(x) - Number(y);
|
351
362
|
});
|
352
363
|
return res;
|
353
364
|
},
|
354
365
|
makeRules: (rules) => Object.entries(rules).reduce((acc2, [k, v]) => [...acc2, { nodeId: k, rules: v }], []),
|
366
|
+
// TODO: This function is strictly related to React nodes, could make sense to move it in the flower-react folder
|
355
367
|
generateNodesForFlowerJson: (nodes) => nodes
|
356
368
|
.filter((e) => !!_get(e, 'props.id'))
|
357
369
|
.map((e) => {
|
358
|
-
const rules =
|
370
|
+
const rules = FlowUtils.makeRules(e.props.to ?? {});
|
359
371
|
const nextRules = getRulesExists(rules);
|
360
372
|
const children = e.props.data?.children;
|
361
373
|
return {
|
@@ -368,29 +380,6 @@ const CoreUtils = {
|
|
368
380
|
disabled: e.props.disabled
|
369
381
|
};
|
370
382
|
}),
|
371
|
-
cleanPath: (name, char = '^') => _trimStart(name, char),
|
372
|
-
getPath: (idValue) => {
|
373
|
-
if (!idValue) {
|
374
|
-
return {
|
375
|
-
path: []
|
376
|
-
};
|
377
|
-
}
|
378
|
-
if (idValue === '*') {
|
379
|
-
return {
|
380
|
-
path: '*'
|
381
|
-
};
|
382
|
-
}
|
383
|
-
if (idValue.indexOf('^') === 0) {
|
384
|
-
const [flowNameFromPath, ...rest] = CoreUtils.cleanPath(idValue).split('.');
|
385
|
-
return {
|
386
|
-
flowNameFromPath,
|
387
|
-
path: rest
|
388
|
-
};
|
389
|
-
}
|
390
|
-
return {
|
391
|
-
path: idValue.split('.')
|
392
|
-
};
|
393
|
-
},
|
394
383
|
allEqual: (arr, arr2) => arr.length === arr2.length && arr.every((v) => arr2.includes(v)),
|
395
384
|
findValidRule: (nextRules, value, prefix) => find(nextRules, (rule) => {
|
396
385
|
// fix per evitare di entrare in un nodo senza regole, ma con un name,
|
@@ -410,53 +399,52 @@ const CoreUtils = {
|
|
410
399
|
if (typeof rule.rules.rules === 'string') {
|
411
400
|
return false;
|
412
401
|
}
|
413
|
-
const [valid] =
|
402
|
+
const [valid] = rulesMatcher(rule.rules.rules, value, true, {
|
414
403
|
prefix
|
415
404
|
});
|
416
405
|
return valid;
|
417
406
|
})
|
418
407
|
};
|
419
408
|
|
420
|
-
const
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
409
|
+
const FormUtils = {
|
410
|
+
cleanPath: (name, char = '^') => _trimStart(name, char),
|
411
|
+
getPath: (idValue) => {
|
412
|
+
if (!idValue) {
|
413
|
+
return {
|
414
|
+
path: []
|
415
|
+
};
|
416
|
+
}
|
417
|
+
if (idValue === '*') {
|
418
|
+
return {
|
419
|
+
path: '*'
|
420
|
+
};
|
421
|
+
}
|
422
|
+
if (idValue.indexOf('^') === 0) {
|
423
|
+
const [formName, ...rest] = FormUtils.cleanPath(idValue).split('.');
|
424
|
+
return {
|
425
|
+
formName,
|
426
|
+
path: rest
|
427
|
+
};
|
428
|
+
}
|
429
|
+
return {
|
430
|
+
path: idValue.split('.')
|
431
|
+
};
|
437
432
|
}
|
438
433
|
};
|
439
|
-
const createFormData = (form) => {
|
440
|
-
const validationErrors = form && form.errors;
|
441
|
-
const allErrors = Object.values(validationErrors || {});
|
442
|
-
return {
|
443
|
-
isSubmitted: form?.isSubmitted || false,
|
444
|
-
isDirty: form?.isDirty || false,
|
445
|
-
hasFocus: form?.hasFocus,
|
446
|
-
errors: form?.errors,
|
447
|
-
customErrors: form?.customErrors,
|
448
|
-
isValidating: form?.isValidating,
|
449
|
-
isValid: allErrors.flat().length === 0
|
450
|
-
};
|
451
|
-
};
|
452
434
|
|
453
|
-
|
435
|
+
/**
|
436
|
+
* Defines a collection of utility functions for processing rules, nodes and graph-like structures
|
437
|
+
*/
|
438
|
+
const CoreUtils = {
|
439
|
+
...FlowUtils,
|
440
|
+
...FormUtils
|
441
|
+
};
|
454
442
|
|
455
|
-
const { generateNodes, hasNode, makeObjectRules, generateRulesName, findValidRule
|
443
|
+
const { generateNodes, hasNode, makeObjectRules, generateRulesName, findValidRule } = CoreUtils;
|
456
444
|
/**
|
457
445
|
* These functions are Redux reducers used in a Flux architecture for managing state transitions and updates in a Flower application.
|
458
446
|
*/
|
459
|
-
const
|
447
|
+
const FlowerCoreBaseReducers = {
|
460
448
|
historyAdd: (state, { payload }) => {
|
461
449
|
if (hasNode(state, payload.name, payload.node)) {
|
462
450
|
state[payload.name].history.push(payload.node);
|
@@ -475,27 +463,11 @@ const FlowerCoreReducers = {
|
|
475
463
|
}
|
476
464
|
return state;
|
477
465
|
},
|
478
|
-
setFormTouched: (state, { payload }) => {
|
479
|
-
if (!_get(state, [
|
480
|
-
typeof payload === 'string' ? payload : payload.flowName,
|
481
|
-
'nodes',
|
482
|
-
typeof payload === 'string' ? payload : payload.currentNode
|
483
|
-
])) {
|
484
|
-
return state;
|
485
|
-
}
|
486
|
-
_set(state, [
|
487
|
-
typeof payload === 'string' ? payload : payload.flowName,
|
488
|
-
'form',
|
489
|
-
typeof payload === 'string' ? payload : payload.currentNode,
|
490
|
-
'isSubmitted'
|
491
|
-
], true);
|
492
|
-
return state;
|
493
|
-
},
|
494
466
|
// TODO check internal logic and use case
|
495
467
|
/* istanbul ignore next */
|
496
468
|
forceAddHistory: (state, { payload }) => {
|
497
469
|
const { name, flowName, history } = payload;
|
498
|
-
const key = name || flowName || ''
|
470
|
+
const key = name || flowName || '';
|
499
471
|
const resultHistory = history.slice(1, -1);
|
500
472
|
state[key].history.push(...resultHistory);
|
501
473
|
return state;
|
@@ -568,7 +540,8 @@ const FlowerCoreReducers = {
|
|
568
540
|
return state;
|
569
541
|
},
|
570
542
|
destroy: (state, { payload }) => {
|
571
|
-
|
543
|
+
delete state[payload.name];
|
544
|
+
return state;
|
572
545
|
},
|
573
546
|
initNodes: (state, { payload }) => {
|
574
547
|
if (payload.persist && _get(state, [payload.name, 'persist']))
|
@@ -591,8 +564,7 @@ const FlowerCoreReducers = {
|
|
591
564
|
current,
|
592
565
|
history,
|
593
566
|
nodes: generateNodes(payload.nodes),
|
594
|
-
nextRules: makeObjectRules(payload.nodes)
|
595
|
-
data: payload.initialData
|
567
|
+
nextRules: makeObjectRules(payload.nodes)
|
596
568
|
});
|
597
569
|
},
|
598
570
|
// TODO usato solo da flower su vscode
|
@@ -609,105 +581,14 @@ const FlowerCoreReducers = {
|
|
609
581
|
}
|
610
582
|
}
|
611
583
|
},
|
612
|
-
formAddCustomErrors: (state, { payload }) => {
|
613
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'customErrors', payload.id], payload.errors);
|
614
|
-
},
|
615
|
-
formAddErrors: (state, { payload }) => {
|
616
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'errors', payload.id], payload.errors);
|
617
|
-
},
|
618
|
-
formRemoveErrors: (state, { payload }) => {
|
619
|
-
_unset(state, [
|
620
|
-
payload.name,
|
621
|
-
'form',
|
622
|
-
payload.currentNode,
|
623
|
-
'errors',
|
624
|
-
payload.id
|
625
|
-
]);
|
626
|
-
_unset(state, [
|
627
|
-
payload.name,
|
628
|
-
'form',
|
629
|
-
payload.currentNode,
|
630
|
-
'customErrors',
|
631
|
-
payload.id
|
632
|
-
]);
|
633
|
-
_unset(state, [payload.name, 'form', payload.currentNode, 'isValidating']);
|
634
|
-
},
|
635
|
-
formFieldTouch: (state, { payload }) => {
|
636
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'touches', payload.id], payload.touched);
|
637
|
-
},
|
638
|
-
formFieldFocus: (state, { payload }) => {
|
639
|
-
if (!payload.focused) {
|
640
|
-
_unset(state, [payload.name, 'form', payload.currentNode, 'hasFocus']);
|
641
|
-
return;
|
642
|
-
}
|
643
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'hasFocus'], payload.id);
|
644
|
-
},
|
645
|
-
addData: (state, { payload }) => {
|
646
|
-
const prevData = _get(state, [payload.flowName, 'data']);
|
647
|
-
_set(state, [payload.flowName, 'data'], { ...prevData, ...payload.value });
|
648
|
-
},
|
649
|
-
addDataByPath: (state, { payload }) => {
|
650
|
-
const { path: newpath } = getPath(payload.id);
|
651
|
-
const currentNode = FlowerStateUtils.makeSelectCurrentNodeId(payload.flowName)(state);
|
652
|
-
if (payload.id && payload.id.length) {
|
653
|
-
_set(state, [payload.flowName, 'data', ...newpath], payload.value);
|
654
|
-
if (payload && payload.dirty) {
|
655
|
-
_set(state, [payload.flowName, 'form', currentNode, 'dirty', payload.id], payload.dirty);
|
656
|
-
_set(state, [payload.flowName, 'form', currentNode, 'isDirty'], true);
|
657
|
-
}
|
658
|
-
}
|
659
|
-
},
|
660
|
-
// TODO usato al momento solo il devtool
|
661
|
-
replaceData: /* istanbul ignore next */ (state, { payload }) => {
|
662
|
-
/* istanbul ignore next */
|
663
|
-
_set(state, [payload.flowName, 'data'], payload.value);
|
664
|
-
},
|
665
|
-
unsetData: (state, { payload }) => {
|
666
|
-
const currentNode = FlowerStateUtils.makeSelectCurrentNodeId(payload.flowName)(state);
|
667
|
-
_unset(state, [
|
668
|
-
payload.flowName,
|
669
|
-
'form',
|
670
|
-
currentNode,
|
671
|
-
'dirty',
|
672
|
-
...payload.id
|
673
|
-
]);
|
674
|
-
_unset(state, [
|
675
|
-
payload.flowName,
|
676
|
-
'form',
|
677
|
-
currentNode,
|
678
|
-
'touches',
|
679
|
-
...payload.id
|
680
|
-
]);
|
681
|
-
_unset(state, [payload.flowName, 'data', ...payload.id]);
|
682
|
-
},
|
683
|
-
setFormIsValidating: (state, { payload }) => {
|
684
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'isValidating'], payload.isValidating);
|
685
|
-
},
|
686
|
-
resetForm: (state, { payload }) => {
|
687
|
-
const touchedFields = _get(state, [payload.flowName, 'form', payload.id, 'errors'], {});
|
688
|
-
Object.keys(touchedFields).forEach((key) => {
|
689
|
-
const { flowNameFromPath = payload.flowName, path } = getPath(key);
|
690
|
-
_unset(state, [flowNameFromPath, 'data', ...path]);
|
691
|
-
});
|
692
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'touches']);
|
693
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'dirty']);
|
694
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'isDirty']);
|
695
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'isSubmitted']);
|
696
|
-
},
|
697
584
|
node: (state, { payload }) => {
|
698
585
|
const { name, history } = payload;
|
699
586
|
const node = payload.nodeId || payload.node || '';
|
700
587
|
const flowName = name || payload.flowName || '';
|
701
|
-
const startNode = _get(state, [payload.name, 'startId']);
|
702
|
-
const currentNodeId = _get(state, [payload.name, 'current'], startNode);
|
703
|
-
FlowerCoreReducers.setFormTouched(state, {
|
704
|
-
type: 'setFormTouched',
|
705
|
-
payload: { flowName, currentNode: currentNodeId }
|
706
|
-
});
|
707
588
|
/* istanbul ignore next */
|
708
589
|
// eslint-disable-next-line no-underscore-dangle
|
709
590
|
if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__') && history) {
|
710
|
-
|
591
|
+
FlowerCoreBaseReducers.forceAddHistory(state, {
|
711
592
|
type: 'forceAddHistory',
|
712
593
|
payload: {
|
713
594
|
name,
|
@@ -716,34 +597,35 @@ const FlowerCoreReducers = {
|
|
716
597
|
}
|
717
598
|
});
|
718
599
|
}
|
719
|
-
|
600
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
720
601
|
type: 'historyAdd',
|
721
602
|
payload: { name: name || flowName || '', node }
|
722
603
|
});
|
723
604
|
},
|
724
605
|
prevToNode: (state, { payload }) => {
|
725
606
|
const { node, name, flowName } = payload;
|
726
|
-
|
607
|
+
FlowerCoreBaseReducers.historyPrevToNode(state, {
|
727
608
|
type: 'historyPrevToNode',
|
728
609
|
payload: { name: name || flowName || '', node }
|
729
610
|
});
|
730
611
|
},
|
731
612
|
next: (state, { payload }) => {
|
732
|
-
const { name, data = {},
|
733
|
-
const flowName = name ||
|
613
|
+
const { name, route, flowName: flow, data = {}, dataIn = {} } = payload;
|
614
|
+
const flowName = name || flow || '';
|
615
|
+
const { FlowerData, FlowerFlow, ...external } = data;
|
734
616
|
const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(flowName)(state);
|
735
617
|
const currentNextRules = FlowerStateUtils.makeSelectCurrentNextRules(flowName)(state);
|
736
|
-
const
|
737
|
-
const
|
618
|
+
const $data = FlowerStateUtils.makeSelectNodeErrors(flowName, currentNodeId)(FlowerData);
|
619
|
+
const internalClonedData = _cloneDeep(FlowerStateUtils.getAllData(FlowerData));
|
620
|
+
const externalClonedData = _cloneDeep(FlowerStateUtils.getAllData(external));
|
738
621
|
const stateWithNodeData = {
|
739
|
-
$in:
|
740
|
-
$
|
741
|
-
|
622
|
+
$in: dataIn,
|
623
|
+
/** @deprecated use $data instead */
|
624
|
+
$form: $data,
|
625
|
+
$data,
|
626
|
+
...externalClonedData,
|
627
|
+
...internalClonedData
|
742
628
|
};
|
743
|
-
FlowerCoreReducers.setFormTouched(state, {
|
744
|
-
type: 'setFormTouched',
|
745
|
-
payload: { flowName, currentNode: currentNodeId }
|
746
|
-
});
|
747
629
|
if (!currentNextRules) {
|
748
630
|
return;
|
749
631
|
}
|
@@ -752,7 +634,7 @@ const FlowerCoreReducers = {
|
|
752
634
|
if (!rulesByName[route]) {
|
753
635
|
return;
|
754
636
|
}
|
755
|
-
|
637
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
756
638
|
type: 'historyAdd',
|
757
639
|
payload: { name: flowName, node: rulesByName[route] }
|
758
640
|
});
|
@@ -763,51 +645,132 @@ const FlowerCoreReducers = {
|
|
763
645
|
if (!nextNumberNode) {
|
764
646
|
return;
|
765
647
|
}
|
766
|
-
|
648
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
767
649
|
type: 'historyAdd',
|
768
650
|
payload: { name: flowName, node: nextNumberNode }
|
769
651
|
});
|
770
652
|
},
|
771
653
|
prev: (state, { payload }) => {
|
772
654
|
const { name, flowName } = payload;
|
773
|
-
|
655
|
+
FlowerCoreBaseReducers.historyPop(state, {
|
774
656
|
type: 'historyPop',
|
775
657
|
payload: { name: name || flowName || '' }
|
776
658
|
});
|
777
659
|
},
|
778
660
|
restart: (state, { payload }) => {
|
779
661
|
const { name, flowName } = payload;
|
780
|
-
|
662
|
+
FlowerCoreBaseReducers.restoreHistory(state, {
|
781
663
|
type: 'restoreHistory',
|
782
664
|
payload: { name: name || flowName || '' }
|
783
665
|
});
|
784
666
|
},
|
785
667
|
reset: (state, { payload }) => {
|
786
|
-
const { name, flowName
|
787
|
-
|
668
|
+
const { name, flowName } = payload;
|
669
|
+
FlowerCoreBaseReducers.restoreHistory(state, {
|
788
670
|
type: 'restoreHistory',
|
789
671
|
payload: { name: name || flowName || '' }
|
790
672
|
});
|
791
|
-
_set(state, [name || flowName || '', 'form'], {});
|
792
|
-
_set(state, [name || flowName || '', 'data'], initialData);
|
793
673
|
}
|
794
674
|
};
|
795
675
|
|
796
|
-
const
|
797
|
-
|
676
|
+
const { getPath } = CoreUtils;
|
677
|
+
/**
|
678
|
+
* formName => FlowerForm
|
679
|
+
* initialData => FlowerForm
|
680
|
+
* fieldName => FlowerField
|
681
|
+
* fieldValue => FlowerField
|
682
|
+
* errors => FlowerField
|
683
|
+
* customErrors => FlowerField
|
684
|
+
* fieldTouched => FlowerField
|
685
|
+
* fieldDirty => FlowerField
|
686
|
+
* fieldHasFocus => FlowerField
|
687
|
+
*/
|
688
|
+
const FlowerCoreDataReducers = {
|
689
|
+
setFormTouched: (state, { payload }) => {
|
690
|
+
if (!_get(state, typeof payload === 'string' ? payload : payload.formName)) {
|
691
|
+
return state;
|
692
|
+
}
|
693
|
+
_set(state, typeof payload === 'string' ? payload : payload.formName, true);
|
694
|
+
return state;
|
695
|
+
},
|
696
|
+
formAddCustomErrors: (state, { payload }) => {
|
697
|
+
_set(state, [payload.formName, 'customErrors', payload.id], payload.errors);
|
698
|
+
},
|
699
|
+
formAddErrors: (state, { payload }) => {
|
700
|
+
_set(state, [payload.formName, 'errors', payload.id], payload.errors);
|
701
|
+
},
|
702
|
+
formRemoveErrors: (state, { payload }) => {
|
703
|
+
_unset(state, [payload.formName, 'errors', payload.id]);
|
704
|
+
_unset(state, [payload.formName, 'customErrors', payload.id]);
|
705
|
+
_unset(state, [payload.formName, 'isValidating']);
|
706
|
+
},
|
707
|
+
formFieldTouch: (state, { payload }) => {
|
708
|
+
_set(state, [payload.formName, 'touches', payload.id], payload.touched);
|
709
|
+
},
|
710
|
+
formFieldDirty: (state, { payload }) => {
|
711
|
+
_set(state, [payload.formName, 'dirty', payload.id], payload.dirty);
|
712
|
+
},
|
713
|
+
formFieldFocus: (state, { payload }) => {
|
714
|
+
if (!payload.focused) {
|
715
|
+
_unset(state, [payload.formName, 'hasFocus']);
|
716
|
+
return;
|
717
|
+
}
|
718
|
+
_set(state, [payload.formName, 'hasFocus'], payload.id);
|
719
|
+
},
|
720
|
+
addData: (state, { payload }) => {
|
721
|
+
const prevData = _get(state, [payload.formName, 'data'], {});
|
722
|
+
_set(state, [payload.formName, 'data'], { ...prevData, ...payload.value });
|
723
|
+
},
|
724
|
+
addDataByPath: (state, { payload }) => {
|
725
|
+
const { path: newpath } = getPath(payload.id);
|
726
|
+
if (payload.id && payload.id.length) {
|
727
|
+
_set(state, [payload.formName, 'data', ...newpath], payload.value);
|
728
|
+
if (payload && payload.dirty) {
|
729
|
+
_set(state, [payload.formName, 'dirty', payload.id], payload.dirty);
|
730
|
+
}
|
731
|
+
}
|
732
|
+
},
|
733
|
+
// TODO usato al momento solo il devtool
|
734
|
+
replaceData: /* istanbul ignore next */ (state, { payload }) => {
|
735
|
+
/* istanbul ignore next */
|
736
|
+
_set(state, [payload.formName, 'data'], payload.value);
|
737
|
+
},
|
738
|
+
unsetData: (state, { payload }) => {
|
739
|
+
_unset(state, [payload.formName, 'data', ...payload.id]);
|
740
|
+
},
|
741
|
+
setFormIsValidating: (state, { payload }) => {
|
742
|
+
_set(state, [payload.formName, 'isValidating'], payload.isValidating);
|
743
|
+
},
|
744
|
+
resetForm: (state, { payload: { formName, initialData } }) => {
|
745
|
+
const touchedFields = _get(state, [formName, 'errors'], {});
|
746
|
+
const newStateData = initialData
|
747
|
+
? Object.keys(touchedFields).reduce((acc, key) => {
|
748
|
+
const { path } = getPath(key);
|
749
|
+
const initialDataByPath = _get(initialData, [...path], undefined);
|
750
|
+
_set(acc, [...path], initialDataByPath);
|
751
|
+
return acc;
|
752
|
+
}, {})
|
753
|
+
: {};
|
754
|
+
_set(state, [formName, 'data'], newStateData);
|
755
|
+
_unset(state, [formName, 'touches']);
|
756
|
+
_unset(state, [formName, 'dirty']);
|
757
|
+
_unset(state, [formName, 'isSubmitted']);
|
758
|
+
},
|
759
|
+
initForm: (state, { payload: { formName, initialData } }) => {
|
760
|
+
_set(state, [formName, 'data'], initialData);
|
761
|
+
}
|
762
|
+
};
|
763
|
+
|
764
|
+
const FlowerCoreReducers = { ...FlowerCoreBaseReducers, ...FlowerCoreDataReducers };
|
765
|
+
|
766
|
+
const FlowerCoreStateBaseSelectors = {
|
767
|
+
selectGlobal: (state) => state && state[exports.REDUCER_NAME.FLOWER_FLOW],
|
798
768
|
selectFlower: (name) => (state) => _get(state, [name]),
|
799
|
-
selectFlowerFormNode: (id) => (state) =>
|
769
|
+
// selectFlowerFormNode: (id) => (state) =>
|
770
|
+
// _get(state, [REDUCER_NAME.FLOWER_DATA, id]),
|
800
771
|
selectFlowerHistory: (flower) => _get(flower, ['history'], []),
|
801
772
|
makeSelectNodesIds: (flower) => _get(flower, ['nodes']),
|
802
773
|
makeSelectStartNodeId: (flower) => _get(flower, ['startId']),
|
803
|
-
getDataByFlow: (flower) => _get(flower, ['data']) ?? {},
|
804
|
-
getDataFromState: (id) => (data) => (id === '*' ? data : _get(data, id)),
|
805
|
-
makeSelectNodeFormSubmitted: (form) => form && form.isSubmitted,
|
806
|
-
makeSelectNodeFormFieldTouched: (id) => (form) => form && form.touches && form.touches[id],
|
807
|
-
makeSelectNodeFormFieldFocused: (id) => (form) => {
|
808
|
-
return form && form.hasFocus === id ? id : undefined;
|
809
|
-
},
|
810
|
-
makeSelectNodeFormFieldDirty: (id) => (form) => form && form.dirty && form.dirty[id],
|
811
774
|
makeSelectCurrentNodeId: (flower, startNodeId) => _get(flower, ['current']) || startNodeId,
|
812
775
|
makeSelectCurrentNodeDisabled: (nodes, current) => !!_get(nodes, [current, 'disabled']),
|
813
776
|
makeSelectPrevNodeRetain: (nodes, history, current) => {
|
@@ -828,7 +791,22 @@ const FlowerCoreStateSelectors = {
|
|
828
791
|
return nodes[prevFlowerNode] && nodes[prevFlowerNode].retain
|
829
792
|
? prevFlowerNode
|
830
793
|
: undefined;
|
794
|
+
}
|
795
|
+
};
|
796
|
+
|
797
|
+
const FlowerCoreStateDataSelectors = {
|
798
|
+
selectGlobalReducerByName: (name) => (state) => state[name] ?? state[exports.REDUCER_NAME.FLOWER_DATA][name],
|
799
|
+
selectGlobalForm: (state) => {
|
800
|
+
return state && state[exports.REDUCER_NAME.FLOWER_DATA];
|
831
801
|
},
|
802
|
+
// getDataByFlow: (flower) => _get(flower, 'data') ?? {},
|
803
|
+
getDataFromState: (id) => (data) => (id === '*' ? data : _get(data, id)),
|
804
|
+
makeSelectNodeFormSubmitted: (form) => form && form.isSubmitted,
|
805
|
+
makeSelectNodeFormFieldTouched: (id) => (form) => form && form.touches && form.touches[id],
|
806
|
+
makeSelectNodeFormFieldFocused: (id) => (form) => {
|
807
|
+
return form && form.hasFocus === id ? id : undefined;
|
808
|
+
},
|
809
|
+
makeSelectNodeFormFieldDirty: (id) => (form) => form && form.dirty && form.dirty[id],
|
832
810
|
makeSelectNodeErrors: createFormData,
|
833
811
|
makeSelectFieldError: (name, id, validate) => (data, form) => {
|
834
812
|
const customErrors = Object.entries((form && form.customErrors) || {})
|
@@ -843,7 +821,7 @@ const FlowerCoreStateSelectors = {
|
|
843
821
|
if (!rule.rules)
|
844
822
|
return true;
|
845
823
|
const transformSelf = CoreUtils.mapKeysDeepLodash(rule.rules, (v, key) => key === '$self' ? id : key);
|
846
|
-
const [hasError] =
|
824
|
+
const [hasError] = rulesMatcher(transformSelf, data, false, {
|
847
825
|
prefix: name
|
848
826
|
});
|
849
827
|
return hasError;
|
@@ -865,39 +843,31 @@ const FlowerCoreStateSelectors = {
|
|
865
843
|
const k = inc;
|
866
844
|
return Object.assign(acc, { [k]: _get(state, k) });
|
867
845
|
}, {});
|
868
|
-
const [disabled] =
|
846
|
+
const [disabled] = rulesMatcher(rules, { ...flat.unflatten(res) }, false, {
|
847
|
+
prefix: flowName
|
848
|
+
});
|
869
849
|
return disabled;
|
870
850
|
}
|
871
851
|
};
|
872
852
|
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
RulesOperators["$ne"] = "$ne";
|
878
|
-
RulesOperators["$gt"] = "$gt";
|
879
|
-
RulesOperators["$gte"] = "$gte";
|
880
|
-
RulesOperators["$lt"] = "$lt";
|
881
|
-
RulesOperators["$lte"] = "$lte";
|
882
|
-
RulesOperators["$strGt"] = "$strGt";
|
883
|
-
RulesOperators["$strGte"] = "$strGte";
|
884
|
-
RulesOperators["$strLt"] = "$strLt";
|
885
|
-
RulesOperators["$strLte"] = "$strLte";
|
886
|
-
RulesOperators["$in"] = "$in";
|
887
|
-
RulesOperators["$nin"] = "$nin";
|
888
|
-
RulesOperators["$all"] = "$all";
|
889
|
-
RulesOperators["$regex"] = "$regex";
|
890
|
-
})(exports.RulesOperators || (exports.RulesOperators = {}));
|
891
|
-
exports.RulesModes = void 0;
|
892
|
-
(function (RulesModes) {
|
893
|
-
RulesModes["$and"] = "$and";
|
894
|
-
RulesModes["$or"] = "$or";
|
895
|
-
})(exports.RulesModes || (exports.RulesModes = {}));
|
853
|
+
const FlowerCoreStateSelectors = {
|
854
|
+
...FlowerCoreStateBaseSelectors,
|
855
|
+
...FlowerCoreStateDataSelectors
|
856
|
+
};
|
896
857
|
|
897
858
|
exports.CoreUtils = CoreUtils;
|
898
859
|
exports.Emitter = Emitter;
|
860
|
+
exports.FlowUtils = FlowUtils;
|
861
|
+
exports.FlowerCoreBaseReducers = FlowerCoreBaseReducers;
|
862
|
+
exports.FlowerCoreDataReducers = FlowerCoreDataReducers;
|
899
863
|
exports.FlowerCoreReducers = FlowerCoreReducers;
|
864
|
+
exports.FlowerCoreStateBaseSelectors = FlowerCoreStateBaseSelectors;
|
865
|
+
exports.FlowerCoreStateDataSelectors = FlowerCoreStateDataSelectors;
|
866
|
+
exports.FlowerCoreStateSelectors = FlowerCoreStateSelectors;
|
900
867
|
exports.FlowerStateUtils = FlowerStateUtils;
|
901
|
-
exports.
|
902
|
-
exports.
|
868
|
+
exports.FormUtils = FormUtils;
|
869
|
+
exports.createFormData = createFormData;
|
903
870
|
exports.devtoolState = devtoolState;
|
871
|
+
exports.flattenRules = flattenRules;
|
872
|
+
exports.rulesMatcher = rulesMatcher;
|
873
|
+
exports.rulesMatcherUtils = rulesMatcherUtils;
|