From 089875d6fdf22fc45ff3ac9d22b0baf999b9a7cb Mon Sep 17 00:00:00 2001
From: Mahendar Chikolla <119734520+Mahendar0701@users.noreply.github.com>
Date: Thu, 23 Jan 2025 08:44:47 +0530
Subject: [PATCH] Fix : View(list/card/board) retention for
encounters/resource/users pages (#10039)
---
src/Routers/routes/ResourceRoutes.tsx | 10 ++------
src/Utils/ViewCache.ts | 23 ++++++++++++++++++
src/Utils/useView.ts | 26 +++++++++++++++++++++
src/components/Auth/Login.tsx | 2 ++
src/components/Common/View.tsx | 24 +++++++++++++++++++
src/components/Facility/FacilityUsers.tsx | 7 +++---
src/components/Resource/ResourceBoard.tsx | 9 +++----
src/components/Resource/ResourceList.tsx | 10 ++++----
src/pages/Appointments/AppointmentsPage.tsx | 9 +++----
9 files changed, 93 insertions(+), 27 deletions(-)
create mode 100644 src/Utils/ViewCache.ts
create mode 100644 src/Utils/useView.ts
create mode 100644 src/components/Common/View.tsx
diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx
index 547aeb53610..357b7812513 100644
--- a/src/Routers/routes/ResourceRoutes.tsx
+++ b/src/Routers/routes/ResourceRoutes.tsx
@@ -1,5 +1,4 @@
-import { Redirect } from "raviger";
-
+import View from "@/components/Common/View";
import BoardView from "@/components/Resource/ResourceBoard";
import ResourceDetails from "@/components/Resource/ResourceDetails";
import { ResourceDetailsUpdate } from "@/components/Resource/ResourceDetailsUpdate";
@@ -7,13 +6,8 @@ import ListView from "@/components/Resource/ResourceList";
import { AppRoutes } from "@/Routers/AppRouter";
-const getDefaultView = () =>
- localStorage.getItem("defaultResourceView") === "list" ? "list" : "board";
-
const ResourceRoutes: AppRoutes = {
- "/resource": () => ,
- "/resource/board": () => ,
- "/resource/list": () => ,
+ "/resource": () => ,
"/resource/:id": ({ id }) => ,
"/resource/:id/update": ({ id }) => ,
};
diff --git a/src/Utils/ViewCache.ts b/src/Utils/ViewCache.ts
new file mode 100644
index 00000000000..a2c2ed302ef
--- /dev/null
+++ b/src/Utils/ViewCache.ts
@@ -0,0 +1,23 @@
+const getKey = (name: string) => {
+ return `${name}`;
+};
+
+/**
+ * Clears the view preference.
+ */
+const invalidate = (name: string) => {
+ localStorage.removeItem(getKey(name));
+};
+
+/**
+ * Clears all the view preferences.
+ */
+const invalidateAll = () => {
+ const viewKeys = ["users", "resource", "appointments"];
+ viewKeys.forEach(invalidate);
+};
+
+export default {
+ invalidate,
+ invalidateAll,
+};
diff --git a/src/Utils/useView.ts b/src/Utils/useView.ts
new file mode 100644
index 00000000000..d3f6b0031c3
--- /dev/null
+++ b/src/Utils/useView.ts
@@ -0,0 +1,26 @@
+import { useEffect, useState } from "react";
+
+export function useView(
+ name: string,
+ defaultView: string,
+): [string, (view: string) => void] {
+ const [view, setView] = useState(() => {
+ return localStorage.getItem(name) || defaultView;
+ });
+ const updateView = (newView: string) => {
+ localStorage.setItem(name, newView);
+ setView(newView);
+ };
+ useEffect(() => {
+ const interval = setInterval(() => {
+ const storedView = localStorage.getItem(name);
+ if (storedView !== view) {
+ setView(storedView || defaultView);
+ }
+ }, 100);
+ return () => {
+ clearInterval(interval);
+ };
+ }, [name, view]);
+ return [view, updateView];
+}
diff --git a/src/components/Auth/Login.tsx b/src/components/Auth/Login.tsx
index 9fcd37a55ac..f4432d6c162 100644
--- a/src/components/Auth/Login.tsx
+++ b/src/components/Auth/Login.tsx
@@ -30,6 +30,7 @@ import BrowserWarning from "@/components/ErrorPages/BrowserWarning";
import { useAuthContext } from "@/hooks/useAuthUser";
import FiltersCache from "@/Utils/FiltersCache";
+import ViewCache from "@/Utils/ViewCache";
import routes from "@/Utils/request/api";
import mutate from "@/Utils/request/mutate";
import request from "@/Utils/request/request";
@@ -242,6 +243,7 @@ const Login = (props: LoginProps) => {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
+ ViewCache.invalidateAll();
const validated = validateData();
if (!validated) return;
diff --git a/src/components/Common/View.tsx b/src/components/Common/View.tsx
new file mode 100644
index 00000000000..cff36841db5
--- /dev/null
+++ b/src/components/Common/View.tsx
@@ -0,0 +1,24 @@
+import React, { ComponentType } from "react";
+
+import { useView } from "@/Utils/useView";
+
+export default function View({
+ name,
+ board,
+ list,
+}: {
+ name: "resource";
+ board: ComponentType;
+ list: ComponentType;
+}) {
+ const [view] = useView(name, "board");
+
+ const views: Record<"board" | "list", ComponentType> = {
+ board,
+ list,
+ };
+
+ const SelectedView = views[view as keyof typeof views] || board;
+
+ return ;
+}
diff --git a/src/components/Facility/FacilityUsers.tsx b/src/components/Facility/FacilityUsers.tsx
index f2fe0e61e12..288feaa187e 100644
--- a/src/components/Facility/FacilityUsers.tsx
+++ b/src/components/Facility/FacilityUsers.tsx
@@ -1,5 +1,4 @@
import { useQuery } from "@tanstack/react-query";
-import { useState } from "react";
import { useTranslation } from "react-i18next";
import CareIcon from "@/CAREUI/icons/CareIcon";
@@ -19,6 +18,7 @@ import useFilters from "@/hooks/useFilters";
import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
+import { useView } from "@/Utils/useView";
export default function FacilityUsers(props: { facilityId: string }) {
const { t } = useTranslation();
@@ -26,7 +26,8 @@ export default function FacilityUsers(props: { facilityId: string }) {
limit: 15,
cacheBlacklist: ["username"],
});
- const [activeTab, setActiveTab] = useState<"card" | "list">("card");
+ const [activeTab, setActiveTab] = useView("users", "card");
+
const { facilityId } = props;
let usersList: JSX.Element = <>>;
@@ -58,7 +59,7 @@ export default function FacilityUsers(props: { facilityId: string }) {
diff --git a/src/components/Resource/ResourceBoard.tsx b/src/components/Resource/ResourceBoard.tsx
index 0b903e82829..0ec92836de3 100644
--- a/src/components/Resource/ResourceBoard.tsx
+++ b/src/components/Resource/ResourceBoard.tsx
@@ -24,6 +24,7 @@ import { RESOURCE_CHOICES } from "@/common/constants";
import routes from "@/Utils/request/api";
import request from "@/Utils/request/request";
+import { useView } from "@/Utils/useView";
import { ResourceRequest } from "@/types/resourceRequest/resourceRequest";
const KanbanBoard = lazy(
@@ -36,6 +37,7 @@ const COMPLETED = ["COMPLETED", "REJECTED"];
const ACTIVE = resourceStatusOptions.filter((o) => !COMPLETED.includes(o));
export default function BoardView() {
+ const [, setView] = useView("resource", "board");
const { qParams, FilterBadges, advancedFilter, updateQuery } = useFilters({
limit: -1,
cacheBlacklist: ["title"],
@@ -45,11 +47,6 @@ export default function BoardView() {
const appliedFilters = formatFilter(qParams);
const { t } = useTranslation();
- const onListViewBtnClick = () => {
- navigate("/resource/list", { query: qParams });
- localStorage.setItem("defaultResourceView", "list");
- };
-
return (
@@ -97,7 +94,7 @@ export default function BoardView() {
-
- {viewMode === "board" ? (
+ {activeTab === "board" ? (
{(