From 87f38f3253ce344f281e50cf4b07e602e3d53a80 Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:08:57 +0530 Subject: [PATCH 1/6] Rename useGetCasesFilters to useGetProjectFilters Rename the case-specific filter hook to useGetProjectFilters to reflect broader project-level filters. Updated the exported function name, file path, JSDoc, and debug/error log messages accordingly. Updated tests and imports (useGetProjectFilters) and mocked usages in CasesTable.test to match the new hook name. --- ...ters.test.tsx => useGetProjectFilters.test.tsx} | 8 ++++---- ...eGetCasesFilters.ts => useGetProjectFilters.ts} | 14 +++++++------- .../cases-table/__tests__/CasesTable.test.tsx | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) rename apps/customer-portal/webapp/src/api/__tests__/{useGetCasesFilters.test.tsx => useGetProjectFilters.test.tsx} (90%) rename apps/customer-portal/webapp/src/api/{useGetCasesFilters.ts => useGetProjectFilters.ts} (83%) diff --git a/apps/customer-portal/webapp/src/api/__tests__/useGetCasesFilters.test.tsx b/apps/customer-portal/webapp/src/api/__tests__/useGetProjectFilters.test.tsx similarity index 90% rename from apps/customer-portal/webapp/src/api/__tests__/useGetCasesFilters.test.tsx rename to apps/customer-portal/webapp/src/api/__tests__/useGetProjectFilters.test.tsx index fa104ad799..ad53e0429c 100644 --- a/apps/customer-portal/webapp/src/api/__tests__/useGetCasesFilters.test.tsx +++ b/apps/customer-portal/webapp/src/api/__tests__/useGetProjectFilters.test.tsx @@ -17,7 +17,7 @@ import { renderHook, waitFor } from "@testing-library/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; const mockFiltersResponse = { statuses: [{ id: "1", label: "Open" }], @@ -55,7 +55,7 @@ const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ); -describe("useGetCasesFilters", () => { +describe("useGetProjectFilters", () => { beforeEach(() => { queryClient.clear(); vi.clearAllMocks(); @@ -69,7 +69,7 @@ describe("useGetCasesFilters", () => { }); it("should return filters from API", async () => { - const { result } = renderHook(() => useGetCasesFilters("123"), { wrapper }); + const { result } = renderHook(() => useGetProjectFilters("123"), { wrapper }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); @@ -82,7 +82,7 @@ describe("useGetCasesFilters", () => { statusText: "Internal Server Error", }); - const { result } = renderHook(() => useGetCasesFilters("123"), { wrapper }); + const { result } = renderHook(() => useGetProjectFilters("123"), { wrapper }); await waitFor(() => expect(result.current.isError).toBe(true)); expect(result.current.error?.message).toContain("Internal Server Error"); diff --git a/apps/customer-portal/webapp/src/api/useGetCasesFilters.ts b/apps/customer-portal/webapp/src/api/useGetProjectFilters.ts similarity index 83% rename from apps/customer-portal/webapp/src/api/useGetCasesFilters.ts rename to apps/customer-portal/webapp/src/api/useGetProjectFilters.ts index a5ec922699..0b8bc542cb 100644 --- a/apps/customer-portal/webapp/src/api/useGetCasesFilters.ts +++ b/apps/customer-portal/webapp/src/api/useGetProjectFilters.ts @@ -22,12 +22,12 @@ import { useAuthApiClient } from "@context/AuthApiContext"; import type { CaseMetadataResponse } from "@models/responses"; /** - * Custom hook to fetch case filters for a specific project. + * Custom hook to fetch all filters (cases, conversations, change requests, etc.) for a specific project. * * @param {string} projectId - The ID of the project to fetch filters for. - * @returns {UseQueryResult} The query result object. + * @returns {UseQueryResult} The query result object containing all filter metadata. */ -export default function useGetCasesFilters( +export default function useGetProjectFilters( projectId: string, ): UseQueryResult { const logger = useLogger(); @@ -37,7 +37,7 @@ export default function useGetCasesFilters( return useQuery({ queryKey: [ApiQueryKeys.PROJECT_CASES, "filters", projectId], queryFn: async (): Promise => { - logger.debug(`Fetching case filters for project: ${projectId}`); + logger.debug(`Fetching project filters for project: ${projectId}`); try { const baseUrl = window.config?.CUSTOMER_PORTAL_BACKEND_BASE_URL; @@ -52,15 +52,15 @@ export default function useGetCasesFilters( if (!response.ok) { throw new Error( - `Error fetching case filters: ${response.statusText}`, + `Error fetching project filters: ${response.statusText}`, ); } const data: CaseMetadataResponse = await response.json(); - logger.debug("[useGetCasesFilters] Data received:", data); + logger.debug("[useGetProjectFilters] Data received:", data); return data; } catch (error) { - logger.error("[useGetCasesFilters] Error:", error); + logger.error("[useGetProjectFilters] Error:", error); throw error; } }, diff --git a/apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesTable.test.tsx b/apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesTable.test.tsx index 03e2ef51a1..c52c09ba9f 100644 --- a/apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesTable.test.tsx +++ b/apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesTable.test.tsx @@ -18,7 +18,7 @@ import { render, screen, waitFor, fireEvent } from "@testing-library/react"; import { describe, expect, it, vi, beforeEach } from "vitest"; import CasesTable from "@components/dashboard/cases-table/CasesTable"; import { useGetProjectCasesPage } from "@api/useGetProjectCasesPage"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { ThemeProvider, createTheme } from "@wso2/oxygen-ui"; const mockNavigate = vi.fn(); @@ -29,7 +29,7 @@ vi.mock("react-router", () => ({ })); vi.mock("@api/useGetProjectCasesPage"); -vi.mock("@api/useGetCasesFilters"); +vi.mock("@api/useGetProjectFilters"); vi.mock("@asgardeo/react", () => ({ useAsgardeo: () => ({ @@ -128,7 +128,7 @@ describe("CasesTable", () => { const theme = createTheme(); const mockProjectId = "proj-123"; const mockUseGetProjectCasesPage = vi.mocked(useGetProjectCasesPage); - const mockUseGetCasesFilters = vi.mocked(useGetCasesFilters); + const mockUseGetCasesFilters = vi.mocked(useGetProjectFilters); beforeEach(() => { vi.clearAllMocks(); @@ -141,7 +141,7 @@ describe("CasesTable", () => { data: undefined, isFetching: false, isError: false, - } as unknown as ReturnType); + } as unknown as ReturnType); }); it("should render correctly", () => { @@ -326,7 +326,7 @@ describe("CasesTable", () => { mockUseGetCasesFilters.mockReturnValue({ isFetching: true, isError: true, - } as unknown as ReturnType); + } as unknown as ReturnType); render( From c6e64e7695537d040a0fbe0e3471fa1abb62b830 Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:09:24 +0530 Subject: [PATCH 2/6] Swap useGetCasesFilters for useGetProjectFilters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace imports/usages of useGetCasesFilters with useGetProjectFilters across the customer-portal webapp and update related JSDoc comments. Files updated: ChangeRequestsPage.tsx, CreateCasePage.tsx, DashboardPage.tsx, SupportPage.tsx, and utils/support.ts. No functional logic changes—this aligns code/comments with the new project-level filters hook name. --- .../customer-portal/webapp/src/pages/ChangeRequestsPage.tsx | 4 ++-- apps/customer-portal/webapp/src/pages/CreateCasePage.tsx | 4 ++-- apps/customer-portal/webapp/src/pages/DashboardPage.tsx | 4 ++-- apps/customer-portal/webapp/src/pages/SupportPage.tsx | 4 ++-- apps/customer-portal/webapp/src/utils/support.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/customer-portal/webapp/src/pages/ChangeRequestsPage.tsx b/apps/customer-portal/webapp/src/pages/ChangeRequestsPage.tsx index 47aef3e940..e30c119612 100644 --- a/apps/customer-portal/webapp/src/pages/ChangeRequestsPage.tsx +++ b/apps/customer-portal/webapp/src/pages/ChangeRequestsPage.tsx @@ -41,7 +41,7 @@ import type { ChangeRequestItem, } from "@models/responses"; import type { ChangeRequestSearchRequest } from "@models/requests"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetChangeRequests, { useGetChangeRequestsInfinite, } from "@api/useGetChangeRequests"; @@ -70,7 +70,7 @@ export default function ChangeRequestsPage(): JSX.Element { const pageSize = 10; // Fetch filter metadata (deployments etc.) - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); // Build API request (following cases listing pattern) const changeRequestSearchRequest = useMemo< diff --git a/apps/customer-portal/webapp/src/pages/CreateCasePage.tsx b/apps/customer-portal/webapp/src/pages/CreateCasePage.tsx index 71c1f0b195..3ec8956235 100644 --- a/apps/customer-portal/webapp/src/pages/CreateCasePage.tsx +++ b/apps/customer-portal/webapp/src/pages/CreateCasePage.tsx @@ -27,7 +27,7 @@ import { } from "react"; import { useLocation, useNavigate, useParams } from "react-router"; import { useQueryClient } from "@tanstack/react-query"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetProjectDetails from "@api/useGetProjectDetails"; import { useGetProjectDeployments } from "@api/useGetProjectDeployments"; import { useGetDeploymentsProducts } from "@api/useGetDeploymentsProducts"; @@ -123,7 +123,7 @@ export default function CreateCasePage(): JSX.Element { const { showLoader, hideLoader } = useLoader(); const { data: projectDetails, isLoading: isProjectLoading } = useGetProjectDetails(projectId || ""); - const { data: filters, isLoading: isFiltersLoading } = useGetCasesFilters( + const { data: filters, isLoading: isFiltersLoading } = useGetProjectFilters( projectId || "", ); const [title, setTitle] = useState(() => relatedCase?.title ?? ""); diff --git a/apps/customer-portal/webapp/src/pages/DashboardPage.tsx b/apps/customer-portal/webapp/src/pages/DashboardPage.tsx index e4cd4e06f4..35e83595a5 100644 --- a/apps/customer-portal/webapp/src/pages/DashboardPage.tsx +++ b/apps/customer-portal/webapp/src/pages/DashboardPage.tsx @@ -21,7 +21,7 @@ import { useAsgardeo } from "@asgardeo/react"; import { useLogger } from "@hooks/useLogger"; import { useLoader } from "@context/linear-loader/LoaderContext"; import { useErrorBanner } from "@context/error-banner/ErrorBannerContext"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { useGetProjectCasesStats } from "@api/useGetProjectCasesStats"; import { DASHBOARD_STATS, @@ -49,7 +49,7 @@ export default function DashboardPage(): JSX.Element { data: filters, isLoading: isFiltersLoading, isError: isErrorFilters, - } = useGetCasesFilters(projectId || ""); + } = useGetProjectFilters(projectId || ""); const { incidentId, queryId } = useMemo( () => getIncidentAndQueryIds(filters?.caseTypes), diff --git a/apps/customer-portal/webapp/src/pages/SupportPage.tsx b/apps/customer-portal/webapp/src/pages/SupportPage.tsx index 4b2f7abf9b..663a077c38 100644 --- a/apps/customer-portal/webapp/src/pages/SupportPage.tsx +++ b/apps/customer-portal/webapp/src/pages/SupportPage.tsx @@ -26,7 +26,7 @@ import ServiceRequestCard from "@components/support/request-cards/ServiceRequest import ChangeRequestCard from "@components/support/request-cards/ChangeRequestCard"; import ChatHistoryList from "@components/support/support-overview-cards/ChatHistoryList"; import { useGetProjectSupportStats } from "@api/useGetProjectSupportStats"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetProjectCases from "@api/useGetProjectCases"; import { useSearchConversations } from "@api/useSearchConversations"; import { useLogger } from "@hooks/useLogger"; @@ -48,7 +48,7 @@ export default function SupportPage(): JSX.Element { const navigate = useNavigate(); const { projectId } = useParams<{ projectId: string }>(); - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); const { incidentId, queryId } = getIncidentAndQueryIds( filterMetadata?.caseTypes, diff --git a/apps/customer-portal/webapp/src/utils/support.ts b/apps/customer-portal/webapp/src/utils/support.ts index fd049fe5a6..93eb0138de 100644 --- a/apps/customer-portal/webapp/src/utils/support.ts +++ b/apps/customer-portal/webapp/src/utils/support.ts @@ -44,7 +44,7 @@ import { createElement, type ComponentType, type ReactNode } from "react"; * Extracts Incident and Query case type IDs from caseTypes metadata. * Used for default caseTypeIds filter in Support overview and All Cases. * - * @param caseTypes - Case types from useGetCasesFilters response. + * @param caseTypes - Case types from useGetProjectFilters response. * @returns {string[]} IDs for Incident and Query types. */ export function getIncidentAndQueryCaseTypeIds( @@ -61,7 +61,7 @@ export function getIncidentAndQueryCaseTypeIds( * Extracts Incident and Query case type IDs separately for stats API. * API expects caseTypes=queryId&caseTypes=incidentId. * - * @param caseTypes - Case types from useGetCasesFilters response. + * @param caseTypes - Case types from useGetProjectFilters response. * @returns {{ incidentId?: string; queryId?: string }} Incident and Query IDs. */ export function getIncidentAndQueryIds(caseTypes?: MetadataItem[]): { @@ -1130,7 +1130,7 @@ export function getAvailableCaseActions( * Returns the Announcement case type ID from the case types metadata. * Used to fetch announcements (cases with type Announcement) from the cases API. * - * @param caseTypes - Array of case types from useGetCasesFilters. + * @param caseTypes - Array of case types from useGetProjectFilters. * @returns {string | undefined} The Announcement type ID or undefined. */ export function getAnnouncementCaseTypeId( From ae3d8eb485585ffe0b747e6077070830b1216edc Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:09:40 +0530 Subject: [PATCH 3/6] Swap useGetCasesFilters for useGetProjectFilters Replace imports and usages of useGetCasesFilters with useGetProjectFilters across components and tests. Updated CasesTable, AddDeploymentModal, EditDeploymentModal and their corresponding test files to use and mock the new project-scoped filters hook so deployment type and filter data are retrieved from the unified useGetProjectFilters API. --- .../dashboard/cases-table/CasesTable.tsx | 4 +-- .../deployments/AddDeploymentModal.tsx | 4 +-- .../deployments/EditDeploymentModal.tsx | 6 ++-- .../__tests__/AddDeploymentModal.test.tsx | 28 +++++++++---------- .../__tests__/EditDeploymentModal.test.tsx | 8 +++--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx b/apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx index 6ada840c10..13f666862b 100644 --- a/apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx +++ b/apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx @@ -20,7 +20,7 @@ import { useNavigate } from "react-router"; import { useAsgardeo } from "@asgardeo/react"; import { getNoveraChatEnabled } from "@utils/settingsStorage"; import { useGetProjectCasesPage } from "@api/useGetProjectCasesPage"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import FilterPopover, { type FilterField, } from "@components/common/filter-panel/FilterPopover"; @@ -46,7 +46,7 @@ const CasesTable = ({ projectId }: CasesTableProps): JSX.Element => { data: filtersMetadata, isFetching: isFetchingFilters, isError: isErrorFilters, - } = useGetCasesFilters(projectId); + } = useGetProjectFilters(projectId); const dynamicFilterFields: FilterField[] = [ { diff --git a/apps/customer-portal/webapp/src/components/project-details/deployments/AddDeploymentModal.tsx b/apps/customer-portal/webapp/src/components/project-details/deployments/AddDeploymentModal.tsx index ff7ef1fd51..aa3da27c44 100644 --- a/apps/customer-portal/webapp/src/components/project-details/deployments/AddDeploymentModal.tsx +++ b/apps/customer-portal/webapp/src/components/project-details/deployments/AddDeploymentModal.tsx @@ -41,7 +41,7 @@ import { } from "react"; import type { SelectChangeEvent } from "@wso2/oxygen-ui"; import { usePostCreateDeployment } from "@api/usePostCreateDeployment"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import ErrorIndicator from "@components/common/error-indicator/ErrorIndicator"; import ErrorBanner from "@components/common/error-banner/ErrorBanner"; @@ -78,7 +78,7 @@ export default function AddDeploymentModal({ data: filtersData, isLoading: isFiltersLoading, isError: isFiltersError, - } = useGetCasesFilters(projectId); + } = useGetProjectFilters(projectId); const deploymentTypes = filtersData?.deploymentTypes ?? []; diff --git a/apps/customer-portal/webapp/src/components/project-details/deployments/EditDeploymentModal.tsx b/apps/customer-portal/webapp/src/components/project-details/deployments/EditDeploymentModal.tsx index a2e83cd1b2..1c9b9c2685 100644 --- a/apps/customer-portal/webapp/src/components/project-details/deployments/EditDeploymentModal.tsx +++ b/apps/customer-portal/webapp/src/components/project-details/deployments/EditDeploymentModal.tsx @@ -37,7 +37,7 @@ import { type ChangeEvent, type JSX, } from "react"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { usePatchDeployment } from "@api/usePatchDeployment"; export interface EditDeploymentModalProps { @@ -57,7 +57,7 @@ const INITIAL_FORM = { /** * Modal for editing a deployment (name, type, description). Always sends active: true. - * Deployment type options come from useGetCasesFilters. + * Deployment type options come from useGetProjectFilters. * * @param {EditDeploymentModalProps} props - open, deployment, projectId, onClose, optional onSuccess/onError. * @returns {JSX.Element} The edit deployment modal. @@ -71,7 +71,7 @@ export default function EditDeploymentModal({ onError, }: EditDeploymentModalProps): JSX.Element { const { data: filtersData, isLoading: isFiltersLoading } = - useGetCasesFilters(projectId); + useGetProjectFilters(projectId); const patchDeployment = usePatchDeployment(); const deploymentTypes = filtersData?.deploymentTypes ?? []; diff --git a/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/AddDeploymentModal.test.tsx b/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/AddDeploymentModal.test.tsx index a8128d3a65..89140de0ca 100644 --- a/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/AddDeploymentModal.test.tsx +++ b/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/AddDeploymentModal.test.tsx @@ -18,10 +18,10 @@ import { render, screen, fireEvent } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import AddDeploymentModal from "@components/project-details/deployments/AddDeploymentModal"; import { usePostCreateDeployment } from "@api/usePostCreateDeployment"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; vi.mock("@api/usePostCreateDeployment"); -vi.mock("@api/useGetCasesFilters"); +vi.mock("@api/useGetProjectFilters"); let mockMutate: any; let defaultModalProps: any; @@ -62,11 +62,11 @@ describe("AddDeploymentModal", () => { isPending: false, } as unknown as ReturnType); - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: mockFiltersData, isLoading: false, isError: false, - } as unknown as ReturnType); + } as unknown as ReturnType); }); it("should render the modal with title and description", () => { @@ -92,11 +92,11 @@ describe("AddDeploymentModal", () => { }); it("should show skeleton while deployment types are loading", () => { - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: undefined, isLoading: true, isError: false, - } as unknown as ReturnType); + } as unknown as ReturnType); render(); @@ -105,11 +105,11 @@ describe("AddDeploymentModal", () => { }); it("should show ErrorIndicator inside modal when deployment types fail to load", () => { - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: undefined, isLoading: false, isError: true, - } as unknown as ReturnType); + } as unknown as ReturnType); render(); @@ -117,11 +117,11 @@ describe("AddDeploymentModal", () => { }); it("should show ErrorBanner outside modal when deployment types fail to load", () => { - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: undefined, isLoading: false, isError: true, - } as unknown as ReturnType); + } as unknown as ReturnType); render(); @@ -134,11 +134,11 @@ describe("AddDeploymentModal", () => { }); it("should dismiss ErrorBanner when dismiss button is clicked", () => { - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: undefined, isLoading: false, isError: true, - } as unknown as ReturnType); + } as unknown as ReturnType); render(); @@ -157,11 +157,11 @@ describe("AddDeploymentModal", () => { }); it("should disable Add Deployment button when filters failed to load", () => { - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: undefined, isLoading: false, isError: true, - } as unknown as ReturnType); + } as unknown as ReturnType); render(); diff --git a/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/EditDeploymentModal.test.tsx b/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/EditDeploymentModal.test.tsx index fba2d1b8cc..2f40824e57 100644 --- a/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/EditDeploymentModal.test.tsx +++ b/apps/customer-portal/webapp/src/components/project-details/deployments/__tests__/EditDeploymentModal.test.tsx @@ -17,11 +17,11 @@ import { act, fireEvent, render, screen } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import EditDeploymentModal from "@components/project-details/deployments/EditDeploymentModal"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { usePatchDeployment } from "@api/usePatchDeployment"; import type { ProjectDeploymentItem } from "@models/responses"; -vi.mock("@api/useGetCasesFilters"); +vi.mock("@api/useGetProjectFilters"); vi.mock("@api/usePatchDeployment"); const mockDeployment: ProjectDeploymentItem = { @@ -56,11 +56,11 @@ const defaultProps = { describe("EditDeploymentModal", () => { beforeEach(() => { vi.clearAllMocks(); - vi.mocked(useGetCasesFilters).mockReturnValue({ + vi.mocked(useGetProjectFilters).mockReturnValue({ data: mockFiltersData, isLoading: false, isError: false, - } as ReturnType); + } as ReturnType); vi.mocked(usePatchDeployment).mockReturnValue({ mutateAsync: vi.fn().mockResolvedValue(undefined), isPending: false, From eb5cc681abd7d38d6fffcdfc42a298fbd386c096 Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:10:04 +0530 Subject: [PATCH 4/6] Replace useGetCasesFilters with useGetProjectFilters Swap usages of useGetCasesFilters to the new useGetProjectFilters hook across UI pages and tests. Updated imports and local variable usages in AllCasesPage, AllConversationsPage, and AnnouncementsPage, and adjusted mocks in DashboardPage.test.tsx and SupportPage.test.tsx to reflect the renamed/project-scoped filters hook. This ensures filter metadata (case types/IDs) is fetched via the project-scoped API used for stats and case/conversation queries. --- apps/customer-portal/webapp/src/pages/AllCasesPage.tsx | 4 ++-- .../customer-portal/webapp/src/pages/AllConversationsPage.tsx | 4 ++-- apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx | 4 ++-- .../webapp/src/pages/__tests__/DashboardPage.test.tsx | 2 +- .../webapp/src/pages/__tests__/SupportPage.test.tsx | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/customer-portal/webapp/src/pages/AllCasesPage.tsx b/apps/customer-portal/webapp/src/pages/AllCasesPage.tsx index 0ab9141858..a897ad1b3c 100644 --- a/apps/customer-portal/webapp/src/pages/AllCasesPage.tsx +++ b/apps/customer-portal/webapp/src/pages/AllCasesPage.tsx @@ -36,7 +36,7 @@ import { } from "@wso2/oxygen-ui"; import { ArrowLeft } from "@wso2/oxygen-ui-icons-react"; import { useGetProjectCasesStats } from "@api/useGetProjectCasesStats"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetProjectCases from "@api/useGetProjectCases"; import { getIncidentAndQueryIds } from "@utils/support"; import { CaseType } from "@constants/supportConstants"; @@ -64,7 +64,7 @@ export default function AllCasesPage(): JSX.Element { const pageSize = 10; // Fetch filter metadata first to get Incident and Query IDs for stats API - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); const { incidentId, queryId } = useMemo( () => getIncidentAndQueryIds(filterMetadata?.caseTypes), diff --git a/apps/customer-portal/webapp/src/pages/AllConversationsPage.tsx b/apps/customer-portal/webapp/src/pages/AllConversationsPage.tsx index 874439cc3f..14996d0b97 100644 --- a/apps/customer-portal/webapp/src/pages/AllConversationsPage.tsx +++ b/apps/customer-portal/webapp/src/pages/AllConversationsPage.tsx @@ -35,7 +35,7 @@ import { } from "@wso2/oxygen-ui"; import { ArrowLeft } from "@wso2/oxygen-ui-icons-react"; import { useLoader } from "@context/linear-loader/LoaderContext"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { useSearchConversations } from "@api/useSearchConversations"; import { useGetConversationStats } from "@api/useGetConversationStats"; import type { @@ -65,7 +65,7 @@ export default function AllConversationsPage(): JSX.Element { const [page, setPage] = useState(1); const pageSize = 10; - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); const searchRequest = useMemo( () => ({ diff --git a/apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx b/apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx index fa92115c11..05939b406a 100644 --- a/apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx +++ b/apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx @@ -28,7 +28,7 @@ import { Pagination, } from "@wso2/oxygen-ui"; import { ArrowLeft } from "@wso2/oxygen-ui-icons-react"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { useGetProjectCasesPage } from "@api/useGetProjectCasesPage"; import { CaseType } from "@constants/supportConstants"; import type { AnnouncementFilterValues } from "@constants/supportConstants"; @@ -52,7 +52,7 @@ export default function AnnouncementsPage(): JSX.Element { const [page, setPage] = useState(1); const pageSize = 10; - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); const caseSearchRequest = useMemo( () => ({ diff --git a/apps/customer-portal/webapp/src/pages/__tests__/DashboardPage.test.tsx b/apps/customer-portal/webapp/src/pages/__tests__/DashboardPage.test.tsx index 238ef41e0b..42c3d31f76 100644 --- a/apps/customer-portal/webapp/src/pages/__tests__/DashboardPage.test.tsx +++ b/apps/customer-portal/webapp/src/pages/__tests__/DashboardPage.test.tsx @@ -99,7 +99,7 @@ const mockCasesStats = { isError: false, }; -vi.mock("@api/useGetCasesFilters", () => ({ +vi.mock("@api/useGetProjectFilters", () => ({ default: vi.fn(() => mockFilters), })); diff --git a/apps/customer-portal/webapp/src/pages/__tests__/SupportPage.test.tsx b/apps/customer-portal/webapp/src/pages/__tests__/SupportPage.test.tsx index 33e8102d48..8880e16c4c 100644 --- a/apps/customer-portal/webapp/src/pages/__tests__/SupportPage.test.tsx +++ b/apps/customer-portal/webapp/src/pages/__tests__/SupportPage.test.tsx @@ -160,8 +160,8 @@ vi.mock("@api/useGetProjectSupportStats", () => ({ useGetProjectSupportStats: (id: string) => mockUseGetProjectSupportStats(id), })); -// Mock useGetCasesFilters (provides caseTypes so caseTypeIds are derived for cases query) -vi.mock("@api/useGetCasesFilters", () => ({ +// Mock useGetProjectFilters (provides caseTypes so caseTypeIds are derived for cases query) +vi.mock("@api/useGetProjectFilters", () => ({ __esModule: true, default: () => ({ data: { From 03af536d6b82f0d9c1083f23f6444e98b1aae9e7 Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:10:39 +0530 Subject: [PATCH 5/6] Use useGetProjectFilters; add timeCardStates Replace references to the old useGetCasesFilters hook with useGetProjectFilters across tests and comments to align with the project-level filters hook. Update mock imports and mockReturnValue usage in AllCasesPage and CreateCasePage tests. Add an optional timeCardStates field to the CaseMetadataResponse interface to include time card state metadata in API responses. --- .../webapp/src/constants/supportConstants.ts | 2 +- apps/customer-portal/webapp/src/models/responses.ts | 1 + .../webapp/src/pages/__tests__/AllCasesPage.test.tsx | 6 +++--- .../webapp/src/pages/__tests__/CreateCasePage.test.tsx | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/customer-portal/webapp/src/constants/supportConstants.ts b/apps/customer-portal/webapp/src/constants/supportConstants.ts index 6faa67706f..7a8f416bff 100644 --- a/apps/customer-portal/webapp/src/constants/supportConstants.ts +++ b/apps/customer-portal/webapp/src/constants/supportConstants.ts @@ -451,7 +451,7 @@ export const ALL_CONVERSATIONS_FILTER_DEFINITIONS: AllConversationsFilterDefinit /** * Configuration for the all cases filters. - * Uses caseStates, caseTypes, severities, issueTypes, deploymentTypes from useGetCasesFilters. + * Uses caseStates, caseTypes, severities, issueTypes, deploymentTypes from useGetProjectFilters. */ export const ALL_CASES_FILTER_DEFINITIONS: AllCasesFilterDefinition[] = [ { diff --git a/apps/customer-portal/webapp/src/models/responses.ts b/apps/customer-portal/webapp/src/models/responses.ts index c6193edbc3..ec056a336a 100644 --- a/apps/customer-portal/webapp/src/models/responses.ts +++ b/apps/customer-portal/webapp/src/models/responses.ts @@ -514,6 +514,7 @@ export interface CaseMetadataResponse { changeRequestImpacts?: MetadataItem[]; caseTypes?: MetadataItem[]; conversationStates?: MetadataItem[]; + timeCardStates?: MetadataItem[]; severityBasedAllocationTime?: Record; } diff --git a/apps/customer-portal/webapp/src/pages/__tests__/AllCasesPage.test.tsx b/apps/customer-portal/webapp/src/pages/__tests__/AllCasesPage.test.tsx index 433d68e181..5fa7908031 100644 --- a/apps/customer-portal/webapp/src/pages/__tests__/AllCasesPage.test.tsx +++ b/apps/customer-portal/webapp/src/pages/__tests__/AllCasesPage.test.tsx @@ -65,7 +65,7 @@ const mockCases = [ vi.mock("@api/useGetProjectCasesStats", () => ({ useGetProjectCasesStats: vi.fn(), })); -vi.mock("@api/useGetCasesFilters", () => ({ +vi.mock("@api/useGetProjectFilters", () => ({ default: vi.fn(), })); vi.mock("@api/useGetProjectCases", () => ({ @@ -73,7 +73,7 @@ vi.mock("@api/useGetProjectCases", () => ({ })); import { useGetProjectCasesStats } from "@api/useGetProjectCasesStats"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetProjectCases from "@api/useGetProjectCases"; // Mock Child Components to test props passing and interactions @@ -141,7 +141,7 @@ describe("AllCasesPage", () => { isFetching: false, isError: false, }); - (useGetCasesFilters as any).mockReturnValue({ + (useGetProjectFilters as any).mockReturnValue({ data: mockCaseMetadata, isFetching: false, }); diff --git a/apps/customer-portal/webapp/src/pages/__tests__/CreateCasePage.test.tsx b/apps/customer-portal/webapp/src/pages/__tests__/CreateCasePage.test.tsx index 79d6309f88..f5d608e13e 100644 --- a/apps/customer-portal/webapp/src/pages/__tests__/CreateCasePage.test.tsx +++ b/apps/customer-portal/webapp/src/pages/__tests__/CreateCasePage.test.tsx @@ -156,8 +156,8 @@ describe("CreateCasePage", () => { })), })); - // Mock useGetCasesFilters hook - vi.mock("../../api/useGetCasesFilters", () => ({ + // Mock useGetProjectFilters hook + vi.mock("../../api/useGetProjectFilters", () => ({ default: vi.fn(() => ({ data: { statuses: [{ id: "1", label: "Open" }], From 89aaba9f4607ce61cd0201952340ec2ca9984367 Mon Sep 17 00:00:00 2001 From: "K.Dileepa Thushan Peiris" Date: Mon, 2 Mar 2026 21:10:57 +0530 Subject: [PATCH 6/6] Switch to useGetProjectFilters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace usages of useGetCasesFilters with useGetProjectFilters across the codebase to use the project-level filter hook. Updated imports in SecurityReportAnalysis.tsx and CaseDetailsActionRow.tsx, adjusted related prop/JSDoc comments, and updated tests to mock the new hook (CaseDetailsContent.test.tsx and CaseDetailsActionRow.test.tsx). No functional changes intended—just aligning to the renamed/appropriate filter API. --- .../src/components/security/SecurityReportAnalysis.tsx | 4 ++-- .../details-tab/__tests__/CaseDetailsContent.test.tsx | 2 +- .../support/case-details/header/CaseDetailsActionRow.tsx | 8 ++++---- .../header/__tests__/CaseDetailsActionRow.test.tsx | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx b/apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx index 328b69bfb7..153aaf9628 100644 --- a/apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx +++ b/apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx @@ -55,7 +55,7 @@ import { import { useNavigate, useParams } from "react-router"; import { CaseType } from "@constants/supportConstants"; import useGetProjectCases from "@api/useGetProjectCases"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import useGetUserDetails from "@api/useGetUserDetails"; import type { AllCasesFilterValues, CaseListItem } from "@models/responses"; import SecurityReportAnalysisSkeleton from "@components/security/SecurityReportAnalysisSkeleton"; @@ -90,7 +90,7 @@ const SecurityReportAnalysis = (): JSX.Element => { const { data: currentUser } = useGetUserDetails(); // Fetch filter metadata - const { data: filterMetadata } = useGetCasesFilters(projectId || ""); + const { data: filterMetadata } = useGetProjectFilters(projectId || ""); // Build case search request for security report analysis cases const caseSearchRequest = useMemo( diff --git a/apps/customer-portal/webapp/src/components/support/case-details/details-tab/__tests__/CaseDetailsContent.test.tsx b/apps/customer-portal/webapp/src/components/support/case-details/details-tab/__tests__/CaseDetailsContent.test.tsx index 8fb834b799..557430d0e6 100644 --- a/apps/customer-portal/webapp/src/components/support/case-details/details-tab/__tests__/CaseDetailsContent.test.tsx +++ b/apps/customer-portal/webapp/src/components/support/case-details/details-tab/__tests__/CaseDetailsContent.test.tsx @@ -50,7 +50,7 @@ const mockCaseDetails = { findingsTotal: null, }; -vi.mock("@api/useGetCasesFilters", () => ({ +vi.mock("@api/useGetProjectFilters", () => ({ default: () => ({ data: { caseStates: [{ id: "3", label: "Closed" }] }, }), diff --git a/apps/customer-portal/webapp/src/components/support/case-details/header/CaseDetailsActionRow.tsx b/apps/customer-portal/webapp/src/components/support/case-details/header/CaseDetailsActionRow.tsx index e17e121116..3320815605 100644 --- a/apps/customer-portal/webapp/src/components/support/case-details/header/CaseDetailsActionRow.tsx +++ b/apps/customer-portal/webapp/src/components/support/case-details/header/CaseDetailsActionRow.tsx @@ -34,7 +34,7 @@ import { CASE_STATUS_ACTIONS, type CaseStatusPaletteIntent, } from "@constants/supportConstants"; -import useGetCasesFilters from "@api/useGetCasesFilters"; +import useGetProjectFilters from "@api/useGetProjectFilters"; import { usePatchCase } from "@api/usePatchCase"; import { useErrorBanner } from "@context/error-banner/ErrorBannerContext"; import { useSuccessBanner } from "@context/success-banner/SuccessBannerContext"; @@ -79,7 +79,7 @@ export interface CaseDetailsActionRowProps { /** When case is closed, used to hide "Open Related Case" after 2 months. */ closedOn?: string | null; onOpenRelatedCase?: () => void; - /** Project ID for useGetCasesFilters and usePatchCase. */ + /** Project ID for useGetProjectFilters and usePatchCase. */ projectId?: string; /** Case ID for PATCH case state. */ caseId?: string; @@ -95,7 +95,7 @@ export interface CaseDetailsActionRowProps { /** * Resolves stateKey for an action by looking up caseState in caseStates. * @param actionLabel - Action label (e.g. "Closed", "Accept Solution"). - * @param caseStates - caseStates from useGetCasesFilters. + * @param caseStates - caseStates from useGetProjectFilters. * @returns stateKey as number, or undefined if not found. */ function getStateKeyForAction( @@ -126,7 +126,7 @@ export default function CaseDetailsActionRow({ const theme = useTheme(); const hasEngineer = !!getAssignedEngineerLabel(assignedEngineer); - const { data: filterMetadata } = useGetCasesFilters(projectId); + const { data: filterMetadata } = useGetProjectFilters(projectId); const caseStates = filterMetadata?.caseStates; const { showSuccess } = useSuccessBanner(); diff --git a/apps/customer-portal/webapp/src/components/support/case-details/header/__tests__/CaseDetailsActionRow.test.tsx b/apps/customer-portal/webapp/src/components/support/case-details/header/__tests__/CaseDetailsActionRow.test.tsx index 5828f6c0f4..6f2e90dad8 100644 --- a/apps/customer-portal/webapp/src/components/support/case-details/header/__tests__/CaseDetailsActionRow.test.tsx +++ b/apps/customer-portal/webapp/src/components/support/case-details/header/__tests__/CaseDetailsActionRow.test.tsx @@ -19,7 +19,7 @@ import { describe, expect, it, vi } from "vitest"; import CaseDetailsActionRow from "@case-details/CaseDetailsActionRow"; import { ThemeProvider, createTheme } from "@wso2/oxygen-ui"; -vi.mock("@api/useGetCasesFilters", () => ({ +vi.mock("@api/useGetProjectFilters", () => ({ default: () => ({ data: { caseStates: [