@inseefr/lunatic 3.6.13 → 3.6.15-rc.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.
Files changed (51) hide show
  1. package/components/shared/Combobox/ComboboxContent.js +0 -3
  2. package/components/shared/Combobox/ComboboxContent.js.map +1 -1
  3. package/esm/components/shared/Combobox/ComboboxContent.js +1 -4
  4. package/esm/components/shared/Combobox/ComboboxContent.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 +55 -1
  12. package/esm/use-lunatic/reducer/reducerInitializer.d.ts +2 -2
  13. package/esm/use-lunatic/reducer/reducerInitializer.js +31 -24
  14. package/esm/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  15. package/esm/use-lunatic/type.d.ts +2 -0
  16. package/esm/use-lunatic/use-lunatic.js +3 -0
  17. package/esm/use-lunatic/use-lunatic.js.map +1 -1
  18. package/esm/utils/getArticulation.d.ts +61 -0
  19. package/esm/utils/getArticulation.js +78 -0
  20. package/esm/utils/getArticulation.js.map +1 -0
  21. package/hooks/useMultiMode.d.ts +49 -0
  22. package/hooks/useMultiMode.js +84 -0
  23. package/hooks/useMultiMode.js.map +1 -0
  24. package/index.d.ts +1 -0
  25. package/index.js +3 -1
  26. package/index.js.map +1 -1
  27. package/package.json +19 -1
  28. package/src/components/shared/Combobox/ComboboxContent.tsx +6 -5
  29. package/src/hooks/useMultiMode.ts +102 -0
  30. package/src/index.ts +1 -0
  31. package/src/stories/behaviour/articulation/articulation.stories.tsx +90 -0
  32. package/src/stories/behaviour/articulation/multimode.stories.tsx +19 -0
  33. package/src/stories/behaviour/articulation/roundabout.json +413 -0
  34. package/src/stories/utils/Orchestrator.tsx +10 -0
  35. package/src/stories/utils/OrchestratorSidebar.tsx +25 -1
  36. package/src/type.source.ts +55 -1
  37. package/src/use-lunatic/reducer/reducerInitializer.tsx +40 -29
  38. package/src/use-lunatic/type.ts +2 -0
  39. package/src/use-lunatic/use-lunatic.ts +4 -0
  40. package/src/utils/getArticulation.ts +117 -0
  41. package/tsconfig.build.tsbuildinfo +1 -1
  42. package/type.source.d.ts +55 -1
  43. package/use-lunatic/reducer/reducerInitializer.d.ts +2 -2
  44. package/use-lunatic/reducer/reducerInitializer.js +31 -24
  45. package/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  46. package/use-lunatic/type.d.ts +2 -0
  47. package/use-lunatic/use-lunatic.js +3 -0
  48. package/use-lunatic/use-lunatic.js.map +1 -1
  49. package/utils/getArticulation.d.ts +61 -0
  50. package/utils/getArticulation.js +78 -0
  51. package/utils/getArticulation.js.map +1 -0
@@ -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 getArticulation_1 = require("../utils/getArticulation");
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, getArticulation_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,8DAA6D;AAC7D,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,mCAAiB,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 { getArticulation } from './utils/getArticulation';
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.getArticulation = 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 getArticulation_1 = require("./utils/getArticulation");
19
+ Object.defineProperty(exports, "getArticulation", { enumerable: true, get: function () { return getArticulation_1.getArticulation; } });
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,2DAA0D;AAAjD,kHAAA,eAAe,OAAA;AAExB,+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.13",
3
+ "version": "3.6.15-rc.0",
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/getArticulation.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/getArticulation.d.ts",
1589
+ "esm/utils/getArticulation.js",
1590
+ "esm/utils/getArticulation.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/getArticulation.d.ts",
1922
+ "utils/getArticulation.js",
1923
+ "utils/getArticulation.js.map",
1907
1924
  "utils/is-element.d.ts",
1908
1925
  "utils/is-element.js",
1909
1926
  "utils/is-element.js.map",
@@ -2017,6 +2034,7 @@
2017
2034
  "prettier": "^3.3.3",
2018
2035
  "react": "^18.3.1",
2019
2036
  "react-dom": "^18.3.1",
2037
+ "react-hot-keys": "^2.7.3",
2020
2038
  "storybook": "^8.2.9",
2021
2039
  "tailwindcss": "^4.1.4",
2022
2040
  "tsx": "^4.19.1",
@@ -1,5 +1,9 @@
1
- import type { KeyboardEvent } from 'react';
2
- import React, { type PropsWithChildren, useCallback, useRef } from 'react';
1
+ import {
2
+ type KeyboardEvent,
3
+ type PropsWithChildren,
4
+ useCallback,
5
+ useRef,
6
+ } from 'react';
3
7
  import classnames from 'classnames';
4
8
  import { KEYBOARD_KEY_CODES } from './constants';
5
9
  import { ComboboxContentBox } from './ComboboxContentBox';
@@ -37,15 +41,12 @@ export function ComboboxContent({
37
41
  const handleKeyDown = useCallback(
38
42
  function (e: KeyboardEvent) {
39
43
  const { key } = e;
40
- e.stopPropagation();
41
44
  switch (key) {
42
45
  case KEYBOARD_KEY_CODES.Escape:
43
46
  case KEYBOARD_KEY_CODES.Enter:
44
47
  case KEYBOARD_KEY_CODES.Tab:
45
48
  ref.current?.focus();
46
49
  break;
47
- default:
48
- // e.preventDefault();
49
50
  }
50
51
  onKeyDown(key);
51
52
  },
@@ -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/getArticulation';
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 { getArticulation } from './utils/getArticulation';
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 { getArticulation } from '../../../utils/getArticulation';
5
+ import { Orchestrator } from '../../utils/Orchestrator';
6
+
7
+ type Source = Parameters<typeof getArticulation>[0];
8
+ type Data = Parameters<typeof getArticulation>[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
+ () => getArticulation(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
+ };