@inseefr/lunatic 3.6.14 → 3.6.15-rc.1

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 (60) hide show
  1. package/components/Roundabout/Roundabout.js +8 -3
  2. package/components/Roundabout/Roundabout.js.map +1 -1
  3. package/esm/components/Roundabout/Roundabout.js +8 -3
  4. package/esm/components/Roundabout/Roundabout.js.map +1 -1
  5. package/esm/hooks/useMultimode.d.ts +49 -0
  6. package/esm/hooks/useMultimode.js +83 -0
  7. package/esm/hooks/useMultimode.js.map +1 -0
  8. package/esm/index.d.ts +1 -0
  9. package/esm/index.js +1 -0
  10. package/esm/index.js.map +1 -1
  11. package/esm/type.source.d.ts +33 -1
  12. package/esm/type.source.js +0 -1
  13. package/esm/type.source.js.map +1 -1
  14. package/esm/use-lunatic/reducer/reduce-go-next-page.js +2 -1
  15. package/esm/use-lunatic/reducer/reduce-go-next-page.js.map +1 -1
  16. package/esm/use-lunatic/reducer/reducerInitializer.d.ts +2 -2
  17. package/esm/use-lunatic/reducer/reducerInitializer.js +31 -24
  18. package/esm/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  19. package/esm/use-lunatic/type.d.ts +2 -0
  20. package/esm/use-lunatic/use-lunatic.js +3 -0
  21. package/esm/use-lunatic/use-lunatic.js.map +1 -1
  22. package/esm/utils/getArticulationState.d.ts +64 -0
  23. package/esm/utils/getArticulationState.js +82 -0
  24. package/esm/utils/getArticulationState.js.map +1 -0
  25. package/hooks/useMultimode.d.ts +49 -0
  26. package/hooks/useMultimode.js +84 -0
  27. package/hooks/useMultimode.js.map +1 -0
  28. package/index.d.ts +1 -0
  29. package/index.js +3 -1
  30. package/index.js.map +1 -1
  31. package/package.json +18 -1
  32. package/src/components/Roundabout/Roundabout.tsx +8 -3
  33. package/src/hooks/useMultimode.ts +102 -0
  34. package/src/index.ts +1 -0
  35. package/src/stories/behaviour/articulation/articulation.stories.tsx +90 -0
  36. package/src/stories/behaviour/articulation/multimode.stories.tsx +19 -0
  37. package/src/stories/behaviour/articulation/roundabout.json +413 -0
  38. package/src/stories/utils/Orchestrator.tsx +3 -0
  39. package/src/stories/utils/OrchestratorSidebar.tsx +25 -1
  40. package/src/type.source.ts +33 -2
  41. package/src/use-lunatic/reducer/reduce-go-next-page.ts +2 -1
  42. package/src/use-lunatic/reducer/reducerInitializer.tsx +40 -29
  43. package/src/use-lunatic/type.ts +2 -0
  44. package/src/use-lunatic/use-lunatic.ts +4 -0
  45. package/src/utils/getArticulationState.ts +124 -0
  46. package/tsconfig.build.tsbuildinfo +1 -1
  47. package/type.source.d.ts +33 -1
  48. package/type.source.js +0 -1
  49. package/type.source.js.map +1 -1
  50. package/use-lunatic/reducer/reduce-go-next-page.js +2 -1
  51. package/use-lunatic/reducer/reduce-go-next-page.js.map +1 -1
  52. package/use-lunatic/reducer/reducerInitializer.d.ts +2 -2
  53. package/use-lunatic/reducer/reducerInitializer.js +31 -24
  54. package/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  55. package/use-lunatic/type.d.ts +2 -0
  56. package/use-lunatic/use-lunatic.js +3 -0
  57. package/use-lunatic/use-lunatic.js.map +1 -1
  58. package/utils/getArticulationState.d.ts +64 -0
  59. package/utils/getArticulationState.js +84 -0
  60. package/utils/getArticulationState.js.map +1 -0
@@ -0,0 +1,82 @@
1
+ import { reducerInitializer } from '../use-lunatic/reducer/reducerInitializer';
2
+ import { times } from './array';
3
+ import { forceInt } from './number';
4
+ export var ArticulationState;
5
+ (function (ArticulationState) {
6
+ ArticulationState[ArticulationState["COMPLETED"] = 1] = "COMPLETED";
7
+ ArticulationState[ArticulationState["STARTED"] = 0] = "STARTED";
8
+ ArticulationState[ArticulationState["NOT_STARTED"] = -1] = "NOT_STARTED";
9
+ })(ArticulationState || (ArticulationState = {}));
10
+ /**
11
+ * Retrieve the articulation state
12
+ *
13
+ * The goal of this function is to provide insights about a roundabout using extra information inserted in the JSON source
14
+ * provided to Lunatic.
15
+ *
16
+ * For instance
17
+ *
18
+ * ```
19
+ * "articulation": {
20
+ * "source": "roundabout",
21
+ * "items": [
22
+ * {
23
+ * "label": "Prénom",
24
+ * "value": "PRENOMS"
25
+ * },
26
+ * {
27
+ * "label": "Sexe",
28
+ * "value": "if SEXE = \"H\" then \"Homme\" else \"Femme\""
29
+ * },
30
+ * {
31
+ * "label": "Age",
32
+ * "value": "cast(AGE, string) || \" ans\""
33
+ * }
34
+ * ]
35
+ * },
36
+ * ```
37
+ *
38
+ * - source is the ID of the roundabout component
39
+ * - items define the field to extract from the roundabout data
40
+ */
41
+ export function getArticulationState(source, data) {
42
+ var _a;
43
+ const roundabout = findComponentById(source.components, source.articulation.source);
44
+ const { variables } = reducerInitializer({ source, data });
45
+ const iterations = forceInt(variables.run((_a = roundabout === null || roundabout === void 0 ? void 0 : roundabout.iterations.value) !== null && _a !== void 0 ? _a : '0'));
46
+ const rows = times(iterations, (k) => source.articulation.items.map((item) => ({
47
+ label: item.label,
48
+ value: variables.run(item.value, { iteration: [k] }),
49
+ })));
50
+ if (!roundabout) {
51
+ return {
52
+ items: [],
53
+ };
54
+ }
55
+ return {
56
+ items: rows.map((row, k) => {
57
+ var _a;
58
+ return ({
59
+ cells: row,
60
+ progress: forceInt((_a = variables.get(roundabout.progressVariable, [k])) !== null && _a !== void 0 ? _a : ArticulationState.NOT_STARTED),
61
+ page: (roundabout.page
62
+ ? `${roundabout.page}.1#${k + 1}`
63
+ : '1'),
64
+ });
65
+ }),
66
+ };
67
+ }
68
+ export function findComponentById(components, id) {
69
+ for (const c of components) {
70
+ if ('id' in c && c.id === id && c.componentType === 'Roundabout') {
71
+ return c;
72
+ }
73
+ if ('components' in c) {
74
+ const child = findComponentById(c.components, id);
75
+ if (child) {
76
+ return child;
77
+ }
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+ //# sourceMappingURL=getArticulationState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getArticulationState.js","sourceRoot":"","sources":["../../src/utils/getArticulationState.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,CAAN,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IAC5B,mEAAa,CAAA;IACb,+DAAW,CAAA;IACX,wEAAgB,CAAA;AACjB,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,QAI5B;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,oBAAoB,CACnC,MAAsD,EACtD,IAAiB;;IAEjB,MAAM,UAAU,GAAG,iBAAiB,CACnC,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,YAAY,CAAC,MAAM,CAC1B,CAAC;IACF,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,QAAQ,CAC1B,SAAS,CAAC,GAAG,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,CAAC,KAAK,mCAAI,GAAG,CAAC,CAClD,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CACpC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAc;KACjE,CAAC,CAAC,CACH,CAAC;IAEF,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO;YACN,KAAK,EAAE,EAAE;SACT,CAAC;IACH,CAAC;IAED,OAAO;QACN,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;;YAAC,OAAA,CAAC;gBAC5B,KAAK,EAAE,GAAG;gBACV,QAAQ,EAAE,QAAQ,CACjB,MAAA,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,mCAC9C,iBAAiB,CAAC,WAAW,CAC9B;gBACD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI;oBACrB,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE;oBACjC,CAAC,CAAC,GAAG,CAAY;aAClB,CAAC,CAAA;SAAA,CAAC;KACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAChC,UAAiC,EACjC,EAAU;IAEV,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,aAAa,KAAK,YAAY,EAAE,CAAC;YAClE,OAAO,CAAC,CAAC;QACV,CAAC;QACD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAClD,IAAI,KAAK,EAAE,CAAC;gBACX,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { LunaticVariablesStore } from '../use-lunatic/commons/variables/lunatic-variables-store';
2
+ import type { LunaticSource } from '../type.source';
3
+ /**
4
+ * Retrieve the multimode state
5
+ *
6
+ * ## Why this hook
7
+ *
8
+ * The goal of this hook is to provide insights about a roundabout using extra information inserted in the JSON source
9
+ * provided to Lunatic.
10
+ *
11
+ * For instance
12
+ *
13
+ * ```
14
+ * {
15
+ * "multimode": {
16
+ * "questionnaire": {
17
+ * "rules": {
18
+ * "IS_MOVED": {
19
+ * "type": "VTL",
20
+ * "value": "nvl(HABITEZ_VOUS_ICI, true)"
21
+ * },
22
+ * }
23
+ * },
24
+ * "leaf": {
25
+ * "source": "id-roundabout-in-questionnaire",
26
+ * "rules": {
27
+ * "IS_MOVED": {
28
+ * "type": "VTL",
29
+ * "value": "nvl(PRENOM_HABITE_PLUS_LA, false)"
30
+ * },
31
+ * }
32
+ * }
33
+ * },
34
+ * }
35
+ * ```
36
+ *
37
+ * Run the expression to check if rules are true or false. A rule is considered as true if at least one expression is evaluated to true
38
+ *
39
+ * ```
40
+ * {
41
+ * "IS_MOVED": true
42
+ * }
43
+ * ```
44
+ */
45
+ export declare function useMultimode(source: LunaticSource, store: LunaticVariablesStore): {
46
+ getMultimode: () => {
47
+ [k: string]: boolean;
48
+ };
49
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useMultimode = useMultimode;
4
+ const react_1 = require("react");
5
+ const getArticulationState_1 = require("../utils/getArticulationState");
6
+ const number_1 = require("../utils/number");
7
+ /**
8
+ * Retrieve the multimode state
9
+ *
10
+ * ## Why this hook
11
+ *
12
+ * The goal of this hook is to provide insights about a roundabout using extra information inserted in the JSON source
13
+ * provided to Lunatic.
14
+ *
15
+ * For instance
16
+ *
17
+ * ```
18
+ * {
19
+ * "multimode": {
20
+ * "questionnaire": {
21
+ * "rules": {
22
+ * "IS_MOVED": {
23
+ * "type": "VTL",
24
+ * "value": "nvl(HABITEZ_VOUS_ICI, true)"
25
+ * },
26
+ * }
27
+ * },
28
+ * "leaf": {
29
+ * "source": "id-roundabout-in-questionnaire",
30
+ * "rules": {
31
+ * "IS_MOVED": {
32
+ * "type": "VTL",
33
+ * "value": "nvl(PRENOM_HABITE_PLUS_LA, false)"
34
+ * },
35
+ * }
36
+ * }
37
+ * },
38
+ * }
39
+ * ```
40
+ *
41
+ * Run the expression to check if rules are true or false. A rule is considered as true if at least one expression is evaluated to true
42
+ *
43
+ * ```
44
+ * {
45
+ * "IS_MOVED": true
46
+ * }
47
+ * ```
48
+ */
49
+ function useMultimode(source, store) {
50
+ const getMultimode = (0, react_1.useCallback)(() => {
51
+ if (!source.multimode) {
52
+ return {};
53
+ }
54
+ const roundabout = (0, getArticulationState_1.findComponentById)(source.components, source.multimode.leaf.source);
55
+ const keys = new Set([
56
+ ...Object.keys(source.multimode.questionnaire.rules),
57
+ ...Object.keys(source.multimode.leaf.rules),
58
+ ]);
59
+ const iterations = (0, number_1.forceInt)(store.run(roundabout?.iterations.value ?? '0'));
60
+ return Object.fromEntries(Array.from(keys).map((key) => {
61
+ // Check the value at questionnaire level
62
+ const questionnaireExpression = source.multimode?.questionnaire.rules[key];
63
+ if (questionnaireExpression &&
64
+ store.run(questionnaireExpression.value)) {
65
+ return [key, true];
66
+ }
67
+ const leafExpression = source.multimode?.leaf.rules[key];
68
+ // There is no expression for the leaf
69
+ if (!leafExpression) {
70
+ return [key, false];
71
+ }
72
+ for (let i = 0; i < iterations; i++) {
73
+ if (store.run(leafExpression.value, { iteration: [i] })) {
74
+ return [key, true];
75
+ }
76
+ }
77
+ return [key, false];
78
+ }));
79
+ }, [source, store]);
80
+ return {
81
+ getMultimode,
82
+ };
83
+ }
84
+ //# sourceMappingURL=useMultimode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMultimode.js","sourceRoot":"","sources":["../src/hooks/useMultimode.ts"],"names":[],"mappings":";;AAgDA,oCAqDC;AAnGD,iCAAoC;AACpC,wEAAkE;AAClE,4CAA2C;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,SAAgB,YAAY,CAC3B,MAAqB,EACrB,KAA4B;IAE5B,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACrC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,UAAU,GAAG,IAAA,wCAAiB,EACnC,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAC5B,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC;YACpB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC;YACpD,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,IAAA,iBAAQ,EAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC;QAE5E,OAAO,MAAM,CAAC,WAAW,CACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC5B,yCAAyC;YACzC,MAAM,uBAAuB,GAC5B,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,IACC,uBAAuB;gBACvB,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,EACvC,CAAC;gBACF,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpB,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAEzD,sCAAsC;YACtC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrB,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzD,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC;YAED,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CACF,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAEpB,OAAO;QACN,YAAY;KACZ,CAAC;AACH,CAAC"}
package/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export { ModalControls } from './components/shared/ModalControls/ModalControls';
7
7
  export { Button } from './components/shared/Button/Button';
8
8
  export { LunaticComponents } from './components/LunaticComponents';
9
9
  export { useLunatic } from './use-lunatic/use-lunatic';
10
+ export { getArticulationState } from './utils/getArticulationState';
10
11
  export { MDLabel } from './components/shared/MDLabel/MDLabel';
11
12
  export type { LunaticComponentDefinition, LunaticControl, LunaticData, LunaticValues, LunaticError, LunaticExpression, LunaticVariable, LunaticCollectedValue, LunaticStateVariable, LunaticState, LunaticPager, LunaticOptions, LunaticChangesHandler, } from './use-lunatic/type';
12
13
  export type { LunaticComponentProps, LunaticExtraProps, } from './components/type';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VTLInterpretationError = exports.VTLMissingDependency = exports.VTLExpressionError = exports.VTLMissingDependencies = exports.MDLabel = exports.useLunatic = exports.LunaticComponents = exports.Button = exports.ModalControls = exports.components = void 0;
3
+ exports.VTLInterpretationError = exports.VTLMissingDependency = exports.VTLExpressionError = exports.VTLMissingDependencies = exports.MDLabel = exports.getArticulationState = exports.useLunatic = exports.LunaticComponents = exports.Button = exports.ModalControls = exports.components = void 0;
4
4
  /**
5
5
  * We should remove this export to avoid `import * as lunatic from "@inseefr/lunatic"` in orchestrators
6
6
  * but this is a breaking change
@@ -15,6 +15,8 @@ var LunaticComponents_1 = require("./components/LunaticComponents");
15
15
  Object.defineProperty(exports, "LunaticComponents", { enumerable: true, get: function () { return LunaticComponents_1.LunaticComponents; } });
16
16
  var use_lunatic_1 = require("./use-lunatic/use-lunatic");
17
17
  Object.defineProperty(exports, "useLunatic", { enumerable: true, get: function () { return use_lunatic_1.useLunatic; } });
18
+ var getArticulationState_1 = require("./utils/getArticulationState");
19
+ Object.defineProperty(exports, "getArticulationState", { enumerable: true, get: function () { return getArticulationState_1.getArticulationState; } });
18
20
  var MDLabel_1 = require("./components/shared/MDLabel/MDLabel");
19
21
  Object.defineProperty(exports, "MDLabel", { enumerable: true, get: function () { return MDLabel_1.MDLabel; } });
20
22
  // Export errors (useful for typeof)
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,gDAA6D;AAApD,qGAAA,OAAO,OAAc;AAC9B,iFAAgF;AAAvE,8GAAA,aAAa,OAAA;AACtB,4DAA2D;AAAlD,gGAAA,MAAM,OAAA;AAEf,oEAAmE;AAA1D,sHAAA,iBAAiB,OAAA;AAC1B,yDAAuD;AAA9C,yGAAA,UAAU,OAAA;AAEnB,+DAA8D;AAArD,kGAAA,OAAO,OAAA;AAyBhB,oCAAoC;AACpC,iEAKgD;AAJ/C,gHAAA,sBAAsB,OAAA;AACtB,4GAAA,kBAAkB,OAAA;AAClB,8GAAA,oBAAoB,OAAA;AACpB,gHAAA,sBAAsB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,gDAA6D;AAApD,qGAAA,OAAO,OAAc;AAC9B,iFAAgF;AAAvE,8GAAA,aAAa,OAAA;AACtB,4DAA2D;AAAlD,gGAAA,MAAM,OAAA;AAEf,oEAAmE;AAA1D,sHAAA,iBAAiB,OAAA;AAC1B,yDAAuD;AAA9C,yGAAA,UAAU,OAAA;AACnB,qEAAoE;AAA3D,4HAAA,oBAAoB,OAAA;AAE7B,+DAA8D;AAArD,kGAAA,OAAO,OAAA;AAyBhB,oCAAoC;AACpC,iEAKgD;AAJ/C,gHAAA,sBAAsB,OAAA;AACtB,4GAAA,kBAAkB,OAAA;AAClB,8GAAA,oBAAoB,OAAA;AACpB,gHAAA,sBAAsB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inseefr/lunatic",
3
- "version": "3.6.14",
3
+ "version": "3.6.15-rc.1",
4
4
  "description": "Library of questionnaire components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -225,6 +225,7 @@
225
225
  "src/hooks/useKeyboardKey.ts",
226
226
  "src/hooks/useListKeyboardHandler.ts",
227
227
  "src/hooks/useLocalStorage.ts",
228
+ "src/hooks/useMultimode.ts",
228
229
  "src/hooks/useRefSync.ts",
229
230
  "src/i18n/build-dictionary.ts",
230
231
  "src/i18n/dictionary.ts",
@@ -235,6 +236,9 @@
235
236
  "src/json.d.ts",
236
237
  "src/stories/accordion/accordion.stories.tsx",
237
238
  "src/stories/accordion/source.json",
239
+ "src/stories/behaviour/articulation/articulation.stories.tsx",
240
+ "src/stories/behaviour/articulation/multimode.stories.tsx",
241
+ "src/stories/behaviour/articulation/roundabout.json",
238
242
  "src/stories/behaviour/cleaning/cleaning.stories.tsx",
239
243
  "src/stories/behaviour/cleaning/source-loop-scopes.json",
240
244
  "src/stories/behaviour/cleaning/source-loop.json",
@@ -431,6 +435,7 @@
431
435
  "src/utils/dom.ts",
432
436
  "src/utils/env.ts",
433
437
  "src/utils/function.ts",
438
+ "src/utils/getArticulationState.ts",
434
439
  "src/utils/is-element.ts",
435
440
  "src/utils/logger.ts",
436
441
  "src/utils/number.spec.ts",
@@ -1323,6 +1328,9 @@
1323
1328
  "esm/hooks/useLocalStorage.d.ts",
1324
1329
  "esm/hooks/useLocalStorage.js",
1325
1330
  "esm/hooks/useLocalStorage.js.map",
1331
+ "esm/hooks/useMultimode.d.ts",
1332
+ "esm/hooks/useMultimode.js",
1333
+ "esm/hooks/useMultimode.js.map",
1326
1334
  "esm/hooks/useRefSync.d.ts",
1327
1335
  "esm/hooks/useRefSync.js",
1328
1336
  "esm/hooks/useRefSync.js.map",
@@ -1577,6 +1585,9 @@
1577
1585
  "esm/utils/function.d.ts",
1578
1586
  "esm/utils/function.js",
1579
1587
  "esm/utils/function.js.map",
1588
+ "esm/utils/getArticulationState.d.ts",
1589
+ "esm/utils/getArticulationState.js",
1590
+ "esm/utils/getArticulationState.js.map",
1580
1591
  "esm/utils/is-element.d.ts",
1581
1592
  "esm/utils/is-element.js",
1582
1593
  "esm/utils/is-element.js.map",
@@ -1649,6 +1660,9 @@
1649
1660
  "hooks/useLocalStorage.d.ts",
1650
1661
  "hooks/useLocalStorage.js",
1651
1662
  "hooks/useLocalStorage.js.map",
1663
+ "hooks/useMultimode.d.ts",
1664
+ "hooks/useMultimode.js",
1665
+ "hooks/useMultimode.js.map",
1652
1666
  "hooks/useRefSync.d.ts",
1653
1667
  "hooks/useRefSync.js",
1654
1668
  "hooks/useRefSync.js.map",
@@ -1904,6 +1918,9 @@
1904
1918
  "utils/function.d.ts",
1905
1919
  "utils/function.js",
1906
1920
  "utils/function.js.map",
1921
+ "utils/getArticulationState.d.ts",
1922
+ "utils/getArticulationState.js",
1923
+ "utils/getArticulationState.js.map",
1907
1924
  "utils/is-element.d.ts",
1908
1925
  "utils/is-element.js",
1909
1926
  "utils/is-element.js.map",
@@ -1,6 +1,7 @@
1
1
  import { CustomRoundabout } from './CustomRoundabout';
2
2
  import type { LunaticComponentProps } from '../type';
3
3
  import { getComponentErrors } from '../shared/ComponentErrors/ComponentErrors';
4
+ import { ArticulationState } from '../../utils/getArticulationState';
4
5
 
5
6
  /**
6
7
  * Roundabout is a special loop component where the user can select the iteration to go to
@@ -8,11 +9,15 @@ import { getComponentErrors } from '../shared/ComponentErrors/ComponentErrors';
8
9
  export function Roundabout(props: LunaticComponentProps<'Roundabout'>) {
9
10
  const goToIteration = (iteration: number) => {
10
11
  if (
11
- props.items[iteration].progress !== 1 &&
12
- props.items[iteration].progress !== 0
12
+ props.items[iteration].progress !== ArticulationState.COMPLETED &&
13
+ props.items[iteration].progress !== ArticulationState.STARTED
13
14
  ) {
14
15
  props.handleChanges([
15
- { name: props.progressVariable, value: 0, iteration: [iteration] },
16
+ {
17
+ name: props.progressVariable,
18
+ value: ArticulationState.STARTED,
19
+ iteration: [iteration],
20
+ },
16
21
  ]);
17
22
  }
18
23
  props.goToPage({
@@ -0,0 +1,102 @@
1
+ import type { LunaticVariablesStore } from '../use-lunatic/commons/variables/lunatic-variables-store';
2
+ import type { LunaticSource } from '../type.source';
3
+ import { useCallback } from 'react';
4
+ import { findComponentById } from '../utils/getArticulationState';
5
+ import { forceInt } from '../utils/number';
6
+
7
+ /**
8
+ * Retrieve the multimode state
9
+ *
10
+ * ## Why this hook
11
+ *
12
+ * The goal of this hook is to provide insights about a roundabout using extra information inserted in the JSON source
13
+ * provided to Lunatic.
14
+ *
15
+ * For instance
16
+ *
17
+ * ```
18
+ * {
19
+ * "multimode": {
20
+ * "questionnaire": {
21
+ * "rules": {
22
+ * "IS_MOVED": {
23
+ * "type": "VTL",
24
+ * "value": "nvl(HABITEZ_VOUS_ICI, true)"
25
+ * },
26
+ * }
27
+ * },
28
+ * "leaf": {
29
+ * "source": "id-roundabout-in-questionnaire",
30
+ * "rules": {
31
+ * "IS_MOVED": {
32
+ * "type": "VTL",
33
+ * "value": "nvl(PRENOM_HABITE_PLUS_LA, false)"
34
+ * },
35
+ * }
36
+ * }
37
+ * },
38
+ * }
39
+ * ```
40
+ *
41
+ * Run the expression to check if rules are true or false. A rule is considered as true if at least one expression is evaluated to true
42
+ *
43
+ * ```
44
+ * {
45
+ * "IS_MOVED": true
46
+ * }
47
+ * ```
48
+ */
49
+ export function useMultimode(
50
+ source: LunaticSource,
51
+ store: LunaticVariablesStore
52
+ ) {
53
+ const getMultimode = useCallback(() => {
54
+ if (!source.multimode) {
55
+ return {};
56
+ }
57
+
58
+ const roundabout = findComponentById(
59
+ source.components,
60
+ source.multimode.leaf.source
61
+ );
62
+
63
+ const keys = new Set([
64
+ ...Object.keys(source.multimode.questionnaire.rules),
65
+ ...Object.keys(source.multimode.leaf.rules),
66
+ ]);
67
+ const iterations = forceInt(store.run(roundabout?.iterations.value ?? '0'));
68
+
69
+ return Object.fromEntries(
70
+ Array.from(keys).map((key) => {
71
+ // Check the value at questionnaire level
72
+ const questionnaireExpression =
73
+ source.multimode?.questionnaire.rules[key];
74
+ if (
75
+ questionnaireExpression &&
76
+ store.run(questionnaireExpression.value)
77
+ ) {
78
+ return [key, true];
79
+ }
80
+
81
+ const leafExpression = source.multimode?.leaf.rules[key];
82
+
83
+ // There is no expression for the leaf
84
+ if (!leafExpression) {
85
+ return [key, false];
86
+ }
87
+
88
+ for (let i = 0; i < iterations; i++) {
89
+ if (store.run(leafExpression.value, { iteration: [i] })) {
90
+ return [key, true];
91
+ }
92
+ }
93
+
94
+ return [key, false];
95
+ })
96
+ );
97
+ }, [source, store]);
98
+
99
+ return {
100
+ getMultimode,
101
+ };
102
+ }
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export { Button } from './components/shared/Button/Button';
8
8
 
9
9
  export { LunaticComponents } from './components/LunaticComponents';
10
10
  export { useLunatic } from './use-lunatic/use-lunatic';
11
+ export { getArticulationState } from './utils/getArticulationState';
11
12
 
12
13
  export { MDLabel } from './components/shared/MDLabel/MDLabel';
13
14
 
@@ -0,0 +1,90 @@
1
+ import source from './roundabout.json';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { useMemo, useState } from 'react';
4
+ import { getArticulationState } from '../../../utils/getArticulationState';
5
+ import { Orchestrator } from '../../utils/Orchestrator';
6
+
7
+ type Source = Parameters<typeof getArticulationState>[0];
8
+ type Data = Parameters<typeof getArticulationState>[1];
9
+
10
+ type Props = {
11
+ source: Source;
12
+ data: Data;
13
+ };
14
+
15
+ function StoryComponent({ source, data }: Props) {
16
+ const [page, setPage] = useState(null as null | string);
17
+ const gotoNav = () => setPage(null);
18
+ const { items } = useMemo(
19
+ () => getArticulationState(source, data),
20
+ [source, data]
21
+ );
22
+
23
+ if (page) {
24
+ return (
25
+ <div>
26
+ {page}
27
+ <button onClick={gotoNav}>&lt; Revenir à l'articulation</button>
28
+ {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
29
+ {/*/ @ts-ignore */}
30
+ <Orchestrator source={source} data={data} initialPage={page} />
31
+ </div>
32
+ );
33
+ }
34
+
35
+ const progressLabel = (n: number) => {
36
+ if (n === -1) {
37
+ return 'Commencer';
38
+ }
39
+ if (n === 0) {
40
+ return 'Continuer';
41
+ }
42
+ return 'Complété';
43
+ };
44
+
45
+ return (
46
+ <div className="space-y-4">
47
+ <h2 className="font-bold text-2xl">Articulation</h2>
48
+ <table className="table">
49
+ <thead>
50
+ <tr>
51
+ {items[0].cells.map((cell, k) => (
52
+ <th key={k}>{cell.label}</th>
53
+ ))}
54
+ <th>Actions</th>
55
+ </tr>
56
+ </thead>
57
+ <tbody>
58
+ {items.map((item, k) => (
59
+ <tr key={k}>
60
+ {item.cells.map((cell, kk) => (
61
+ <td key={kk}>{cell.value}</td>
62
+ ))}
63
+ <td>
64
+ <button onClick={() => console.log('ToDo')} className="btn">
65
+ {progressLabel(item.progress)}
66
+ </button>
67
+ </td>
68
+ </tr>
69
+ ))}
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+ );
74
+ }
75
+
76
+ const meta: Meta<typeof StoryComponent> = {
77
+ title: 'Behaviour/Articulation',
78
+ component: StoryComponent,
79
+ };
80
+
81
+ export default meta;
82
+
83
+ type Story = StoryObj<typeof StoryComponent>;
84
+
85
+ export const Basic: Story = {
86
+ args: {
87
+ source: source as Source,
88
+ data: {},
89
+ },
90
+ };
@@ -0,0 +1,19 @@
1
+ import source from './roundabout.json';
2
+
3
+ import { Meta, StoryObj } from '@storybook/react';
4
+ import { Orchestrator } from '../../utils/Orchestrator';
5
+
6
+ const meta: Meta<typeof Orchestrator> = {
7
+ title: 'Behaviour/Articulation/MultiMode',
8
+ component: Orchestrator,
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Orchestrator>;
13
+
14
+ export const Default: Story = {
15
+ args: {
16
+ source,
17
+ multiMode: true,
18
+ },
19
+ };