@inseefr/lunatic 3.4.10 → 3.4.11-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 (82) hide show
  1. package/components/Loop/Loop.js +27 -7
  2. package/components/Loop/Loop.js.map +1 -1
  3. package/components/RosterForLoop/RosterForLoop.js +37 -8
  4. package/components/RosterForLoop/RosterForLoop.js.map +1 -1
  5. package/components/Sequence/Sequence.d.ts +1 -1
  6. package/components/Subsequence/Subsequence.d.ts +1 -1
  7. package/components/library.d.ts +2 -2
  8. package/esm/components/Loop/Loop.js +27 -7
  9. package/esm/components/Loop/Loop.js.map +1 -1
  10. package/esm/components/RosterForLoop/RosterForLoop.js +34 -8
  11. package/esm/components/RosterForLoop/RosterForLoop.js.map +1 -1
  12. package/esm/components/Sequence/Sequence.d.ts +1 -1
  13. package/esm/components/Subsequence/Subsequence.d.ts +1 -1
  14. package/esm/components/library.d.ts +2 -2
  15. package/esm/i18n/dictionary.d.ts +8 -0
  16. package/esm/i18n/dictionary.js +5 -0
  17. package/esm/i18n/dictionary.js.map +1 -1
  18. package/esm/i18n/index.d.ts +1 -1
  19. package/esm/type.source.js +0 -1
  20. package/esm/type.source.js.map +1 -1
  21. package/esm/use-lunatic/commons/variables/behaviours/resizing-behaviour.js +23 -7
  22. package/esm/use-lunatic/commons/variables/behaviours/resizing-behaviour.js.map +1 -1
  23. package/esm/use-lunatic/commons/variables/lunatic-variables-store.d.ts +3 -1
  24. package/esm/use-lunatic/commons/variables/lunatic-variables-store.js.map +1 -1
  25. package/esm/use-lunatic/commons/variables/lunatic-variables-store.spec.js +66 -1
  26. package/esm/use-lunatic/commons/variables/lunatic-variables-store.spec.js.map +1 -1
  27. package/esm/use-lunatic/props/getComponentTypeProps.d.ts +4 -4
  28. package/esm/use-lunatic/reducer/commons/index.d.ts +0 -1
  29. package/esm/use-lunatic/reducer/commons/index.js +0 -1
  30. package/esm/use-lunatic/reducer/commons/index.js.map +1 -1
  31. package/esm/use-lunatic/type.d.ts +1 -0
  32. package/esm/utils/array.d.ts +4 -0
  33. package/esm/utils/array.js +15 -2
  34. package/esm/utils/array.js.map +1 -1
  35. package/esm/utils/array.spec.js +12 -1
  36. package/esm/utils/array.spec.js.map +1 -1
  37. package/i18n/dictionary.d.ts +8 -0
  38. package/i18n/dictionary.js +5 -0
  39. package/i18n/dictionary.js.map +1 -1
  40. package/i18n/index.d.ts +1 -1
  41. package/package.json +1 -8
  42. package/src/components/Loop/Loop.tsx +42 -12
  43. package/src/components/RosterForLoop/RosterForLoop.tsx +42 -2
  44. package/src/components/RosterForLoop/__snapshots__/RosterForLoop.spec.tsx.snap +18 -0
  45. package/src/i18n/dictionary.ts +5 -0
  46. package/src/stories/pairwise/data.json +1 -1
  47. package/src/stories/pairwise/source.json +3 -1
  48. package/src/type.source.ts +0 -1
  49. package/src/use-lunatic/__snapshots__/use-lunatic.test.ts.snap +0 -323
  50. package/src/use-lunatic/commons/variables/behaviours/resizing-behaviour.ts +35 -10
  51. package/src/use-lunatic/commons/variables/lunatic-variables-store.spec.ts +68 -1
  52. package/src/use-lunatic/commons/variables/lunatic-variables-store.ts +3 -1
  53. package/src/use-lunatic/reducer/commons/index.ts +0 -1
  54. package/src/use-lunatic/type.ts +1 -0
  55. package/src/utils/array.spec.ts +18 -1
  56. package/src/utils/array.ts +21 -3
  57. package/tsconfig.build.tsbuildinfo +1 -1
  58. package/type.source.js +0 -1
  59. package/type.source.js.map +1 -1
  60. package/use-lunatic/commons/variables/behaviours/resizing-behaviour.js +22 -6
  61. package/use-lunatic/commons/variables/behaviours/resizing-behaviour.js.map +1 -1
  62. package/use-lunatic/commons/variables/lunatic-variables-store.d.ts +3 -1
  63. package/use-lunatic/commons/variables/lunatic-variables-store.js.map +1 -1
  64. package/use-lunatic/commons/variables/lunatic-variables-store.spec.js +66 -1
  65. package/use-lunatic/commons/variables/lunatic-variables-store.spec.js.map +1 -1
  66. package/use-lunatic/props/getComponentTypeProps.d.ts +4 -4
  67. package/use-lunatic/reducer/commons/index.d.ts +0 -1
  68. package/use-lunatic/reducer/commons/index.js +0 -6
  69. package/use-lunatic/reducer/commons/index.js.map +1 -1
  70. package/use-lunatic/type.d.ts +1 -0
  71. package/utils/array.d.ts +4 -0
  72. package/utils/array.js +16 -2
  73. package/utils/array.js.map +1 -1
  74. package/utils/array.spec.js +11 -0
  75. package/utils/array.spec.js.map +1 -1
  76. package/esm/use-lunatic/reducer/commons/resize-array-variable.d.ts +0 -5
  77. package/esm/use-lunatic/reducer/commons/resize-array-variable.js +0 -21
  78. package/esm/use-lunatic/reducer/commons/resize-array-variable.js.map +0 -1
  79. package/src/use-lunatic/reducer/commons/resize-array-variable.ts +0 -28
  80. package/use-lunatic/reducer/commons/resize-array-variable.d.ts +0 -5
  81. package/use-lunatic/reducer/commons/resize-array-variable.js +0 -23
  82. package/use-lunatic/reducer/commons/resize-array-variable.js.map +0 -1
@@ -1,6 +1,11 @@
1
1
  const dictionary = {
2
2
  DEFAULT_BUTTON_ADD: { fr: 'Ajouter une ligne', en: 'Add row' },
3
3
  DEFAULT_BUTTON_REMOVE: { fr: 'Supprimer une ligne', en: 'Remove row' },
4
+ DEFAULT_BUTTON_REMOVE_THAT_ROW: {
5
+ fr: 'Supprimer cette ligne',
6
+ en: 'Remove that row',
7
+ },
8
+ ACTION_HEADER: { fr: 'Action', en: 'Action' },
4
9
  MODAL_IGNORE: { fr: 'Poursuivre', en: 'Ignore' },
5
10
  MODAL_CORRECT: { fr: 'Corriger ma réponse', en: 'Correct' },
6
11
  DK: { fr: 'Ne sais pas', en: "Don't know" },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "COLLECTED": {
3
- "PRENOM": { "COLLECTED": ["Dad", "Mom", "Unknow"] },
3
+ "PRENOM": { "COLLECTED": ["Dad", "Mom", "Daughter"] },
4
4
  "AGE": { "COLLECTED": [30, 29, 5] },
5
5
  "LINKS": {
6
6
  "COLLECTED": [[null]]
@@ -341,7 +341,9 @@
341
341
  "resizing": {
342
342
  "PRENOM": {
343
343
  "sizeForLinksVariables": ["count(PRENOM)", "count(PRENOM)"],
344
- "linksVariables": ["LINKS"]
344
+ "linksVariables": ["LINKS"],
345
+ "size": "count(PRENOM)",
346
+ "variables": ["AGE"]
345
347
  }
346
348
  }
347
349
  }
@@ -1,4 +1,3 @@
1
- /* eslint-disable */
2
1
  /**
3
2
  * This file was automatically generated by json-schema-to-typescript.
4
3
  * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
@@ -1855,329 +1855,6 @@ exports[`use-lunatic() > overview > with loop > should handle initialPage 1`] =
1855
1855
  ]
1856
1856
  `;
1857
1857
 
1858
- exports[`use-lunatic() > overview > with loop > should handle lastReachedPage 1`] = `
1859
- [
1860
- {
1861
- "children": [
1862
- {
1863
- "children": [],
1864
- "current": false,
1865
- "description": undefined,
1866
- "id": "lujqeci5",
1867
- "label": <MDLabel
1868
- expression="Votre santé"
1869
- />,
1870
- "page": "2",
1871
- "reached": true,
1872
- "type": "Subsequence",
1873
- },
1874
- {
1875
- "children": [],
1876
- "current": false,
1877
- "description": undefined,
1878
- "id": "lujqbyzl",
1879
- "label": <MDLabel
1880
- expression="Votre logement"
1881
- />,
1882
- "page": "3",
1883
- "reached": true,
1884
- "type": "Subsequence",
1885
- },
1886
- ],
1887
- "current": true,
1888
- "description": undefined,
1889
- "id": "lujqfpva",
1890
- "label": <MDLabel
1891
- expression="I - Séquence 1"
1892
- />,
1893
- "page": "1",
1894
- "reached": true,
1895
- "type": "Sequence",
1896
- },
1897
- {
1898
- "children": [
1899
- {
1900
- "children": [],
1901
- "current": false,
1902
- "description": undefined,
1903
- "id": "lulbmyhr",
1904
- "label": <MDLabel
1905
- expression="Commentaire sur composition du logement"
1906
- />,
1907
- "page": "8",
1908
- "reached": true,
1909
- "type": "Subsequence",
1910
- },
1911
- ],
1912
- "current": false,
1913
- "description": undefined,
1914
- "id": "lujqrqmp",
1915
- "label": <MDLabel
1916
- expression="II - Habitants du logement"
1917
- />,
1918
- "page": "5",
1919
- "reached": true,
1920
- "type": "Sequence",
1921
- },
1922
- {
1923
- "children": [
1924
- {
1925
- "children": [],
1926
- "current": false,
1927
- "description": undefined,
1928
- "id": "lujykwaz",
1929
- "label": <MDLabel
1930
- expression="Caractéristiques de Quentin"
1931
- />,
1932
- "page": "10.1#1",
1933
- "reached": true,
1934
- "type": "Subsequence",
1935
- },
1936
- {
1937
- "children": [],
1938
- "current": false,
1939
- "description": undefined,
1940
- "id": "lujykwaz",
1941
- "label": <MDLabel
1942
- expression="Caractéristiques de Luna"
1943
- />,
1944
- "page": "10.1#2",
1945
- "reached": true,
1946
- "type": "Subsequence",
1947
- },
1948
- {
1949
- "children": [],
1950
- "current": false,
1951
- "description": undefined,
1952
- "id": "lujykwaz",
1953
- "label": <MDLabel
1954
- expression="Caractéristiques de Paul"
1955
- />,
1956
- "page": "10.1#3",
1957
- "reached": true,
1958
- "type": "Subsequence",
1959
- },
1960
- {
1961
- "children": [],
1962
- "current": false,
1963
- "description": undefined,
1964
- "id": "lujyik5q",
1965
- "label": <MDLabel
1966
- expression="Autres caractéristiques de Luna : filtrée pour le premier individu"
1967
- />,
1968
- "page": "11.1#2",
1969
- "reached": true,
1970
- "type": "Subsequence",
1971
- },
1972
- {
1973
- "children": [],
1974
- "current": false,
1975
- "description": undefined,
1976
- "id": "luk0swcz",
1977
- "label": <MDLabel
1978
- expression="Encore d'autres caractéristiques de Luna : filtrée pour le premier individu"
1979
- />,
1980
- "page": "11.2#2",
1981
- "reached": true,
1982
- "type": "Subsequence",
1983
- },
1984
- {
1985
- "children": [],
1986
- "current": false,
1987
- "description": undefined,
1988
- "id": "lujyik5q",
1989
- "label": <MDLabel
1990
- expression="Autres caractéristiques de Paul : filtrée pour le premier individu"
1991
- />,
1992
- "page": "11.1#3",
1993
- "reached": false,
1994
- "type": "Subsequence",
1995
- },
1996
- {
1997
- "children": [],
1998
- "current": false,
1999
- "description": undefined,
2000
- "id": "luk0swcz",
2001
- "label": <MDLabel
2002
- expression="Encore d'autres caractéristiques de Paul : filtrée pour le premier individu"
2003
- />,
2004
- "page": "11.2#3",
2005
- "reached": false,
2006
- "type": "Subsequence",
2007
- },
2008
- ],
2009
- "current": false,
2010
- "description": undefined,
2011
- "id": "lujyi4pe",
2012
- "label": <MDLabel
2013
- expression="III - Détail des individus"
2014
- />,
2015
- "page": "9",
2016
- "reached": true,
2017
- "type": "Sequence",
2018
- },
2019
- {
2020
- "children": [
2021
- {
2022
- "children": [],
2023
- "current": false,
2024
- "description": undefined,
2025
- "id": "lumfc98o",
2026
- "label": <MDLabel
2027
- expression="Belle sous-séquence pour Quentin"
2028
- />,
2029
- "page": "12.2#1",
2030
- "reached": false,
2031
- "type": "Subsequence",
2032
- },
2033
- {
2034
- "children": [],
2035
- "current": false,
2036
- "description": undefined,
2037
- "id": "lumfe3bj",
2038
- "label": <MDLabel
2039
- expression="Autre belle sous-seq"
2040
- />,
2041
- "page": "12.3#1",
2042
- "reached": false,
2043
- "type": "Subsequence",
2044
- },
2045
- ],
2046
- "current": false,
2047
- "description": undefined,
2048
- "id": "luk1ojt5",
2049
- "label": <MDLabel
2050
- expression="IV - Belle séquence pour Quentin"
2051
- />,
2052
- "page": "12.1#1",
2053
- "reached": false,
2054
- "type": "Sequence",
2055
- },
2056
- {
2057
- "children": [],
2058
- "current": false,
2059
- "description": undefined,
2060
- "id": "lulbelgr",
2061
- "label": <MDLabel
2062
- expression="V - Autre séquence pour Quentin"
2063
- />,
2064
- "page": "12.4#1",
2065
- "reached": false,
2066
- "type": "Sequence",
2067
- },
2068
- {
2069
- "children": [
2070
- {
2071
- "children": [],
2072
- "current": false,
2073
- "description": undefined,
2074
- "id": "lumfc98o",
2075
- "label": <MDLabel
2076
- expression="Belle sous-séquence pour Luna"
2077
- />,
2078
- "page": "12.2#2",
2079
- "reached": false,
2080
- "type": "Subsequence",
2081
- },
2082
- {
2083
- "children": [],
2084
- "current": false,
2085
- "description": undefined,
2086
- "id": "lumfe3bj",
2087
- "label": <MDLabel
2088
- expression="Autre belle sous-seq"
2089
- />,
2090
- "page": "12.3#2",
2091
- "reached": false,
2092
- "type": "Subsequence",
2093
- },
2094
- ],
2095
- "current": false,
2096
- "description": undefined,
2097
- "id": "luk1ojt5",
2098
- "label": <MDLabel
2099
- expression="IV - Belle séquence pour Luna"
2100
- />,
2101
- "page": "12.1#2",
2102
- "reached": false,
2103
- "type": "Sequence",
2104
- },
2105
- {
2106
- "children": [],
2107
- "current": false,
2108
- "description": undefined,
2109
- "id": "lulbelgr",
2110
- "label": <MDLabel
2111
- expression="V - Autre séquence pour Luna"
2112
- />,
2113
- "page": "12.4#2",
2114
- "reached": false,
2115
- "type": "Sequence",
2116
- },
2117
- {
2118
- "children": [
2119
- {
2120
- "children": [],
2121
- "current": false,
2122
- "description": undefined,
2123
- "id": "lumfc98o",
2124
- "label": <MDLabel
2125
- expression="Belle sous-séquence pour Paul"
2126
- />,
2127
- "page": "12.2#3",
2128
- "reached": false,
2129
- "type": "Subsequence",
2130
- },
2131
- {
2132
- "children": [],
2133
- "current": false,
2134
- "description": undefined,
2135
- "id": "lumfe3bj",
2136
- "label": <MDLabel
2137
- expression="Autre belle sous-seq"
2138
- />,
2139
- "page": "12.3#3",
2140
- "reached": false,
2141
- "type": "Subsequence",
2142
- },
2143
- ],
2144
- "current": false,
2145
- "description": undefined,
2146
- "id": "luk1ojt5",
2147
- "label": <MDLabel
2148
- expression="IV - Belle séquence pour Paul"
2149
- />,
2150
- "page": "12.1#3",
2151
- "reached": false,
2152
- "type": "Sequence",
2153
- },
2154
- {
2155
- "children": [],
2156
- "current": false,
2157
- "description": undefined,
2158
- "id": "lulbelgr",
2159
- "label": <MDLabel
2160
- expression="V - Autre séquence pour Paul"
2161
- />,
2162
- "page": "12.4#3",
2163
- "reached": false,
2164
- "type": "Sequence",
2165
- },
2166
- {
2167
- "children": [],
2168
- "current": false,
2169
- "description": undefined,
2170
- "id": "COMMENT-SEQ",
2171
- "label": <MDLabel
2172
- expression="Commentaire"
2173
- />,
2174
- "page": "13",
2175
- "reached": false,
2176
- "type": "Sequence",
2177
- },
2178
- ]
2179
- `;
2180
-
2181
1858
  exports[`use-lunatic() > overview > with loop > should work with loop 1`] = `
2182
1859
  [
2183
1860
  {
@@ -1,9 +1,8 @@
1
1
  import type { LunaticVariablesStore } from '../lunatic-variables-store';
2
2
  import type { LunaticSource } from '../../../type';
3
3
  import { forceInt } from '../../../../utils/number';
4
- import { resizeArrayVariable } from '../../../reducer/commons';
5
4
  import { getExpressionAsString } from '../../../../utils/vtl';
6
- import { resizeArray } from '../../../../utils/array';
5
+ import { resizeArray, resizeDownArrayWithIndex } from '../../../../utils/array';
7
6
 
8
7
  /**
9
8
  * Resizing behaviour for the store
@@ -42,8 +41,20 @@ export function resizingBehaviour(
42
41
  const newSize = forceInt(store.run(resizingInfo.size));
43
42
  for (const variableName of resizingInfo.variables) {
44
43
  const value = store.get(variableName);
45
- if (!Array.isArray(value) || value.length !== newSize) {
46
- store.set(variableName, resizeArrayVariable(value, newSize, null), {
44
+ if (Array.isArray(value) && e.detail.removedIndex) {
45
+ store.set(
46
+ variableName,
47
+ resizeDownArrayWithIndex(value, e.detail.removedIndex),
48
+ {
49
+ cause: 'resizing',
50
+ }
51
+ );
52
+ }
53
+ if (
54
+ !e.detail.removedIndex &&
55
+ (!Array.isArray(value) || value.length !== newSize)
56
+ ) {
57
+ store.set(variableName, resizeArray(value, newSize, null), {
47
58
  cause: 'resizing',
48
59
  });
49
60
  }
@@ -61,6 +72,7 @@ function resizePairwise(
61
72
  },
62
73
  args: {
63
74
  iteration?: number[];
75
+ removedIndex?: number;
64
76
  }
65
77
  ) {
66
78
  // Handle expression being sent as an array or an object (ensure backward compatibility)
@@ -78,12 +90,25 @@ function resizePairwise(
78
90
  });
79
91
  resizingInfo.linksVariables.forEach((variable) => {
80
92
  const value = store.get(variable, args.iteration);
81
- const resizedValue = resizeArray(
82
- // The value is not an array, force an array
83
- Array.isArray(value) ? value.map((i) => resizeArray(i, ySize, null)) : [],
84
- xSize,
85
- new Array(ySize).fill(null)
86
- );
93
+ let resizedValue;
94
+ if (args.removedIndex) {
95
+ const removedIndex = args.removedIndex;
96
+ resizedValue = resizeDownArrayWithIndex(
97
+ Array.isArray(value)
98
+ ? value.map((i) => resizeDownArrayWithIndex(i, removedIndex))
99
+ : [],
100
+ removedIndex
101
+ );
102
+ } else {
103
+ resizedValue = resizeArray(
104
+ // The value is not an array, force an array
105
+ Array.isArray(value)
106
+ ? value.map((i) => resizeArray(i, ySize, null))
107
+ : [],
108
+ xSize,
109
+ new Array(ySize).fill(null)
110
+ );
111
+ }
87
112
  store.set(variable, resizedValue);
88
113
  });
89
114
  }
@@ -281,6 +281,28 @@ describe('lunatic-variables-store', () => {
281
281
  cause: 'resizing',
282
282
  });
283
283
  });
284
+
285
+ it('should resize variables with Index', () => {
286
+ variables.set('PRENOM', ['John', 'Jane', 'Marc']);
287
+ variables.set('AGE', [20, 30, 40]);
288
+ const spy = vi.fn();
289
+ variables.on('change', (e) => spy(e.detail));
290
+ resizingBehaviour(variables, {
291
+ PRENOM: {
292
+ size: 'count(PRENOM)',
293
+ variables: ['AGE'],
294
+ },
295
+ });
296
+ variables.set('PRENOM', ['John', 'Marc'], { removedIndex: 1 });
297
+ expect((variables.get('PRENOM') as string[]).length).toEqual(2);
298
+ expect((variables.get('AGE') as string[]).length).toEqual(2);
299
+ expect(spy).toHaveBeenLastCalledWith({
300
+ name: 'AGE',
301
+ value: [20, 40],
302
+ cause: 'resizing',
303
+ });
304
+ });
305
+
284
306
  it('should resize pairwise with the array syntax', () => {
285
307
  variables.set('PRENOM', []);
286
308
  variables.set('LINKS', [[]]);
@@ -316,7 +338,29 @@ describe('lunatic-variables-store', () => {
316
338
  [null, null, null],
317
339
  ]);
318
340
  });
319
- it('should handle both pairwise and normal resize', () => {
341
+ it('should resize pairwise with the object syntax with index', () => {
342
+ variables.set('PRENOM', ['John', 'Jane', 'Marc']);
343
+ variables.set('LINKS', [
344
+ [null, 2, 4],
345
+ [1, null, 2],
346
+ [3, 2, null],
347
+ ]);
348
+ resizingBehaviour(variables, {
349
+ PRENOM: {
350
+ sizeForLinksVariables: {
351
+ xAxisSize: 'count(PRENOM)',
352
+ yAxisSize: 'count(PRENOM)',
353
+ },
354
+ linksVariables: ['LINKS'],
355
+ },
356
+ });
357
+ variables.set('PRENOM', ['John', 'Marc'], { removedIndex: 1 });
358
+ expect(variables.get('LINKS') as string[][]).toEqual([
359
+ [null, 4],
360
+ [3, null],
361
+ ]);
362
+ });
363
+ it('should handle both: pairwise and normal resize', () => {
320
364
  variables.set('PRENOM', []);
321
365
  variables.set('NOM', []);
322
366
  variables.set('LINKS', [[]]);
@@ -336,6 +380,29 @@ describe('lunatic-variables-store', () => {
336
380
  ]);
337
381
  expect(variables.get('NOM') as string[]).toEqual([null, null, null]);
338
382
  });
383
+ it('should handle both: pairwise and normal resize with index', () => {
384
+ variables.set('PRENOM', ['John', 'Jane', 'Marc']);
385
+ variables.set('AGE', [40, 30, 20]);
386
+ variables.set('LINKS', [
387
+ [null, 2, 4],
388
+ [1, null, 2],
389
+ [3, 2, null],
390
+ ]);
391
+ resizingBehaviour(variables, {
392
+ PRENOM: {
393
+ sizeForLinksVariables: ['count(PRENOM)', 'count(PRENOM)'],
394
+ linksVariables: ['LINKS'],
395
+ size: 'count(PRENOM)',
396
+ variables: ['AGE'],
397
+ },
398
+ });
399
+ variables.set('PRENOM', ['John', 'Marc'], { removedIndex: 1 });
400
+ expect(variables.get('LINKS') as string[][]).toEqual([
401
+ [null, 4],
402
+ [3, null],
403
+ ]);
404
+ expect(variables.get('AGE') as string[]).toEqual([40, 20]);
405
+ });
339
406
  });
340
407
 
341
408
  describe('cleaning', () => {
@@ -33,6 +33,8 @@ export type EventArgs = {
33
33
  value: unknown;
34
34
  /** Iteration changed (for array). */
35
35
  iteration?: IterationLevel | undefined;
36
+ /** removedIndex: when resize an array directly with only one handleChange (remove one line in tableLoop) */
37
+ removedIndex?: number;
36
38
  /** What triggered this change. */
37
39
  cause?: 'resizing' | 'cleaning';
38
40
  /** Extra sent when setting the variable. */
@@ -123,7 +125,7 @@ export class LunaticVariablesStore {
123
125
  public set(
124
126
  name: string,
125
127
  value: unknown,
126
- args: Pick<EventArgs['change'], 'iteration' | 'cause'> = {}
128
+ args: Pick<EventArgs['change'], 'iteration' | 'cause' | 'removedIndex'> = {}
127
129
  ): LunaticVariable {
128
130
  if (!this.dictionary.has(name)) {
129
131
  this.dictionary.set(
@@ -1,2 +1 @@
1
- export { default as resizeArrayVariable } from './resize-array-variable';
2
1
  export * from './validate-condition-filter';
@@ -349,5 +349,6 @@ export type LunaticChangesHandler = (
349
349
  name: string;
350
350
  value: any;
351
351
  iteration?: number[];
352
+ removedIndex?: number;
352
353
  }[]
353
354
  ) => void;
@@ -1,5 +1,10 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { firstValueItem, resizeArray, setAtIndex } from './array';
2
+ import {
3
+ firstValueItem,
4
+ resizeArray,
5
+ resizeDownArrayWithIndex,
6
+ setAtIndex,
7
+ } from './array';
3
8
 
4
9
  describe('array', () => {
5
10
  describe('resizeArray()', () => {
@@ -45,4 +50,16 @@ describe('array', () => {
45
50
  expect(firstValueItem([null, 1, 2])).toBe(1);
46
51
  expect(firstValueItem([null, undefined, false])).toBe(false);
47
52
  });
53
+ describe('resizeDownArrayWithIndex()', () => {
54
+ it('should remove an element of array', () => {
55
+ expect(resizeDownArrayWithIndex([1, 2, 3, 4], 2)).toEqual([1, 2, 4]);
56
+ expect(resizeDownArrayWithIndex([1, 2, 3, 4], 0)).toEqual([2, 3, 4]);
57
+ expect(resizeDownArrayWithIndex([1, 2, 3, 4], 3)).toEqual([1, 2, 3]);
58
+ });
59
+
60
+ it('should not remove element (out of index)', () => {
61
+ expect(resizeDownArrayWithIndex([1, 2, 3, 4], -1)).toEqual([1, 2, 3, 4]);
62
+ expect(resizeDownArrayWithIndex([1, 2, 3, 4], 4)).toEqual([1, 2, 3, 4]);
63
+ });
64
+ });
48
65
  });
@@ -51,6 +51,9 @@ export function getAtIndex(arr: unknown, indexes: number[]): unknown {
51
51
  return current;
52
52
  }
53
53
 
54
+ /**
55
+ * Cast the variable into an array and adjust the length if necessary
56
+ */
54
57
  export function resizeArray<T = unknown>(
55
58
  array: unknown,
56
59
  newLength: number,
@@ -63,14 +66,29 @@ export function resizeArray<T = unknown>(
63
66
  if (array.length === newLength) {
64
67
  return array;
65
68
  }
66
- return new Array(newLength).fill(defaultValue ?? null).map(function (
67
- value,
69
+ return new Array(newLength).fill(defaultValue ?? null).reduce(function (
70
+ step,
71
+ current,
68
72
  index
69
73
  ) {
70
- return index < array.length ? array[index] : value;
74
+ if (index < array.length) {
75
+ return [...step, array[index]];
76
+ }
77
+ return [...step, current];
71
78
  }, []);
72
79
  }
73
80
 
81
+ export function resizeDownArrayWithIndex<T = unknown>(
82
+ array: T[],
83
+ removedIndex: number
84
+ ): T[] {
85
+ // the removedIndex is not in array
86
+ if (0 > removedIndex || array.length <= removedIndex) {
87
+ return array;
88
+ }
89
+ return [...array].filter((_, i) => i !== removedIndex);
90
+ }
91
+
74
92
  /**
75
93
  * Return the first non-null/undefined value of an array
76
94
  */