@flowerforce/flower-core 3.3.1-beta.2 → 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 -257
- package/dist/index.esm.js +231 -256
- 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 +109 -105
- 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} +1 -1
- 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: Object.values(form?.dirty || {}).some(Boolean) || 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,91 +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
|
-
formFieldDirty: (state, { payload }) => {
|
639
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'dirty', payload.id], payload.dirty);
|
640
|
-
},
|
641
|
-
formFieldFocus: (state, { payload }) => {
|
642
|
-
if (!payload.focused) {
|
643
|
-
_unset(state, [payload.name, 'form', payload.currentNode, 'hasFocus']);
|
644
|
-
return;
|
645
|
-
}
|
646
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'hasFocus'], payload.id);
|
647
|
-
},
|
648
|
-
addData: (state, { payload }) => {
|
649
|
-
const prevData = _get(state, [payload.flowName, 'data']);
|
650
|
-
_set(state, [payload.flowName, 'data'], { ...prevData, ...payload.value });
|
651
|
-
},
|
652
|
-
addDataByPath: (state, { payload }) => {
|
653
|
-
const { path: newpath } = getPath(payload.id);
|
654
|
-
const currentNode = FlowerStateUtils.makeSelectCurrentNodeId(payload.flowName)(state);
|
655
|
-
if (payload.id && payload.id.length) {
|
656
|
-
_set(state, [payload.flowName, 'data', ...newpath], payload.value);
|
657
|
-
if (payload && payload.dirty) {
|
658
|
-
_set(state, [payload.flowName, 'form', currentNode, 'dirty', payload.id], payload.dirty);
|
659
|
-
}
|
660
|
-
}
|
661
|
-
},
|
662
|
-
// TODO usato al momento solo il devtool
|
663
|
-
replaceData: /* istanbul ignore next */ (state, { payload }) => {
|
664
|
-
/* istanbul ignore next */
|
665
|
-
_set(state, [payload.flowName, 'data'], payload.value);
|
666
|
-
},
|
667
|
-
unsetData: (state, { payload }) => {
|
668
|
-
_unset(state, [payload.flowName, 'data', ...payload.id]);
|
669
|
-
},
|
670
|
-
setFormIsValidating: (state, { payload }) => {
|
671
|
-
_set(state, [payload.name, 'form', payload.currentNode, 'isValidating'], payload.isValidating);
|
672
|
-
},
|
673
|
-
resetForm: (state, { payload }) => {
|
674
|
-
const touchedFields = _get(state, [payload.flowName, 'form', payload.id, 'errors'], {});
|
675
|
-
Object.keys(touchedFields).forEach((key) => {
|
676
|
-
const { flowNameFromPath = payload.flowName, path } = getPath(key);
|
677
|
-
_unset(state, [flowNameFromPath, 'data', ...path]);
|
678
|
-
});
|
679
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'touches']);
|
680
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'dirty']);
|
681
|
-
_unset(state, [payload.flowName, 'form', payload.id, 'isSubmitted']);
|
682
|
-
},
|
683
584
|
node: (state, { payload }) => {
|
684
585
|
const { name, history } = payload;
|
685
586
|
const node = payload.nodeId || payload.node || '';
|
686
587
|
const flowName = name || payload.flowName || '';
|
687
|
-
const startNode = _get(state, [payload.name, 'startId']);
|
688
|
-
const currentNodeId = _get(state, [payload.name, 'current'], startNode);
|
689
|
-
FlowerCoreReducers.setFormTouched(state, {
|
690
|
-
type: 'setFormTouched',
|
691
|
-
payload: { flowName, currentNode: currentNodeId }
|
692
|
-
});
|
693
588
|
/* istanbul ignore next */
|
694
589
|
// eslint-disable-next-line no-underscore-dangle
|
695
590
|
if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__') && history) {
|
696
|
-
|
591
|
+
FlowerCoreBaseReducers.forceAddHistory(state, {
|
697
592
|
type: 'forceAddHistory',
|
698
593
|
payload: {
|
699
594
|
name,
|
@@ -702,34 +597,35 @@ const FlowerCoreReducers = {
|
|
702
597
|
}
|
703
598
|
});
|
704
599
|
}
|
705
|
-
|
600
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
706
601
|
type: 'historyAdd',
|
707
602
|
payload: { name: name || flowName || '', node }
|
708
603
|
});
|
709
604
|
},
|
710
605
|
prevToNode: (state, { payload }) => {
|
711
606
|
const { node, name, flowName } = payload;
|
712
|
-
|
607
|
+
FlowerCoreBaseReducers.historyPrevToNode(state, {
|
713
608
|
type: 'historyPrevToNode',
|
714
609
|
payload: { name: name || flowName || '', node }
|
715
610
|
});
|
716
611
|
},
|
717
612
|
next: (state, { payload }) => {
|
718
|
-
const { name, data = {},
|
719
|
-
const flowName = name ||
|
613
|
+
const { name, route, flowName: flow, data = {}, dataIn = {} } = payload;
|
614
|
+
const flowName = name || flow || '';
|
615
|
+
const { FlowerData, FlowerFlow, ...external } = data;
|
720
616
|
const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(flowName)(state);
|
721
617
|
const currentNextRules = FlowerStateUtils.makeSelectCurrentNextRules(flowName)(state);
|
722
|
-
const
|
723
|
-
const
|
618
|
+
const $data = FlowerStateUtils.makeSelectNodeErrors(flowName, currentNodeId)(FlowerData);
|
619
|
+
const internalClonedData = _cloneDeep(FlowerStateUtils.getAllData(FlowerData));
|
620
|
+
const externalClonedData = _cloneDeep(FlowerStateUtils.getAllData(external));
|
724
621
|
const stateWithNodeData = {
|
725
|
-
$in:
|
726
|
-
$
|
727
|
-
|
622
|
+
$in: dataIn,
|
623
|
+
/** @deprecated use $data instead */
|
624
|
+
$form: $data,
|
625
|
+
$data,
|
626
|
+
...externalClonedData,
|
627
|
+
...internalClonedData
|
728
628
|
};
|
729
|
-
FlowerCoreReducers.setFormTouched(state, {
|
730
|
-
type: 'setFormTouched',
|
731
|
-
payload: { flowName, currentNode: currentNodeId }
|
732
|
-
});
|
733
629
|
if (!currentNextRules) {
|
734
630
|
return;
|
735
631
|
}
|
@@ -738,7 +634,7 @@ const FlowerCoreReducers = {
|
|
738
634
|
if (!rulesByName[route]) {
|
739
635
|
return;
|
740
636
|
}
|
741
|
-
|
637
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
742
638
|
type: 'historyAdd',
|
743
639
|
payload: { name: flowName, node: rulesByName[route] }
|
744
640
|
});
|
@@ -749,51 +645,132 @@ const FlowerCoreReducers = {
|
|
749
645
|
if (!nextNumberNode) {
|
750
646
|
return;
|
751
647
|
}
|
752
|
-
|
648
|
+
FlowerCoreBaseReducers.historyAdd(state, {
|
753
649
|
type: 'historyAdd',
|
754
650
|
payload: { name: flowName, node: nextNumberNode }
|
755
651
|
});
|
756
652
|
},
|
757
653
|
prev: (state, { payload }) => {
|
758
654
|
const { name, flowName } = payload;
|
759
|
-
|
655
|
+
FlowerCoreBaseReducers.historyPop(state, {
|
760
656
|
type: 'historyPop',
|
761
657
|
payload: { name: name || flowName || '' }
|
762
658
|
});
|
763
659
|
},
|
764
660
|
restart: (state, { payload }) => {
|
765
661
|
const { name, flowName } = payload;
|
766
|
-
|
662
|
+
FlowerCoreBaseReducers.restoreHistory(state, {
|
767
663
|
type: 'restoreHistory',
|
768
664
|
payload: { name: name || flowName || '' }
|
769
665
|
});
|
770
666
|
},
|
771
667
|
reset: (state, { payload }) => {
|
772
|
-
const { name, flowName
|
773
|
-
|
668
|
+
const { name, flowName } = payload;
|
669
|
+
FlowerCoreBaseReducers.restoreHistory(state, {
|
774
670
|
type: 'restoreHistory',
|
775
671
|
payload: { name: name || flowName || '' }
|
776
672
|
});
|
777
|
-
_set(state, [name || flowName || '', 'form'], {});
|
778
|
-
_set(state, [name || flowName || '', 'data'], initialData);
|
779
673
|
}
|
780
674
|
};
|
781
675
|
|
782
|
-
const
|
783
|
-
|
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],
|
784
768
|
selectFlower: (name) => (state) => _get(state, [name]),
|
785
|
-
selectFlowerFormNode: (id) => (state) =>
|
769
|
+
// selectFlowerFormNode: (id) => (state) =>
|
770
|
+
// _get(state, [REDUCER_NAME.FLOWER_DATA, id]),
|
786
771
|
selectFlowerHistory: (flower) => _get(flower, ['history'], []),
|
787
772
|
makeSelectNodesIds: (flower) => _get(flower, ['nodes']),
|
788
773
|
makeSelectStartNodeId: (flower) => _get(flower, ['startId']),
|
789
|
-
getDataByFlow: (flower) => _get(flower, ['data']) ?? {},
|
790
|
-
getDataFromState: (id) => (data) => (id === '*' ? data : _get(data, id)),
|
791
|
-
makeSelectNodeFormSubmitted: (form) => form && form.isSubmitted,
|
792
|
-
makeSelectNodeFormFieldTouched: (id) => (form) => form && form.touches && form.touches[id],
|
793
|
-
makeSelectNodeFormFieldFocused: (id) => (form) => {
|
794
|
-
return form && form.hasFocus === id ? id : undefined;
|
795
|
-
},
|
796
|
-
makeSelectNodeFormFieldDirty: (id) => (form) => form && form.dirty && form.dirty[id],
|
797
774
|
makeSelectCurrentNodeId: (flower, startNodeId) => _get(flower, ['current']) || startNodeId,
|
798
775
|
makeSelectCurrentNodeDisabled: (nodes, current) => !!_get(nodes, [current, 'disabled']),
|
799
776
|
makeSelectPrevNodeRetain: (nodes, history, current) => {
|
@@ -814,7 +791,22 @@ const FlowerCoreStateSelectors = {
|
|
814
791
|
return nodes[prevFlowerNode] && nodes[prevFlowerNode].retain
|
815
792
|
? prevFlowerNode
|
816
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];
|
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;
|
817
808
|
},
|
809
|
+
makeSelectNodeFormFieldDirty: (id) => (form) => form && form.dirty && form.dirty[id],
|
818
810
|
makeSelectNodeErrors: createFormData,
|
819
811
|
makeSelectFieldError: (name, id, validate) => (data, form) => {
|
820
812
|
const customErrors = Object.entries((form && form.customErrors) || {})
|
@@ -829,7 +821,7 @@ const FlowerCoreStateSelectors = {
|
|
829
821
|
if (!rule.rules)
|
830
822
|
return true;
|
831
823
|
const transformSelf = CoreUtils.mapKeysDeepLodash(rule.rules, (v, key) => key === '$self' ? id : key);
|
832
|
-
const [hasError] =
|
824
|
+
const [hasError] = rulesMatcher(transformSelf, data, false, {
|
833
825
|
prefix: name
|
834
826
|
});
|
835
827
|
return hasError;
|
@@ -851,39 +843,31 @@ const FlowerCoreStateSelectors = {
|
|
851
843
|
const k = inc;
|
852
844
|
return Object.assign(acc, { [k]: _get(state, k) });
|
853
845
|
}, {});
|
854
|
-
const [disabled] =
|
846
|
+
const [disabled] = rulesMatcher(rules, { ...flat.unflatten(res) }, false, {
|
847
|
+
prefix: flowName
|
848
|
+
});
|
855
849
|
return disabled;
|
856
850
|
}
|
857
851
|
};
|
858
852
|
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
RulesOperators["$ne"] = "$ne";
|
864
|
-
RulesOperators["$gt"] = "$gt";
|
865
|
-
RulesOperators["$gte"] = "$gte";
|
866
|
-
RulesOperators["$lt"] = "$lt";
|
867
|
-
RulesOperators["$lte"] = "$lte";
|
868
|
-
RulesOperators["$strGt"] = "$strGt";
|
869
|
-
RulesOperators["$strGte"] = "$strGte";
|
870
|
-
RulesOperators["$strLt"] = "$strLt";
|
871
|
-
RulesOperators["$strLte"] = "$strLte";
|
872
|
-
RulesOperators["$in"] = "$in";
|
873
|
-
RulesOperators["$nin"] = "$nin";
|
874
|
-
RulesOperators["$all"] = "$all";
|
875
|
-
RulesOperators["$regex"] = "$regex";
|
876
|
-
})(exports.RulesOperators || (exports.RulesOperators = {}));
|
877
|
-
exports.RulesModes = void 0;
|
878
|
-
(function (RulesModes) {
|
879
|
-
RulesModes["$and"] = "$and";
|
880
|
-
RulesModes["$or"] = "$or";
|
881
|
-
})(exports.RulesModes || (exports.RulesModes = {}));
|
853
|
+
const FlowerCoreStateSelectors = {
|
854
|
+
...FlowerCoreStateBaseSelectors,
|
855
|
+
...FlowerCoreStateDataSelectors
|
856
|
+
};
|
882
857
|
|
883
858
|
exports.CoreUtils = CoreUtils;
|
884
859
|
exports.Emitter = Emitter;
|
860
|
+
exports.FlowUtils = FlowUtils;
|
861
|
+
exports.FlowerCoreBaseReducers = FlowerCoreBaseReducers;
|
862
|
+
exports.FlowerCoreDataReducers = FlowerCoreDataReducers;
|
885
863
|
exports.FlowerCoreReducers = FlowerCoreReducers;
|
864
|
+
exports.FlowerCoreStateBaseSelectors = FlowerCoreStateBaseSelectors;
|
865
|
+
exports.FlowerCoreStateDataSelectors = FlowerCoreStateDataSelectors;
|
866
|
+
exports.FlowerCoreStateSelectors = FlowerCoreStateSelectors;
|
886
867
|
exports.FlowerStateUtils = FlowerStateUtils;
|
887
|
-
exports.
|
888
|
-
exports.
|
868
|
+
exports.FormUtils = FormUtils;
|
869
|
+
exports.createFormData = createFormData;
|
889
870
|
exports.devtoolState = devtoolState;
|
871
|
+
exports.flattenRules = flattenRules;
|
872
|
+
exports.rulesMatcher = rulesMatcher;
|
873
|
+
exports.rulesMatcherUtils = rulesMatcherUtils;
|