Skip to content

Commit

Permalink
feat: allow arbitrary response for suggester
Browse files Browse the repository at this point in the history
  • Loading branch information
QRuhier committed Jan 10, 2025
1 parent e552c7c commit bc7067e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/constants/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
const { RADIO } = DATATYPE_VIS_HINT;

export const defaultState = {
allowArbitrary: false,
mandatory: false,
hasSpecialCode: false,
specialLabel: '',
Expand All @@ -22,6 +23,7 @@ export const defaultState = {
};

export const defaultForm = {
allowArbitrary: false,
mandatory: false,
hasSpecialCode: false,
specialLabel: '',
Expand All @@ -35,6 +37,7 @@ export const defaultForm = {
export function formToState(form, transformers) {
const {
id,
allowArbitrary,
mandatory,
visHint,
hasSpecialCode,
Expand All @@ -47,6 +50,7 @@ export function formToState(form, transformers) {

return {
id,
allowArbitrary,
mandatory,
visHint,
hasSpecialCode,
Expand All @@ -64,6 +68,7 @@ export function formToState(form, transformers) {
export function stateToForm(currentState, transformers) {
const {
id,
allowArbitrary,
visHint,
mandatory,
hasSpecialCode,
Expand All @@ -75,6 +80,7 @@ export function stateToForm(currentState, transformers) {

return {
id,
allowArbitrary,
mandatory,
visHint,
hasSpecialCode,
Expand Down
15 changes: 13 additions & 2 deletions src/model/formToState/component-new-edit/response-format-table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const defaultMeasureState = {
cloneDeep(CodesListDefaultState),
{ id: uuid() },
),
allowArbitrary: false,
visHint: RADIO,
},
};
Expand All @@ -76,6 +77,7 @@ export const defaultMeasureForm = {
type: SIMPLE,
[SIMPLE]: defaultMeasureSimpleState,
[SINGLE_CHOICE]: {
allowArbitrary: false,
hasSpecialCode: false,
specialLabel: '',
specialCode: '',
Expand Down Expand Up @@ -172,13 +174,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,
};
Expand Down Expand Up @@ -253,6 +259,7 @@ export function stateToFormMeasure(
type,
[SIMPLE]: simpleState,
[SINGLE_CHOICE]: {
allowArbitrary,
visHint,
[DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState,
},
Expand All @@ -273,6 +280,7 @@ export function stateToFormMeasure(
type,
[SIMPLE]: simpleState,
[SINGLE_CHOICE]: {
allowArbitrary,
visHint,
[DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm,
},
Expand All @@ -282,6 +290,7 @@ export function stateToFormMeasure(
export function stateToFormMeasureList(currentState, codesListsStore) {
const {
[SINGLE_CHOICE]: {
allowArbitrary,
visHint,
[DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListState,
},
Expand All @@ -295,6 +304,7 @@ export function stateToFormMeasureList(currentState, codesListsStore) {
return {
...currentState,
[SINGLE_CHOICE]: {
allowArbitrary,
visHint,
[DEFAULT_CODES_LIST_SELECTOR_PATH]: codesListForm,
},
Expand Down Expand Up @@ -377,6 +387,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 {
Expand Down
5 changes: 4 additions & 1 deletion src/model/transformations/response-format-single.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function remoteToState(remote) {
const {
responses: [
{
Datatype: { visualizationHint: visHint },
Datatype: { allowArbitrary, visualizationHint: visHint },
mandatory,
nonResponseModality,
CodeListReference,
Expand All @@ -26,6 +26,7 @@ export function remoteToState(remote) {
CodeList.remoteToState(CodeListReference),
id,
mandatory,
allowArbitrary,
visHint,
hasSpecialCode: !!nonResponseModality,
specialLabel:
Expand All @@ -45,6 +46,7 @@ export function remoteToState(remote) {
export function stateToRemote(state, collectedVariables) {
const {
[DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId },
allowArbitrary,
visHint,
mandatory,
id,
Expand All @@ -54,6 +56,7 @@ export function stateToRemote(state, collectedVariables) {
Response.stateToRemote({
id,
mandatory,
allowArbitrary,
visHint,
codesListId,
typeName: TEXT,
Expand Down
2 changes: 2 additions & 0 deletions src/model/transformations/response-format-table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ function stateToResponseState(state) {
} else {
const {
mandatory,
allowArbitrary,
visHint,
[DEFAULT_CODES_LIST_SELECTOR_PATH]: { id: codesListId },
} = measureTypeState;
Expand All @@ -327,6 +328,7 @@ function stateToResponseState(state) {
typeName: TEXT,
maxLength: 1,
pattern: '',
allowArbitrary,
visHint,
};
}
Expand Down
8 changes: 8 additions & 0 deletions src/model/transformations/response.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
DATATYPE_TYPE_FROM_NAME,
DATATYPE_VIS_HINT,
UI_BEHAVIOUR,
} from '../../constants/pogues-constants';
import { uuid } from '../../utils/utils';
Expand All @@ -26,6 +27,7 @@ export function stateToRemote(state, response) {
mayears: Mayears,
mamonths: Mamonths,
codesListId: CodeListReference,
allowArbitrary,
visHint: visualizationHint,
hasSpecialCode,
specialLabel,
Expand Down Expand Up @@ -55,6 +57,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;
Expand Down
32 changes: 32 additions & 0 deletions src/model/transformations/response.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, expect, test } from 'vitest';

import {
DATATYPE_TYPE_FROM_NAME,
DATATYPE_VIS_HINT,
UI_BEHAVIOUR,
} from '../../constants/pogues-constants';
import { stateToRemote } from './response';
Expand Down Expand Up @@ -169,6 +170,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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,22 @@ function ResponseFormatSingle({
</Field>
)}
{visHint === SUGGESTER ? (
<SuggesterLists selectorPathParent={selectorPathComposed} />
<>
<SuggesterLists selectorPathParent={selectorPathComposed} />
<Field
name="allowArbitrary"
component={ListRadios}
label={Dictionary.allowArbitraryResponse}
required
// Convert string "true"/"false" to boolean true/false when storing in Redux form
parse={(value) => value === 'true'}
// Convert true/false/undefined to string "true"/"false" when displaying the form
format={(value) => (value === true ? 'true' : 'false')}
>
<GenericOption value="true">{Dictionary.yes}</GenericOption>
<GenericOption value="false">{Dictionary.no}</GenericOption>
</Field>
</>
) : (
<CodesLists
selectorPathParent={selectorPathComposed}
Expand Down Expand Up @@ -212,6 +227,7 @@ const mapStateToProps = (state, { selectorPathParent, responseFormatType }) => {
componentsStore: state.appState.activeComponentsById,
collectedVariablesStore: state.appState.collectedVariableByQuestion,
visHint: selector(state, `${path}visHint`),
allowArbitrary: selector(state, `${path}allowArbitrary`),
path,
};
};
Expand Down

0 comments on commit bc7067e

Please sign in to comment.