Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questionnaire List & Edit UI Redesign #10678

Merged
merged 20 commits into from
Feb 21, 2025
Merged

Questionnaire List & Edit UI Redesign #10678

merged 20 commits into from
Feb 21, 2025

Conversation

amjithtitus09
Copy link
Contributor

@amjithtitus09 amjithtitus09 commented Feb 18, 2025

@ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate bug / test a new feature.
  • Update product documentation.
  • 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

Summary by CodeRabbit

  • New Features

    • Expanded localization options now enable creating, searching, and managing questionnaires with improved navigation and selection features.
    • The questionnaire editor has been enhanced with organization and tag management capabilities, along with clearer error notifications during cloning.
    • Preview mode now disables data interactions to prevent unintended actions.
  • Style

    • Improved layouts include scrollable content areas, refined date picker behavior, and updated styling for footers and encounter notes for a cleaner, more consistent user experience.

@amjithtitus09 amjithtitus09 requested a review from a team as a code owner February 18, 2025 14:25
Copy link

cloudflare-workers-and-pages bot commented Feb 18, 2025

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4461967
Status: ✅  Deploy successful!
Preview URL: https://a3f7f285.care-fe.pages.dev
Branch Preview URL: https://quest-ui-redesign.care-fe.pages.dev

View logs

Copy link

netlify bot commented Feb 18, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 0394f0f
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67b866f69d353b0008350619
😎 Deploy Preview https://deploy-preview-10678.preview.ohc.network
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@amjithtitus09
Copy link
Contributor Author

Issue created for Questionnaire Preview Redesign #10679

Copy link

cypress bot commented Feb 18, 2025

CARE    Run #4914

Run Properties:  status check passed Passed #4914  •  git commit 70a93a2caf: Questionnaire List & Edit UI Redesign
Project CARE
Branch Review quest-ui-redesign
Run status status check passed Passed #4914
Run duration 06m 54s
Commit git commit 70a93a2caf: Questionnaire List & Edit UI Redesign
Committer Amjith Titus
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 11
View all changes introduced in this branch ↗︎

Copy link
Contributor

coderabbitai bot commented Feb 18, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request implements multiple enhancements across the localization and questionnaire modules. New keys are added to the localization JSON file to support questionnaire creation, navigation, and search functions. Several components have been updated to include an isPreview flag that conditionally disables data fetching. The PR also refactors error handling in the questionnaire cloning process and introduces new UI elements and layout improvements for managing organizations, tags, and other questionnaire properties. Minor UI styling adjustments have been applied to various components for a refined presentation.

Changes

File(s) Change Summary
public/locale/en.json Added new localization entries: create_questionnaire, navigation, properties, retired, select_subject_type, search_questionnaires, and search_organizations.
src/components/Questionnaire/CloneQuestionnaireSheet.tsx Refactored error handling in the clone mutation and added validation to ensure at least one organization is selected.
src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx Updated mutation query key for cache invalidation and adjusted layout for tag management.
src/components/Questionnaire/QuestionRenderer.tsx, src/components/Questionnaire/QuestionTypes/{Allergy,Diagnosis,MedicationRequest,MedicationStatement,Symptom}Question.tsx Introduced an isPreview flag to conditionally disable queries and UI actions for preview modes.
src/components/Questionnaire/QuestionnaireEditor.tsx Added new interfaces and functions (e.g., StatusSelector, OrganizationSelector) for enhanced organization, tag, and layout management in the editor.
src/components/Questionnaire/QuestionnaireForm.tsx Modified to conditionally render submission elements based on the encounterId not being "preview".
src/components/Questionnaire/QuestionnaireList.tsx, src/components/Questionnaire/show.tsx Updated UI elements and icons, modified filtering logic, and adjusted query keys for improved list and detail views.
src/components/ui/input.tsx Added an onFocus handler to display the date picker when the input type is "date".
src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx, src/components/Resource/ResourceForm.tsx, src/pages/Encounters/tabs/EncounterNotesTab.tsx Removed background styling classes (e.g., bg-background) to refine visual presentation in footers and layout areas.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant CB as Clone Button
    participant M as cloneQuestionnaire Mutation
    participant EH as Error Handler
    participant T as Toast

    U->>CB: Click "Clone" button
    CB->>M: Trigger cloneQuestionnaire mutation
    alt Mutation Fails
        M-->>EH: Return error object with details
        EH->>T: Iterate over error messages
        T-->>U: Display each error message
    else Mutation Succeeds
        M-->>CB: Successful clone response
    end
Loading
sequenceDiagram
    participant Q as Question Component
    participant PC as Preview Checker (isPreview)
    participant UQ as useQuery Hook
    participant DF as Data Fetch

    Q->>PC: Check if ID equals "preview"
    alt isPreview is true
        PC-->>UQ: Disable query (enabled: false)
        UQ-->>Q: Skip data fetching (preview mode)
    else isPreview is false
        PC-->>UQ: Enable query
        UQ->>DF: Fetch data from API
        DF-->>UQ: Return data
        UQ-->>Q: Display fetched data
    end
Loading

Possibly related PRs

Suggested labels

tested

Poem

Oh, how I hop with glee under the moon so bright,
New keys and toggles make my code sparkle in the night!
With tags and orgs now dancing in a neat array,
Preview checks ensure smooth hops all day.
My little paws tap to the rhythm of refined UI,
A rabbit’s delight as new features amplify!
🐇✨


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 70a93a2 and 0394f0f.

📒 Files selected for processing (2)
  • public/locale/en.json (8 hunks)
  • src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (2 hunks)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • 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 for this PR. (Beta)
  • @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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (6)
src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx (2)

127-139: 🛠️ Refactor suggestion

Add error handling for API failures.

The useEffect hook should handle potential API errors to prevent silent failures and provide feedback to users.

 const { data: patientAllergies } = useQuery({
+  onError: (error) => {
+    // Handle error appropriately (e.g., show toast notification)
+    console.error('Failed to fetch allergies:', error);
+  },
   queryKey: ["allergies", patientId],
   queryFn: query(allergyIntoleranceApi.getAllergy, {

411-415: 🛠️ Refactor suggestion

Add date format validation.

The last_occurrence date should be validated before updating to prevent invalid dates.

 onChange={(e) =>
+  const date = new Date(e.target.value);
+  if (!isNaN(date.getTime())) {
     handleUpdateAllergy(index, {
       last_occurrence: e.target.value,
     })
+  }
 }
src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx (3)

108-120: ⚠️ Potential issue

Add missing dependencies to useEffect.

The effect uses updateQuestionnaireResponseCB and questionnaireResponse.question_id but they're not included in the dependency array. This could lead to stale closures.

 useEffect(() => {
   if (patientDiagnoses?.results) {
     updateQuestionnaireResponseCB(
       [
         {
           type: "diagnosis",
           value: patientDiagnoses.results.map(convertToDiagnosisRequest),
         },
       ],
       questionnaireResponse.question_id,
     );
   }
-}, [patientDiagnoses]);
+}, [patientDiagnoses, updateQuestionnaireResponseCB, questionnaireResponse.question_id]);

287-298: 🛠️ Refactor suggestion

Add date validation to prevent invalid inputs.

The date input lacks validation constraints which could allow invalid dates to be entered.

 <Input
   type="date"
   value={diagnosis.onset?.onset_datetime || ""}
+  min="1900-01-01"
+  max={new Date().toISOString().split('T')[0]}
   onChange={(e) =>
     onUpdate?.({
       onset: { onset_datetime: e.target.value },
     })
   }
   disabled={disabled || !!diagnosis.id}
   className="h-8 md:h-9"
 />

96-106: 🛠️ Refactor suggestion

Add error and loading states for better user experience.

The query implementation should handle and communicate error and loading states to users.

-const { data: patientDiagnoses } = useQuery({
+const { data: patientDiagnoses, isLoading, error } = useQuery({
   queryKey: ["diagnoses", patientId],
   queryFn: query(diagnosisApi.listDiagnosis, {
     pathParams: { patientId },
     queryParams: {
       encounter: encounterId,
       limit: 100,
     },
   }),
   enabled: encounterId !== "preview",
 });
+
+if (isLoading) {
+  return <div className="text-sm text-gray-500">{t("loading_diagnoses")}</div>;
+}
+
+if (error) {
+  return <div className="text-sm text-red-500">{t("error_loading_diagnoses")}</div>;
+}
src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx (1)

121-128: ⚠️ Potential issue

Add null safety checks for patientMedications.

The current implementation assumes patientMedications is always defined. Add null safety checks to prevent potential runtime errors.

 useEffect(() => {
-  if (patientMedications?.results) {
+  if (patientMedications?.results?.length) {
     updateQuestionnaireResponseCB(
       [{ type: "medication_statement", value: patientMedications.results }],
       questionnaireResponse.question_id,
     );
+  } else if (patientMedications?.results) {
+    // Handle empty results case
+    updateQuestionnaireResponseCB(
+      [{ type: "medication_statement", value: [] }],
+      questionnaireResponse.question_id,
+    );
   }
 }, [patientMedications]);
🧹 Nitpick comments (20)
src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx (1)

290-300: Good optimization, but consider handling preview mode explicitly.

The addition of the enabled option to prevent unnecessary API calls in preview mode is a good optimization. However, consider the following improvements:

  1. Document the preview mode behavior in the component's JSDoc.
  2. Consider explicitly handling the preview mode case in the useEffect hook.

Add JSDoc comments to document the behavior:

+/**
+ * SymptomQuestion component for managing symptoms in a questionnaire.
+ * @remarks
+ * - In preview mode (encounterId === "preview"), the symptoms query is disabled
+ *   and the component will show an empty initial state.
+ */
 export function SymptomQuestion({

Handle preview mode explicitly in the effect:

 useEffect(() => {
+  if (encounterId === "preview") {
+    return; // Exit early for preview mode
+  }
   if (patientSymptoms?.results) {
     updateQuestionnaireResponseCB(
src/components/Questionnaire/QuestionRenderer.tsx (1)

82-82: Consider improving the preview mode implementation.

While the change correctly implements the preview mode behavior, there are a few improvements to consider:

  1. Handle the case when encounterId is undefined to avoid unexpected behavior.
  2. Use a constant for the "preview" value to prevent typos and make refactoring easier.
  3. Consider using a dedicated boolean prop for preview mode instead of overloading encounterId.

Here's a suggested implementation:

+const PREVIEW_ENCOUNTER_ID = "preview";
+
 export function QuestionRenderer({
   questions,
   responses,
   onResponseChange,
   errors,
   clearError,
   disabled,
   activeGroupId,
-  encounterId,
+  encounterId = "",
   facilityId,
   patientId,
 }: QuestionRendererProps) {
   // ...
   <QuestionGroup
     // ...
-    disabled={disabled || encounterId === "preview"}
+    disabled={disabled || encounterId === PREVIEW_ENCOUNTER_ID}
     // ...
   />
   // ...
 }

Alternatively, consider using a dedicated prop:

 interface QuestionRendererProps {
   // ...
   encounterId?: string;
+  isPreview?: boolean;
   // ...
 }

 export function QuestionRenderer({
   // ...
   encounterId,
+  isPreview = false,
   // ...
 }: QuestionRendererProps) {
   // ...
   <QuestionGroup
     // ...
-    disabled={disabled || encounterId === "preview"}
+    disabled={disabled || isPreview}
     // ...
   />
   // ...
 }
src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx (3)

106-113: Consider handling the preview mode in the useEffect.

The useEffect should account for the preview mode to prevent unnecessary state updates.

 useEffect(() => {
-  if (patientMedications?.results) {
+  if (patientMedications?.results && encounterId !== "preview") {
     updateQuestionnaireResponseCB(
       [{ type: "medication_request", value: patientMedications.results }],
       questionnaireResponse.question_id,
     );
   }
-}, [patientMedications]);
+}, [patientMedications, encounterId]);

171-183: Consider using immutable state updates.

The current implementation directly mutates the medication object. Consider using a more immutable approach to prevent potential state-related issues.

 const handleUpdateMedication = (
   index: number,
   updates: Partial<MedicationRequest>,
 ) => {
-  const newMedications = medications.map((medication, i) =>
-    i === index ? { ...medication, ...updates } : medication,
-  );
+  const newMedications = medications.map((medication, i) =>
+    i === index
+      ? { ...medication, ...updates, updatedAt: new Date().toISOString() }
+      : medication,
+  );

   updateQuestionnaireResponseCB(
     [{ type: "medication_request", value: newMedications }],
     questionnaireResponse.question_id,
   );
 };

828-840: Enhance date picker accessibility.

The date picker could benefit from additional accessibility attributes and better error handling.

 <DateTimePicker
   value={
     medication.authored_on
       ? new Date(medication.authored_on)
       : undefined
   }
   onChange={(date) => {
     if (!date) return;
     onUpdate?.({ authored_on: date.toISOString() });
   }}
   disabled={disabled || isReadOnly}
+  aria-label={t("authored_on")}
+  aria-required="true"
+  onError={(error) => {
+    console.error('Date validation error:', error);
+  }}
 />
src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx (2)

408-419: Enhance date input user experience.

Consider adding explicit focus handling to invoke the native date picker when the input receives focus.

 <Input
   type="date"
   value={allergy.last_occurrence || ""}
   onChange={(e) =>
     handleUpdateAllergy(index, {
       last_occurrence: e.target.value,
     })
   }
+  onFocus={(e) => e.target.showPicker?.()}
   disabled={disabled}
   className="h-8 mt-1"
 />

467-475: Improve accessibility of status indicators.

Using only opacity for status indicators may not provide sufficient contrast. Consider adding additional visual cues.

 const rowClassName = `group ${
   allergy.verification_status === "entered_in_error"
-    ? "opacity-40 pointer-events-none"
+    ? "opacity-40 pointer-events-none bg-gray-50"
     : allergy.clinical_status === "inactive"
-      ? "opacity-60"
+      ? "opacity-60 bg-gray-50"
       : allergy.clinical_status === "resolved"
-        ? "line-through"
+        ? "line-through bg-green-50"
         : ""
 }`;
src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx (1)

96-106: LGTM! Good performance optimization.

The addition of the enabled property to prevent unnecessary API calls during preview mode is a good optimization. This aligns well with similar changes in other questionnaire components.

Consider extracting the "preview" string as a constant to maintain consistency across components:

+const PREVIEW_MODE = "preview";
+
 const { data: patientDiagnoses } = useQuery({
   queryKey: ["diagnoses", patientId],
   queryFn: query(diagnosisApi.listDiagnosis, {
     pathParams: { patientId },
     queryParams: {
       encounter: encounterId,
       limit: 100,
     },
   }),
-  enabled: encounterId !== "preview",
+  enabled: encounterId !== PREVIEW_MODE,
 });
src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx (4)

109-119: Good optimization for preview mode, but consider error handling.

The enabled condition is a good optimization to prevent unnecessary API calls in preview mode. However, consider adding error handling and pagination for better reliability.

 const { data: patientMedications } = useQuery({
   queryKey: ["medication_statements", patientId],
   queryFn: query(medicationStatementApi.list, {
     pathParams: { patientId },
     queryParams: {
       limit: 100,
       encounter: encounterId,
     },
   }),
   enabled: encounterId !== "preview",
+  retry: 3,
+  onError: (error) => {
+    // Handle error appropriately
+    console.error('Failed to fetch medications:', error);
+  }
 });

130-140: Add validation for medication code.

The handleAddMedication function should validate the medication code before adding it to prevent invalid data.

 const handleAddMedication = (medication: Code) => {
+  if (!medication?.code || !medication?.display) {
+    console.warn('Invalid medication code:', medication);
+    return;
+  }
   const newMedications: MedicationStatementRequest[] = [
     ...medications,
     { ...MEDICATION_STATEMENT_INITIAL_VALUE, medication },
   ];
   updateQuestionnaireResponseCB(
     [{ type: "medication_statement", value: newMedications }],
     questionnaireResponse.question_id,
   );
   setExpandedMedicationIndex(newMedications.length - 1);
 };

225-248: Enhance table header accessibility.

The table header could benefit from improved accessibility attributes for better screen reader support.

-<div className="hidden lg:grid grid-cols-[300px,180px,170px,250px,260px,190px,200px,48px] bg-gray-50 border-b text-sm font-medium text-gray-500">
+<div 
+  role="row"
+  className="hidden lg:grid grid-cols-[300px,180px,170px,250px,260px,190px,200px,48px] bg-gray-50 border-b text-sm font-medium text-gray-500">
-  <div className="font-semibold text-gray-600 p-3 border-r">
+  <div role="columnheader" className="font-semibold text-gray-600 p-3 border-r">
     {t("medicine")}
   </div>
   // Apply similar changes to other header cells
 </div>

378-384: Optimize component rendering with React.memo.

The MedicationStatementGridRow component could benefit from memoization to prevent unnecessary re-renders.

-const MedicationStatementGridRow: React.FC<MedicationStatementGridRowProps> = ({
+const MedicationStatementGridRow = React.memo<MedicationStatementGridRowProps>(({
   medication,
   disabled,
   onUpdate,
   onRemove,
   index,
-}) => {
+}) => {
   // Component implementation
-};
+});
src/components/Questionnaire/QuestionnaireEditor.tsx (6)

67-67: Unused ObservationType state variable.
const [observation, setObservation] = useState<ObservationType | undefined>(); is declared but never used. Consider removing it if it's not part of a planned future feature.

Also applies to: 614-614


103-147: New interfaces and props typings.
These interfaces (Organization, StylingMetadata, OrganizationResponse, TagResponse, QuestionnairePropertiesProps) look well-structured. However, the QuestionnairePropertiesProps is quite large; consider splitting it into smaller, domain-specific props if it grows further.


344-446: TagSelector logic.
Mirrors the approach of OrganizationSelector. Consider refactoring common code to avoid duplication (e.g., shared “Selector” component).


772-779: handleToggleTag function.
Identical to handleToggleOrganization; potential duplication. You could unify toggling logic with a single helper to reduce repetition.


808-815: Tab triggers for “edit” and “preview.”
The icons and labels look correct. Consider adding i18n translations for "Edit form" / "Preview form" if they're user-facing.


894-917: Duplicated QuestionnaireProperties in mobile vs. desktop.
The approach of rendering properties differently for mobile (lg:hidden) vs. desktop (hidden lg:block) works, but if the logic grows, consider refactoring into a single responsive layout to avoid duplication.

Also applies to: 1064-1088

src/components/Questionnaire/QuestionnaireList.tsx (1)

130-156: Consider adding loading state for description popover.

While the popover implementation is good, consider showing a loading state when fetching detailed content to improve user experience.

 <PopoverContent className="w-80">
   <div className="space-y-2">
+    {isLoading ? (
+      <div className="flex items-center justify-center py-4">
+        <Loader2 className="h-4 w-4 animate-spin" />
+      </div>
+    ) : (
     <h4 className="font-medium">{questionnaire.title}</h4>
     <p className="text-sm text-gray-600">
       {questionnaire.description}
     </p>
+    )}
   </div>
 </PopoverContent>
src/components/Questionnaire/QuestionnaireForm.tsx (1)

466-527: Consider extracting form actions into a separate component.

The form actions section (search and buttons) is quite large. Consider extracting it into a separate component for better maintainability.

+interface FormActionsProps {
+  questionnaireForms: QuestionnaireFormState[];
+  subjectType?: string;
+  onSelect: (selected: QuestionnaireDetail) => void;
+  onCancel?: () => void;
+  onSubmit: () => void;
+  isPending: boolean;
+  hasErrors: boolean;
+}
+
+function FormActions({
+  questionnaireForms,
+  subjectType,
+  onSelect,
+  onCancel,
+  onSubmit,
+  isPending,
+  hasErrors,
+}: FormActionsProps) {
+  return (
+    <>
+      <div className="flex gap-4 items-center m-4 max-w-4xl">
+        <QuestionnaireSearch
+          subjectType={subjectType}
+          onSelect={onSelect}
+          disabled={isPending}
+        />
+      </div>
+      {questionnaireForms.length > 0 && (
+        <div className="flex justify-end gap-4 mx-4 mt-4 max-w-4xl">
+          <Button
+            type="button"
+            variant="outline"
+            onClick={onCancel}
+            disabled={isPending}
+          >
+            {t("cancel")}
+          </Button>
+          <Button
+            type="submit"
+            onClick={onSubmit}
+            disabled={isPending || hasErrors}
+            className="relative"
+          >
+            {isPending ? (
+              <>
+                <span className="opacity-0">{t("submit")}</span>
+                <div className="absolute inset-0 flex items-center justify-center">
+                  <div className="h-5 w-5 animate-spin rounded-full border-b-2 border-white" />
+                </div>
+              </>
+            ) : (
+              t("submit")
+            )}
+          </Button>
+        </div>
+      )}
+    </>
+  );
+}

Then use it in the main component:

-{encounterId !== "preview" && (
-  <>
-    <div className="flex gap-4 items-center m-4 max-w-4xl">
-      ...
-    </div>
-    {questionnaireForms.length > 0 && (
-      <div className="flex justify-end gap-4 mx-4 mt-4 max-w-4xl">
-        ...
-      </div>
-    )}
-  </>
-)}
+{encounterId !== "preview" && (
+  <FormActions
+    questionnaireForms={questionnaireForms}
+    subjectType={subjectType}
+    onSelect={(selected) => {
+      if (questionnaireForms.some((form) => form.questionnaire.id === selected.id)) {
+        return;
+      }
+      setQuestionnaireForms((prev) => [
+        ...prev,
+        {
+          questionnaire: selected,
+          responses: initializeResponses(selected.questions),
+          errors: [],
+        },
+      ]);
+    }}
+    onCancel={onCancel}
+    onSubmit={handleSubmit}
+    isPending={isPending}
+    hasErrors={hasErrors}
+  />
+)}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2fd019f and b8ee52a.

📒 Files selected for processing (15)
  • eslint.config.mjs (1 hunks)
  • public/locale/en.json (8 hunks)
  • src/components/Questionnaire/CloneQuestionnaireSheet.tsx (3 hunks)
  • src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (3 hunks)
  • src/components/Questionnaire/QuestionRenderer.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionnaireEditor.tsx (21 hunks)
  • src/components/Questionnaire/QuestionnaireForm.tsx (1 hunks)
  • src/components/Questionnaire/QuestionnaireList.tsx (3 hunks)
  • src/components/Questionnaire/show.tsx (3 hunks)
  • src/components/ui/input.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/Questionnaire/show.tsx
🔇 Additional comments (31)
src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx (1)

94-104: LGTM! Good optimization to prevent unnecessary API calls.

The addition of the enabled property to prevent API calls during preview mode is a good performance optimization.

src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx (1)

116-125: LGTM! Efficient handling of preview mode.

The addition of the enabled property to prevent unnecessary API calls during preview mode is a good optimization.

src/components/Questionnaire/QuestionnaireEditor.tsx (16)

3-11: New icon imports from lucide-react.
The newly introduced icons appear properly used in this file (e.g., SquarePenIcon for "Preview form"). No issues noted.


17-17: cn import usage.
The cn helper is used consistently to conditionally merge class names. No concerns here.


79-79: Import of QuestionnaireTagModel.
The import is utilized in newly introduced tag-related selectors. This inclusion is valid.


82-85: Imports for sheets.
CloneQuestionnaireSheet and ManageQuestionnaireTagsSheet are referenced later. All good.


149-185: StatusSelector implementation.
Nicely encapsulates radio button logic for questionnaire status (active, draft, retired). The code is clear, with proper translation for each label.


187-229: SubjectTypeSelector implementation.
Similar to StatusSelector, this well-structured radio button group is easy to extend in the future (e.g., more subject types).


231-342: OrganizationSelector logic.
Provides a read-only view when id is specified (edit mode), and a dynamic selection view when creating a new questionnaire. This is a clean approach.


448-513: QuestionnaireProperties component.
Good breakdown of different property selectors (status, subject type, organizations, tags). The 'version' field is disabled, so if versioning is changed in the future, ensure there's a path for updates.


515-603: LAYOUT_OPTIONS and LayoutOptionCard.
Defines multiple grid layouts for grouping sub-questions. This is robust and user-friendly.


611-613: States for tags and tag search query.
Like organization states, these are well-defined. No immediate concerns.


628-656: Data fetching hooks for organizations and tags.
The react-query usage is consistent with the rest of the codebase. Consider advanced caching strategies if data grows large.


819-820: Styling changes for the editor layout.
Adopting a responsive split (flex-col md:flex-row) is a good approach for multi-device support.


1006-1008: Styling updates and new index prop usage for QuestionEditor.
Allows better control over question ordering and highlighting. Implementation looks sensible.

Also applies to: 1009-1058


1197-1220: Collapsible header and expanded state changes.
Clear toggling behavior using ChevronsDownUp vs. ChevronsUpDown. No issues.


1466-1505: New group layout options.
Encapsulated in a RadioGroup to set containerClasses. This fosters flexible nested layouts and is well done.


1645-1732: Sub-question management under type "group".
Matches the top-level question approach, allowing indefinite nesting. Implementation is straightforward and consistent.

src/components/ui/input.tsx (1)

16-21: Automatic date picker invocation.
Calling showPicker() is convenient for date inputs, but not all browsers support it. Consider a fallback for broader compatibility, or confirm that the target user base supports this feature.

eslint.config.mjs (1)

69-70: Changed lint rules from "error" to "warn".
Lowering severity for @typescript-eslint/no-unused-vars and @typescript-eslint/no-unused-expressions may allow minor code smells to accumulate. Verify this is intentional for development flexibility.

Also applies to: 77-78

src/components/Questionnaire/QuestionnaireList.tsx (2)

3-10: LGTM! Well-structured imports.

The imports are well-organized, separating UI components and icons. The addition of lucide-react icons and UI components enhances the visual experience.

Also applies to: 14-21


58-90: Great implementation of filtering functionality!

The implementation of tabs and search provides a clean and intuitive way to filter questionnaires. The use of flex layout ensures good responsiveness.

src/components/Questionnaire/CloneQuestionnaireSheet.tsx (1)

215-217: LGTM! Improved validation logic.

The addition of organization selection validation ensures data integrity.

src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (2)

73-74: LGTM! Consistent query key naming.

The update to use "questionnaireDetail" as the query key maintains consistency across components.


155-280: Great implementation of scrollable content!

The ScrollArea implementation improves the user experience by handling overflow content elegantly while maintaining accessibility.

public/locale/en.json (6)

658-658: New Localization Entry for Creating a Questionnaire Added.
The new key "create_questionnaire": "Create Questionnaire" is clear, concise, and consistent with existing naming conventions for similar actions. Please verify that this key is correctly referenced in the questionnaire creation UI components.


1390-1390: New Localization Entry for Navigation Added.
The entry "navigation": "Navigation" is straightforward and fits well within the context of interface labels. Ensure that any updated navigation components in the redesign properly consume this key for internationalization.


1749-1749: New Localization Key for Properties Added.
The "properties": "Properties" entry follows the same style as other keys in the file. Please confirm that UI elements that display properties are updated to use this new key where appropriate.


1885-1885: New Localization Key for Retired Status Added.
The "retired": "Retired" entry is succinct and clear. Verify that any status indicators or filters that denote a “retired” state are now referring to this key to maintain consistency across the application.


1968-1968: New Localization Key for Searching Questionnaires Added.
The entry "search_questionnaires": "Search Questionnaires" is descriptive and aligned with other search-related keys. Please double-check that the questionnaire search functionality leverages this key to display accurate UI text.


2025-2025: New Localization Key for Subject Type Selection Added.
The "select_subject_type": "Select Subject Type" entry is clear and user-friendly. Ensure that any dropdowns or selection components in the questionnaire editing process are updated to use this key.

@nihal467
Copy link
Member

nihal467 commented Feb 19, 2025

image

  • keep the left side (Navigation) and right side (Questionnaire) card width static, currently its dynamic width management based on question heading text is weird

image

  • add * to the organisation
  • add missing i18n translation for the place holder

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/components/Questionnaire/QuestionnaireEditor.tsx (2)

103-147: LGTM! Well-structured interfaces with clear type definitions.

The interfaces are well-organized and provide good type safety. The QuestionnairePropertiesProps interface effectively encapsulates all the necessary properties for organization and tag management.

Consider splitting the large QuestionnairePropertiesProps interface into smaller, focused interfaces for better maintainability:

+interface SelectionConfig<T> {
+  selectedIds: string[];
+  onToggle: (id: string) => void;
+  searchQuery: string;
+  setSearchQuery: (query: string) => void;
+  available?: T;
+  isLoading?: boolean;
+}
+
 interface QuestionnairePropertiesProps {
   questionnaire: QuestionnaireDetail;
   updateQuestionnaireField: <K extends keyof QuestionnaireDetail>(
     field: K,
     value: QuestionnaireDetail[K],
   ) => void;
   id?: string;
   organizations?: OrganizationResponse;
-  organizationSelection: {
-    selectedIds: string[];
-    onToggle: (orgId: string) => void;
-    searchQuery: string;
-    setSearchQuery: (query: string) => void;
-    available?: OrganizationResponse;
-    isLoading?: boolean;
-  };
+  organizationSelection: SelectionConfig<OrganizationResponse>;
   tags?: QuestionnaireTagModel[];
-  tagSelection: {
-    selectedIds: string[];
-    onToggle: (tagId: string) => void;
-    searchQuery: string;
-    setSearchQuery: (query: string) => void;
-    available?: TagResponse;
-    isLoading?: boolean;
-  };
+  tagSelection: SelectionConfig<TagResponse>;
 }

231-446: Reduce code duplication in selector components.

The OrganizationSelector and TagSelector components share very similar code patterns, especially in their Command components and Badge rendering logic.

Consider creating a reusable EntitySelector component:

interface EntitySelectorProps<T> {
  id?: string;
  entities?: T[];
  selection: {
    selectedIds: string[];
    onToggle: (id: string) => void;
    searchQuery: string;
    setSearchQuery: (query: string) => void;
    available?: { results: T[] };
    isLoading?: boolean;
  };
  labels: {
    none: string;
    search: string;
    notFound: string;
    manage: string;
  };
  renderBadge: (entity: T) => React.ReactNode;
  renderItem: (entity: T) => React.ReactNode;
  ManageSheet: React.ComponentType<any>;
}

This would reduce duplication and make the code more maintainable.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b8ee52a and 3391699.

📒 Files selected for processing (1)
  • src/components/Questionnaire/QuestionnaireEditor.tsx (21 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test
  • GitHub Check: OSSAR-Scan
  • GitHub Check: cypress-run (1)
  • GitHub Check: OSSAR-Scan
🔇 Additional comments (2)
src/components/Questionnaire/QuestionnaireEditor.tsx (2)

819-1089: Well-implemented responsive layout system.

The three-column layout with proper responsive breakpoints is well-implemented. The navigation and properties panels are appropriately hidden/shown based on screen size.


1466-1504: Excellent implementation of group layout options.

The layout options for group questions are well-implemented with:

  • Clear visual previews
  • Responsive grid layout
  • Consistent styling with the design system
  • Good use of RadioGroup for option selection

@amjithtitus09
Copy link
Contributor Author

@nihal467 Done

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
src/components/Questionnaire/QuestionnaireEditor.tsx (3)

809-817: Improve icon and text alignment in tab triggers.

The icon and text alignment in tab triggers could be improved for better visual consistency.

-          <TabsTrigger value="edit">
-            <ViewIcon className="w-4 h-4 mr-2" />
-            Edit form
-          </TabsTrigger>
-          <TabsTrigger value="preview">
-            <SquarePenIcon className="w-4 h-4 mr-2" />
-            Preview form
-          </TabsTrigger>
+          <TabsTrigger value="edit" className="flex items-center">
+            <ViewIcon className="w-4 h-4 mr-2" />
+            <span>Edit form</span>
+          </TabsTrigger>
+          <TabsTrigger value="preview" className="flex items-center">
+            <SquarePenIcon className="w-4 h-4 mr-2" />
+            <span>Preview form</span>
+          </TabsTrigger>

846-847: Enhance navigation button accessibility.

The navigation button could benefit from improved accessibility.

-            className={`w-full text-left px-3 py-2 text-sm rounded-md hover:bg-gray-200 flex items-center gap-2 ${
+            className={`w-full text-left px-3 py-2 text-sm rounded-md hover:bg-gray-200 focus:ring-2 focus:ring-primary-500 focus:outline-none flex items-center gap-2 ${

1681-1685: Enhance sub-question container styling.

The sub-question container styling is well-structured but could benefit from visual hierarchy improvements.

-                  <div
-                    key={subQuestion.id}
-                    id={`question-${subQuestion.id}`}
-                    className="relative bg-white rounded-lg shadow-md"
-                  >
+                  <div
+                    key={subQuestion.id}
+                    id={`question-${subQuestion.id}`}
+                    className="relative bg-white rounded-lg shadow-md transition-shadow hover:shadow-lg"
+                  >
public/locale/en.json (4)

658-658: New Localization Key for "Create Questionnaire"
The key "create_questionnaire": "Create Questionnaire" is added to support the new questionnaire creation UI. The wording is clear and aligns with existing naming conventions.


1749-1749: New "Properties" Entry
The new key "properties": "Properties" provides a label for properties. Ensure that the term “Properties” is contextually clear to users (e.g., whether referring to application settings, questionnaire properties, etc.).


2026-2026: New "Select Subject Type" Prompt
The entry "select_subject_type": "Select Subject Type" is introduced to facilitate user prompts when picking a subject type. Please verify that the usage distinguishes it from any non-prompt labels and that an asterisk or other indicator is applied where required by design.


2135-2135: New "Subject Type" Label
The key "subject_type": "Subject Type" is added. There is potential overlap with "select_subject_type"; please double-check that they are used in distinct contexts (e.g., one for a dropdown prompt vs. a plain label) to avoid redundancy.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3391699 and 0a50f3c.

📒 Files selected for processing (2)
  • public/locale/en.json (8 hunks)
  • src/components/Questionnaire/QuestionnaireEditor.tsx (21 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: cypress-run (1)
  • GitHub Check: Cloudflare Pages: care-fe
🔇 Additional comments (8)
src/components/Questionnaire/QuestionnaireEditor.tsx (3)

740-740: Remove console.log statement.

Remove debugging console.log statement from production code.

-      console.log("Update Questionnaire", questionnaire);

821-823: Improve responsive layout structure.

The layout structure has been improved with responsive classes, but there's room for better organization.

The use of md:flex-row and md:w-60 for the navigation sidebar, along with the transparent card styling, creates a clean and responsive layout. The header alignment with flex-row items-center justify-between is also well implemented.

Also applies to: 968-969


1468-1506: Well-implemented group layout options.

The group layout options implementation is clean and user-friendly.

The use of radio group with visual previews for layout options provides excellent UX. The implementation includes:

  • Clear visual feedback with preview
  • Proper styling for selected state
  • Responsive grid layout
  • Accessible form controls
public/locale/en.json (5)

1390-1390: Addition of "Navigation" Label
The entry "navigation": "Navigation" is introduced. Verify that its usage in the UI aligns with the intended static label for the navigation section as mentioned in the redesign feedback.


1885-1885: Addition of "Retired" Label
The entry "retired": "Retired" has been added. This should be consistent with similar status labels in the system. Confirm its usage across components that indicate a retired state.


1966-1966: New "Search Organizations" Localization Key
The key "search_organizations": "Search Organizations" is added. This entry complements other search functionality keys and is worded clearly.

Likely an incorrect or invalid review comment.


1969-1969: New "Search Questionnaires" Entry
The key "search_questionnaires": "Search Questionnaires" is now available. Ensure that its styling and usage in the UI are consistent with similar search keys for entities like patients and facilities.


2372-2372: Addition of "Version" Label
The entry "version": "Version" is provided. This key will likely support display of the application's version info (for example, in a footer or about section). Its simplicity is appropriate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amjithtitus09, it’s not redirecting back after a successful edit. Should it?

Line 675

amjithtitus09 and others added 2 commits February 20, 2025 16:56
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/components/Questionnaire/QuestionnaireEditor.tsx (1)

671-681: ⚠️ Potential issue

Add navigation after successful update.

Based on the past review comment, the code doesn't redirect after a successful edit. Consider adding navigation similar to the create flow.

 const { mutate: updateQuestionnaire, isPending: isUpdating } = useMutation({
   mutationFn: mutate(questionnaireApi.update, {
     pathParams: { id: id! },
   }),
   onSuccess: () => {
     toast.success("Questionnaire updated successfully");
+    navigate(`/admin/questionnaire/${id}`);
   },
   onError: (_error) => {
     toast.error("Failed to update questionnaire");
   },
 });
🧹 Nitpick comments (4)
src/components/Questionnaire/QuestionnaireEditor.tsx (4)

103-107: Consider making the organization name more descriptive.

The Organization interface could benefit from additional validation or constraints on the name field, such as minimum length or format requirements, to ensure meaningful organization names.

 interface Organization {
   id: string;
-  name: string;
+  name: string; // @minLength(2) @pattern(^[a-zA-Z0-9\s-]+$)
   description?: string;
 }

473-482: Add aria-required attribute for better accessibility.

The organization selector is marked as required with an asterisk, but missing the aria-required attribute for screen readers.

 <Label>
   {t("organizations")} <span className="text-red-500">*</span>
 </Label>
 <OrganizationSelector
+  aria-required="true"
   id={id}
   organizations={organizations}
   selection={organizationSelection}
 />

1479-1481: Add type safety for styling metadata.

The styling metadata access could be more type-safe by providing a default value and type checking.

-question.styling_metadata?.containerClasses ||
-LAYOUT_OPTIONS[0].value
+question.styling_metadata?.containerClasses ??
+LAYOUT_OPTIONS[0].value as string

967-1063: Consider extracting question list into a separate component.

The question list rendering logic is complex and could be extracted into a separate component for better maintainability and reusability.

Consider creating a QuestionList component to handle the rendering and management of questions, which would help reduce the complexity of the main component.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3a65239 and 9709690.

📒 Files selected for processing (2)
  • public/locale/en.json (8 hunks)
  • src/components/Questionnaire/QuestionnaireEditor.tsx (20 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cloudflare Pages: care-fe
🔇 Additional comments (7)
public/locale/en.json (7)

659-659: New i18n entry: "create_questionnaire"
The key "create_questionnaire": "Create Questionnaire" is clear and concise. Please ensure that the corresponding UI elements now use this key for their label.


1391-1391: New i18n entry: "navigation"
The entry "navigation": "Navigation" fits well for labeling the navigation section. Verify that its usage is consistent with other similar UI elements in your application.


1750-1750: New i18n entry: "properties"
The key "properties": "Properties" adds a useful label for property sections. Ensure that it is referenced wherever a properties field or panel is displayed to maintain consistency across the UI.


1886-1886: New i18n entry: "retired"
The introduction of "retired": "Retired" appears well-named for indicating a retired status. Please double-check that it aligns with the overall status terminology used in the app.


1967-1967: New i18n entry: "search_organizations"
The new key "search_organizations": "Search Organizations" provides a clear prompt for searching organizations. Confirm that all UI components utilizing organization search reference this key to ensure a unified experience.


1970-1970: New i18n entry: "search_questionnaires"
The key "search_questionnaires": "Search Questionnaires" is appropriate for the redesigned questionnaire listing functionality. Make sure that this new entry is used in the search input or filter related to questionnaires.


2027-2027: New i18n entry: "select_subject_type"
The added entry "select_subject_type": "Select Subject Type" is self-explanatory and will aid in user form interactions. Verify that wherever the subject type selection is required in the UI, this key is properly implemented.

Copy link

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 70a93a2
Status:⚡️  Build in progress...

View logs

Copy link

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 70a93a2
Status: ✅  Deploy successful!
Preview URL: https://d7d14c4a.care-fe.pages.dev
Branch Preview URL: https://quest-ui-redesign.care-fe.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (2)

155-155: Consider using a more flexible height calculation.

The current height calculation using h-[calc(100vh-11rem)] might not work well across all screen sizes and devices. Consider using a more flexible approach or adding responsive breakpoints.

-          <ScrollArea className="h-[calc(100vh-11rem)]">
+          <ScrollArea className="h-[calc(100vh-11rem)] sm:h-[calc(100vh-13rem)] lg:h-[calc(100vh-15rem)]">

283-284: Improve footer styling and positioning.

The footer styling can be improved:

  1. The gray background color makes the border less visible
  2. With ScrollArea, some positioning classes might be redundant
-        <SheetFooter className=" bottom-0 left-0 right-0 p-4 border-t">
-          <div className="flex w-full justify-end gap-4 bg-gray-100">
+        <SheetFooter className="p-4 border-t bg-white">
+          <div className="flex w-full justify-end gap-4">
src/components/Questionnaire/QuestionnaireEditor.tsx (3)

102-141: Add JSDoc documentation to interfaces.

The new interfaces are well-structured but would benefit from JSDoc documentation to improve code maintainability and IDE support.

Add documentation like this:

+/**
+ * Represents an organization entity
+ * @interface Organization
+ * @property {string} id - Unique identifier for the organization
+ * @property {string} name - Name of the organization
+ * @property {string} [description] - Optional description of the organization
+ */
 interface Organization {
   id: string;
   name: string;
   description?: string;
 }

467-469: Add aria-required attribute for better accessibility.

The organization field is marked as required with an asterisk, but should also include the aria-required attribute for better accessibility.

-          <Label>
+          <Label aria-required="true">
             {t("organizations")} <span className="text-red-500">*</span>
           </Label>

510-561: Memoize layout options for better performance.

The LAYOUT_OPTIONS constant includes JSX elements in the preview property. These could be memoized to prevent unnecessary re-renders.

Consider using useMemo for the preview components:

+import { useMemo } from 'react';

-const LAYOUT_OPTIONS = [
+const LAYOUT_OPTIONS = useMemo(() => [
   {
     id: "full-width",
     value: "grid grid-cols-1",
     label: "Full Width",
     preview: (
       <div className="space-y-1 w-full">
         <div className="h-2 w-full bg-gray-200 rounded" />
         <div className="h-2 w-full bg-gray-200 rounded" />
       </div>
     ),
   },
   // ... other options
-] as const;
+], []) as const;
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4461967 and 70a93a2.

📒 Files selected for processing (6)
  • src/components/Questionnaire/CloneQuestionnaireSheet.tsx (4 hunks)
  • src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx (1 hunks)
  • src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (3 hunks)
  • src/components/Questionnaire/QuestionnaireEditor.tsx (19 hunks)
  • src/components/Resource/ResourceForm.tsx (1 hunks)
  • src/pages/Encounters/tabs/EncounterNotesTab.tsx (3 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx
  • src/pages/Encounters/tabs/EncounterNotesTab.tsx
  • src/components/Resource/ResourceForm.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Questionnaire/CloneQuestionnaireSheet.tsx
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: cypress-run (1)
  • GitHub Check: Cloudflare Pages: care-fe
🔇 Additional comments (3)
src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx (2)

26-26: LGTM!

The ScrollArea import is correctly placed and will help manage overflow content while maintaining a fixed footer.


73-73: LGTM!

The query key change to "questionnaireDetail" maintains consistency with similar changes across the codebase.

src/components/Questionnaire/QuestionnaireEditor.tsx (1)

652-661: Add redirection after successful questionnaire creation.

Based on the past review comment, the component doesn't redirect back after a successful edit. Consider adding navigation after successful updates.

Add navigation after successful update:

 const { mutate: createQuestionnaire, isPending: isCreating } = useMutation({
   mutationFn: mutate(questionnaireApi.create),
   onSuccess: (data: QuestionnaireDetail) => {
     toast.success("Questionnaire created successfully");
     navigate(`/admin/questionnaire/${data.slug}`);
   },
   onError: (_error) => {
     toast.error("Failed to create questionnaire");
   },
 });

 const { mutate: updateQuestionnaire, isPending: isUpdating } = useMutation({
   mutationFn: mutate(questionnaireApi.update, {
     pathParams: { id: id! },
   }),
   onSuccess: () => {
     toast.success("Questionnaire updated successfully");
+    navigate(`/admin/questionnaire/${id}`);
   },
   onError: (_error) => {
     toast.error("Failed to update questionnaire");
   },
 });

});

const { data: availableTags, isLoading: isLoadingAvailableTags } = useQuery({
queryKey: ["tags", tagSearchQuery],
Copy link
Member

@rithviknishad rithviknishad Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's keep the key more verbose. this could be mixed up with other tags (maybe patient tags when it comes up)

Suggested change
queryKey: ["tags", tagSearchQuery],
queryKey: ["questinnaire_tags", tagSearchQuery],

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alrighty

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Feb 21, 2025
Copy link

Conflicts have been detected against the base branch. Please merge the base branch into your branch.
cc: @amjithtitus09

See: https://docs.ohc.network/docs/contributing#how-to-resolve-merge-conflicts

Copy link

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0394f0f
Status:⚡️  Build in progress...

View logs

@amjithtitus09 amjithtitus09 merged commit da97c2f into develop Feb 21, 2025
7 of 13 checks passed
@amjithtitus09 amjithtitus09 deleted the quest-ui-redesign branch February 21, 2025 11:44
Copy link

@amjithtitus09 Your efforts have helped advance digital healthcare and TeleICU systems. 🚀 Thank you for taking the time out to make CARE better. We hope you continue to innovate and contribute; your impact is immense! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge conflict pull requests with merge conflict needs review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error message should be clear Bug: Create Button for tag creation in questionnaire is not working
6 participants