Repository: ohcnetwork/care_fe
Pull request #10841: Status Filters and Search for valueset list
Author: login: AdityaJ2305
Labels: name: needs review
name: Tested
Created: 2025-02-27T07:41:02Z | Merged: 2025-03-04T12:12:14Z

## Proposed Changes

- Fixes #10772 
- [x] cacheblacklist for questionnaire
- [x] minor typo changes for questionnaire in en.json
- [x] Status filter and search for valueset  
- [x] Added disableCache prop to disable caching entirely 

@rithviknishad @Jacobjeevan  Updated the checklist 👆 😅 

@ohcnetwork/care-fe-code-reviewers

## Merge Checklist

- [ ] Add specs that demonstrate bug / test a new feature.
- [ ] Update [product documentation](https://docs.ohc.network).
- [x] Ensure that UI text is kept in I18n files.
- [ ] Prep screenshot or demo video for changelog entry, and attach it to issue.
- [x] Request for Peer Reviews
- [ ] Completion of QA


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
	- Updated UI text for managing questionnaires and value sets, including clear labels for creating, viewing, and searching.
	- Enhanced the value set management interface with a new search field and tabbed filtering options by status.
	- Improved loading state handling for a smoother user experience.
	- Introduced an option to disable caching in data retrieval for more up-to-date results.
	- New icons and components added to the ValueSetList for improved functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Linked issue #10772: Feat: Add search functionality for valueset by name and status
Is your feature request related to a problem? Please describe.
Currently there is no search functionality included in the valueset page. The user has to manually look or scroll down to find the required valueset which is not giving a good user experience.

Describe the solution you'd like
There should be a search functionality which fetches valueset based on name and status like we do have for questionnaire section




Linked issue comments: user: login: AdityaJ2305
created_at: 2025-02-22T18:31:39Z
body: Hey Team, I would like to work on this issue 
author_association: MEMBER
user: login: AdityaJ2305
created_at: 2025-02-27T06:12:17Z
body: Hey @Jacobjeevan @rithviknishad , could you assign me this issue, backend PR just got merged 
author_association: MEMBER

Diff:
diff --git a/public/locale/en.json b/public/locale/en.json
index 9d6df393904..df3f0f18502 100644
--- a/public/locale/en.json
+++ b/public/locale/en.json
@@ -709,6 +709,7 @@
   "create_template": "Create Template",
   "create_user": "Create User",
   "create_user_and_add_to_org": "Create a new user and add them to the organization.",
+  "create_valueset": "Create ValueSet",
   "created": "Created",
   "created_by": "Created By",
   "created_date": "Created Date",
@@ -1411,7 +1412,8 @@
   "make_facility_public": "Make this facility public",
   "make_facility_public_description": "When enabled, this facility will be visible to the public and can be discovered by anyone using the platform",
   "make_multiple_beds_label": "Do you want to make multiple beds?",
-  "manage_and_view_questionnaires": "Manage and view questionnaires",
+  "manage_and_view_questionnaires": "Manage and View Questionnaires",
+  "manage_and_view_valuesets": "Manage and View ValueSets",
   "manage_bed_presets": "Manage Presets of Bed",
   "manage_facility_users": "Manage encounters",
   "manage_my_schedule": "Manage my schedule",
@@ -2106,6 +2108,7 @@
   "search_user": "Search User",
   "search_user_description": "Search for a user and assign a role to add them to the patient.",
   "search_users": "Search users...",
+  "search_valuesets": "Search ValueSets",
   "searching": "Searching...",
   "see_attachments": "See Attachments",
   "see_details": "See Details",
@@ -2501,7 +2504,7 @@
   "valid_year_of_birth": "Please enter a valid year of birth (YYYY)",
   "value": "Value",
   "value_set": "Value Set",
-  "valuesets": "Valuesets",
+  "valuesets": "ValueSets",
   "vehicle_preference": "Vehicle preference",
   "vendor_name": "Vendor Name",
   "ventilator_interface": "Respiratory Support Type",
diff --git a/src/components/Questionnaire/QuestionnaireList.tsx b/src/components/Questionnaire/QuestionnaireList.tsx
index d3ba62e4f70..cdfe453f9e9 100644
--- a/src/components/Questionnaire/QuestionnaireList.tsx
+++ b/src/components/Questionnaire/QuestionnaireList.tsx
@@ -23,6 +23,7 @@ import questionnaireApi from "@/types/questionnaire/questionnaireApi";
 export function QuestionnaireList() {
   const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
 
   const navigate = useNavigate();
diff --git a/src/components/ValueSet/ValueSetList.tsx b/src/components/ValueSet/ValueSetList.tsx
index 360d50e619c..8edeea02175 100644
--- a/src/components/ValueSet/ValueSetList.tsx
+++ b/src/components/ValueSet/ValueSetList.tsx
@@ -1,10 +1,19 @@
 import { useQuery } from "@tanstack/react-query";
-import { PlusIcon } from "lucide-react";
-import { Link, useNavigate } from "raviger";
+import {
+  ArchiveIcon,
+  FileCheckIcon,
+  HelpCircle,
+  NotepadTextDashedIcon,
+  Pencil,
+  PlusIcon,
+  Search,
+} from "lucide-react";
+import { Link } from "raviger";
 import { useTranslation } from "react-i18next";
 
 import { Badge } from "@/components/ui/badge";
 import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
 import {
   Table,
   TableBody,
@@ -13,6 +22,7 @@ import {
   TableHeader,
   TableRow,
 } from "@/components/ui/table";
+import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
 
 import Loading from "@/components/Common/Loading";
 
@@ -23,9 +33,9 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 
 export function ValueSetList() {
   const { t } = useTranslation();
-  const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
@@ -33,106 +43,158 @@ export function ValueSetList() {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name,
+        status: qParams.status || "active",
       },
     }),
   });
 
-  if (isLoading) {
-    return <Loading />;
-  }
-
   const valuesets = response?.results || [];
 
   return (
     <div className="container mx-auto px-4 py-6">
-      <div className="mb-6 flex items-center justify-between">
-        <div>
+      <div className="mb-4 ">
+        <div className="mb-2">
           <h1 className="text-2xl font-bold">{t("valuesets")}</h1>
+          <p className="text-gray-600">{t("manage_and_view_valuesets")}</p>
         </div>
-        <Button asChild>
-          <Link href="/admin/valuesets/create">
-            <PlusIcon className="mr-2 size-4" />
-            {t("create_new")}
-          </Link>
-        </Button>
-      </div>
 
-      <div className="overflow-hidden rounded-lg bg-white shadow">
-        <Table className="min-w-full divide-y divide-gray-200">
-          <TableHeader className="bg-gray-50">
-            <TableRow>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("name")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("slug")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("status")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("description")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("system")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("actions")}
-              </TableHead>
-            </TableRow>
-          </TableHeader>
-          <TableBody className="divide-y divide-gray-200 bg-white">
-            {valuesets.map((valueset) => (
-              <TableRow key={valueset.id} className="hover:bg-gray-50">
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <div className="text-sm font-medium text-gray-900">
-                    {valueset.name}
-                  </div>
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.slug}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <Badge
-                    className={
-                      {
-                        active:
-                          "bg-green-100 text-green-800 hover:bg-green-200",
-                        draft:
-                          "bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
-                        retired: "bg-red-100 text-red-800 hover:bg-red-200",
-                        unknown: "bg-gray-100 text-gray-800 hover:bg-gray-200",
-                      }[valueset.status]
-                    }
-                  >
-                    {t(valueset.status)}
-                  </Badge>
-                </TableCell>
-                <TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
-                  {valueset.description}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.is_system_defined ? t("yes") : t("no")}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm">
-                  {!valueset.is_system_defined && (
-                    <Button
-                      variant="primary"
-                      size="sm"
-                      onClick={() =>
-                        navigate(`/admin/valuesets/${valueset.slug}/edit`)
-                      }
-                    >
-                      {t("edit")}
-                    </Button>
-                  )}
-                </TableCell>
-              </TableRow>
-            ))}
-          </TableBody>
-        </Table>
+        <div className="flex flex-col md:flex-row items-center justify-between mt-8 gap-2">
+          <div className="flex lg:flex-row flex-col items-center gap-4">
+            <Tabs
+              defaultValue="active"
+              value={qParams.status || "active"}
+              onValueChange={(value) => updateQuery({ status: value })}
+              className="w-full"
+            >
+              <TabsList>
+                <TabsTrigger value="active">
+                  <FileCheckIcon className="w-4 h-4 mr-2 " />
+                  {t("active")}
+                </TabsTrigger>
+                <TabsTrigger value="draft">
+                  <NotepadTextDashedIcon className="w-4 h-4 mr-2" />
+                  {t("draft")}
+                </TabsTrigger>
+                <TabsTrigger value="retired">
+                  <ArchiveIcon className="w-4 h-4 mr-2" />
+                  {t("retired")}
+                </TabsTrigger>
+                <TabsTrigger value="unknown">
+                  <HelpCircle className="w-4 h-4 mr-2 " />
+                  {t("unknown")}
+                </TabsTrigger>
+              </TabsList>
+            </Tabs>
+            <div className="relative md:min-w-80 w-full">
+              <Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-500" />
+              <Input
+                placeholder={t("search_valuesets")}
+                className="pl-10"
+                value={qParams.name || ""}
+                onChange={(e) => updateQuery({ name: e.target.value })}
+              />
+            </div>
+          </div>
+          <Button>
+            <Link
+              href="/admin/valuesets/create"
+              className="flex items-center gap-2"
+            >
+              <PlusIcon className="w-4 h-4" />
+              {t("create_valueset")}
+            </Link>
+          </Button>
+        </div>
       </div>
-      <Pagination totalCount={response?.count ?? 0} />
+
+      {isLoading ? (
+        <Loading />
+      ) : (
+        <>
+          <div className="overflow-hidden rounded-lg bg-white shadow">
+            <Table className="min-w-full divide-y divide-gray-200">
+              <TableHeader className="bg-gray-50">
+                <TableRow>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("name")}
+                  </TableHead>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("slug")}
+                  </TableHead>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("status")}
+                  </TableHead>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("description")}
+                  </TableHead>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("system")}
+                  </TableHead>
+                  <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
+                    {t("actions")}
+                  </TableHead>
+                </TableRow>
+              </TableHeader>
+              <TableBody className="divide-y divide-gray-200 bg-white">
+                {valuesets.map((valueset) => (
+                  <TableRow key={valueset.id} className="hover:bg-gray-50">
+                    <TableCell className="whitespace-nowrap px-6 py-4">
+                      <div className="text-sm font-medium text-gray-900">
+                        {valueset.name}
+                      </div>
+                    </TableCell>
+                    <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
+                      {valueset.slug}
+                    </TableCell>
+                    <TableCell className="whitespace-nowrap px-6 py-4">
+                      <Badge
+                        className={
+                          {
+                            active:
+                              "bg-green-100 text-green-800 hover:bg-green-200",
+                            draft:
+                              "bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
+                            retired: "bg-red-100 text-red-800 hover:bg-red-200",
+                            unknown:
+                              "bg-gray-100 text-gray-800 hover:bg-gray-200",
+                          }[valueset.status]
+                        }
+                      >
+                        {t(valueset.status)}
+                      </Badge>
+                    </TableCell>
+                    <TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
+                      {valueset.description}
+                    </TableCell>
+                    <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
+                      {valueset.is_system_defined ? t("yes") : t("no")}
+                    </TableCell>
+                    <TableCell className="whitespace-nowrap px-6 py-4 text-sm">
+                      {!valueset.is_system_defined && (
+                        <Button
+                          variant="outline"
+                          size="sm"
+                          className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
+                        >
+                          <Link
+                            href={`/admin/valuesets/${valueset.slug}/edit`}
+                            className="flex items-center gap-2"
+                          >
+                            <Pencil className="w-4 h-4 mr-0" />
+                            {t("edit")}
+                          </Link>
+                        </Button>
+                      )}
+                    </TableCell>
+                  </TableRow>
+                ))}
+              </TableBody>
+            </Table>
+          </div>
+          <Pagination totalCount={response?.count ?? 0} />
+        </>
+      )}
     </div>
   );
 }
diff --git a/src/hooks/useFilters.tsx b/src/hooks/useFilters.tsx
index a0c10a7a24e..2dba60cbfc9 100644
--- a/src/hooks/useFilters.tsx
+++ b/src/hooks/useFilters.tsx
@@ -26,9 +26,11 @@ interface FilterBadgeProps {
 export default function useFilters({
   limit = 14,
   cacheBlacklist = [],
+  disableCache = false,
 }: {
   limit?: number;
   cacheBlacklist?: string[];
+  disableCache?: boolean;
 }) {
   const { t } = useTranslation();
   const hasPagination = limit > 0;
@@ -40,6 +42,7 @@ export default function useFilters({
   }>({ value: false });
 
   const updateCache = (query: QueryParam) => {
+    if (disableCache) return;
     const blacklist = FILTERS_CACHE_BLACKLIST.concat(cacheBlacklist);
     FiltersCache.set(query, blacklist);
   };


Reviews:
user: login: Jacobjeevan
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-27T08:41:37Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-27T09:28:11Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-27T09:31:13Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

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

<details>
<summary>src/components/ValueSet/ValueSetList.tsx (1)</summary><blockquote>

`166-168`: **Consider adding text truncation with tooltip.**

For description cells that may contain lengthy text, consider adding a tooltip that shows the full description on hover to improve user experience.

```diff
-<TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
+<TableCell 
+  className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal max-w-xs"
+  title={valueset.description}
+>
  {valueset.description}
</TableCell>
```

</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 eb598e996f6fd965a863b6d54c76650a83384e81 and 97e77f28723c83ad8bfbd602ef0fbcedd832f952.

</details>

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

* `src/components/ValueSet/ValueSetList.tsx` (3 hunks)

</details>

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

* GitHub Check: Redirect rules - care-ohc
* GitHub Check: Header rules - care-ohc
* GitHub Check: Pages changed - care-ohc
* GitHub Check: Test
* GitHub Check: cypress-run (1)
* GitHub Check: OSSAR-Scan

</details>

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

<details>
<summary>src/components/ValueSet/ValueSetList.tsx (10)</summary>

`2-10`: **Good organization of imports.**

The imports are well-organized and include all necessary icons for the new UI elements (status tabs and search). This improves code readability.

---

`16-16`: **Appropriate component imports.**

The addition of the Input and Tabs components is appropriate for implementing the search and filter functionality requested in issue #10772.



Also applies to: 25-25

---

`37-40`: **Good use of cacheBlacklist for dynamic filters.**

The implementation of `cacheBlacklist` for "name" and "status" is appropriate since these are dynamic filtering parameters that shouldn't persist in cache. The `updateQuery` function is correctly extracted from the hook for updating these filter parameters.

---

`47-48`: **Default status filter correctly implemented.**

The query parameters now include the name search term and status filter with "active" as the default, which aligns with the UI's default tab selection on line 66.

---

`63-107`: **Well-designed filter and search UI.**

The implementation of status tabs and search functionality is clean and responsive. The flex layout adapts well to different screen sizes with appropriate gap spacing and responsive design (flex-col/flex-row based on viewport size).

The search input with the icon prefix and the status tabs with relevant icons enhance usability, making the interface intuitive.

---

`90-98`: **Search implementation works well with filter state.**

The search input is correctly implemented with:
1. Icon positioning
2. Placeholder text from translations
3. Value derived from query parameters
4. onChange handler that updates the query state

This creates a cohesive user experience when filtering value sets.

---

`65-89`: **Status filter tabs improve usability.**

The tabs implementation provides a clear visual indication of the current filter state, with appropriate icons that enhance understanding. The `onValueChange` handler correctly updates the query parameters using the `updateQuery` function.

---

`110-194`: **Improved loading state handling.**

The conditional rendering approach for the loading state is better than an early return as it maintains layout consistency. When data is loading, only the table area shows the loading indicator while preserving the header and filter UI.

---

`95-96`: **Value and onChange handlers are well implemented.**

The input value correctly uses fallback to empty string when `qParams.name` is undefined or null, which addresses the previous review comment about name handling.

---

`67-68`: **Verify tab selection persistence.**

The tab selection correctly uses the query parameter for its value, ensuring the UI stays synchronized with the URL state. This enables bookmark-friendly URLs and maintains state across page refreshes.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-27T09:37:38Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-27T14:39:54Z
user: login: rithviknishad
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-02-28T09:59:49Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-28T10:14:39Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

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

<details>
<summary>src/components/ValueSet/ValueSetList.tsx (1)</summary><blockquote>

`63-107`: **Improved UI with search and filter tabs**

The implementation of tabs for status filtering and search input provides a more user-friendly interface for managing value sets. Consider adding debouncing to the search input to prevent excessive API calls.


Consider adding debounce functionality to the search input to limit API calls while typing:

```diff
+import { useDebounce } from "@/hooks/useDebounce"; // Add this import if not already available

export function ValueSetList() {
  const { t } = useTranslation();
  const navigate = useNavigate();
+  const [searchTerm, setSearchTerm] = useState("");
+  const debouncedSearchTerm = useDebounce(searchTerm, 500);

+  // Update query when debounced search term changes
+  useEffect(() => {
+    updateQuery({ name: debouncedSearchTerm });
+  }, [debouncedSearchTerm]);

  // Rest of component code...

  // In the search input:
  <Input
    placeholder={t("search_valuesets")}
    className="pl-10"
-    value={qParams.name || ""}
-    onChange={(e) => updateQuery({ name: e.target.value })}
+    value={searchTerm}
+    onChange={(e) => setSearchTerm(e.target.value)}
  />
```

</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 b05d2ac45bcd8ee66ddfcfbc48497c365f46f758 and 317cf2b88897c0b334361827d5ec9a503ef39116.

</details>

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

* `src/components/Questionnaire/QuestionnaireList.tsx` (1 hunks)
* `src/components/ValueSet/ValueSetList.tsx` (3 hunks)
* `src/hooks/useFilters.tsx` (2 hunks)

</details>

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

* src/components/Questionnaire/QuestionnaireList.tsx

</details>

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

* GitHub Check: Test
* GitHub Check: OSSAR-Scan
* GitHub Check: cypress-run (1)

</details>

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

<details>
<summary>src/hooks/useFilters.tsx (1)</summary>

`29-29`: **Feature enhancement: Caching control added to useFilters hook**

Good implementation of the `disableCache` parameter. This gives components like `ValueSetList` and `QuestionnaireList` control over whether to use the cache, allowing for more flexible data fetching strategies.



Also applies to: 33-33, 45-45

</details>
<details>
<summary>src/components/ValueSet/ValueSetList.tsx (5)</summary>

`2-10`: **Organized imports for enhanced UI components**

Good organization of imports for the new UI components and icons. These imports support the new filter and search functionality.

---

`16-16`: **New UI component imports for enhanced functionality**

The addition of `Input` and tab components supports the new search and filter features, which aligns with the PR objective of implementing status filters and search.



Also applies to: 25-25

---

`37-40`: **Added cache control and query management**

Good implementation of the filter hooks with `disableCache: true`. This ensures that the value set list always fetches fresh data instead of using cached results.

---

`47-48`: **Enhanced query parameters for filtering**

The addition of name and status parameters to the API query enables the search and status filtering functionality required by the PR.

---

`110-194`: **Improved loading state and table rendering**

Good use of conditional rendering based on loading state. The table is now only rendered when data is available, providing a better user experience.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-28T10:18:33Z
user: login: rithviknishad
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-03T05:21:21Z
user: login: khavinshankar
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T06:15:27Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T06:17:49Z
user: login: AdityaJ2305
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T06:25:51Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

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

<details>
<summary>src/components/ValueSet/ValueSetList.tsx (4)</summary><blockquote>

`36-39`: **Consider adding a comment explaining the `disableCache` option.**

While you've explained the purpose of `disableCache` in a review comment, it would be helpful to add a code comment explaining its purpose for future maintainers.


```diff
 const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
   limit: 15,
-  disableCache: true,
+  disableCache: true, // Prevents caching of filter state to ensure fresh data on each filter change
 });
```

---

`89-97`: **Consider implementing debounce for the search input.**

The current implementation will trigger a new API request on every keystroke, which might lead to excessive network requests. Consider implementing a debounce mechanism to reduce the number of requests.


```diff
+import { useDebounce } from "@/hooks/useDebounce"; // You may need to create this hook

export function ValueSetList() {
  const { t } = useTranslation();
  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
    limit: 15,
    disableCache: true,
  });
+  const [searchTerm, setSearchTerm] = React.useState(qParams.name || "");
+  
+  // Debounce search term to avoid excessive API calls
+  useDebounce(
+    () => {
+      updateQuery({ name: searchTerm });
+    },
+    300, // 300ms delay
+    [searchTerm]
+  );

  // Rest of your component...

  // Then update the Input component:
  <Input
    placeholder={t("search_valuesets")}
    className="pl-10"
-    value={qParams.name || ""}
-    onChange={(e) => updateQuery({ name: e.target.value })}
+    value={searchTerm}
+    onChange={(e) => setSearchTerm(e.target.value)}
  />
```

---

`173-189`: **Consider extracting the edit button to a separate component.**

The edit button logic for non-system-defined valuesets could be extracted to a separate component to improve readability and maintainability. This would also make it easier to test this specific functionality.


```diff
+// New component (could be defined elsewhere)
+const EditValueSetButton = ({ valueset }) => {
+  const { t } = useTranslation();
+  
+  if (valueset.is_system_defined) {
+    return null;
+  }
+  
+  return (
+    <Button
+      variant="outline"
+      size="sm"
+      className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
+    >
+      <Link
+        href={`/admin/valuesets/${valueset.slug}/edit`}
+        className="flex items-center gap-2"
+      >
+        <Pencil className="w-4 h-4 mr-0" />
+        {t("edit")}
+      </Link>
+    </Button>
+  );
+};

// Then in the table cell:
<TableCell className="whitespace-nowrap px-6 py-4 text-sm">
-  {!valueset.is_system_defined && (
-    <Button
-      variant="outline"
-      size="sm"
-      className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
-    >
-      <Link
-        href={`/admin/valuesets/${valueset.slug}/edit`}
-        className="flex items-center gap-2"
-      >
-        <Pencil className="w-4 h-4 mr-0" />
-        {t("edit")}
-      </Link>
-    </Button>
-  )}
+  <EditValueSetButton valueset={valueset} />
</TableCell>
```

---

`167-169`: **Consider handling long descriptions better.**

While you're using `truncate`, `break-words`, and `whitespace-normal` classes for description cells, consider adding a tooltip or expandable view for very long descriptions to improve user experience.


```diff
-<TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
-  {valueset.description}
-</TableCell>
+<TableCell 
+  className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal max-w-xs"
+  title={valueset.description} // Simple tooltip on hover
+>
+  {valueset.description}
+</TableCell>
```

</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 3c990b0ab18208b63f6cb90bc30323aef924c395 and 0676e128f24cca932be1881447f791149f3d6f34.

</details>

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

* `src/components/ValueSet/ValueSetList.tsx` (3 hunks)

</details>

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

* GitHub Check: cypress-run (1)

</details>

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

<details>
<summary>src/components/ValueSet/ValueSetList.tsx (8)</summary>

`2-10`: **Improved organization of icon imports.**

The icons are now properly grouped into a single import statement from 'lucide-react', which makes the code more maintainable and easier to read.

---

`11-11`: **Link component is now used appropriately.**

The Link from raviger is now used for navigation instead of buttons, addressing a previous review comment correctly.

---

`16-16`: **Good addition of UI components for filtering.**

The addition of Input and Tab components is appropriate for implementing the new search and status filter functionality required in the PR objectives.



Also applies to: 25-25

---

`46-47`: **Good implementation of filter parameters.**

The query parameters for name and status are correctly implemented to support the search and filtering requirements from the PR objectives.

---

`62-108`: **Well-structured and responsive filter UI.**

The implementation of the filters UI is well-organized with:
1. Responsive layout using flex-col/flex-row
2. Clear tab structure for status filtering
3. Search input with appropriate icon
4. Create button positioned correctly

This provides a good user experience across different screen sizes.

---

`111-197`: **Improved loading state handling.**

The conditional rendering of the loading state is now properly implemented, showing a loading indicator when data is being fetched and the table with results when data is available.

---

`150-166`: **Good use of conditional styling for status badges.**

The status badges with different colors for different statuses (active, draft, retired, unknown) provide clear visual feedback about the valueset status. Good implementation of the styling logic.

---

`180-187`: **Same issue with Button+Link nesting as mentioned earlier.**

Similar to the create button, the edit button should be refactored to improve accessibility.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T20:51:38Z
user: login: khavinshankar
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-04T12:12:05Z

Review comments:
diff_hunk: @@ -2479,7 +2482,7 @@
   "valid_year_of_birth": "Please enter a valid year of birth (YYYY)",
   "value": "Value",
   "value_set": "Value Set",
-  "valuesets": "Valuesets",
+  "valuesets": "ValueSets",
path: public/locale/en.json
user: login: Jacobjeevan
body: Let's modify this key and one above to follow singular/plural rules for translation.

https://www.i18next.com/translation-function/plurals
created_at: 2025-02-27T08:38:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    cacheBlacklist: ["name", "status"],
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name || undefined,
path: src/components/ValueSet/ValueSetList.tsx
user: login: Jacobjeevan
body: name should be undefined by default, so this check is unnecessary 🤔 
created_at: 2025-02-27T08:38:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    cacheBlacklist: ["name", "status"],
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name || undefined,
path: src/components/ValueSet/ValueSetList.tsx
user: login: AdityaJ2305
body: Done 
created_at: 2025-02-27T09:28:11Z
author_association: MEMBER
diff_hunk: @@ -2479,7 +2482,7 @@
   "valid_year_of_birth": "Please enter a valid year of birth (YYYY)",
   "value": "Value",
   "value_set": "Value Set",
-  "valuesets": "Valuesets",
+  "valuesets": "ValueSets",
path: public/locale/en.json
user: login: AdityaJ2305
body: @Jacobjeevan, both are used for different purposes. Plural rules should only be applied when they serve the same purpose in the same context
created_at: 2025-02-27T09:31:13Z
author_association: MEMBER
diff_hunk: @@ -2479,7 +2482,7 @@
   "valid_year_of_birth": "Please enter a valid year of birth (YYYY)",
   "value": "Value",
   "value_set": "Value Set",
-  "valuesets": "Valuesets",
+  "valuesets": "ValueSets",
path: public/locale/en.json
user: login: AdityaJ2305
body: There are many places where we have exactly same value. but with different keys , just bcoz of diff purpose of usage 

created_at: 2025-02-27T14:39:54Z
author_association: MEMBER
diff_hunk: @@ -23,6 +23,7 @@ import questionnaireApi from "@/types/questionnaire/questionnaireApi";
 export function QuestionnaireList() {
   const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    cacheBlacklist: ["title", "status"],
   });
path: src/components/Questionnaire/QuestionnaireList.tsx
user: login: rithviknishad
body: can we add a prop to disable cache entirely wherever needed? so that we don't need to specify cacheBlacklist if it's set to true
created_at: 2025-02-28T09:59:33Z
author_association: MEMBER
diff_hunk: @@ -23,6 +23,7 @@ import questionnaireApi from "@/types/questionnaire/questionnaireApi";
 export function QuestionnaireList() {
   const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    cacheBlacklist: ["title", "status"],
   });
path: src/components/Questionnaire/QuestionnaireList.tsx
user: login: AdityaJ2305
body: Done 
created_at: 2025-02-28T10:14:39Z
author_association: MEMBER
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name,
+        status: qParams.status || "active",
       },
     }),
   });
 
-  if (isLoading) {
-    return <Loading />;
-  }
-
   const valuesets = response?.results || [];
 
   return (
     <div className="container mx-auto px-4 py-6">
-      <div className="mb-6 flex items-center justify-between">
-        <div>
+      <div className="mb-4 ">
+        <div className="mb-2">
           <h1 className="text-2xl font-bold">{t("valuesets")}</h1>
+          <p className="text-gray-600">{t("manage_and_view_valuesets")}</p>
         </div>
-        <Button asChild>
-          <Link href="/admin/valuesets/create">
-            <PlusIcon className="mr-2 size-4" />
-            {t("create_new")}
-          </Link>
-        </Button>
-      </div>
 
-      <div className="overflow-hidden rounded-lg bg-white shadow">
-        <Table className="min-w-full divide-y divide-gray-200">
-          <TableHeader className="bg-gray-50">
-            <TableRow>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("name")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("slug")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("status")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("description")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("system")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("actions")}
-              </TableHead>
-            </TableRow>
-          </TableHeader>
-          <TableBody className="divide-y divide-gray-200 bg-white">
-            {valuesets.map((valueset) => (
-              <TableRow key={valueset.id} className="hover:bg-gray-50">
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <div className="text-sm font-medium text-gray-900">
-                    {valueset.name}
-                  </div>
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.slug}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <Badge
-                    className={
-                      {
-                        active:
-                          "bg-green-100 text-green-800 hover:bg-green-200",
-                        draft:
-                          "bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
-                        retired: "bg-red-100 text-red-800 hover:bg-red-200",
-                        unknown: "bg-gray-100 text-gray-800 hover:bg-gray-200",
-                      }[valueset.status]
-                    }
-                  >
-                    {t(valueset.status)}
-                  </Badge>
-                </TableCell>
-                <TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
-                  {valueset.description}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.is_system_defined ? t("yes") : t("no")}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm">
-                  {!valueset.is_system_defined && (
-                    <Button
-                      variant="primary"
-                      size="sm"
-                      onClick={() =>
-                        navigate(`/admin/valuesets/${valueset.slug}/edit`)
-                      }
-                    >
-                      {t("edit")}
-                    </Button>
-                  )}
-                </TableCell>
-              </TableRow>
-            ))}
-          </TableBody>
-        </Table>
+        <div className="flex flex-col md:flex-row items-center justify-between mt-8 gap-2">
+          <div className="flex lg:flex-row flex-col items-center gap-4">
+            <Tabs
+              defaultValue="active"
+              value={qParams.status || "active"}
+              onValueChange={(value) => updateQuery({ status: value })}
+              className="w-full"
+            >
+              <TabsList>
+                <TabsTrigger value="active">
+                  <FileCheckIcon className="w-4 h-4 mr-2 " />
+                  {t("active")}
+                </TabsTrigger>
+                <TabsTrigger value="draft">
+                  <NotepadTextDashedIcon className="w-4 h-4 mr-2" />
+                  {t("draft")}
+                </TabsTrigger>
+                <TabsTrigger value="retired">
+                  <ArchiveIcon className="w-4 h-4 mr-2" />
+                  {t("retired")}
+                </TabsTrigger>
+                <TabsTrigger value="unknown">
+                  <HelpCircle className="w-4 h-4 mr-2 " />
+                  {t("unknown")}
+                </TabsTrigger>
+              </TabsList>
+            </Tabs>
+            <div className="relative md:min-w-80 w-full">
+              <Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-500" />
+              <Input
+                placeholder={t("search_valuesets")}
+                className="pl-10"
+                value={qParams.name || ""}
+                onChange={(e) => updateQuery({ name: e.target.value })}
+              />
+            </div>
+          </div>
+
+          <div className="flex items-center md:self-start">
+            <Button onClick={() => navigate("/admin/valuesets/create")}>
path: src/components/ValueSet/ValueSetList.tsx
user: login: khavinshankar
body: consider using links if it is only for redirection
created_at: 2025-03-03T06:10:20Z
author_association: MEMBER
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
path: src/components/ValueSet/ValueSetList.tsx
user: login: khavinshankar
body: what is this for? like why are we disabling it here, usually valuesets don't change at runtime, there are more like static data
created_at: 2025-03-03T06:12:48Z
author_association: MEMBER
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
path: src/components/ValueSet/ValueSetList.tsx
user: login: AdityaJ2305
body: It is for disabling the filters applied , like search input and tabs filters applied 
https://github.com/ohcnetwork/care_fe/pull/10841#discussion_r1975142069
created_at: 2025-03-03T06:17:48Z
author_association: MEMBER
diff_hunk: @@ -24,115 +34,164 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 export function ValueSetList() {
   const { t } = useTranslation();
   const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name,
+        status: qParams.status || "active",
       },
     }),
   });
 
-  if (isLoading) {
-    return <Loading />;
-  }
-
   const valuesets = response?.results || [];
 
   return (
     <div className="container mx-auto px-4 py-6">
-      <div className="mb-6 flex items-center justify-between">
-        <div>
+      <div className="mb-4 ">
+        <div className="mb-2">
           <h1 className="text-2xl font-bold">{t("valuesets")}</h1>
+          <p className="text-gray-600">{t("manage_and_view_valuesets")}</p>
         </div>
-        <Button asChild>
-          <Link href="/admin/valuesets/create">
-            <PlusIcon className="mr-2 size-4" />
-            {t("create_new")}
-          </Link>
-        </Button>
-      </div>
 
-      <div className="overflow-hidden rounded-lg bg-white shadow">
-        <Table className="min-w-full divide-y divide-gray-200">
-          <TableHeader className="bg-gray-50">
-            <TableRow>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("name")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("slug")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("status")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("description")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("system")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("actions")}
-              </TableHead>
-            </TableRow>
-          </TableHeader>
-          <TableBody className="divide-y divide-gray-200 bg-white">
-            {valuesets.map((valueset) => (
-              <TableRow key={valueset.id} className="hover:bg-gray-50">
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <div className="text-sm font-medium text-gray-900">
-                    {valueset.name}
-                  </div>
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.slug}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <Badge
-                    className={
-                      {
-                        active:
-                          "bg-green-100 text-green-800 hover:bg-green-200",
-                        draft:
-                          "bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
-                        retired: "bg-red-100 text-red-800 hover:bg-red-200",
-                        unknown: "bg-gray-100 text-gray-800 hover:bg-gray-200",
-                      }[valueset.status]
-                    }
-                  >
-                    {t(valueset.status)}
-                  </Badge>
-                </TableCell>
-                <TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
-                  {valueset.description}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.is_system_defined ? t("yes") : t("no")}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm">
-                  {!valueset.is_system_defined && (
-                    <Button
-                      variant="primary"
-                      size="sm"
-                      onClick={() =>
-                        navigate(`/admin/valuesets/${valueset.slug}/edit`)
-                      }
-                    >
-                      {t("edit")}
-                    </Button>
-                  )}
-                </TableCell>
-              </TableRow>
-            ))}
-          </TableBody>
-        </Table>
+        <div className="flex flex-col md:flex-row items-center justify-between mt-8 gap-2">
+          <div className="flex lg:flex-row flex-col items-center gap-4">
+            <Tabs
+              defaultValue="active"
+              value={qParams.status || "active"}
+              onValueChange={(value) => updateQuery({ status: value })}
+              className="w-full"
+            >
+              <TabsList>
+                <TabsTrigger value="active">
+                  <FileCheckIcon className="w-4 h-4 mr-2 " />
+                  {t("active")}
+                </TabsTrigger>
+                <TabsTrigger value="draft">
+                  <NotepadTextDashedIcon className="w-4 h-4 mr-2" />
+                  {t("draft")}
+                </TabsTrigger>
+                <TabsTrigger value="retired">
+                  <ArchiveIcon className="w-4 h-4 mr-2" />
+                  {t("retired")}
+                </TabsTrigger>
+                <TabsTrigger value="unknown">
+                  <HelpCircle className="w-4 h-4 mr-2 " />
+                  {t("unknown")}
+                </TabsTrigger>
+              </TabsList>
+            </Tabs>
+            <div className="relative md:min-w-80 w-full">
+              <Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-500" />
+              <Input
+                placeholder={t("search_valuesets")}
+                className="pl-10"
+                value={qParams.name || ""}
+                onChange={(e) => updateQuery({ name: e.target.value })}
+              />
+            </div>
+          </div>
+
+          <div className="flex items-center md:self-start">
+            <Button onClick={() => navigate("/admin/valuesets/create")}>
path: src/components/ValueSet/ValueSetList.tsx
user: login: AdityaJ2305
body: Done 
created_at: 2025-03-03T06:25:51Z
author_association: MEMBER
diff_hunk: @@ -23,116 +33,168 @@ import valuesetApi from "@/types/valueset/valuesetApi";
 
 export function ValueSetList() {
   const { t } = useTranslation();
-  const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name,
+        status: qParams.status || "active",
       },
     }),
   });
path: src/components/ValueSet/ValueSetList.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Consider adding error handling for the API request.**

The component doesn't handle potential API errors. Consider adding error handling to provide feedback to the user when the API request fails.


```diff
-const { data: response, isLoading } = useQuery({
+const { data: response, isLoading, error } = useQuery({
   queryKey: ["valuesets", qParams],
   queryFn: query(valuesetApi.list, {
     queryParams: {
       limit: resultsPerPage,
       offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
       name: qParams.name,
       status: qParams.status || "active",
     },
   }),
 });

// Then in the return statement, add error handling:
if (error) {
  return (
    <div className="text-red-500 p-4">
      {t("error_loading_valuesets")}: {error.message}
    </div>
  );
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  const { data: response, isLoading, error } = useQuery({
    queryKey: ["valuesets", qParams],
    queryFn: query(valuesetApi.list, {
      queryParams: {
        limit: resultsPerPage,
        offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
        name: qParams.name,
        status: qParams.status || "active",
      },
    }),
  });

  if (error) {
    return (
      <div className="text-red-500 p-4">
        {t("error_loading_valuesets")}: {error.message}
      </div>
    );
  }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-03T20:51:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,116 +33,168 @@
 
 export function ValueSetList() {
   const { t } = useTranslation();
-  const navigate = useNavigate();
-  const { qParams, Pagination, resultsPerPage } = useFilters({
+  const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
     limit: 15,
+    disableCache: true,
   });
   const { data: response, isLoading } = useQuery({
     queryKey: ["valuesets", qParams],
     queryFn: query(valuesetApi.list, {
       queryParams: {
         limit: resultsPerPage,
         offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
+        name: qParams.name,
+        status: qParams.status || "active",
       },
     }),
   });
 
-  if (isLoading) {
-    return <Loading />;
-  }
-
   const valuesets = response?.results || [];
 
   return (
     <div className="container mx-auto px-4 py-6">
-      <div className="mb-6 flex items-center justify-between">
-        <div>
+      <div className="mb-4 ">
+        <div className="mb-2">
           <h1 className="text-2xl font-bold">{t("valuesets")}</h1>
+          <p className="text-gray-600">{t("manage_and_view_valuesets")}</p>
         </div>
-        <Button asChild>
-          <Link href="/admin/valuesets/create">
-            <PlusIcon className="mr-2 size-4" />
-            {t("create_new")}
-          </Link>
-        </Button>
-      </div>
 
-      <div className="overflow-hidden rounded-lg bg-white shadow">
-        <Table className="min-w-full divide-y divide-gray-200">
-          <TableHeader className="bg-gray-50">
-            <TableRow>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("name")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("slug")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("status")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("description")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("system")}
-              </TableHead>
-              <TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">
-                {t("actions")}
-              </TableHead>
-            </TableRow>
-          </TableHeader>
-          <TableBody className="divide-y divide-gray-200 bg-white">
-            {valuesets.map((valueset) => (
-              <TableRow key={valueset.id} className="hover:bg-gray-50">
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <div className="text-sm font-medium text-gray-900">
-                    {valueset.name}
-                  </div>
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.slug}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4">
-                  <Badge
-                    className={
-                      {
-                        active:
-                          "bg-green-100 text-green-800 hover:bg-green-200",
-                        draft:
-                          "bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
-                        retired: "bg-red-100 text-red-800 hover:bg-red-200",
-                        unknown: "bg-gray-100 text-gray-800 hover:bg-gray-200",
-                      }[valueset.status]
-                    }
-                  >
-                    {t(valueset.status)}
-                  </Badge>
-                </TableCell>
-                <TableCell className="px-6 py-4 truncate text-sm text-gray-900 break-words whitespace-normal">
-                  {valueset.description}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
-                  {valueset.is_system_defined ? t("yes") : t("no")}
-                </TableCell>
-                <TableCell className="whitespace-nowrap px-6 py-4 text-sm">
-                  {!valueset.is_system_defined && (
-                    <Button
-                      variant="primary"
-                      size="sm"
-                      onClick={() =>
-                        navigate(`/admin/valuesets/${valueset.slug}/edit`)
-                      }
-                    >
-                      {t("edit")}
-                    </Button>
-                  )}
-                </TableCell>
-              </TableRow>
-            ))}
-          </TableBody>
-        </Table>
+        <div className="flex flex-col md:flex-row items-center justify-between mt-8 gap-2">
+          <div className="flex lg:flex-row flex-col items-center gap-4">
+            <Tabs
+              defaultValue="active"
+              value={qParams.status || "active"}
+              onValueChange={(value) => updateQuery({ status: value })}
+              className="w-full"
+            >
+              <TabsList>
+                <TabsTrigger value="active">
+                  <FileCheckIcon className="w-4 h-4 mr-2 " />
+                  {t("active")}
+                </TabsTrigger>
+                <TabsTrigger value="draft">
+                  <NotepadTextDashedIcon className="w-4 h-4 mr-2" />
+                  {t("draft")}
+                </TabsTrigger>
+                <TabsTrigger value="retired">
+                  <ArchiveIcon className="w-4 h-4 mr-2" />
+                  {t("retired")}
+                </TabsTrigger>
+                <TabsTrigger value="unknown">
+                  <HelpCircle className="w-4 h-4 mr-2 " />
+                  {t("unknown")}
+                </TabsTrigger>
+              </TabsList>
+            </Tabs>
+            <div className="relative md:min-w-80 w-full">
+              <Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-500" />
+              <Input
+                placeholder={t("search_valuesets")}
+                className="pl-10"
+                value={qParams.name || ""}
+                onChange={(e) => updateQuery({ name: e.target.value })}
+              />
+            </div>
+          </div>
+          <Button>
+            <Link
+              href="/admin/valuesets/create"
+              className="flex items-center gap-2"
+            >
+              <PlusIcon className="w-4 h-4" />
+              {t("create_valueset")}
+            </Link>
+          </Button>
path: src/components/ValueSet/ValueSetList.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Improve Button+Link combination for better accessibility.**

The current implementation wraps a Link inside a Button, which can cause accessibility issues. It's better to use either a Link styled as a button or use an onClick handler with the Button.


```diff
-<Button>
-  <Link
-    href="/admin/valuesets/create"
-    className="flex items-center gap-2"
-  >
-    <PlusIcon className="w-4 h-4" />
-    {t("create_valueset")}
-  </Link>
-</Button>
+<Link href="/admin/valuesets/create">
+  <Button className="flex items-center gap-2">
+    <PlusIcon className="w-4 h-4" />
+    {t("create_valueset")}
+  </Button>
+</Link>
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
          <Link href="/admin/valuesets/create">
            <Button className="flex items-center gap-2">
              <PlusIcon className="w-4 h-4" />
              {t("create_valueset")}
            </Button>
          </Link>
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-03T20:51:37Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-02-27T07:41:10Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
The changes include updates to localization entries in the JSON file, adding new keys and adjusting capitalization for consistency around value sets and questionnaires. Additionally, the `QuestionnaireList` component now includes a `disableCache` property to disable caching. The `ValueSetList` component has been revamped with expanded imports, a new search input, tabbed navigation, and an updated use of the `useFilters` hook to include an `updateQuery` function. Loading state handling has also been refined.

## Changes

| File(s)                                      | Change Summary                                                                                                                                                                                                                                                                                      |
|----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `public/locale/en.json`                      | Added new key-value pairs (`"create_valueset"`, `"manage_and_view_valuesets"`, `"search_valuesets"`) and updated existing entries (`"manage_and_view_questionnaires"`, corrected `"Valuesets"` to `"ValueSets"`) for localization consistency.                                               |
| `src/components/Questionnaire/QuestionnaireList.tsx` | Added a new `disableCache` property to the `useFilters` hook call to disable caching behavior.                                                                                                                                                           |
| `src/components/ValueSet/ValueSetList.tsx`             | Expanded the component with new icon and UI component imports, introduced a dynamic search input and tabbed navigation for filtering, updated the `useFilters` hook to return an `updateQuery` function, and refined loading state rendering.                                      |
| `src/hooks/useFilters.tsx`                   | Introduced a new optional parameter `disableCache` to the `useFilters` hook, allowing users to specify whether caching should be disabled.                                                                                                                                                    |

## Possibly related PRs
- **ohcnetwork/care_fe#9685**: The changes in the main PR are related to the modifications in the `public/locale/en.json` file, as both PRs involve updates to key-value pairs within the same JSON structure.
- **ohcnetwork/care_fe#9995**: The changes in the main PR related to the `public/locale/en.json` file involve modifications and additions of key-value pairs, while the retrieved PR also modifies the same file by adding a new entry for error handling.
- **ohcnetwork/care_fe#10738**: The changes in the main PR are related to those in the retrieved PR as both involve modifications to the `public/locale/en.json` file, specifically adding new key-value pairs related to value sets.

## Suggested labels
`tested`, `changes required`

## Suggested reviewers
- rithviknishad
- Jacobjeevan

## Poem
> I'm a rabbit hopping through the code,  
> New keys and tabs lighten my load.  
> With filters and queries in playful flight,  
> Localization shines so clear and bright.  
> In a garden of code, I cheer with delight 🐇.  
> May our changes bring smiles, day and night!

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

---

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?

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

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

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai):

- 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-02-27T07:41:22Z
body: ### <span aria-hidden="true">✅</span> Deploy Preview for *care-ohc* ready!


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 0676e128f24cca932be1881447f791149f3d6f34 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/care-ohc/deploys/67c6152ee21a180008c321e6 |
|<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-10841.preview.ohc.network](https://deploy-preview-10841.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.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTEwODQxLnByZXZpZXcub2hjLm5ldHdvcmsifQ.-zAMVnu0a1I4OQKSkk-sLmajPjHA8fx5yaTD2qYQZCA)<br /><br />_Use your smartphone camera to open QR code link._</details> |
---
<!-- [care-ohc Preview](https://deploy-preview-10841.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: AdityaJ2305
created_at: 2025-02-27T15:21:06Z
body: @rithviknishad @Jacobjeevan  Ready for review 

@nihal467 Ready for testing 
author_association: MEMBER
user: login: AdityaJ2305
created_at: 2025-02-28T10:15:22Z
body: @rithviknishad , Just let me know is it correct, if yes, I'll update all over the place in some other follow up PR and in this only 
author_association: MEMBER
user: login: nihal467
created_at: 2025-03-04T10:32:58Z
body: LGTM
author_association: MEMBER
user: login: github-actions[bot]
created_at: 2025-03-04T12:12:29Z
body: @AdityaJ2305 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