Repository: ohcnetwork/care_fe
Pull request #11394: Add Support for Valueset Options in Choice Question & Quantity
Author: login: gigincg
Labels: name: Tested
name: P1
description: breaking issue or vital feature
Created: 2025-03-19T07:39:15Z | Merged: 2025-03-19T14:14:51Z

## Proposed Changes
- Add Support for Valueset Options in Choice Question
- Add Support for Quantity Questions

@ohcnetwork/care-fe-code-reviewers

## Merge Checklist

- [ ] Add specs that demonstrate bug / test a new feature.
- [ ] Update [product documentation](https://docs.ohc.network).
- [ ] Ensure that UI text is kept in I18n files.
- [ ] Prep screenshot or demo video for changelog entry, and attach it to issue.
- [ ] Request for Peer Reviews
- [ ] Completion of QA in Mobile Devices
- [ ] Completion of QA in Desktop Devices


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enabled quantity-type answer handling with dedicated numeric input and selection options.
  - Introduced a toggle to mark questions as components and conditional selection for coding versus value inputs.
  - Added a new `QuantityQuestion` component for handling quantity-type questions.
  - Enhanced display of coding information in response values.

- **Refactor**
  - Streamlined the extraction and display of response values, including improved handling of units and coding.
  - Enhanced form validation to ensure comprehensive checks on answer inputs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx
index d826d487bb7..84e1b005136 100644
--- a/src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx
+++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx
@@ -89,9 +89,7 @@ export default function QuestionnaireResponseView({
                     );
                     if (!questionResponse) return null;
 
-                    const value =
-                      questionResponse.values[0]?.value ||
-                      questionResponse.values[0]?.value_quantity?.value;
+                    const value = questionResponse.values[0]?.value;
 
                     return (
                       <div key={question.id} className="grid grid-cols-2 gap-4">
diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx
index bba948cfd72..54028512a0d 100644
--- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx
+++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx
@@ -77,8 +77,15 @@ function QuestionResponseValue({ question, response }: QuestionResponseProps) {
       <div className="text-xs text-gray-500">{question.text}</div>
       <div className="space-y-1">
         {response.values.map((valueObj, index) => {
-          const value = valueObj.value || valueObj.value_quantity?.value;
-          if (!value) return null;
+          const value = valueObj.value;
+
+          const coding = valueObj.coding;
+
+          const unit = valueObj.unit;
+
+          if (!value && !coding) return null;
+
+          const precedentUnit = unit ? unit : question.unit;
 
           return (
             <div
@@ -86,8 +93,13 @@ function QuestionResponseValue({ question, response }: QuestionResponseProps) {
               className="text-sm font-medium whitespace-pre-wrap"
             >
               {formatValue(value, question.type)}
-              {question.unit?.code && (
-                <span className="ml-1 text-xs">{question.unit.code}</span>
+              {precedentUnit && (
+                <span className="ml-1 text-xs">{precedentUnit.code}</span>
+              )}
+              {coding && (
+                <span className="ml-1 text-xs">
+                  {coding.display} ({coding.code})
+                </span>
               )}
               {index === response.values.length - 1 && response.note && (
                 <span className="ml-2 text-xs text-gray-500">
diff --git a/src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx b/src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx
index 95475f7acc5..b850b1588c4 100644
--- a/src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx
+++ b/src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx
@@ -8,7 +8,10 @@ import {
   SelectValue,
 } from "@/components/ui/select";
 
+import ValueSetSelect from "@/components/Questionnaire/ValueSetSelect";
+
 import { properCase } from "@/Utils/utils";
+import { Code } from "@/types/questionnaire/code";
 import type {
   QuestionnaireResponse,
   ResponseValue,
@@ -39,7 +42,7 @@ export const ChoiceQuestion = memo(function ChoiceQuestion({
 }: ChoiceQuestionProps) {
   const options = question.answer_option || [];
   const currentValue = questionnaireResponse.values[index]?.value?.toString();
-
+  const currentCoding = questionnaireResponse.values[index]?.coding;
   const handleValueChange = (newValue: string) => {
     clearError();
     const newValues = [...questionnaireResponse.values];
@@ -55,25 +58,53 @@ export const ChoiceQuestion = memo(function ChoiceQuestion({
     );
   };
 
+  const handleCodingChange = (newValue: Code) => {
+    clearError();
+    const newValues = [...questionnaireResponse.values];
+    newValues[index] = {
+      type: "quantity",
+      coding: {
+        code: newValue.code,
+        system: newValue.system,
+        display: newValue.display,
+      },
+    };
+
+    updateQuestionnaireResponseCB(
+      newValues,
+      questionnaireResponse.question_id,
+      questionnaireResponse.note,
+    );
+  };
   return (
-    <Select
-      value={currentValue}
-      onValueChange={handleValueChange}
-      disabled={disabled}
-    >
-      <SelectTrigger className="w-full">
-        <SelectValue placeholder="Select an option" />
-      </SelectTrigger>
-      <SelectContent>
-        {options.map((option: AnswerOption) => (
-          <SelectItem
-            key={option.value.toString()}
-            value={option.value.toString()}
-          >
-            {properCase(option.display || option.value)}
-          </SelectItem>
-        ))}
-      </SelectContent>
-    </Select>
+    <>
+      {question.answer_value_set ? (
+        <ValueSetSelect
+          system={question.answer_value_set}
+          value={currentCoding}
+          onSelect={handleCodingChange}
+        ></ValueSetSelect>
+      ) : (
+        <Select
+          value={currentValue}
+          onValueChange={handleValueChange}
+          disabled={disabled}
+        >
+          <SelectTrigger className="w-full">
+            <SelectValue placeholder="Select an option" />
+          </SelectTrigger>
+          <SelectContent>
+            {options.map((option: AnswerOption) => (
+              <SelectItem
+                key={option.value.toString()}
+                value={option.value.toString()}
+              >
+                {properCase(option.display || option.value)}
+              </SelectItem>
+            ))}
+          </SelectContent>
+        </Select>
+      )}
+    </>
   );
 });
diff --git a/src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx b/src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx
new file mode 100644
index 00000000000..3d9a018de21
--- /dev/null
+++ b/src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx
@@ -0,0 +1,132 @@
+import { memo } from "react";
+
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+
+import ValueSetSelect from "@/components/Questionnaire/ValueSetSelect";
+
+import { Code } from "@/types/questionnaire/code";
+import type {
+  QuestionnaireResponse,
+  ResponseValue,
+} from "@/types/questionnaire/form";
+import type { Question } from "@/types/questionnaire/question";
+
+interface QuantityQuestionProps {
+  question: Question;
+  questionnaireResponse: QuestionnaireResponse;
+  updateQuestionnaireResponseCB: (
+    values: ResponseValue[],
+    questionId: string,
+    note?: string,
+  ) => void;
+  disabled?: boolean;
+  clearError: () => void;
+  index?: number;
+}
+
+export const QuantityQuestion = memo(function QuantityQuestion({
+  question,
+  questionnaireResponse,
+  updateQuestionnaireResponseCB,
+  disabled = false,
+  clearError,
+  index = 0,
+}: QuantityQuestionProps) {
+  const currentValue = questionnaireResponse.values[index]?.value as
+    | number
+    | undefined;
+  const currentUnit = questionnaireResponse.values[index]?.unit;
+  const currentCoding = questionnaireResponse.values[index]?.coding;
+
+  const handleValueChange = (value: string) => {
+    clearError();
+    const numericValue = value === "" ? undefined : parseFloat(value);
+    const newValues = [...questionnaireResponse.values];
+    newValues[index] = {
+      type: "quantity",
+      value: numericValue,
+      unit: currentUnit,
+      coding: currentCoding,
+    };
+
+    updateQuestionnaireResponseCB(
+      newValues,
+      questionnaireResponse.question_id,
+      questionnaireResponse.note,
+    );
+  };
+
+  const handleUnitChange = (newUnit: Code) => {
+    clearError();
+    const newValues = [...questionnaireResponse.values];
+    newValues[index] = {
+      type: "quantity",
+      value: currentValue,
+      unit: newUnit,
+      coding: currentCoding,
+    };
+
+    updateQuestionnaireResponseCB(
+      newValues,
+      questionnaireResponse.question_id,
+      questionnaireResponse.note,
+    );
+  };
+
+  const handleCodingChange = (newCoding: Code) => {
+    clearError();
+    const newValues = [...questionnaireResponse.values];
+    newValues[index] = {
+      type: "quantity",
+      value: currentValue,
+      unit: currentUnit,
+      coding: newCoding,
+    };
+
+    updateQuestionnaireResponseCB(
+      newValues,
+      questionnaireResponse.question_id,
+      questionnaireResponse.note,
+    );
+  };
+
+  return (
+    <div className="flex gap-4">
+      {question.answer_value_set && (
+        <div className="space-y-2">
+          <Label htmlFor={`${question.id}-coding`}>Type</Label>
+          <div className="w-[200px]">
+            <ValueSetSelect
+              system={question.answer_value_set}
+              value={currentCoding}
+              onSelect={handleCodingChange}
+            />
+          </div>
+        </div>
+      )}
+      <div className="space-y-2">
+        <Label htmlFor={`${question.id}-value`}>Value</Label>
+        <Input
+          id={`${question.id}-value`}
+          type="number"
+          value={currentValue?.toString() || ""}
+          onChange={(e) => handleValueChange(e.target.value)}
+          step="0.01"
+          disabled={disabled}
+          className="w-[200px]"
+        />
+      </div>
+      <div className="space-y-2">
+        <Label htmlFor={`${question.id}-unit`}>Unit</Label>
+        <div className="w-[200px]">
+          <ValueSetSelect
+            system="system-ucum-units"
+            value={currentUnit}
+            onSelect={handleUnitChange}
+          />
+        </div>
+      </div>
+    </div>
+  );
+});
diff --git a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx
index cd7d9206e22..1cad85b8073 100644
--- a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx
+++ b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx
@@ -26,6 +26,7 @@ import { MedicationRequestQuestion } from "./MedicationRequestQuestion";
 import { MedicationStatementQuestion } from "./MedicationStatementQuestion";
 import { NotesInput } from "./NotesInput";
 import { NumberQuestion } from "./NumberQuestion";
+import { QuantityQuestion } from "./QuantityQuestion";
 import { SymptomQuestion } from "./SymptomQuestion";
 import { TextQuestion } from "./TextQuestion";
 
@@ -106,6 +107,9 @@ export function QuestionInput({
       case "integer":
         return <NumberQuestion {...commonProps} />;
 
+      case "quantity":
+        return <QuantityQuestion {...commonProps} />;
+
       case "choice":
         return <ChoiceQuestion {...commonProps} />;
 
diff --git a/src/components/Questionnaire/QuestionnaireEditor.tsx b/src/components/Questionnaire/QuestionnaireEditor.tsx
index e11ac9ee7d3..8ed126730c7 100644
--- a/src/components/Questionnaire/QuestionnaireEditor.tsx
+++ b/src/components/Questionnaire/QuestionnaireEditor.tsx
@@ -1441,6 +1441,21 @@ function QuestionEditor({
               </p>
               <div className="">
                 <div className="flex flex-wrap gap-4">
+                  {type === "group" && (
+                    <div className="flex items-center gap-2">
+                      <Switch
+                        checked={question.is_component ?? false}
+                        onCheckedChange={(val) =>
+                          updateField("is_component", val)
+                        }
+                        id={`is_component-${getQuestionPath()}`}
+                      />
+                      <Label htmlFor={`is_component-${getQuestionPath()}`}>
+                        {t("is_component")}
+                      </Label>
+                    </div>
+                  )}
+
                   <div className="flex items-center gap-2">
                     <Switch
                       checked={question.collect_time ?? false}
@@ -1536,40 +1551,63 @@ function QuestionEditor({
             </div>
           )}
 
-          {type === "choice" && (
+          {(type === "choice" || type === "quantity") && (
             <div className="space-y-4">
               <Card>
-                <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
-                  <div>
-                    <CardTitle className="text-base font-medium">
-                      Answer Options
-                    </CardTitle>
-                    <p className="text-sm text-gray-500">
-                      Define possible answers for this question
-                    </p>
-                  </div>
-                  <Select
-                    value={question.answer_value_set ? "valueset" : "custom"}
-                    onValueChange={(val: string) =>
-                      updateField(
-                        "answer_value_set",
-                        val === "custom" ? undefined : "valueset",
-                      )
-                    }
-                  >
-                    <SelectTrigger className="w-[200px]">
-                      <SelectValue placeholder={t("select_a_value_set")} />
-                    </SelectTrigger>
-                    <SelectContent>
-                      <SelectItem value="custom">
-                        {t("custom_options")}
-                      </SelectItem>
-                      <SelectItem value="valueset">{t("value_set")}</SelectItem>
-                    </SelectContent>
-                  </Select>
-                </CardHeader>
+                {question.type === "choice" && (
+                  <>
+                    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+                      <div>
+                        <CardTitle className="text-base font-medium">
+                          Answer Options
+                        </CardTitle>
+                        <p className="text-sm text-gray-500">
+                          Define possible answers for this question
+                        </p>
+                      </div>
+                      <Select
+                        value={
+                          question.answer_value_set ? "valueset" : "custom"
+                        }
+                        onValueChange={(val: string) =>
+                          updateField(
+                            "answer_value_set",
+                            val === "custom" ? undefined : "valueset",
+                            { answer_option: [] },
+                          )
+                        }
+                      >
+                        <SelectTrigger className="w-[200px]">
+                          <SelectValue placeholder={t("select_a_value_set")} />
+                        </SelectTrigger>
+                        <SelectContent>
+                          <SelectItem value="custom">
+                            {t("custom_options")}
+                          </SelectItem>
+                          <SelectItem value="valueset">
+                            {t("value_set")}
+                          </SelectItem>
+                        </SelectContent>
+                      </Select>
+                    </CardHeader>
+                  </>
+                )}
+
+                {question.type === "quantity" && (
+                  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+                    <div>
+                      <CardTitle className="text-base font-medium">
+                        Quantity
+                      </CardTitle>
+                      <p className="text-sm text-gray-500">
+                        Select the valueset of options for this quantity
+                        question
+                      </p>
+                    </div>
+                  </CardHeader>
+                )}
 
-                {!question.answer_value_set ? (
+                {question.type === "choice" && !question.answer_value_set ? (
                   <CardContent className="space-y-4">
                     {(answer_option || []).map((opt, idx) => (
                       <div
diff --git a/src/components/Questionnaire/QuestionnaireForm.tsx b/src/components/Questionnaire/QuestionnaireForm.tsx
index a0f5b27d2b9..82e06e863ae 100644
--- a/src/components/Questionnaire/QuestionnaireForm.tsx
+++ b/src/components/Questionnaire/QuestionnaireForm.tsx
@@ -555,7 +555,13 @@ export function QuestionnaireForm({
               (Array.isArray(v.value) ? v.value.length > 0 : true),
           );
 
-          if (!hasValue) {
+          const hasProperty = (arr: any[] | undefined, prop: string) =>
+            Array.isArray(arr) && arr.some((item) => item?.[prop] != null);
+
+          const hasCoding = hasProperty(response?.values, "coding");
+          const hasUnit = hasProperty(response?.values, "unit");
+
+          if (!hasValue && !hasCoding && !hasUnit) {
             errors.push({
               question_id: q.id,
               error: t("field_required"),
@@ -650,8 +656,15 @@ export function QuestionnaireForm({
                       value: value.value.toISOString(),
                     };
                   }
-                  if (value.value_code) {
-                    return { value_code: value.value_code };
+                  if (value.unit) {
+                    return {
+                      value: value.value?.toString(),
+                      unit: value.unit,
+                      coding: value.coding,
+                    };
+                  }
+                  if (value.coding) {
+                    return { coding: value.coding };
                   }
                   return { value: String(value.value) };
                 }),
diff --git a/src/components/Questionnaire/ValueSetSelect.tsx b/src/components/Questionnaire/ValueSetSelect.tsx
index 874af2c1b9f..f80de708469 100644
--- a/src/components/Questionnaire/ValueSetSelect.tsx
+++ b/src/components/Questionnaire/ValueSetSelect.tsx
@@ -25,10 +25,10 @@ import useBreakpoints from "@/hooks/useBreakpoints";
 
 import routes from "@/Utils/request/api";
 import query from "@/Utils/request/query";
-import { Code, ValueSetSystem } from "@/types/questionnaire/code";
+import { Code } from "@/types/questionnaire/code";
 
 interface Props {
-  system: ValueSetSystem;
+  system: string;
   value?: Code | null;
   onSelect: (value: Code) => void;
   placeholder?: string;
diff --git a/src/types/questionnaire/form.ts b/src/types/questionnaire/form.ts
index 4a932eb384b..5ce0489ca2e 100644
--- a/src/types/questionnaire/form.ts
+++ b/src/types/questionnaire/form.ts
@@ -5,7 +5,6 @@ import { MedicationRequest } from "@/types/emr/medicationRequest";
 import { MedicationStatementRequest } from "@/types/emr/medicationStatement";
 import { SymptomRequest } from "@/types/emr/symptom/symptom";
 import { Code } from "@/types/questionnaire/code";
-import { Quantity } from "@/types/questionnaire/quantity";
 import { StructuredQuestionType } from "@/types/questionnaire/question";
 import { CreateAppointmentQuestion } from "@/types/scheduling/schedule";
 
@@ -13,10 +12,10 @@ import { CreateAppointmentQuestion } from "@/types/scheduling/schedule";
  * A short hand for defining response value types
  */
 type RV<T extends string, V> = {
-  value_code?: Code;
-  value_quantity?: Quantity;
+  coding?: Code;
+  unit?: Code;
   type: T;
-  value: V;
+  value?: V;
 };
 
 export type ResponseValue =
@@ -24,6 +23,7 @@ export type ResponseValue =
   | RV<"number", number | undefined>
   | RV<"boolean", boolean | undefined>
   | RV<"dateTime", Date | undefined>
+  | RV<"quantity", number | undefined>
   | RV<"allergy_intolerance", AllergyIntoleranceRequest[]>
   | RV<"medication_request", MedicationRequest[]>
   | RV<"medication_statement", MedicationStatementRequest[]>
diff --git a/src/types/questionnaire/question.ts b/src/types/questionnaire/question.ts
index d99d1c46237..8f696cf6eb7 100644
--- a/src/types/questionnaire/question.ts
+++ b/src/types/questionnaire/question.ts
@@ -87,6 +87,7 @@ export interface Question {
     containerClasses?: string;
   };
   required?: boolean;
+  is_component?: boolean;
   collect_time?: boolean;
   collect_performer?: boolean;
   collect_body_site?: boolean;


Reviews:
user: login: bodhish
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T07:46:46Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (5)</summary><blockquote>

<details>
<summary>src/types/questionnaire/quantity.ts (1)</summary><blockquote>

`12-16`: **Good addition of structured quantity support.**

The new QuestionnaireQuantity interface provides a more structured approach to handling quantities with proper typing for value, unit, and coding properties. This aligns with the PR objective of supporting quantity questions.

However, consider adding a comment explaining the difference between this and the existing Quantity interface to prevent confusion for other developers.



```diff
export interface QuestionnaireQuantity {
  value: number;
  unit: Code;
  coding: Code;
+  // This interface extends the concept of Quantity with structured Code objects
+  // for both unit and coding, supporting valueset options
}
```

</blockquote></details>
<details>
<summary>src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx (1)</summary><blockquote>

`99-101`: **Consider displaying unit information for quantity values.**

When displaying the value of a quantity, only the numeric value is shown without its unit, which could be confusing for users viewing quantity responses.


Consider adding unit display for quantity values:

```diff
<div className="font-medium">
-  {String(value)}
+  {String(value)} {questionResponse.values[0]?.unit?.display || ''}
  {questionResponse.note && (
    <span className="ml-2 text-sm text-gray-500">
      ({questionResponse.note})
    </span>
  )}
</div>
```

</blockquote></details>
<details>
<summary>src/types/questionnaire/form.ts (1)</summary><blockquote>

`22-35`: **Consider removing commented-out code.**

There are several commented-out type definitions that are not currently used. These might be confusing for future developers trying to understand the code.


```diff
-// type RVValue<T extends string, V> = RVBase<T, V> & {
-//   value: V;
-// };
-
-// type RVCode<T extends string> = RVBase<T, Code> & {
-//   value: Code;
-// };
-
-// type RVQuantity<T extends string> = RVBase<T, QuestionnaireQuantity> & {
-//   value: QuestionnaireQuantity;
-// };
-
-// type RV<T extends string, V> = RVValue<T, V> | RVCode<T> | RVQuantity<T>;
```

</blockquote></details>
<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (2)</summary><blockquote>

`1554-1607`: **Enhance UI organization and remove unnecessary Fragment.**

Good implementation of support for both choice and quantity question types. The code properly separates the UI elements with appropriate headers and descriptions for each type.

The Fragment (`<>...</>`) used at lines 1558-1592 is unnecessary since it contains only a single child. Consider removing it:

```diff
- {question.type === "choice" && (
-   <>
-     <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
       // rest of the code
-     </CardHeader>
-   </>
- )}
+ {question.type === "choice" && (
+   <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
      // rest of the code
+   </CardHeader>
+ )}
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Biome (1.9.4)</summary>

[error] 1558-1592: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment


(lint/complexity/noUselessFragments)

</details>

</details>

---

`1629-1632`: **Review the answer_option reset logic.**

The code is setting `answer_option` both in the first parameter and in the additional fields object. This appears redundant and potentially confusing.

```diff
- updateField("answer_option", newOptions, {
-   answer_option: [],
- });
+ updateField("answer_option", newOptions || []);
```

The empty array fallback in the suggested code ensures that if `newOptions` is undefined, an empty array will be used instead, achieving the same safety but with clearer intent.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 0a046d9ec73a21663c9c77d82733b2c1d8405761 and 05812a76694ef3a56592ce29d125f6290b73b176.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx` (1 hunks)
* `src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx` (1 hunks)
* `src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx` (3 hunks)
* `src/components/Questionnaire/QuestionnaireEditor.tsx` (3 hunks)
* `src/components/Questionnaire/QuestionnaireForm.tsx` (2 hunks)
* `src/components/Questionnaire/ValueSetSelect.tsx` (1 hunks)
* `src/types/questionnaire/form.ts` (1 hunks)
* `src/types/questionnaire/quantity.ts` (2 hunks)
* `src/types/questionnaire/question.ts` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Definitions (2)</summary>

<details>
<summary>src/types/questionnaire/form.ts (1)</summary><blockquote>

<details>
<summary>src/types/questionnaire/quantity.ts (1) (1)</summary>

* `QuestionnaireQuantity` (12-16)

</details>

</blockquote></details>
<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (1)</summary><blockquote>

<details>
<summary>src/components/ui/select.tsx (5) (5)</summary>

* `Select` (151-151)
* `SelectTrigger` (154-154)
* `SelectValue` (153-153)
* `SelectContent` (155-155)
* `SelectItem` (157-157)

</details>

</blockquote></details>

</details><details>
<summary>🪛 Biome (1.9.4)</summary>

<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx</summary>

[error] 1558-1592: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment


(lint/complexity/noUselessFragments)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: cypress-run (1)

</details>

<details>
<summary>🔇 Additional comments (21)</summary><blockquote>

<details>
<summary>src/types/questionnaire/question.ts (1)</summary>

`90-90`: **LGTM! The new `is_component` property enhances question flexibility.**

The addition of an optional `is_component` property to the Question interface aligns with the PR objective of adding support for valueset options in choice questions. This property allows for distinguishing between regular questions and component questions.

</details>
<details>
<summary>src/types/questionnaire/quantity.ts (1)</summary>

`1-1`: **Import for Code type looks good.**

The import of the Code type is necessary for the new QuestionnaireQuantity interface.

</details>
<details>
<summary>src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx (1)</summary>

`92-92`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify the value extraction change.**

The simplification of value extraction from `questionResponse.values[0]?.value || questionResponse.values[0]?.value_quantity?.value` to just `questionResponse.values[0]?.value` removes the fallback to quantity values. This could cause display issues for existing quantity responses.


Please verify that all quantity values are properly displayed with this change. It seems the PR introduces a new approach to handling quantities, and this simplification assumes all values (including quantities) will be directly accessible via the `value` property.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check how quantity values are stored in the system
echo "Searching for quantity-related code patterns..."
rg -A 3 "value_quantity" --type ts
```

Length of output: 2110

---

🏁 Script executed:

```shell
#!/bin/bash
# Check how questionResponse.values are used in QuestionnaireResponseView.tsx besides the simplified extraction.
echo "Searching within QuestionnaireResponseView.tsx for any quantity fallback handling..."
rg "questionResponse.values" src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx
```

Length of output: 350

---



</details>

**Action: Confirm Handling of Quantity Responses in QuestionnaireResponseView**

After verification, it appears that the fallback logic for quantity values (previously using `questionResponse.values[0]?.value_quantity?.value`) has been completely removed from the file. The search confirms that this view now only extracts the value via:

```tsx
const value = questionResponse.values[0]?.value;
```

However, other parts of the codebase (e.g., in ObservationsList.tsx and ObservationChart.tsx) still explicitly check for and display quantity values. Please verify through thorough testing that the new approach correctly handles quantity responses in this view—either by ensuring that quantity data is now directly available via the `value` property, or by updating the logic to include a proper fallback if needed.

- **File to check:** `src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx` (Line 92)
- **Concern:** Removed fallback extraction for quantity values may lead to display issues if a response holds only a quantity value.

</details>
<details>
<summary>src/components/Questionnaire/ValueSetSelect.tsx (2)</summary>

`28-28`: **LGTM! Code import is correctly added.**

The import statement for the Code type is properly added, providing access to the necessary type definition.

---

`31-31`: <details>
<summary>✅ Verification successful</summary>

**Type simplification looks good but verify usage.**

Changing the system property type from ValueSetSystem to string simplifies the interface and increases flexibility. This change supports the PR objective of adding valueset options in choice questions.



Verify that all call sites properly handle the string type for system:

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for ValueSetSelect component usage to verify correct system parameter passing
echo "Checking ValueSetSelect component usage..."
rg -A 5 -B 5 "<ValueSetSelect" --type tsx
```

Length of output: 166

---

**Action Required: Re-verify ValueSetSelect usage with updated script settings**  
The current command failed to run due to an unrecognized file type for TSX files. Please re-run the following updated script to verify that all call sites handle the `system` property as a string:



- This script searches through all TSX files for `<ValueSetSelect` component usage.
- After running, please review the output to ensure that each usage passes a string to the `system` prop.
- If necessary, manually verify that the string type is correctly handled across the application.

---

🏁 Script executed:

```shell

#!/bin/bash
echo "Checking ValueSetSelect component usage in TSX files..."
rg -A 5 -B 5 "<ValueSetSelect" --include "*.tsx"
```

Length of output: 735

---

**Action Required: Verify TSX Usage of ValueSetSelect**

The type simplification from `ValueSetSystem` to `string` in the `system` property is appropriate given the PR objective. However, we still need to ensure that all call sites handling `ValueSetSelect` are updated to pass a string for the `system` prop.

To further verify this, please re-run the following updated script which uses a file pattern filter via `rg -g`:



**Next Steps:**
- **If the script produces output:** Review each usage to confirm that the `system` prop is passed as a string.
- **If no output is produced:** Manually verify that the component is either not in use or that the usage conforms to the new string type.

Please perform this verification manually, as the automated search did not produce conclusive output.

---

🏁 Script executed:

```shell

#!/bin/bash
echo "Checking ValueSetSelect component usage in TSX files..."
rg -A 5 -B 5 -g "*.tsx" "<ValueSetSelect"
```

Length of output: 12359

---



</details>

**Final Verification: ValueSetSelect `system` Prop Usage is Correct**

The type simplification to use a string for the `system` property fits the PR objective. Based on the search results:
- All call sites across the codebase use literal strings (e.g., `"system-condition-code"`, `"system-medication"`, etc.) for the `system` prop.
- The few instances where the value is passed dynamically (such as `system={options[activeTab].system}` or `system={question.answer_value_set}`) are presumed to resolve to a string.

The evidence indicates that all usages conform to the new string-based type, and no further modifications are needed.

</details>
<details>
<summary>src/components/Questionnaire/QuestionnaireForm.tsx (3)</summary>

`558-565`: **Good addition of validation for coding and unit.**

The additional validation checks for `coding` and `unit` properties ensure that questions with these properties are properly validated, enhancing the form's ability to handle more complex data types from ValueSet options.

---

`566-566`: **Boolean condition updated correctly.**

The updated condition now correctly checks for any of the three possible value types (value, coding, or unit), which aligns with the expanded response value structure.

---

`661-666`: **Proper handling of response value types.**

The conditional return statements now properly handle the new `coding` and `unit` properties, ensuring these values are correctly passed to the backend when submitting the form.

</details>
<details>
<summary>src/types/questionnaire/form.ts (3)</summary>

`8-8`: **Imported QuestionnaireQuantity type for new quantity support.**

Good addition of the QuestionnaireQuantity import to support the new quantity response type.

---

`15-20`: **Refactored RV type to support ValueSet options.**

The RV type has been properly updated to include optional `coding` and `unit` properties instead of the previous `value_code` and `value_quantity`, making the value property optional as well. This change aligns with the PR objective to support ValueSet options in questions.

---

`41-41`: **Added support for quantity response types.**

Good addition of the `quantity` response type that uses the QuestionnaireQuantity interface. This provides proper typing for quantity responses.

</details>
<details>
<summary>src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx (4)</summary>

`80-85`: **Improved value extraction logic.**

The value extraction has been simplified and improved by extracting the properties into separate constants, making the code more readable and maintainable.

---

`86-86`: **Enhanced validation with both value and coding checks.**

The component now correctly checks for both `value` and `coding` before rendering, ensuring that the component only renders when there's actual data to display.

---

`88-88`: **Smart fallback to question unit.**

The `precedentUnit` variable provides a nice fallback to the question's unit when the response unit is not available, improving the user experience by consistently showing units when available.

---

`96-103`: **Enhanced display of coding and unit information.**

The updated rendering logic properly displays both the unit and coding information when available, showing the coding display and code in parentheses for better readability.

</details>
<details>
<summary>src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx (5)</summary>

`11-12`: **Added ValueSetSelect import for coding selection.**

Good addition of the ValueSetSelect import to handle the selection of coding values from valuesets.

---

`14-14`: **Imported Code type for typing.**

The Code type import is necessary for the new coding functionality and proper type checking.

---

`45-45`: **Added support for getting current coding value.**

Good addition of the `currentCoding` variable to extract the current coding value from the response, enabling proper state management for the ValueSetSelect component.

---

`61-78`: **Implemented robust coding value handler.**

The `handleCodingChange` function properly handles coding values similarly to the existing `handleValueChange` function, ensuring consistent behavior for both types of values.

---

`80-111`: **Added conditional rendering for ValueSet options.**

Good implementation of conditional rendering based on the presence of `question.answer_value_set`. This allows the component to handle both traditional select options and ValueSet-based options.

The filtering of empty options in the standard Select component is also a good addition that prevents users from selecting empty values.

</details>
<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (1)</summary>

`1444-1457`: **Good addition of the component toggle for group questions.**

This new switch component for the `is_component` property is well-integrated into the existing UI, properly conditional on the question type being "group". It enhances the questionnaire structure by allowing group questions to be marked as components.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T07:47:18Z
user: login: bodhish
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-19T07:58:09Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx (1)</summary><blockquote>

`36-41`: **Consider adding validation for the quantity value.**

While the component correctly handles type casting and undefined values, you might want to consider adding validation for minimum/maximum values based on question properties.


```diff
  const currentValue = questionnaireResponse.values[index]?.value as
    | number
    | undefined;
  const currentUnit = questionnaireResponse.values[index]?.unit;
  const currentCoding = questionnaireResponse.values[index]?.coding;
+
+  // Add validation constraints if provided in question properties
+  const minValue = question.min_value_decimal;
+  const maxValue = question.max_value_decimal;
```

Then in the Input component:

```diff
        <Input
          id={`${question.id}-value`}
          type="number"
          value={currentValue?.toString() || ""}
          onChange={(e) => handleValueChange(e.target.value)}
          step="0.01"
+         min={minValue}
+         max={maxValue}
          disabled={disabled}
          className="w-[200px]"
        />
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 05812a76694ef3a56592ce29d125f6290b73b176 and 9174792c1d87eb5f8023ef236a3a7b7ac1dc4ee8.

</details>

<details>
<summary>📒 Files selected for processing (4)</summary>

* `src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx` (1 hunks)
* `src/components/Questionnaire/QuestionTypes/QuestionInput.tsx` (2 hunks)
* `src/components/Questionnaire/QuestionnaireForm.tsx` (2 hunks)
* `src/types/questionnaire/form.ts` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* src/types/questionnaire/form.ts
* src/components/Questionnaire/QuestionnaireForm.tsx

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Definitions (2)</summary>

<details>
<summary>src/components/Questionnaire/QuestionTypes/QuestionInput.tsx (1)</summary><blockquote>

<details>
<summary>src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx (1) (1)</summary>

* `QuantityQuestion` (28-132)

</details>

</blockquote></details>
<details>
<summary>src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx (1)</summary><blockquote>

<details>
<summary>src/types/questionnaire/form.ts (2) (2)</summary>

* `QuestionnaireResponse` (49-58)
* `ResponseValue` (35-47)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (2)</summary>

* GitHub Check: cypress-run (1)
* GitHub Check: Cloudflare Pages: care-fe

</details>

<details>
<summary>🔇 Additional comments (5)</summary><blockquote>

<details>
<summary>src/components/Questionnaire/QuestionTypes/QuestionInput.tsx (2)</summary>

`29-29`: **New import for QuantityQuestion component.**

The import is correctly placed with the other question type component imports.

---

`110-112`: **Added support for "quantity" question type.**

The implementation correctly adds a new case for handling quantity question types using the imported QuantityQuestion component. The common props are passed consistently with other question type components.

</details>
<details>
<summary>src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx (3)</summary>

`1-27`: **Well-structured imports and props interface.**

The component has appropriate imports and a well-defined interface that aligns with other question type components. The props structure follows the established pattern in the codebase.

---

`28-93`: **Clean implementation of QuantityQuestion component.**

The component properly:
- Uses memo for performance optimization
- Extracts current values from the questionnaire response
- Implements handlers for value, unit, and coding changes
- Maintains immutability by creating new arrays before updates
- Clears errors before applying changes

---

`94-131`: **Well-designed UI layout for quantity input.**

The UI layout is clean with appropriate spacing and width constraints. The component conditionally renders the coding type selection based on the presence of an answer_value_set, which aligns with the PR objective of supporting valueset options.

Note that the unit selection uses a hardcoded "system-ucum-units" value. Ensure this is the intended behavior for all quantity questions.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T08:17:30Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (1)</summary><blockquote>

`1557-1594`: **Remove unnecessary Fragment wrapper.**

The Fragment (`<>...</>`) used here is redundant since it only contains a single child element. This was also flagged by the static analysis tool.

```diff
-                {question.type === "choice" && (
-                  <>
-                    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
-                      <div>
-                        <CardTitle className="text-base font-medium">
-                          Answer Options
-                        </CardTitle>
-                        <p className="text-sm text-gray-500">
-                          Define possible answers for this question
-                        </p>
-                      </div>
-                      <Select
-                        value={
-                          question.answer_value_set ? "valueset" : "custom"
-                        }
-                        onValueChange={(val: string) =>
-                          updateField(
-                            "answer_value_set",
-                            val === "custom" ? undefined : "valueset",
-                            { answer_option: [] },
-                          )
-                        }
-                      >
-                        <SelectTrigger className="w-[200px]">
-                          <SelectValue placeholder={t("select_a_value_set")} />
-                        </SelectTrigger>
-                        <SelectContent>
-                          <SelectItem value="custom">
-                            {t("custom_options")}
-                          </SelectItem>
-                          <SelectItem value="valueset">
-                            {t("value_set")}
-                          </SelectItem>
-                        </SelectContent>
-                      </Select>
-                    </CardHeader>
-                  </>
+                {question.type === "choice" && (
+                    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+                      <div>
+                        <CardTitle className="text-base font-medium">
+                          Answer Options
+                        </CardTitle>
+                        <p className="text-sm text-gray-500">
+                          Define possible answers for this question
+                        </p>
+                      </div>
+                      <Select
+                        value={
+                          question.answer_value_set ? "valueset" : "custom"
+                        }
+                        onValueChange={(val: string) =>
+                          updateField(
+                            "answer_value_set",
+                            val === "custom" ? undefined : "valueset",
+                            { answer_option: [] },
+                          )
+                        }
+                      >
+                        <SelectTrigger className="w-[200px]">
+                          <SelectValue placeholder={t("select_a_value_set")} />
+                        </SelectTrigger>
+                        <SelectContent>
+                          <SelectItem value="custom">
+                            {t("custom_options")}
+                          </SelectItem>
+                          <SelectItem value="valueset">
+                            {t("value_set")}
+                          </SelectItem>
+                        </SelectContent>
+                      </Select>
+                    </CardHeader>
                )}
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Biome (1.9.4)</summary>

[error] 1558-1593: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment


(lint/complexity/noUselessFragments)

</details>

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 4316a64514eb4acb2d14c43b3a4b0f601345b17a and b0aec5b7a5b8b3e9f513bc4f54c7109bd3cccd31.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `src/components/Questionnaire/QuestionnaireEditor.tsx` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Definitions (1)</summary>

<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (1)</summary><blockquote>

<details>
<summary>src/components/ui/select.tsx (5) (5)</summary>

* `Select` (151-151)
* `SelectTrigger` (154-154)
* `SelectValue` (153-153)
* `SelectContent` (155-155)
* `SelectItem` (157-157)

</details>

</blockquote></details>

</details><details>
<summary>🪛 Biome (1.9.4)</summary>

<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx</summary>

[error] 1558-1593: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment


(lint/complexity/noUselessFragments)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: cypress-run (1)

</details>

<details>
<summary>🔇 Additional comments (4)</summary><blockquote>

<details>
<summary>src/components/Questionnaire/QuestionnaireEditor.tsx (4)</summary>

`1444-1457`: **Well implemented component flag toggle for group-type questions.**

The addition of the `is_component` switch for group-type questions follows the established UI pattern in the codebase. This implementation is clean and consistent with the existing toggle switches in this section.

---

`1554-1555`: **Good enhancement for supporting multiple question types.**

The condition has been expanded to handle both "choice" and "quantity" question types, which aligns with the PR objective of adding support for valueset options in both question types.

---

`1596-1608`: **Well designed UI for quantity question type.**

The new CardHeader for quantity question types is well implemented, with clear labels and descriptive text that helps users understand the purpose of this option. The UI is consistent with the existing components.

---

`1610-1707`: **Properly handled answer options rendering logic.**

The conditional rendering for choice vs. valueset options is well implemented, with appropriate handling of both cases. I particularly like how the code resets the answer_option to an empty array when changing between valueset and custom options, which prevents potential issues with stale data.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T13:48:02Z

Review comments:
diff_hunk: @@ -89,9 +89,7 @@ export default function QuestionnaireResponseView({
                     );
                     if (!questionResponse) return null;
 
-                    const value =
-                      questionResponse.values[0]?.value ||
-                      questionResponse.values[0]?.value_quantity?.value;
+                    const value = questionResponse.values[0]?.value;
path: src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx
user: login: bodhish
body: I think you don't need to cache value here as its only used once. 
created_at: 2025-03-19T07:46:46Z
author_association: MEMBER
diff_hunk: @@ -55,25 +58,56 @@ export const ChoiceQuestion = memo(function ChoiceQuestion({
     );
   };
 
+  const handleCodingChange = (newValue: Code) => {
+    clearError();
+    const newValues = [...questionnaireResponse.values];
+    newValues[index] = {
+      type: "quantity",
+      coding: {
+        code: newValue.code,
+        system: newValue.system,
+        display: newValue.display,
+      },
+    };
+
+    updateQuestionnaireResponseCB(
+      newValues,
+      questionnaireResponse.question_id,
+      questionnaireResponse.note,
+    );
+  };
   return (
-    <Select
-      value={currentValue}
-      onValueChange={handleValueChange}
-      disabled={disabled}
-    >
-      <SelectTrigger className="w-full">
-        <SelectValue placeholder="Select an option" />
-      </SelectTrigger>
-      <SelectContent>
-        {options.map((option: AnswerOption) => (
-          <SelectItem
-            key={option.value.toString()}
-            value={option.value.toString()}
-          >
-            {properCase(option.display || option.value)}
-          </SelectItem>
-        ))}
-      </SelectContent>
-    </Select>
+    <>
+      {question.answer_value_set ? (
+        <ValueSetSelect
+          system={question.answer_value_set}
+          value={currentCoding}
+          onSelect={handleCodingChange}
+        ></ValueSetSelect>
+      ) : (
+        <Select
+          value={currentValue}
+          onValueChange={handleValueChange}
+          disabled={disabled}
+        >
+          <SelectTrigger className="w-full">
+            <SelectValue placeholder="Select an option" />
+          </SelectTrigger>
+          <SelectContent>
+            {options
+              // TODO: Temporary fix to remove empty options
+              .filter((option) => option.value !== "")
path: src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx
user: login: bodhish
body: I think its fixed, I saw a PR
created_at: 2025-03-19T07:50:20Z
author_association: MEMBER
diff_hunk: @@ -555,7 +555,15 @@ export function QuestionnaireForm({
               (Array.isArray(v.value) ? v.value.length > 0 : true),
           );
 
-          if (!hasValue) {
+          const hasCoding = response?.values?.some(
+            (v) => v.coding !== undefined && v.coding !== null,
+          );
+
+          const hasUnit = response?.values?.some(
+            (v) => v.unit !== undefined && v.unit !== null,
+          );
path: src/components/Questionnaire/QuestionnaireForm.tsx
user: login: bodhish
body: ```suggestion
          const hasProperty = (arr, prop) =>
  Array.isArray(arr) && arr.some((item) => item?.[prop] != null);

const hasCoding = hasProperty(response?.values, 'coding');
const hasUnit = hasProperty(response?.values, 'unit');

```
created_at: 2025-03-19T07:57:06Z
author_association: MEMBER
diff_hunk: @@ -5,25 +5,40 @@ import { MedicationRequest } from "@/types/emr/medicationRequest";
 import { MedicationStatementRequest } from "@/types/emr/medicationStatement";
 import { SymptomRequest } from "@/types/emr/symptom/symptom";
 import { Code } from "@/types/questionnaire/code";
-import { Quantity } from "@/types/questionnaire/quantity";
+import { QuestionnaireQuantity } from "@/types/questionnaire/quantity";
 import { StructuredQuestionType } from "@/types/questionnaire/question";
 import { CreateAppointmentQuestion } from "@/types/scheduling/schedule";
 
 /**
  * A short hand for defining response value types
  */
 type RV<T extends string, V> = {
-  value_code?: Code;
-  value_quantity?: Quantity;
+  coding?: Code;
+  unit?: Code;
   type: T;
-  value: V;
+  value?: V;
 };
 
+// type RVValue<T extends string, V> = RVBase<T, V> & {
+//   value: V;
+// };
+
+// type RVCode<T extends string> = RVBase<T, Code> & {
+//   value: Code;
+// };
+
+// type RVQuantity<T extends string> = RVBase<T, QuestionnaireQuantity> & {
+//   value: QuestionnaireQuantity;
+// };
+
+// type RV<T extends string, V> = RVValue<T, V> | RVCode<T> | RVQuantity<T>;
path: src/types/questionnaire/form.ts
user: login: bodhish
body: Cleanup?
created_at: 2025-03-19T07:57:39Z
author_association: MEMBER

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-19T07:39:24Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This pull request refactors the logic for handling response values and user input in several components. The changes include simplifying value extraction in consultation detail views, enhancing the display logic in questionnaire responses, and adding conditional rendering based on available answer value sets. Additionally, new handling for quantity-type questions is introduced alongside updates in type definitions and editor configurations to support additional properties such as a component flag. Validation logic in the form component has also been extended to cover new fields.

## Changes

| File(s) | Change Summary |
| --- | --- |
| `src/components/Facility/ConsultationDetails/QuestionnaireResponseView.tsx`<br>`src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx` | Simplified extraction of response values by removing fallback logic (e.g., no longer using `value_quantity?.value`) and refined display logic by introducing direct access to `value` as well as handling for `coding` and `unit`. |
| `src/components/Questionnaire/QuestionTypes/ChoiceQuestion.tsx` | Introduced conditional rendering that checks for `question.answer_value_set`. Added a new `ValueSetSelect` import, a `currentCoding` variable, and a `handleCodingChange` method to update the questionnaire response based on coding selection. |
| `src/components/Questionnaire/QuestionnaireEditor.tsx`<br>`src/components/Questionnaire/QuestionnaireForm.tsx`<br>`src/components/Questionnaire/ValueSetSelect.tsx`<br>`src/components/Questionnaire/QuestionTypes/QuestionInput.tsx` | Modified editor and form logic: added a toggle for the `is_component` property, expanded answer options handling for "choice" and "quantity" types, and enhanced validation by checking for coding and unit values. Also, updated the `system` property type in the value set select component. |
| `src/types/questionnaire/form.ts`<br>`src/types/questionnaire/question.ts` | Updated type definitions by replacing `value_code` and `value_quantity` with `coding` and `unit`, making the `value` property optional, and adding an optional `is_component` property to the `Question` interface. |
| `src/components/Questionnaire/QuestionTypes/QuantityQuestion.tsx` | Added a new `QuantityQuestion` component to handle quantity-type questions with dedicated change handlers for value, unit, and coding. The component features a structured UI for number inputs and dropdowns for unit and coding selection. |

## Possibly related issues

- **ohcnetwork/care_fe#11329**: The modifications to the response value extraction and type updates align with backend changes and address similar objectives regarding how response values are structured and handled.

## Possibly related PRs

- **ohcnetwork/care_fe#9644**: The changes in the main PR, which simplify the value extraction logic in the `QuestionnaireResponseView` component, are related to the modifications in the `DiagnosisQuestion` component of the retrieved PR, as both involve updates to how values are processed and displayed, particularly with the introduction of the `ValueSetSelect` component for managing responses.

## Suggested labels

`needs review`

## Suggested reviewers

- rithviknishad
- Jacobjeevan

## Poem

> In the meadow of code, I hop with delight,  
> Tweaking responses to make them just right.  
> With crisp new logic and a skip in my step,  
> Units and codings now gracefully adept.  
> Carrot bytes and joyful hops, our work shines bright!  
> (\_/)( •_•) ( •_•)>⌐■-■  
> Happy coding from your friendly rabbit!

<!-- walkthrough_end -->

<!-- announcements_start -->

> [!TIP]
> <details>
> <summary>⚡🧪 Multi-step agentic review comment chat (experimental)</summary>
> 
> - We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
> 						- To enable this feature, set early_access to true under in the settings.
> 
> </details>

<!-- announcements_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=ohcnetwork/care_fe&utm_content=11394):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: netlify[bot]
created_at: 2025-03-19T07:39:32Z
body: ### <span aria-hidden="true">✅</span> Deploy Preview for *care-ohc* ready!


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | b0aec5b7a5b8b3e9f513bc4f54c7109bd3cccd31 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/care-ohc/deploys/67dac9bad8887000083d62ac |
|<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-11394.preview.ohc.network](https://deploy-preview-11394.preview.ohc.network) |
|<span aria-hidden="true">📱</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br />![QR Code](https://app.netlify.com/qr-code/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTExMzk0LnByZXZpZXcub2hjLm5ldHdvcmsifQ.F0bf7GQ1orgSaAApGn2aQA-sqhSN_PX6R0owkzKoTRk)<br /><br />_Use your smartphone camera to open QR code link._</details> |
---
<!-- [care-ohc Preview](https://deploy-preview-11394.preview.ohc.network) -->
_To edit notification comments on pull requests, go to your [Netlify site configuration](https://app.netlify.com/sites/care-ohc/configuration/notifications#deploy-webhooks)._
author_association: NONE
user: login: cloudflare-workers-and-pages[bot]
created_at: 2025-03-19T07:40:14Z
body: ## Deploying care-fe with &nbsp;<a href="https://pages.dev"><img alt="Cloudflare Pages" src="https://user-images.githubusercontent.com/23264/106598434-9e719e00-654f-11eb-9e59-6167043cfa01.png" width="16"></a> &nbsp;Cloudflare Pages

<table><tr><td><strong>Latest commit:</strong> </td><td>
<code>b0aec5b</code>
</td></tr>
<tr><td><strong>Status:</strong></td><td>🚫&nbsp; Build failed.</td></tr>
</table>

[View logs](https://dash.cloudflare.com/db6d08276fae8cc36808cc6d13f71ca6/pages/view/care-fe/915d790f-61d4-46ff-aaf7-96cc55eac8a1)

author_association: NONE
user: login: cypress[bot]
created_at: 2025-03-19T07:49:22Z
body: 
<h3>
  <a href="https://cloud.cypress.io/projects/wf7d2m?utm_source=github&utm_medium=failed&utm_campaign=project">CARE</a>&nbsp;
  <img src="https://assets.cypress.io/github-pr-comment-icons/chevron.svg" alt="" height="14" width="14" />&nbsp;
  <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?utm_source=github&utm_medium=failed&utm_campaign=run%20number">Run #5309</a>
</h3>

<details>
  <summary>
    <strong>Run Properties:</strong>&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" alt="status check failed" height="10" width="10" />&nbsp;Failed&nbsp;<a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?utm_source=github&utm_medium=failed&utm_campaign=run%20number">#5309</a></code> &nbsp;&bull;&nbsp;
    <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/ohcnetwork/care_fe/commit/b0aec5b7a5b8b3e9f513bc4f54c7109bd3cccd31">b0aec5b7a5</a>: Add Support for Valueset Options in Choice Question & Quantity</code>
  </summary><br />

  <table width="744">
    <tbody>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Project</strong>
        </td>
        <td width="520">
          <code><a href="https://cloud.cypress.io/projects/wf7d2m?utm_source=github&utm_medium=failed&utm_campaign=project">CARE</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td width="224">
          <strong>Branch Review</strong>
        </th>
        <td>
          <code><a href="https://cloud.cypress.io/projects/wf7d2m/branches/valueset_quantity_support/review?utm_source=github&utm_medium=failed&utm_campaign=review%20changes&changeRequest=11394">valueset_quantity_support</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run status</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" alt="status check failed" height="10" width="10" />&nbsp;Failed&nbsp;<a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?utm_source=github&utm_medium=failed&utm_campaign=run%20number">#5309</a></code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Run duration</strong></td>
        <td><code>09m 25s</code></td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Commit</strong></td>
        <td>
          <code><img src="https://assets.cypress.io/github-pr-comment-icons/git-commit.svg" alt="git commit" width="10" height="10" /> <a href="https://github.com/ohcnetwork/care_fe/commit/b0aec5b7a5b8b3e9f513bc4f54c7109bd3cccd31">b0aec5b7a5</a>: Add Support for Valueset Options in Choice Question & Quantity</code>
        </td>
      </tr>
      <tr />
      <tr height="48">
        <td><strong>Committer</strong></td>
        <td><code>Gigin George</code></td>
      </tr>
    </tbody>
    <tfoot>
      <tr />
      <tr height="48">
        <td colspan="2">
          <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/properties?utm_source=github&utm_medium=failed&utm_campaign=properties">View all properties for this run ↗︎</a>
        </td>
      </tr>
    </tfoot>
  </table>
  <hr />
</details>

<table width="744">
  <thead>
    <tr />
    <tr height="48">
      <th colspan="2" align="left" width="744">Test results</th>
    </tr>
  </thead>
  <tbody>
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" alt="Tests that failed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?reviewViewBy=FAILED&utm_source=github&utm_medium=failed&utm_campaign=failed%20tests">
          <strong>Failures</strong>
        </a>
      </td>
      <td>
        <code><strong>1</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/flaky-v3.svg" alt="Tests that were flaky" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?reviewViewBy=FLAKY&utm_source=github&utm_medium=failed&utm_campaign=flaky%20tests">
          <strong>Flaky</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/pending.svg" alt="Tests that did not run due to a developer annotating a test with .skip" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/test-results?utm_source=github&utm_medium=failed&utm_campaign=pending%20tests&statuses=%5B%7B%22value%22%3A%22PENDING%22%2C%22label%22%3A%22PENDING%22%7D%5D">
          <strong>Pending</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/skipped-v3.svg" alt="Tests that did not run due to a failure in a mocha hook" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/test-results?utm_source=github&utm_medium=failed&utm_campaign=skipped%20tests&statuses=%5B%7B%22value%22%3A%22SKIPPED%22%2C%22label%22%3A%22SKIPPED%22%7D%5D">
          <strong>Skipped</strong>
        </a>
      </td>
      <td>
        <code><strong>0</strong></code>
      </td>
    </tr>
    <tr />
    <tr height="48">
      <td width="224">
        <img src="https://assets.cypress.io/github-pr-comment-icons/passed.svg" alt="Tests that passed" width="10" height="10" />&nbsp;
        <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview?utm_source=github&utm_medium=failed&utm_campaign=passed%20tests">
          <strong>Passing</strong>
        </a>
      </td>
      <td>
        <code><strong>11</strong></code>
      </td>
    </tr><tfoot>
    <tr height="48"><td colspan="2"><a href="https://cloud.cypress.io/projects/wf7d2m/branches/valueset_quantity_support/review?utm_source=github&utm_medium=failed&utm_campaign=review%20changes&changeRequest=11394">View all changes introduced in this branch ↗︎</a></td></tr></tfoot>
  </tbody>
</table>


<hr></hr>
<h3>
  Tests for review
</h3>
<details>
  <summary><img src="https://assets.cypress.io/github-pr-comment-icons/failed.svg" width="12" height="12" alt="Failed" />&nbsp; <b> cypress/e2e/facility_spec/facility_creation.cy.ts</b> • 1 failed test  </summary>

  <a href='https://cloud.cypress.io/projects/wf7d2m/runs/5309/test-results?utm_source=github&utm_medium=failed&utm_campaign=view%20spec&specs=%5B%7B%22value%22%3A%22%5B%5C%22150cf2b4-c532-4005-ac0f-7329e6596957%5C%22%5D%22%2C%22label%22%3A%22cypress%2Fe2e%2Ffacility_spec%2Ffacility_creation.cy.ts%22%7D%5D'><code>View</code></a> <a href='https://cloud.cypress.io/projects/wf7d2m/runs/5309/test-results/instance/150cf2b4-c532-4005-ac0f-7329e6596957/stdout?utm_source=github&utm_medium=failed&utm_campaign=view%20spec%20stdout'><code>Output</code></a> 

  <table>
    <tr>
      <th align="left" colspan="2" style="width: 100%">
      Test
      </th>
      <th>Artifacts</th>
    </tr>
      <tr>
        <td colspan="2">
          <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview/3e13e169-8abb-4d5c-a7b9-ca0f40245933?reviewViewBy=FAILED&utm_source=github&utm_medium=failed&utm_campaign=view%20test">
            Facility Management > Create a new facility using the admin role and verify validation errors
          </a>
        </td>
        <td>
          <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/test-results/3e13e169-8abb-4d5c-a7b9-ca0f40245933/replay?utm_source=github&utm_medium=failed&utm_campaign=view%20Test%20Replay">
            <code><b>Test Replay</b></code>
          </a> <a href="https://cloud.cypress.io/projects/wf7d2m/runs/5309/overview/3e13e169-8abb-4d5c-a7b9-ca0f40245933/screenshots?reviewViewBy=FAILED&utm_source=github&utm_medium=failed&utm_campaign=view%20test%20screenshots">
            <code>Screenshots</code>
          </a>
        </td>
      </tr></table>
  </details>


author_association: NONE
user: login: nihal467
created_at: 2025-03-19T10:58:43Z
body: LGTM, we have a unrelated issue where concept code are not verified properly

#### Unrelated Bug

![image](https://github.com/user-attachments/assets/2ac3726a-12b3-49b5-a148-86828c857d82)

When we create a new value set and verify the SNOMED code, even though a success toast is shown on the frontend, the code still remains unverified.

For reference, below is the payload and preview. You can ignore the same code being fetched in three concept fields, as it worked like that earlier.

![image](https://github.com/user-attachments/assets/1abeb333-eb38-4753-911c-788b8a084ad3)
![image](https://github.com/user-attachments/assets/8d356248-0c25-490f-86aa-099162b51c03)


Note: It randomly successfully fetches the code and marks it as system verified.

![image](https://github.com/user-attachments/assets/cae7f758-20b6-4945-b01f-203c9e82604c)

author_association: MEMBER
user: login: github-actions[bot]
created_at: 2025-03-19T14:15:09Z
body: @gigincg Your efforts have helped advance digital healthcare and TeleICU systems. :rocket: Thank you for taking the time out to make CARE better. We hope you continue to innovate and contribute; your impact is immense! :raised_hands:
author_association: NONE