From 6f71dd86a7165d75db137825a2a0e74ad6c0876e Mon Sep 17 00:00:00 2001 From: Vadim Laletin Date: Fri, 22 Nov 2024 23:33:04 +0100 Subject: [PATCH 1/2] Add support for choiceColumn in choice questions. Ref #378 --- .../widgets/choice/index.tsx | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx b/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx index 180fec98..6d6b0fe4 100644 --- a/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx +++ b/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx @@ -4,12 +4,13 @@ import _, { debounce } from 'lodash'; import { useCallback, useContext } from 'react'; import { QuestionItemProps } from 'sdc-qrf'; -import { QuestionnaireItemAnswerOption, QuestionnaireResponseItemAnswer } from '@beda.software/aidbox-types'; +import { QuestionnaireItemAnswerOption, QuestionnaireResponseItemAnswer, QuestionnaireResponseItemAnswerValue } from '@beda.software/aidbox-types'; import { AsyncSelect, Select } from 'src/components/Select'; import { ValueSetExpandProvider } from 'src/contexts'; -import { getDisplay } from 'src/utils/questionnaire'; +import { getDisplay as getAnswerValueDisplay } from 'src/utils/questionnaire'; +import { evaluate } from 'src/utils'; import s from '../../BaseQuestionnaireResponseForm.module.scss'; import { useFieldController } from '../../hooks'; @@ -19,10 +20,11 @@ interface ChoiceQuestionSelectProps { options: QuestionnaireItemAnswerOption[]; repeats?: boolean; placeholder?: string; + getDisplay?: (value?: QuestionnaireResponseItemAnswerValue) => string | number | null; } export function ChoiceQuestionSelect(props: ChoiceQuestionSelectProps) { - const { value, onChange, options, repeats = false, placeholder = t`Select...` } = props; + const { value, onChange, options, repeats = false, placeholder = t`Select...`, getDisplay = getAnswerValueDisplay } = props; return ( <> @@ -43,14 +45,23 @@ export function ChoiceQuestionSelect(props: ChoiceQuestionSelectProps) { ); } -export function QuestionChoice({ parentPath, questionItem }: QuestionItemProps) { - const { linkId, answerOption, repeats, answerValueSet } = questionItem; +export function QuestionChoice({ parentPath, questionItem, context }: QuestionItemProps) { + const { linkId, answerOption, repeats, answerValueSet, choiceColumn } = questionItem; const fieldName = [...parentPath, linkId]; const { value, formItem, onChange, placeholder = t`Select...` } = useFieldController(fieldName, questionItem); const onSelect = useCallback((option: any) => onChange([].concat(option)), [onChange]); + const getDisplay = useCallback((value?: QuestionnaireResponseItemAnswerValue) => { + const specificValueType = value && (Object.keys(value)[0] as keyof QuestionnaireResponseItemAnswerValue) + if (choiceColumn && specificValueType) { + return (evaluate(value[specificValueType], choiceColumn![0]!.path!, context)[0] ?? null) as string | number | null; + } + + return getAnswerValueDisplay(value); + }, [choiceColumn, context]); + if (answerValueSet) { return ( @@ -60,6 +71,7 @@ export function QuestionChoice({ parentPath, questionItem }: QuestionItemProps) onChange={onSelect} repeats={repeats} placeholder={placeholder} + getDisplay={getDisplay} /> ); @@ -73,6 +85,7 @@ export function QuestionChoice({ parentPath, questionItem }: QuestionItemProps) onChange={onSelect} repeats={repeats} placeholder={placeholder} + getDisplay={getDisplay} /> ); @@ -84,10 +97,11 @@ interface ChoiceQuestionValueSetProps { onChange: (option: any) => void; repeats?: boolean; placeholder?: string; + getDisplay?: (value?: QuestionnaireResponseItemAnswerValue) => string | number | null; } export function ChoiceQuestionValueSet(props: ChoiceQuestionValueSetProps) { - const { answerValueSet, value, onChange, repeats = false, placeholder } = props; + const { answerValueSet, value, onChange, repeats = false, placeholder, getDisplay = getAnswerValueDisplay } = props; const expand = useContext(ValueSetExpandProvider); const loadOptions = useCallback( From b47461cd7a3a121ff1e0a5026bd15504803b6de2 Mon Sep 17 00:00:00 2001 From: Vadim Laletin Date: Fri, 22 Nov 2024 23:48:40 +0100 Subject: [PATCH 2/2] Reformat --- .../widgets/choice/index.tsx | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx b/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx index 6d6b0fe4..93633232 100644 --- a/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx +++ b/src/components/BaseQuestionnaireResponseForm/widgets/choice/index.tsx @@ -4,13 +4,17 @@ import _, { debounce } from 'lodash'; import { useCallback, useContext } from 'react'; import { QuestionItemProps } from 'sdc-qrf'; -import { QuestionnaireItemAnswerOption, QuestionnaireResponseItemAnswer, QuestionnaireResponseItemAnswerValue } from '@beda.software/aidbox-types'; +import { + QuestionnaireItemAnswerOption, + QuestionnaireResponseItemAnswer, + QuestionnaireResponseItemAnswerValue, +} from '@beda.software/aidbox-types'; import { AsyncSelect, Select } from 'src/components/Select'; import { ValueSetExpandProvider } from 'src/contexts'; +import { evaluate } from 'src/utils'; import { getDisplay as getAnswerValueDisplay } from 'src/utils/questionnaire'; -import { evaluate } from 'src/utils'; import s from '../../BaseQuestionnaireResponseForm.module.scss'; import { useFieldController } from '../../hooks'; @@ -24,7 +28,14 @@ interface ChoiceQuestionSelectProps { } export function ChoiceQuestionSelect(props: ChoiceQuestionSelectProps) { - const { value, onChange, options, repeats = false, placeholder = t`Select...`, getDisplay = getAnswerValueDisplay } = props; + const { + value, + onChange, + options, + repeats = false, + placeholder = t`Select...`, + getDisplay = getAnswerValueDisplay, + } = props; return ( <> @@ -53,14 +64,20 @@ export function QuestionChoice({ parentPath, questionItem, context }: QuestionIt const onSelect = useCallback((option: any) => onChange([].concat(option)), [onChange]); - const getDisplay = useCallback((value?: QuestionnaireResponseItemAnswerValue) => { - const specificValueType = value && (Object.keys(value)[0] as keyof QuestionnaireResponseItemAnswerValue) - if (choiceColumn && specificValueType) { - return (evaluate(value[specificValueType], choiceColumn![0]!.path!, context)[0] ?? null) as string | number | null; - } - - return getAnswerValueDisplay(value); - }, [choiceColumn, context]); + const getDisplay = useCallback( + (value?: QuestionnaireResponseItemAnswerValue) => { + const specificValueType = value && (Object.keys(value)[0] as keyof QuestionnaireResponseItemAnswerValue); + if (choiceColumn && specificValueType) { + return (evaluate(value[specificValueType], choiceColumn![0]!.path!, context)[0] ?? null) as + | string + | number + | null; + } + + return getAnswerValueDisplay(value); + }, + [choiceColumn, context], + ); if (answerValueSet) { return (