diff --git a/src/stories/checkbox-group/checkbox-group.stories.jsx b/src/stories/checkbox-group/checkbox-group.stories.jsx index 5c0fc57404..7d20ae65ad 100644 --- a/src/stories/checkbox-group/checkbox-group.stories.jsx +++ b/src/stories/checkbox-group/checkbox-group.stories.jsx @@ -2,6 +2,7 @@ import React from 'react'; import Orchestrator from '../utils/orchestrator'; import source from './source'; import sourceComponentset from './sourceComponentset'; +import sourceWithCondition from './sourceWithCondition.json'; import sourceLoop from './sourceLoop'; import defaultArgTypes from '../utils/default-arg-types'; @@ -42,3 +43,10 @@ Loop.args = { ...Default.args, source: sourceLoop, }; + +export const WithCondition = Template.bind({}); + +WithCondition.args = { + ...Default.args, + source: sourceWithCondition, +}; diff --git a/src/stories/checkbox-group/sourceWithCondition.json b/src/stories/checkbox-group/sourceWithCondition.json new file mode 100644 index 0000000000..40c59810bd --- /dev/null +++ b/src/stories/checkbox-group/sourceWithCondition.json @@ -0,0 +1,238 @@ +{ + "components": [ + { + "id": "number", + "componentType": "InputNumber", + "page": "1", + "label": { + "value": "\"Votre age\"", + "type": "VTL|MD" + }, + "response": { + "name": "AGE" + } + }, + { + "id": "checkboxes", + "componentType": "CheckboxGroup", + "page": "2", + "label": { + "value": "\"Pour quelle raison principale n’étiez-vous pas disponible ?\"", + "type": "VTL|MD" + }, + "responses": [ + { + "id": "kmort6x9-QOP-kmosa98y", + "label": { + "value": "\"Vous suiviez (ou aviez le projet de suivre) des études ou une formation\"", + "type": "VTL" + }, + "response": { "name": "CHECK1" } + }, + { + "id": "kmort6x9-QOP-kmos360k", + "label": { + "value": "\"Vous aviez des problèmes de santé ou étiez en situation de handicap\"", + "type": "VTL" + }, + "response": { "name": "CHECK2" } + }, + { + "id": "new_id_1", + "label": { + "value": "\"Vous étiez sur le point d’avoir un enfant\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) <= 50", + "type": "VTL" + }, + "response": { "name": "CHECK3" } + }, + { + "id": "new_id_2", + "label": { + "value": "\"Vous vous occupiez de vos enfants ou d’un proche\"", + "type": "VTL" + }, + "response": { "name": "CHECK4" } + }, + { + "id": "new_id_3", + "label": { + "value": "\"Vous étiez en vacances, preniez du temps pour vous ou réfléchissiez à votre avenir\"", + "type": "VTL" + }, + "response": { "name": "CHECK5" } + }, + { + "id": "new_id_4", + "label": { + "value": "\"Vous étiez à la retraite ou proche de la retraite\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) >= 50", + "type": "VTL" + }, + "response": { "name": "CHECK6" } + }, + { + "id": "new_id_5", + "label": { + "value": "\"Vous aviez des difficultés pour vous déplacer (pas le permis de conduire, voiture en panne, pas de transport à proximité…)\"", + "type": "VTL" + }, + "response": { "name": "CHECK7" } + }, + { + "id": "new_id_6", + "label": { + "value": "\"Vous déménagiez\"", + "type": "VTL" + }, + "response": { "name": "CHECK8" } + }, + { + "id": "new_id_7", + "label": { + "value": "\"Vous aviez des problèmes de papier / titre de séjour\"", + "type": "VTL" + }, + "response": { "name": "CHECK9" } + }, + { + "id": "new_id_8", + "label": { + "value": "\"Pour une autre raison\"", + "type": "VTL" + }, + "response": { "name": "CHECK10" } + } + ] + } + ], + "variables": [ + { + "variableType": "COLLECTED", + "name": "CHECK1", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK2", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK3", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK4", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK5", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK6", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK7", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK8", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK9", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "CHECK10", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "AGE", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + } + ] +} diff --git a/src/stories/checkbox-one/checkboxOne.stories.jsx b/src/stories/checkbox-one/checkboxOne.stories.jsx index 6bcdb751b1..b2eb906361 100644 --- a/src/stories/checkbox-one/checkboxOne.stories.jsx +++ b/src/stories/checkbox-one/checkboxOne.stories.jsx @@ -1,6 +1,7 @@ import React from 'react'; import Orchestrator from '../utils/orchestrator'; import source from './source'; +import sourceWithCondition from './sourceWithCondition.json'; import defaultArgTypes from '../utils/default-arg-types'; const stories = { @@ -19,6 +20,13 @@ const stories = { export default stories; const Template = (args) => ; -export const Default = Template.bind({}); +export const Default = Template.bind({}); Default.args = { id: 'checkboxOne', source, shortcut: false }; + +export const WithCondition = Template.bind({}); +WithCondition.args = { + id: 'checkboxOneCondition', + source: sourceWithCondition, + shortcut: false, +}; diff --git a/src/stories/checkbox-one/sourceWithCondition.json b/src/stories/checkbox-one/sourceWithCondition.json new file mode 100644 index 0000000000..4f457f1d69 --- /dev/null +++ b/src/stories/checkbox-one/sourceWithCondition.json @@ -0,0 +1,150 @@ +{ + "components": [ + { + "id": "number", + "componentType": "InputNumber", + "page": "1", + "label": { + "value": "\"Votre age\"", + "type": "VTL|MD" + }, + "response": { + "name": "AGE" + } + }, + { + "response": { + "name": "CHECK" + }, + "id": "checkboxes", + "componentType": "CheckboxOne", + "page": "2", + "label": { + "value": "\"Pour quelle raison principale n’étiez-vous pas disponible ?\"", + "type": "VTL|MD" + }, + "options": [ + { + "id": "check1", + "label": { + "value": "\"Vous suiviez (ou aviez le projet de suivre) des études ou une formation\"", + "type": "VTL" + }, + "value": "CHECK1" + }, + { + "id": "check2", + "label": { + "value": "\"Vous aviez des problèmes de santé ou étiez en situation de handicap\"", + "type": "VTL" + }, + "value": "CHECK2" + }, + { + "id": "check3", + "label": { + "value": "\"Vous étiez sur le point d’avoir un enfant\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) <= 50", + "type": "VTL" + }, + "value": "CHECK3", + "description": { + "value": "\"AGE <= 50\"", + "type": "VTL|MD" + } + }, + { + "id": "check4", + "label": { + "value": "\"Vous vous occupiez de vos enfants ou d’un proche\"", + "type": "VTL" + }, + "value": "CHECK4" + }, + { + "id": "check5", + "label": { + "value": "\"Vous étiez en vacances, preniez du temps pour vous ou réfléchissiez à votre avenir\"", + "type": "VTL" + }, + "value": "CHECK5" + }, + { + "id": "check6", + "label": { + "value": "\"Vous étiez à la retraite ou proche de la retraite\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) >= 50", + "type": "VTL" + }, + "value": "CHECK6", + "description": { + "value": "\"AGE >= 50\"", + "type": "VTL|MD" + } + }, + { + "id": "check7", + "label": { + "value": "\"Vous aviez des difficultés pour vous déplacer (pas le permis de conduire, voiture en panne, pas de transport à proximité…)\"", + "type": "VTL" + }, + "value": "CHECK7" + }, + { + "id": "check8", + "label": { + "value": "\"Vous déménagiez\"", + "type": "VTL" + }, + "value": "CHECK8" + }, + { + "id": "check9", + "label": { + "value": "\"Vous aviez des problèmes de papier / titre de séjour\"", + "type": "VTL" + }, + "value": "CHECK9" + }, + { + "id": "check10", + "label": { + "value": "\"Pour une autre raison\"", + "type": "VTL" + }, + "value": "CHECK10" + } + ] + } + ], + "variables": [ + { + "variableType": "COLLECTED", + "name": "CHECK", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "AGE", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + } + ] +} diff --git a/src/stories/dropdown/dropdown.stories.jsx b/src/stories/dropdown/dropdown.stories.jsx index 691415f29e..f00f3048c7 100644 --- a/src/stories/dropdown/dropdown.stories.jsx +++ b/src/stories/dropdown/dropdown.stories.jsx @@ -1,6 +1,7 @@ import React from 'react'; import Orchestrator from '../utils/orchestrator'; import source from './source'; +import sourceWithCondition from './sourceWithCondition.json'; import data from './data'; import defaultArgTypes from '../utils/default-arg-types'; @@ -14,7 +15,6 @@ export default stories; const Template = (args) => ; export const Default = Template.bind({}); - Default.args = { id: 'dropdown', source, @@ -23,3 +23,12 @@ Default.args = { editable: false, writable: true, }; + +export const WithCondition = Template.bind({}); +Default.args = { + id: 'dropdown', + source: sourceWithCondition, + disabled: false, + editable: false, + writable: true, +}; diff --git a/src/stories/dropdown/sourceWithCondition.json b/src/stories/dropdown/sourceWithCondition.json new file mode 100644 index 0000000000..1c03e053c4 --- /dev/null +++ b/src/stories/dropdown/sourceWithCondition.json @@ -0,0 +1,150 @@ +{ + "components": [ + { + "id": "number", + "componentType": "InputNumber", + "page": "1", + "label": { + "value": "\"Votre age\"", + "type": "VTL|MD" + }, + "response": { + "name": "AGE" + } + }, + { + "response": { + "name": "DROPDOWN" + }, + "id": "checkboxes", + "componentType": "Dropdown", + "page": "2", + "label": { + "value": "\"Pour quelle raison principale n’étiez-vous pas disponible ?\"", + "type": "VTL|MD" + }, + "options": [ + { + "id": "check1", + "label": { + "value": "\"Vous suiviez (ou aviez le projet de suivre) des études ou une formation\"", + "type": "VTL" + }, + "value": "1" + }, + { + "id": "check2", + "label": { + "value": "\"Vous aviez des problèmes de santé ou étiez en situation de handicap\"", + "type": "VTL" + }, + "value": "2" + }, + { + "id": "check3", + "label": { + "value": "\"Vous étiez sur le point d’avoir un enfant\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) <= 50", + "type": "VTL" + }, + "value": "3", + "description": { + "value": "\"AGE <= 50\"", + "type": "VTL|MD" + } + }, + { + "id": "check4", + "label": { + "value": "\"Vous vous occupiez de vos enfants ou d’un proche\"", + "type": "VTL" + }, + "value": "4" + }, + { + "id": "check5", + "label": { + "value": "\"Vous étiez en vacances, preniez du temps pour vous ou réfléchissiez à votre avenir\"", + "type": "VTL" + }, + "value": "5" + }, + { + "id": "check6", + "label": { + "value": "\"Vous étiez à la retraite ou proche de la retraite\"", + "type": "VTL" + }, + "conditionFilter": { + "value": "cast(AGE, number) >= 50", + "type": "VTL" + }, + "value": "6", + "description": { + "value": "\"AGE >= 50\"", + "type": "VTL|MD" + } + }, + { + "id": "check7", + "label": { + "value": "\"Vous aviez des difficultés pour vous déplacer (pas le permis de conduire, voiture en panne, pas de transport à proximité…)\"", + "type": "VTL" + }, + "value": "7" + }, + { + "id": "check8", + "label": { + "value": "\"Vous déménagiez\"", + "type": "VTL" + }, + "value": "8" + }, + { + "id": "check9", + "label": { + "value": "\"Vous aviez des problèmes de papier / titre de séjour\"", + "type": "VTL" + }, + "value": "9" + }, + { + "id": "check10", + "label": { + "value": "\"Pour une autre raison\"", + "type": "VTL" + }, + "value": "10" + } + ] + } + ], + "variables": [ + { + "variableType": "COLLECTED", + "name": "DROPDOWN", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + }, + { + "variableType": "COLLECTED", + "name": "AGE", + "values": { + "PREVIOUS": null, + "COLLECTED": null, + "FORCED": null, + "EDITED": null, + "INPUTED": null + } + } + ] +} diff --git a/src/use-lunatic/commons/fill-components/fill-specific-expression.ts b/src/use-lunatic/commons/fill-components/fill-specific-expression.ts index 52136bd7c7..40e2bf4de6 100644 --- a/src/use-lunatic/commons/fill-components/fill-specific-expression.ts +++ b/src/use-lunatic/commons/fill-components/fill-specific-expression.ts @@ -130,6 +130,48 @@ function fillTable( }; } +/** + * For CheckboxGroup some responses can be filtered via a conditionFilter + */ +function fillCheckboxGroup( + component: DeepTranslateExpression< + LunaticComponentDefinition<'CheckboxGroup'> + >, + state: LunaticState +) { + return { + ...component, + responses: component.responses.filter((response) => { + if (!('conditionFilter' in response)) { + return true; + } + + return state.executeExpression(response.conditionFilter); + }), + }; +} + +/** + * For Radio / CheckboxOne some options can be filtered via a conditionFilter + */ +function fillRadio( + component: DeepTranslateExpression< + LunaticComponentDefinition<'CheckboxOne' | 'Radio' | 'Dropdown'> + >, + state: LunaticState +) { + return { + ...component, + options: component.options.filter((o) => { + if (!('conditionFilter' in o)) { + return true; + } + + return state.executeExpression(o.conditionFilter); + }), + }; +} + /** * Fill component specific props (RoundAbout for instance) */ @@ -149,6 +191,12 @@ function fillSpecificExpressions( return fillPairwise(component, state); case 'Table': return fillTable(component, state); + case 'CheckboxGroup': + return fillCheckboxGroup(component, state); + case 'Radio': + case 'CheckboxOne': + case 'Dropdown': + return fillRadio(component, state); default: return component; } diff --git a/src/use-lunatic/type-source.ts b/src/use-lunatic/type-source.ts index bfef3eb6d5..1e33cff3e0 100644 --- a/src/use-lunatic/type-source.ts +++ b/src/use-lunatic/type-source.ts @@ -3,6 +3,12 @@ */ export type LabelType = { value: string; type: 'VTL' | 'VTL|MD' }; +type ComponentOption = { + value: string; + label: LabelType; + conditionFilter?: ConditionFilterType; +}; + export type ComponentTypeEnum = | 'Sequence' | 'Subsequence' @@ -129,9 +135,6 @@ export type ComponentType = | (ComponentTypeBase & ComponentRoundaboutType) | (ComponentTypeBase & ComponentSuggesterType) | (ComponentTypeBase & ComponentInputOrTextareaType) - | (ComponentTypeBase & { - componentType: 'CheckboxOne'; - }) | (ComponentTypeBase & { componentType: 'ConfirmationModal'; }) @@ -218,6 +221,7 @@ export type ComponentCheckboxGroupType = { label: LabelType; response: ResponseType; id: string; + conditionFilter?: ConditionFilterType; }>; }; @@ -228,15 +232,15 @@ export type ComponentCheckboxBooleanType = { }; export type ComponentRadioType = { - componentType: 'Radio'; - options: { value: string; label: LabelType }[]; + componentType: 'Radio' | 'CheckboxOne'; + options: ComponentOption[]; response: ResponseType; missingResponse?: ResponseType; }; export type ComponentDropdownType = { componentType: 'Dropdown'; - options: { value: string; label: LabelType }[]; + options: ComponentOption[]; response: ResponseType; missingResponse?: ResponseType; };