From ff38e29bc0c7b00e6083426ca75aea6cfff4e2fd Mon Sep 17 00:00:00 2001 From: Quentin Ruhier Date: Fri, 10 Jan 2025 13:36:48 +0100 Subject: [PATCH 1/5] feat: allow arbitrary response for suggester --- src/constants/dictionary.ts | 4 +++ .../response-format-single.jsx | 7 +++- .../response-format-table.jsx | 15 ++++++-- .../response-format-single.jsx | 5 ++- .../transformations/response-format-table.jsx | 2 ++ src/model/transformations/response.jsx | 12 ++++++- src/model/transformations/response.spec.jsx | 36 ++++++++++++++++++- .../single/response-format-single.jsx | 18 +++++++++- 8 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/constants/dictionary.ts b/src/constants/dictionary.ts index 83c77bf8f..b5726c0b2 100644 --- a/src/constants/dictionary.ts +++ b/src/constants/dictionary.ts @@ -515,6 +515,10 @@ const dictionary: Dictionary = { fr: 'Retrouver dans le questionnaire', en: 'Retrieve in the questionnaire', }, + allowArbitraryResponse: { + fr: 'Autoriser une réponse libre', + en: 'Allow arbitrary response', + }, list: { fr: 'Liste', en: 'List', diff --git a/src/model/formToState/component-new-edit/response-format-single.jsx b/src/model/formToState/component-new-edit/response-format-single.jsx index 08436f739..b0d3b1af8 100644 --- a/src/model/formToState/component-new-edit/response-format-single.jsx +++ b/src/model/formToState/component-new-edit/response-format-single.jsx @@ -10,12 +10,14 @@ import { const { RADIO } = DATATYPE_VIS_HINT; export const defaultState = { + allowArbitrary: false, mandatory: false, visHint: RADIO, // [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultState), }; export const defaultForm = { + allowArbitrary: false, mandatory: false, visHint: RADIO, // [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultForm), @@ -24,6 +26,7 @@ export const defaultForm = { export function formToState(form, transformers) { const { id, + allowArbitrary, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, @@ -31,6 +34,7 @@ export function formToState(form, transformers) { return { id, + allowArbitrary, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: @@ -39,10 +43,11 @@ export function formToState(form, transformers) { } export function stateToForm(currentState, transformers) { - const { id, visHint, mandatory } = currentState; + const { id, allowArbitrary, visHint, mandatory } = currentState; return { id, + allowArbitrary, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: diff --git a/src/model/formToState/component-new-edit/response-format-table.jsx b/src/model/formToState/component-new-edit/response-format-table.jsx index f43dc3df0..5a409eba5 100644 --- a/src/model/formToState/component-new-edit/response-format-table.jsx +++ b/src/model/formToState/component-new-edit/response-format-table.jsx @@ -66,6 +66,7 @@ export const defaultMeasureState = { cloneDeep(CodesListDefaultState), { id: uuid() }, ), + allowArbitrary: false, visHint: RADIO, }, }; @@ -75,6 +76,7 @@ export const defaultMeasureForm = { type: SIMPLE, [SIMPLE]: defaultMeasureSimpleState, [SINGLE_CHOICE]: { + allowArbitrary: false, [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultForm), visHint: RADIO, }, @@ -166,13 +168,17 @@ export function formToStateMeasure(form, codesListMeasure) { [simpleType]: { ...simpleForm }, }; } else { - const { visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm } = - measureForm; + const { + allowArbitrary, + visHint, + [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, + } = measureForm; const codesList = codesListMeasure ? codesListMeasure.formToStateComponent(codesListForm) : CodesListFactory().formToState(codesListForm); state[SINGLE_CHOICE] = { + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesList, }; @@ -247,6 +253,7 @@ export function stateToFormMeasure( type, [SIMPLE]: simpleState, [SINGLE_CHOICE]: { + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState, }, @@ -267,6 +274,7 @@ export function stateToFormMeasure( type, [SIMPLE]: simpleState, [SINGLE_CHOICE]: { + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, }, @@ -276,6 +284,7 @@ export function stateToFormMeasure( export function stateToFormMeasureList(currentState, codesListsStore) { const { [SINGLE_CHOICE]: { + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState, }, @@ -289,6 +298,7 @@ export function stateToFormMeasureList(currentState, codesListsStore) { return { ...currentState, [SINGLE_CHOICE]: { + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, }, @@ -371,6 +381,7 @@ const Factory = (initialState = {}, codesListsStore) => { state[SINGLE_CHOICE] = { [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListsStore[measureState[DEFAULT_CODES_LIST_SELECTOR_PATH].id], + allowArbitrary: measureState.allowArbitrary, visHint: measureState.visHint, }; } else { diff --git a/src/model/transformations/response-format-single.jsx b/src/model/transformations/response-format-single.jsx index 7321d4eb8..28c5b5b2b 100644 --- a/src/model/transformations/response-format-single.jsx +++ b/src/model/transformations/response-format-single.jsx @@ -11,7 +11,7 @@ export function remoteToState(remote) { const { responses: [ { - Datatype: { visualizationHint: visHint }, + Datatype: { allowArbitrary, visualizationHint: visHint }, mandatory, CodeListReference, id, @@ -24,6 +24,7 @@ export function remoteToState(remote) { CodeList.remoteToState(CodeListReference), id, mandatory, + allowArbitrary, visHint, }; } @@ -31,6 +32,7 @@ export function remoteToState(remote) { export function stateToRemote(state, collectedVariables) { const { [DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId }, + allowArbitrary, visHint, mandatory, id, @@ -40,6 +42,7 @@ export function stateToRemote(state, collectedVariables) { Response.stateToRemote({ id, mandatory, + allowArbitrary, visHint, codesListId, typeName: TEXT, diff --git a/src/model/transformations/response-format-table.jsx b/src/model/transformations/response-format-table.jsx index 9c7e559b7..fb353d16b 100644 --- a/src/model/transformations/response-format-table.jsx +++ b/src/model/transformations/response-format-table.jsx @@ -318,6 +318,7 @@ function stateToResponseState(state) { } else { const { mandatory, + allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId }, } = measureTypeState; @@ -327,6 +328,7 @@ function stateToResponseState(state) { typeName: TEXT, maxLength: 1, pattern: '', + allowArbitrary, visHint, }; } diff --git a/src/model/transformations/response.jsx b/src/model/transformations/response.jsx index 934c35c24..b1e166587 100644 --- a/src/model/transformations/response.jsx +++ b/src/model/transformations/response.jsx @@ -1,4 +1,7 @@ -import { DATATYPE_TYPE_FROM_NAME } from '../../constants/pogues-constants'; +import { + DATATYPE_TYPE_FROM_NAME, + DATATYPE_VIS_HINT, +} from '../../constants/pogues-constants'; import { uuid } from '../../utils/utils'; export function stateToRemote(state, response) { @@ -23,6 +26,7 @@ export function stateToRemote(state, response) { mayears: Mayears, mamonths: Mamonths, codesListId: CodeListReference, + allowArbitrary, visHint: visualizationHint, collectedVariable: CollectedVariableReference, } = state; @@ -47,6 +51,12 @@ export function stateToRemote(state, response) { model.CodeListReference = CodeListReference; if (mandatory !== undefined) model.mandatory = mandatory === '' ? false : mandatory; + if (allowArbitrary !== undefined) + // we keep allowArbitrary value only for suggester + model.Datatype.allowArbitrary = + visualizationHint === DATATYPE_VIS_HINT.SUGGESTER + ? allowArbitrary + : undefined; if (visualizationHint !== undefined) model.Datatype.visualizationHint = visualizationHint; if (MaxLength !== undefined) model.Datatype.MaxLength = MaxLength; diff --git a/src/model/transformations/response.spec.jsx b/src/model/transformations/response.spec.jsx index cca8afab2..b97316768 100644 --- a/src/model/transformations/response.spec.jsx +++ b/src/model/transformations/response.spec.jsx @@ -1,7 +1,10 @@ import { format } from 'url'; import { describe, expect, test } from 'vitest'; -import { DATATYPE_TYPE_FROM_NAME } from '../../constants/pogues-constants'; +import { + DATATYPE_TYPE_FROM_NAME, + DATATYPE_VIS_HINT, +} from '../../constants/pogues-constants'; import { stateToRemote } from './response'; describe('response tranformations', () => { @@ -166,6 +169,37 @@ describe('response tranformations', () => { expect(result.Datatype.Unit).toEqual(unit); }); + test('when allowArbitrary is defined', () => { + const typeName = 'TEXT'; + const allowArbitrary = true; + + // Get all values of DATATYPE_VIS_HINT except 'SUGGESTER' + const nonSuggesterVisHints = Object.values(DATATYPE_VIS_HINT).filter( + (visHint) => visHint !== DATATYPE_VIS_HINT.SUGGESTER, + ); + + const resultSuggester = stateToRemote({ + typeName, + id: '1', + visHint: DATATYPE_VIS_HINT.SUGGESTER, + allowArbitrary, + }); + + expect(resultSuggester.Datatype.allowArbitrary).toEqual(allowArbitrary); + + // Test for all non-SUGGESTER visHint values + nonSuggesterVisHints.forEach((visHint) => { + const result = stateToRemote({ + typeName, + id: '1', + visHint, + allowArbitrary, + }); + + expect(result.Datatype.allowArbitrary).toEqual(undefined); + }); + }); + test('when Format is defined', () => { const typeName = 'DATE'; const result = stateToRemote({ diff --git a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx index ff46711de..aa35a5564 100644 --- a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx +++ b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx @@ -168,7 +168,22 @@ function ResponseFormatSingle({ )} {visHint === SUGGESTER ? ( - + <> + + value === 'true'} + // Convert true/false/undefined to string "true"/"false" when displaying the form + format={(value) => (value === true ? 'true' : 'false')} + > + {Dictionary.yes} + {Dictionary.no} + + ) : ( { componentsStore: state.appState.activeComponentsById, collectedVariablesStore: state.appState.collectedVariableByQuestion, visHint: selector(state, `${path}visHint`), + allowArbitrary: selector(state, `${path}allowArbitrary`), path, }; }; From 005be108006f54993c96a9d79c97ad1ee7825a40 Mon Sep 17 00:00:00 2001 From: Quentin Ruhier Date: Fri, 10 Jan 2025 17:21:58 +0100 Subject: [PATCH 2/5] fix: do not allow arbitrary in table --- .../response-format-table.jsx | 14 ++------- .../transformations/response-format-table.jsx | 2 -- .../single/response-format-single.jsx | 31 +++++++++++-------- .../response-format/table/input-measure.jsx | 1 + 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/model/formToState/component-new-edit/response-format-table.jsx b/src/model/formToState/component-new-edit/response-format-table.jsx index 5a409eba5..d48aecc02 100644 --- a/src/model/formToState/component-new-edit/response-format-table.jsx +++ b/src/model/formToState/component-new-edit/response-format-table.jsx @@ -66,7 +66,6 @@ export const defaultMeasureState = { cloneDeep(CodesListDefaultState), { id: uuid() }, ), - allowArbitrary: false, visHint: RADIO, }, }; @@ -168,17 +167,13 @@ export function formToStateMeasure(form, codesListMeasure) { [simpleType]: { ...simpleForm }, }; } else { - const { - allowArbitrary, - visHint, - [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, - } = measureForm; + const { visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm } = + measureForm; const codesList = codesListMeasure ? codesListMeasure.formToStateComponent(codesListForm) : CodesListFactory().formToState(codesListForm); state[SINGLE_CHOICE] = { - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesList, }; @@ -253,7 +248,6 @@ export function stateToFormMeasure( type, [SIMPLE]: simpleState, [SINGLE_CHOICE]: { - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState, }, @@ -274,7 +268,6 @@ export function stateToFormMeasure( type, [SIMPLE]: simpleState, [SINGLE_CHOICE]: { - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, }, @@ -284,7 +277,6 @@ export function stateToFormMeasure( export function stateToFormMeasureList(currentState, codesListsStore) { const { [SINGLE_CHOICE]: { - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState, }, @@ -298,7 +290,6 @@ export function stateToFormMeasureList(currentState, codesListsStore) { return { ...currentState, [SINGLE_CHOICE]: { - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, }, @@ -381,7 +372,6 @@ const Factory = (initialState = {}, codesListsStore) => { state[SINGLE_CHOICE] = { [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListsStore[measureState[DEFAULT_CODES_LIST_SELECTOR_PATH].id], - allowArbitrary: measureState.allowArbitrary, visHint: measureState.visHint, }; } else { diff --git a/src/model/transformations/response-format-table.jsx b/src/model/transformations/response-format-table.jsx index fb353d16b..9c7e559b7 100644 --- a/src/model/transformations/response-format-table.jsx +++ b/src/model/transformations/response-format-table.jsx @@ -318,7 +318,6 @@ function stateToResponseState(state) { } else { const { mandatory, - allowArbitrary, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId }, } = measureTypeState; @@ -328,7 +327,6 @@ function stateToResponseState(state) { typeName: TEXT, maxLength: 1, pattern: '', - allowArbitrary, visHint, }; } diff --git a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx index aa35a5564..df0e81f10 100644 --- a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx +++ b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx @@ -37,6 +37,7 @@ function ResponseFormatSingle({ path, formName, allowPrecision, + disableSetArbitrary, }) { const selectorPath = responseFormatType; @@ -170,19 +171,21 @@ function ResponseFormatSingle({ {visHint === SUGGESTER ? ( <> - value === 'true'} - // Convert true/false/undefined to string "true"/"false" when displaying the form - format={(value) => (value === true ? 'true' : 'false')} - > - {Dictionary.yes} - {Dictionary.no} - + {!disableSetArbitrary && ( + value === 'true'} + // Convert true/false/undefined to string "true"/"false" when displaying the form + format={(value) => (value === true ? 'true' : 'false')} + > + {Dictionary.yes} + {Dictionary.no} + + )} ) : ( { diff --git a/src/widgets/component-new-edit/components/response-format/table/input-measure.jsx b/src/widgets/component-new-edit/components/response-format/table/input-measure.jsx index 54a835595..dd23b2d8b 100644 --- a/src/widgets/component-new-edit/components/response-format/table/input-measure.jsx +++ b/src/widgets/component-new-edit/components/response-format/table/input-measure.jsx @@ -44,6 +44,7 @@ function InputMeasure({ selectorPath }) { selectorPathParent={selectorPath} showMandatory={false} allowPrecision={false} + disableSetArbitrary={true} /> From 85897b86dcef6a12cec725cc322f2f3af4c0c5c2 Mon Sep 17 00:00:00 2001 From: Quentin Ruhier Date: Fri, 24 Jan 2025 17:29:00 +0100 Subject: [PATCH 3/5] feat: handle arbitrary variable for suggester --- .../component-new-edit/collected-variable.jsx | 4 + src/model/remote-to-stores.jsx | 7 ++ .../transformations/collected-variable.jsx | 21 +++- .../collected-variable.spec.jsx | 80 +++++++++++++++ src/model/transformations/component.jsx | 97 +++++++++++++++++++ src/model/transformations/component.spec.jsx | 96 +++++++++++++++++- .../variables/collected-variables-utils.jsx | 40 +++++++- .../collected-variables-utils.spec.jsx | 35 ++++++- 8 files changed, 371 insertions(+), 9 deletions(-) diff --git a/src/model/formToState/component-new-edit/collected-variable.jsx b/src/model/formToState/component-new-edit/collected-variable.jsx index abaa4b46f..e6d5b4462 100644 --- a/src/model/formToState/component-new-edit/collected-variable.jsx +++ b/src/model/formToState/component-new-edit/collected-variable.jsx @@ -47,6 +47,7 @@ export function formToState(form) { y, z, mesureLevel, + arbitraryOfVariable, codeListReference, codeListReferenceLabel, isCollected, @@ -61,6 +62,7 @@ export function formToState(form) { x, y, z, + arbitraryOfVariable, isCollected, alternativeLabel, mesureLevel, @@ -94,6 +96,7 @@ export function storeToForm(currentStore) { x, y, z, + arbitraryOfVariable, isCollected = '1', alternativeLabel, mesureLevel, @@ -107,6 +110,7 @@ export function storeToForm(currentStore) { x, y, z, + arbitraryOfVariable, isCollected, alternativeLabel, mesureLevel, diff --git a/src/model/remote-to-stores.jsx b/src/model/remote-to-stores.jsx index 59f7a0162..95b8f07c9 100644 --- a/src/model/remote-to-stores.jsx +++ b/src/model/remote-to-stores.jsx @@ -44,6 +44,12 @@ export function questionnaireRemoteToStores(remote, currentStores = {}) { remote.Child, collectedVariables, ); + + const arbitraryVariables = Component.getArbitraryResponsesFromRemote( + remote.Child, + collectedVariables, + ); + const codesListsStore = CodesList.remoteToStore( codesLists, variableclarification, @@ -56,6 +62,7 @@ export function questionnaireRemoteToStores(remote, currentStores = {}) { responsesByVariable, codesListsStore, variableclarification, + arbitraryVariables, ), }; // Components store diff --git a/src/model/transformations/collected-variable.jsx b/src/model/transformations/collected-variable.jsx index 33277d005..f61ebb954 100644 --- a/src/model/transformations/collected-variable.jsx +++ b/src/model/transformations/collected-variable.jsx @@ -20,6 +20,7 @@ export function remoteToStore( responsesByVariable, codesListsStore, variableclarification, + arbitraryVariables, ) { remote.forEach((variable) => { if (variableclarification) { @@ -45,9 +46,26 @@ export function remoteToStore( } } } + if (arbitraryVariables) { + const extendedArbitraryVariable = arbitraryVariables.find( + (arbitraryVariable) => + arbitraryVariable.CollectedVariableReference === variable.id, + ); + if (extendedArbitraryVariable) { + variable.arbitraryOfVariable = + extendedArbitraryVariable.arbitraryOfVariable; + } + } }); return remote.reduce((acc, ev) => { - const { Name: name, Label: label, CodeListReference, z, mesureLevel } = ev; + const { + Name: name, + Label: label, + CodeListReference, + z, + mesureLevel, + arbitraryOfVariable, + } = ev; const id = ev.id || uuid(); const formatSingleRemote = remoteToStateFormatSimple({ @@ -69,6 +87,7 @@ export function remoteToStore( ...responsesByVariable[id], z, mesureLevel, + arbitraryOfVariable, }, }; }, {}); diff --git a/src/model/transformations/collected-variable.spec.jsx b/src/model/transformations/collected-variable.spec.jsx index b636126dd..bc3c25c76 100644 --- a/src/model/transformations/collected-variable.spec.jsx +++ b/src/model/transformations/collected-variable.spec.jsx @@ -218,6 +218,86 @@ describe('collected variable tranformations', () => { output, ); }); + + test('should add the arbitrary variables to the collected', () => { + const input = [ + { + id: 'm6aty8by', + Name: 'SUGGESTER', + type: 'CollectedVariableType', + Label: 'SUGGESTER label', + Datatype: { + type: 'TextDatatypeType', + Pattern: '', + typeName: 'TEXT', + MaxLength: 1, + }, + CodeListReference: 'id', + }, + { + id: 'm6atzjnb', + Name: 'SUGGESTER_ARBITRARY', + type: 'CollectedVariableType', + Label: 'SUGGESTER_ARBITRARY label', + Datatype: { + type: 'TextDatatypeType', + typeName: 'TEXT', + MaxLength: 249, + }, + arbitraryOfVariable: 'm6aty8by', + }, + ]; + const arbitraryVariables = [ + { + Datatype: { + type: 'TextDatatypeType', + typeName: 'TEXT', + MaxLength: 249, + }, + mandatory: false, + CollectedVariableReference: 'm6atzjnb', + arbitraryOfVariable: 'm6aty8by', + }, + ]; + const responsesByVariable = { m6aty8by: {} }; + const codesListStore = { id: { label: 'label' } }; + const variableclarification = []; + const output = { + m6aty8by: { + id: 'm6aty8by', + name: 'SUGGESTER', + label: 'SUGGESTER label', + type: TEXT, + codeListReference: 'id', + codeListReferenceLabel: 'label', + TEXT: { + maxLength: 1, + pattern: '', + }, + }, + m6atzjnb: { + id: 'm6atzjnb', + name: 'SUGGESTER_ARBITRARY', + label: 'SUGGESTER_ARBITRARY label', + type: TEXT, + codeListReferenceLabel: '', + TEXT: { + maxLength: 249, + }, + arbitraryOfVariable: 'm6aty8by', + }, + }; + + expect( + remoteToStore( + input, + responsesByVariable, + codesListStore, + variableclarification, + arbitraryVariables, + ), + ).toEqual(output); + }); }); describe('remoteToComponentState', () => { test('should return the state representation of a collected variable', () => { diff --git a/src/model/transformations/component.jsx b/src/model/transformations/component.jsx index 7822ec03b..74ee92d65 100644 --- a/src/model/transformations/component.jsx +++ b/src/model/transformations/component.jsx @@ -174,6 +174,61 @@ export const getClarificarionfromremote = (Children, collectedVariables) => { return variableClarification; }; +/* + * Get the list of questions containing an attribute "ArbitraryResponse". + * Currently we only look at single response questions. + */ +const getArbitraryQuestions = (Children) => { + const arbitraryQuestions = []; + const childr = Children.filter((children) => children.Child?.length !== 0); + childr.forEach((item) => { + item.Child?.forEach((component) => { + // component is a subsequence + if (component.type === 'SequenceType') { + component.Child.forEach((question) => { + if ( + // single choice question + question.questionType === SINGLE_CHOICE && + question.ArbitraryResponse !== undefined + ) { + arbitraryQuestions.push(question); + } + }); + } else if ( + // component is a single choice question + component.questionType === SINGLE_CHOICE && + component.ArbitraryResponse !== undefined + ) { + arbitraryQuestions.push(component); + } + }); + }); + return arbitraryQuestions; +}; + +/* + * Get the list of arbitrary variables. + * An arbitrary variable is the "ArbitraryResponse" object of a question, + * adding "arbitraryOfVariable" which is the corresponding Response variable. + */ +export const getArbitraryResponsesFromRemote = (Children) => { + const arbitraryVariables = []; + const arbitraryQuestions = getArbitraryQuestions(Children); + + arbitraryQuestions.forEach((question) => { + // a question with arbitrary is a singleReponse question so it has only one Response + const responseVariableId = question.Response[0].CollectedVariableReference; + + const arbitraryVariable = { + ...question.ArbitraryResponse, + arbitraryOfVariable: responseVariableId, + }; + arbitraryVariables.push(arbitraryVariable); + }); + + return arbitraryVariables; +}; + function remoteToVariableResponseNested(children = [], acc = {}) { children.forEach((child) => { const { @@ -226,6 +281,7 @@ function remoteToState(remote, componentGroup, codesListsStore) { Control: controls, Response: responses, ClarificationQuestion: responsesClarification, + ArbitraryResponse: arbitraryResponse, ResponseStructure: responseStructure, Child: children, parent, @@ -250,6 +306,10 @@ function remoteToState(remote, componentGroup, codesListsStore) { responseFinal = responseFinal.concat(clar.Response); }); } + if (arbitraryResponse !== undefined) { + responseFinal.push(arbitraryResponse); + } + const state = { id, name, @@ -629,6 +689,36 @@ function getClarificationResponseTableQuestion( }; } +function getArbitraryResponse(collectedVariablesStore, collectedVariables) { + const collectedvariablequestion = []; + Object.values(collectedVariablesStore).forEach((collec) => { + if (collectedVariables !== undefined) { + collectedVariables.forEach((variables) => { + if (collec.id === variables) { + collectedvariablequestion.push(collec); + } + }); + } + }); + + for (const collected of collectedvariablequestion) { + const isArbitraryVariable = collected.arbitraryOfVariable !== undefined; + // we can have only one collected variable that is an arbitrary variable + if (isArbitraryVariable) { + const responseModel = { + mandatory: false, + typeName: collected.type, + maxLength: collected.TEXT.maxLength, + collectedVariable: collected.id, + }; + const arbitraryResponse = Response.stateToRemote(responseModel); + return arbitraryResponse; + } + } + + return undefined; +} + function storeToRemoteNested( state, store, @@ -686,8 +776,15 @@ function storeToRemoteNested( responsesClarification, flowControl, ); + remote.FlowControl = remoteclarification.flowcontrolefinal; remote.ClarificationQuestion = remoteclarification.ClarificationQuestion; + + const remoteArbitrary = getArbitraryResponse( + collectedVariablesStore, + collectedVariables, + ); + remote.ArbitraryResponse = remoteArbitrary; } if ( responseFormat.type === MULTIPLE_CHOICE && diff --git a/src/model/transformations/component.spec.jsx b/src/model/transformations/component.spec.jsx index e8c4c121d..608232b36 100644 --- a/src/model/transformations/component.spec.jsx +++ b/src/model/transformations/component.spec.jsx @@ -38,6 +38,43 @@ describe('component tranformations', () => { questionType: 'SIMPLE', type: 'QuestionType', }, + { + Control: [], + Declaration: [], + FlowControl: [], + Label: ['question'], + Name: 'QUESTION', + Response: [ + { + CollectedVariableReference: 'm6awmxim', + CodeListReference: 'listId', + Datatype: { + typeName: 'TEXT', + type: 'TextDatatypeType', + MaxLength: 1, + allowArbitrary: true, + visualizationHint: 'SUGGESTER', + }, + id: 'm5qyf09t', + mandatory: false, + }, + ], + ArbitraryResponse: { + id: 'm6awrflv', + Datatype: { + type: 'TextDatatypeType', + typeName: 'TEXT', + MaxLength: 249, + }, + mandatory: false, + CollectedVariableReference: 'm6awei7a', + }, + TargetMode: ['CAWI'], + depth: 2, + id: 'm5qy1yf9', + questionType: 'SINGLE_CHOICE', + type: 'QuestionType', + }, ], Control: [], Declaration: [], @@ -64,7 +101,7 @@ describe('component tranformations', () => { type: 'SequenceType', }, ], - CodeLists: { CodeList: [] }, + CodeLists: { CodeList: [{ id: 'listId', Label: 'listLabel' }] }, ComponentGroup: [ { Label: ['Components for page 1'], @@ -98,6 +135,30 @@ describe('component tranformations', () => { id: 'khj4uvok', type: 'CollectedVariableType', }, + { + id: 'm6awmxim', + Name: 'SUGGESTER', + type: 'CollectedVariableType', + Label: 'SUGGESTER label', + Datatype: { + type: 'TextDatatypeType', + Pattern: '', + typeName: 'TEXT', + MaxLength: 1, + }, + CodeListReference: 'L_PRODEAP_EAU_2024', + }, + { + id: 'm6awei7a', + Name: 'SUGGESTER_ARBITRARY', + type: 'CollectedVariableType', + Label: 'SUGGESTER_ARBITRARY label', + Datatype: { + type: 'TextDatatypeType', + typeName: 'TEXT', + MaxLength: 249, + }, + }, ], }, agency: 'fr.insee', @@ -109,7 +170,7 @@ describe('component tranformations', () => { owner: 'FAKEPERMISSION', }; const questionnaireId = 'khj4mf0r'; - const codesListsStore = {}; + const codesListsStore = { id: { label: 'label' } }; const iterations = []; const filters = []; @@ -156,6 +217,35 @@ describe('component tranformations', () => { type: 'QUESTION', weight: 0, }, + m5qy1yf9: { + TargetMode: ['CAWI'], + children: [], + collectedVariables: ['m6awmxim', 'm6awei7a'], + controls: {}, + declarations: {}, + flowControl: [], + dynamiqueSpecified: 'Redirections', + id: 'm5qy1yf9', + label: 'question', + name: 'QUESTION', + parent: 'khj54mjm', + redirections: {}, + responseFormat: { + type: 'SINGLE_CHOICE', + SINGLE_CHOICE: { + visHint: 'SUGGESTER', + allowArbitrary: true, + id: 'm5qyf09t', + mandatory: false, + CodesList: { + id: 'listId', + }, + }, + }, + responsesClarification: undefined, + type: 'QUESTION', + weight: 1, + }, khj4mf0r: { TargetMode: ['CAWI'], children: ['khj54mjm'], @@ -174,7 +264,7 @@ describe('component tranformations', () => { }, khj54mjm: { TargetMode: ['CAWI'], - children: ['khj4le7i'], + children: ['khj4le7i', 'm5qy1yf9'], controls: {}, declarations: {}, flowControl: [], diff --git a/src/utils/variables/collected-variables-utils.jsx b/src/utils/variables/collected-variables-utils.jsx index 922d38aac..73c724eb8 100644 --- a/src/utils/variables/collected-variables-utils.jsx +++ b/src/utils/variables/collected-variables-utils.jsx @@ -1,6 +1,7 @@ import { COMPONENT_TYPE, DATATYPE_NAME, + DATATYPE_VIS_HINT, DEFAULT_CODES_LIST_SELECTOR_PATH, DIMENSION_FORMATS, DIMENSION_TYPE, @@ -86,6 +87,7 @@ export function getCollectedVariable( coordinates, reponseFormatValues = {}, alternativeLabel = '', + arbitraryOfVariable = undefined, ) { let collectedVariable = { ...reponseFormatValues, @@ -97,6 +99,11 @@ export function getCollectedVariable( if (coordinates) collectedVariable = { ...collectedVariable, ...coordinates }; if (alternativeLabel) collectedVariable = { ...collectedVariable, ...alternativeLabel }; + if (arbitraryOfVariable) + collectedVariable = { + ...collectedVariable, + arbitraryOfVariable: arbitraryOfVariable, + }; return collectedVariable; } @@ -168,8 +175,12 @@ export function getCollectedVariablesMultiple( export function getCollectedVariablesSingle(questionName, form) { const collectedVariables = []; - collectedVariables.push( - getCollectedVariable(questionName, `${questionName} label`, undefined, { + + const mainCollectedVariable = getCollectedVariable( + questionName, + `${questionName} label`, + undefined, + { codeListReference: form.CodesList.id, codeListReferenceLabel: form.CodesList.label, type: TEXT, @@ -177,9 +188,32 @@ export function getCollectedVariablesSingle(questionName, form) { maxLength: 1, pattern: '', }, - }), + }, ); + collectedVariables.push(mainCollectedVariable); + + // get arbitrary variable for suggester + if (form.allowArbitrary && form.visHint === DATATYPE_VIS_HINT.SUGGESTER) { + const arbitraryResponseName = `${questionName}_ARBITRARY`; + collectedVariables.push( + getCollectedVariable( + arbitraryResponseName, + `${arbitraryResponseName} label`, + undefined, + { + type: TEXT, + [TEXT]: { + maxLength: 249, + }, + }, + undefined, + mainCollectedVariable.id, + ), + ); + } + + // get clarification variables for codes lists form.CodesList.codes?.forEach((code) => { if (code.precisionid && code.precisionid !== '') { collectedVariables.push( diff --git a/src/utils/variables/collected-variables-utils.spec.jsx b/src/utils/variables/collected-variables-utils.spec.jsx index 8bcae0407..0ce5a134e 100644 --- a/src/utils/variables/collected-variables-utils.spec.jsx +++ b/src/utils/variables/collected-variables-utils.spec.jsx @@ -39,7 +39,7 @@ describe('generateCollectedVariables', () => { }); describe('getCollectedVariablesSingle', () => { - test('should return collected variables for QCM without precision in codesList', () => { + test('should return collected variables for QCU without precision in codesList', () => { const questionName = 'questionName'; const form = { CodesList: { @@ -89,7 +89,7 @@ describe('getCollectedVariablesSingle', () => { ]); }); - test('should return collected variables for QCM with precision in codesList', () => { + test('should return collected variables for QCU with precision in codesList', () => { const questionName = 'questionName'; const form = { CodesList: { @@ -150,6 +150,37 @@ describe('getCollectedVariablesSingle', () => { }, ]); }); + + test('should return suggester arbitrary variable if allowArbitrary', () => { + const questionName = 'questionName'; + const form = { + allowArbitrary: true, + visHint: 'SUGGESTER', + CodesList: { id: 'id', label: 'label', codes: [] }, + }; + + const result = getCollectedVariablesSingle(questionName, form); + + expect(result).toEqual([ + { + id: result[0].id, + name: 'questionName', + label: 'questionName label', + codeListReference: form.CodesList.id, + codeListReferenceLabel: form.CodesList.label, + type: 'TEXT', + TEXT: { maxLength: 1, pattern: '' }, + }, + { + id: result[1].id, + name: 'questionName_ARBITRARY', + label: 'questionName_ARBITRARY label', + type: 'TEXT', + TEXT: { maxLength: 249 }, + arbitraryOfVariable: result[0].id, + }, + ]); + }); }); describe('getCollectedVariablesTable', () => { From 4b00e80d89edcbc786ab665b0febca0bd608fcb0 Mon Sep 17 00:00:00 2001 From: Quentin Ruhier Date: Thu, 30 Jan 2025 09:47:15 +0100 Subject: [PATCH 4/5] chore: rename "allowArbitrary" -> "allowArbitraryResponse" --- .../component-new-edit/response-format-single.jsx | 12 ++++++------ .../component-new-edit/response-format-table.jsx | 2 +- src/model/transformations/component.spec.jsx | 4 ++-- .../transformations/response-format-single.jsx | 8 ++++---- src/model/transformations/response.jsx | 10 +++++----- src/model/transformations/response.spec.jsx | 14 ++++++++------ src/utils/variables/collected-variables-utils.jsx | 5 ++++- .../variables/collected-variables-utils.spec.jsx | 4 ++-- .../single/response-format-single.jsx | 4 ++-- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/model/formToState/component-new-edit/response-format-single.jsx b/src/model/formToState/component-new-edit/response-format-single.jsx index b0d3b1af8..7cf3acb61 100644 --- a/src/model/formToState/component-new-edit/response-format-single.jsx +++ b/src/model/formToState/component-new-edit/response-format-single.jsx @@ -10,14 +10,14 @@ import { const { RADIO } = DATATYPE_VIS_HINT; export const defaultState = { - allowArbitrary: false, + allowArbitraryResponse: false, mandatory: false, visHint: RADIO, // [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultState), }; export const defaultForm = { - allowArbitrary: false, + allowArbitraryResponse: false, mandatory: false, visHint: RADIO, // [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultForm), @@ -26,7 +26,7 @@ export const defaultForm = { export function formToState(form, transformers) { const { id, - allowArbitrary, + allowArbitraryResponse, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm, @@ -34,7 +34,7 @@ export function formToState(form, transformers) { return { id, - allowArbitrary, + allowArbitraryResponse, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: @@ -43,11 +43,11 @@ export function formToState(form, transformers) { } export function stateToForm(currentState, transformers) { - const { id, allowArbitrary, visHint, mandatory } = currentState; + const { id, allowArbitraryResponse, visHint, mandatory } = currentState; return { id, - allowArbitrary, + allowArbitraryResponse, mandatory, visHint, [DEFAULT_CODES_LIST_SELECTOR_PATH]: diff --git a/src/model/formToState/component-new-edit/response-format-table.jsx b/src/model/formToState/component-new-edit/response-format-table.jsx index d48aecc02..6b14f61ac 100644 --- a/src/model/formToState/component-new-edit/response-format-table.jsx +++ b/src/model/formToState/component-new-edit/response-format-table.jsx @@ -75,7 +75,7 @@ export const defaultMeasureForm = { type: SIMPLE, [SIMPLE]: defaultMeasureSimpleState, [SINGLE_CHOICE]: { - allowArbitrary: false, + allowArbitraryResponse: false, [DEFAULT_CODES_LIST_SELECTOR_PATH]: cloneDeep(CodesListDefaultForm), visHint: RADIO, }, diff --git a/src/model/transformations/component.spec.jsx b/src/model/transformations/component.spec.jsx index 608232b36..54bca51e9 100644 --- a/src/model/transformations/component.spec.jsx +++ b/src/model/transformations/component.spec.jsx @@ -52,7 +52,7 @@ describe('component tranformations', () => { typeName: 'TEXT', type: 'TextDatatypeType', MaxLength: 1, - allowArbitrary: true, + allowArbitraryResponse: true, visualizationHint: 'SUGGESTER', }, id: 'm5qyf09t', @@ -234,7 +234,7 @@ describe('component tranformations', () => { type: 'SINGLE_CHOICE', SINGLE_CHOICE: { visHint: 'SUGGESTER', - allowArbitrary: true, + allowArbitraryResponse: true, id: 'm5qyf09t', mandatory: false, CodesList: { diff --git a/src/model/transformations/response-format-single.jsx b/src/model/transformations/response-format-single.jsx index 28c5b5b2b..fbce6748b 100644 --- a/src/model/transformations/response-format-single.jsx +++ b/src/model/transformations/response-format-single.jsx @@ -11,7 +11,7 @@ export function remoteToState(remote) { const { responses: [ { - Datatype: { allowArbitrary, visualizationHint: visHint }, + Datatype: { allowArbitraryResponse, visualizationHint: visHint }, mandatory, CodeListReference, id, @@ -24,7 +24,7 @@ export function remoteToState(remote) { CodeList.remoteToState(CodeListReference), id, mandatory, - allowArbitrary, + allowArbitraryResponse, visHint, }; } @@ -32,7 +32,7 @@ export function remoteToState(remote) { export function stateToRemote(state, collectedVariables) { const { [DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId }, - allowArbitrary, + allowArbitraryResponse, visHint, mandatory, id, @@ -42,7 +42,7 @@ export function stateToRemote(state, collectedVariables) { Response.stateToRemote({ id, mandatory, - allowArbitrary, + allowArbitraryResponse, visHint, codesListId, typeName: TEXT, diff --git a/src/model/transformations/response.jsx b/src/model/transformations/response.jsx index b1e166587..a4edfa07a 100644 --- a/src/model/transformations/response.jsx +++ b/src/model/transformations/response.jsx @@ -26,7 +26,7 @@ export function stateToRemote(state, response) { mayears: Mayears, mamonths: Mamonths, codesListId: CodeListReference, - allowArbitrary, + allowArbitraryResponse, visHint: visualizationHint, collectedVariable: CollectedVariableReference, } = state; @@ -51,11 +51,11 @@ export function stateToRemote(state, response) { model.CodeListReference = CodeListReference; if (mandatory !== undefined) model.mandatory = mandatory === '' ? false : mandatory; - if (allowArbitrary !== undefined) - // we keep allowArbitrary value only for suggester - model.Datatype.allowArbitrary = + if (allowArbitraryResponse !== undefined) + // we keep allowArbitraryResponse value only for suggester + model.Datatype.allowArbitraryResponse = visualizationHint === DATATYPE_VIS_HINT.SUGGESTER - ? allowArbitrary + ? allowArbitraryResponse : undefined; if (visualizationHint !== undefined) model.Datatype.visualizationHint = visualizationHint; diff --git a/src/model/transformations/response.spec.jsx b/src/model/transformations/response.spec.jsx index b97316768..1e2d7b7ed 100644 --- a/src/model/transformations/response.spec.jsx +++ b/src/model/transformations/response.spec.jsx @@ -169,9 +169,9 @@ describe('response tranformations', () => { expect(result.Datatype.Unit).toEqual(unit); }); - test('when allowArbitrary is defined', () => { + test('when allowArbitraryResponse is defined', () => { const typeName = 'TEXT'; - const allowArbitrary = true; + const allowArbitraryResponse = true; // Get all values of DATATYPE_VIS_HINT except 'SUGGESTER' const nonSuggesterVisHints = Object.values(DATATYPE_VIS_HINT).filter( @@ -182,10 +182,12 @@ describe('response tranformations', () => { typeName, id: '1', visHint: DATATYPE_VIS_HINT.SUGGESTER, - allowArbitrary, + allowArbitraryResponse, }); - expect(resultSuggester.Datatype.allowArbitrary).toEqual(allowArbitrary); + expect(resultSuggester.Datatype.allowArbitraryResponse).toEqual( + allowArbitraryResponse, + ); // Test for all non-SUGGESTER visHint values nonSuggesterVisHints.forEach((visHint) => { @@ -193,10 +195,10 @@ describe('response tranformations', () => { typeName, id: '1', visHint, - allowArbitrary, + allowArbitraryResponse, }); - expect(result.Datatype.allowArbitrary).toEqual(undefined); + expect(result.Datatype.allowArbitraryResponse).toEqual(undefined); }); }); diff --git a/src/utils/variables/collected-variables-utils.jsx b/src/utils/variables/collected-variables-utils.jsx index 73c724eb8..7c7956d05 100644 --- a/src/utils/variables/collected-variables-utils.jsx +++ b/src/utils/variables/collected-variables-utils.jsx @@ -194,7 +194,10 @@ export function getCollectedVariablesSingle(questionName, form) { collectedVariables.push(mainCollectedVariable); // get arbitrary variable for suggester - if (form.allowArbitrary && form.visHint === DATATYPE_VIS_HINT.SUGGESTER) { + if ( + form.allowArbitraryResponse && + form.visHint === DATATYPE_VIS_HINT.SUGGESTER + ) { const arbitraryResponseName = `${questionName}_ARBITRARY`; collectedVariables.push( getCollectedVariable( diff --git a/src/utils/variables/collected-variables-utils.spec.jsx b/src/utils/variables/collected-variables-utils.spec.jsx index 0ce5a134e..7a63fff09 100644 --- a/src/utils/variables/collected-variables-utils.spec.jsx +++ b/src/utils/variables/collected-variables-utils.spec.jsx @@ -151,10 +151,10 @@ describe('getCollectedVariablesSingle', () => { ]); }); - test('should return suggester arbitrary variable if allowArbitrary', () => { + test('should return suggester arbitrary variable if allowArbitraryResponse', () => { const questionName = 'questionName'; const form = { - allowArbitrary: true, + allowArbitraryResponse: true, visHint: 'SUGGESTER', CodesList: { id: 'id', label: 'label', codes: [] }, }; diff --git a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx index df0e81f10..bc7a272ce 100644 --- a/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx +++ b/src/widgets/component-new-edit/components/response-format/single/response-format-single.jsx @@ -173,7 +173,7 @@ function ResponseFormatSingle({ {!disableSetArbitrary && ( { componentsStore: state.appState.activeComponentsById, collectedVariablesStore: state.appState.collectedVariableByQuestion, visHint: selector(state, `${path}visHint`), - allowArbitrary: selector(state, `${path}allowArbitrary`), + allowArbitraryResponse: selector(state, `${path}allowArbitraryResponse`), path, }; }; From 4167539a1af8b8003e6fc68e4d226f4425e16400 Mon Sep 17 00:00:00 2001 From: Quentin Ruhier Date: Thu, 30 Jan 2025 09:51:23 +0100 Subject: [PATCH 5/5] chore: review changes --- src/constants/dictionary.ts | 2 +- .../component-new-edit/collected-variable.jsx | 8 ++++---- src/model/remote-to-stores.jsx | 2 +- src/model/transformations/collected-variable.jsx | 8 ++++---- .../transformations/collected-variable.spec.jsx | 6 +++--- src/model/transformations/component.jsx | 15 ++++++++------- src/utils/variables/collected-variables-utils.jsx | 6 +++--- .../variables/collected-variables-utils.spec.jsx | 2 +- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/constants/dictionary.ts b/src/constants/dictionary.ts index b5726c0b2..d15bbcc5c 100644 --- a/src/constants/dictionary.ts +++ b/src/constants/dictionary.ts @@ -517,7 +517,7 @@ const dictionary: Dictionary = { }, allowArbitraryResponse: { fr: 'Autoriser une réponse libre', - en: 'Allow arbitrary response', + en: 'Allow an arbitrary response', }, list: { fr: 'Liste', diff --git a/src/model/formToState/component-new-edit/collected-variable.jsx b/src/model/formToState/component-new-edit/collected-variable.jsx index e6d5b4462..aafbd92d5 100644 --- a/src/model/formToState/component-new-edit/collected-variable.jsx +++ b/src/model/formToState/component-new-edit/collected-variable.jsx @@ -47,7 +47,7 @@ export function formToState(form) { y, z, mesureLevel, - arbitraryOfVariable, + arbitraryVariableOfVariableId, codeListReference, codeListReferenceLabel, isCollected, @@ -62,7 +62,7 @@ export function formToState(form) { x, y, z, - arbitraryOfVariable, + arbitraryVariableOfVariableId, isCollected, alternativeLabel, mesureLevel, @@ -96,7 +96,7 @@ export function storeToForm(currentStore) { x, y, z, - arbitraryOfVariable, + arbitraryVariableOfVariableId, isCollected = '1', alternativeLabel, mesureLevel, @@ -110,7 +110,7 @@ export function storeToForm(currentStore) { x, y, z, - arbitraryOfVariable, + arbitraryVariableOfVariableId, isCollected, alternativeLabel, mesureLevel, diff --git a/src/model/remote-to-stores.jsx b/src/model/remote-to-stores.jsx index 95b8f07c9..186dc9dd4 100644 --- a/src/model/remote-to-stores.jsx +++ b/src/model/remote-to-stores.jsx @@ -45,7 +45,7 @@ export function questionnaireRemoteToStores(remote, currentStores = {}) { collectedVariables, ); - const arbitraryVariables = Component.getArbitraryResponsesFromRemote( + const arbitraryVariables = Component.getArbitraryVariablesFromRemote( remote.Child, collectedVariables, ); diff --git a/src/model/transformations/collected-variable.jsx b/src/model/transformations/collected-variable.jsx index f61ebb954..2b7ab3e81 100644 --- a/src/model/transformations/collected-variable.jsx +++ b/src/model/transformations/collected-variable.jsx @@ -52,8 +52,8 @@ export function remoteToStore( arbitraryVariable.CollectedVariableReference === variable.id, ); if (extendedArbitraryVariable) { - variable.arbitraryOfVariable = - extendedArbitraryVariable.arbitraryOfVariable; + variable.arbitraryVariableOfVariableId = + extendedArbitraryVariable.arbitraryVariableOfVariableId; } } }); @@ -64,7 +64,7 @@ export function remoteToStore( CodeListReference, z, mesureLevel, - arbitraryOfVariable, + arbitraryVariableOfVariableId, } = ev; const id = ev.id || uuid(); @@ -87,7 +87,7 @@ export function remoteToStore( ...responsesByVariable[id], z, mesureLevel, - arbitraryOfVariable, + arbitraryVariableOfVariableId, }, }; }, {}); diff --git a/src/model/transformations/collected-variable.spec.jsx b/src/model/transformations/collected-variable.spec.jsx index bc3c25c76..cd2218cb3 100644 --- a/src/model/transformations/collected-variable.spec.jsx +++ b/src/model/transformations/collected-variable.spec.jsx @@ -244,7 +244,7 @@ describe('collected variable tranformations', () => { typeName: 'TEXT', MaxLength: 249, }, - arbitraryOfVariable: 'm6aty8by', + arbitraryVariableOfVariableId: 'm6aty8by', }, ]; const arbitraryVariables = [ @@ -256,7 +256,7 @@ describe('collected variable tranformations', () => { }, mandatory: false, CollectedVariableReference: 'm6atzjnb', - arbitraryOfVariable: 'm6aty8by', + arbitraryVariableOfVariableId: 'm6aty8by', }, ]; const responsesByVariable = { m6aty8by: {} }; @@ -284,7 +284,7 @@ describe('collected variable tranformations', () => { TEXT: { maxLength: 249, }, - arbitraryOfVariable: 'm6aty8by', + arbitraryVariableOfVariableId: 'm6aty8by', }, }; diff --git a/src/model/transformations/component.jsx b/src/model/transformations/component.jsx index 74ee92d65..e0ee412e1 100644 --- a/src/model/transformations/component.jsx +++ b/src/model/transformations/component.jsx @@ -209,9 +209,9 @@ const getArbitraryQuestions = (Children) => { /* * Get the list of arbitrary variables. * An arbitrary variable is the "ArbitraryResponse" object of a question, - * adding "arbitraryOfVariable" which is the corresponding Response variable. + * extented with "arbitraryVariableOfVariableId" which is the corresponding Response variable id. */ -export const getArbitraryResponsesFromRemote = (Children) => { +export const getArbitraryVariablesFromRemote = (Children) => { const arbitraryVariables = []; const arbitraryQuestions = getArbitraryQuestions(Children); @@ -221,7 +221,7 @@ export const getArbitraryResponsesFromRemote = (Children) => { const arbitraryVariable = { ...question.ArbitraryResponse, - arbitraryOfVariable: responseVariableId, + arbitraryVariableOfVariableId: responseVariableId, }; arbitraryVariables.push(arbitraryVariable); }); @@ -690,19 +690,20 @@ function getClarificationResponseTableQuestion( } function getArbitraryResponse(collectedVariablesStore, collectedVariables) { - const collectedvariablequestion = []; + const collectedVariableQuestions = []; Object.values(collectedVariablesStore).forEach((collec) => { if (collectedVariables !== undefined) { collectedVariables.forEach((variables) => { if (collec.id === variables) { - collectedvariablequestion.push(collec); + collectedVariableQuestions.push(collec); } }); } }); - for (const collected of collectedvariablequestion) { - const isArbitraryVariable = collected.arbitraryOfVariable !== undefined; + for (const collected of collectedVariableQuestions) { + const isArbitraryVariable = + collected.arbitraryVariableOfVariableId !== undefined; // we can have only one collected variable that is an arbitrary variable if (isArbitraryVariable) { const responseModel = { diff --git a/src/utils/variables/collected-variables-utils.jsx b/src/utils/variables/collected-variables-utils.jsx index 7c7956d05..8d0562e7a 100644 --- a/src/utils/variables/collected-variables-utils.jsx +++ b/src/utils/variables/collected-variables-utils.jsx @@ -87,7 +87,7 @@ export function getCollectedVariable( coordinates, reponseFormatValues = {}, alternativeLabel = '', - arbitraryOfVariable = undefined, + arbitraryVariableOfVariableId = undefined, ) { let collectedVariable = { ...reponseFormatValues, @@ -99,10 +99,10 @@ export function getCollectedVariable( if (coordinates) collectedVariable = { ...collectedVariable, ...coordinates }; if (alternativeLabel) collectedVariable = { ...collectedVariable, ...alternativeLabel }; - if (arbitraryOfVariable) + if (arbitraryVariableOfVariableId) collectedVariable = { ...collectedVariable, - arbitraryOfVariable: arbitraryOfVariable, + arbitraryVariableOfVariableId: arbitraryVariableOfVariableId, }; return collectedVariable; } diff --git a/src/utils/variables/collected-variables-utils.spec.jsx b/src/utils/variables/collected-variables-utils.spec.jsx index 7a63fff09..e15460374 100644 --- a/src/utils/variables/collected-variables-utils.spec.jsx +++ b/src/utils/variables/collected-variables-utils.spec.jsx @@ -177,7 +177,7 @@ describe('getCollectedVariablesSingle', () => { label: 'questionName_ARBITRARY label', type: 'TEXT', TEXT: { maxLength: 249 }, - arbitraryOfVariable: result[0].id, + arbitraryVariableOfVariableId: result[0].id, }, ]); });