diff --git a/apps/customer-portal/webapp/src/components/footer/Footer.tsx b/apps/customer-portal/webapp/src/components/common/footer/Footer.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/footer/Footer.tsx rename to apps/customer-portal/webapp/src/components/common/footer/Footer.tsx diff --git a/apps/customer-portal/webapp/src/components/footer/__tests__/Footer.test.tsx b/apps/customer-portal/webapp/src/components/common/footer/__tests__/Footer.test.tsx similarity index 97% rename from apps/customer-portal/webapp/src/components/footer/__tests__/Footer.test.tsx rename to apps/customer-portal/webapp/src/components/common/footer/__tests__/Footer.test.tsx index 8ea3b7f511..aa7dd7a53e 100644 --- a/apps/customer-portal/webapp/src/components/footer/__tests__/Footer.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/footer/__tests__/Footer.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import Footer from "@/components/footer/Footer"; +import Footer from "@/components/common/footer/Footer"; import { COMPANY_NAME, PRIVACY_POLICY_URL, diff --git a/apps/customer-portal/webapp/src/components/header/Actions.tsx b/apps/customer-portal/webapp/src/components/common/header/Actions.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/header/Actions.tsx rename to apps/customer-portal/webapp/src/components/common/header/Actions.tsx index f04633b2ed..18e04987a9 100644 --- a/apps/customer-portal/webapp/src/components/header/Actions.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/Actions.tsx @@ -23,7 +23,7 @@ import { import { Users } from "@wso2/oxygen-ui-icons-react"; import type { JSX } from "react"; import { JOIN_COMMUNITY_URL } from "@/constants/appLayoutConstants"; -import UserProfile from "@/components/header/UserProfile"; +import UserProfile from "@/components/common/header/UserProfile"; /** * Actions component for the header. diff --git a/apps/customer-portal/webapp/src/components/header/Brand.tsx b/apps/customer-portal/webapp/src/components/common/header/Brand.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/header/Brand.tsx rename to apps/customer-portal/webapp/src/components/common/header/Brand.tsx diff --git a/apps/customer-portal/webapp/src/components/header/Header.tsx b/apps/customer-portal/webapp/src/components/common/header/Header.tsx similarity index 94% rename from apps/customer-portal/webapp/src/components/header/Header.tsx rename to apps/customer-portal/webapp/src/components/common/header/Header.tsx index 8c0749a1ad..d90dd7ed00 100644 --- a/apps/customer-portal/webapp/src/components/header/Header.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/Header.tsx @@ -20,10 +20,10 @@ import { useNavigate, useLocation, useParams } from "react-router"; import useGetProjects from "@/api/useGetProjects"; import { useLogger } from "@/hooks/useLogger"; import type { ProjectListItem } from "@/models/responses"; -import Brand from "@/components/header/Brand"; -import Actions from "@/components/header/Actions"; -import SearchBar from "@/components/header/SearchBar"; -import ProjectSwitcher from "@/components/header/ProjectSwitcher"; +import Brand from "@/components/common/header/Brand"; +import Actions from "@/components/common/header/Actions"; +import SearchBar from "@/components/common/header/SearchBar"; +import ProjectSwitcher from "@/components/common/header/ProjectSwitcher"; /** * Props for the Header component. @@ -73,6 +73,7 @@ export default function Header({ onToggleSidebar }: HeaderProps): JSX.Element { data: projectsResponse, fetchNextPage, hasNextPage, + isLoading, isFetchingNextPage, isError, } = useGetProjects({}, true); @@ -175,6 +176,7 @@ export default function Header({ onToggleSidebar }: HeaderProps): JSX.Element { projects={projects} selectedProject={selectedProject} onProjectChange={handleProjectChange} + isLoading={isLoading} /> {/* header search bar */} diff --git a/apps/customer-portal/webapp/src/components/header/ProjectSwitcher.tsx b/apps/customer-portal/webapp/src/components/common/header/ProjectSwitcher.tsx similarity index 77% rename from apps/customer-portal/webapp/src/components/header/ProjectSwitcher.tsx rename to apps/customer-portal/webapp/src/components/common/header/ProjectSwitcher.tsx index 53b7aca110..587f931719 100644 --- a/apps/customer-portal/webapp/src/components/header/ProjectSwitcher.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/ProjectSwitcher.tsx @@ -14,7 +14,12 @@ // specific language governing permissions and limitations // under the License. -import { Box, ComplexSelect, Header as HeaderUI } from "@wso2/oxygen-ui"; +import { + Box, + ComplexSelect, + Header as HeaderUI, + Skeleton, +} from "@wso2/oxygen-ui"; import { FolderOpen } from "@wso2/oxygen-ui-icons-react"; import type { JSX } from "react"; import type { ProjectListItem } from "@/models/responses"; @@ -35,6 +40,10 @@ interface ProjectSwitcherProps { * Callback function to handle project change. */ onProjectChange: (projectId: string) => void; + /** + * If true, the component is in a loading state. + */ + isLoading?: boolean; } /** @@ -47,7 +56,30 @@ export default function ProjectSwitcher({ projects, selectedProject, onProjectChange, + isLoading, }: ProjectSwitcherProps): JSX.Element { + if (isLoading) { + return ( + + + + + + + ); + } + return ( {/* project switcher select */} @@ -61,9 +93,7 @@ export default function ProjectSwitcher({ * Find the project from the URL parameters. */ const project = projects.find((project) => project.id === selected); - /** - * Return the project name and icon. - */ + return ( @@ -80,7 +110,7 @@ export default function ProjectSwitcher({ ))} diff --git a/apps/customer-portal/webapp/src/components/header/SearchBar.tsx b/apps/customer-portal/webapp/src/components/common/header/SearchBar.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/header/SearchBar.tsx rename to apps/customer-portal/webapp/src/components/common/header/SearchBar.tsx diff --git a/apps/customer-portal/webapp/src/components/header/UserProfile.tsx b/apps/customer-portal/webapp/src/components/common/header/UserProfile.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/header/UserProfile.tsx rename to apps/customer-portal/webapp/src/components/common/header/UserProfile.tsx diff --git a/apps/customer-portal/webapp/src/components/header/__tests__/Actions.test.tsx b/apps/customer-portal/webapp/src/components/common/header/__tests__/Actions.test.tsx similarity index 97% rename from apps/customer-portal/webapp/src/components/header/__tests__/Actions.test.tsx rename to apps/customer-portal/webapp/src/components/common/header/__tests__/Actions.test.tsx index 32f5542c50..1459a2fc9a 100644 --- a/apps/customer-portal/webapp/src/components/header/__tests__/Actions.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/__tests__/Actions.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import Actions from "@/components/header/Actions"; +import Actions from "@/components/common/header/Actions"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/header/__tests__/Brand.test.tsx b/apps/customer-portal/webapp/src/components/common/header/__tests__/Brand.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/header/__tests__/Brand.test.tsx rename to apps/customer-portal/webapp/src/components/common/header/__tests__/Brand.test.tsx index e42d949206..d0217df785 100644 --- a/apps/customer-portal/webapp/src/components/header/__tests__/Brand.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/__tests__/Brand.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import Brand from "@/components/header/Brand"; +import Brand from "@/components/common/header/Brand"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/header/__tests__/Header.test.tsx b/apps/customer-portal/webapp/src/components/common/header/__tests__/Header.test.tsx similarity index 91% rename from apps/customer-portal/webapp/src/components/header/__tests__/Header.test.tsx rename to apps/customer-portal/webapp/src/components/common/header/__tests__/Header.test.tsx index 68cfe188a3..d7f1e6de6a 100644 --- a/apps/customer-portal/webapp/src/components/header/__tests__/Header.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/__tests__/Header.test.tsx @@ -16,7 +16,7 @@ import { render, screen, fireEvent } from "@testing-library/react"; import { describe, expect, it, vi, beforeEach } from "vitest"; -import Header from "@/components/header/Header"; +import Header from "@/components/common/header/Header"; import { mockProjects } from "@/models/mockData"; // Mock @wso2/oxygen-ui @@ -133,10 +133,11 @@ vi.mock("../SearchBar", () => ({ })); vi.mock("../ProjectSwitcher", () => ({ - default: ({ projects, selectedProject, onProjectChange }: any) => ( + default: ({ projects, selectedProject, onProjectChange, isLoading }: any) => (
({ MenuItem: Object.assign( ({ value, children }: any) => , { - Text: ({ primary }: any) => primary, + Text: ({ primary, secondary }: any) => ( + <> + {primary} {secondary} + + ), }, ), }, @@ -70,7 +81,12 @@ describe("ProjectSwitcher", () => { expect(screen.getByTestId("project-select")).toBeInTheDocument(); mockProjects.forEach((project) => { - expect(screen.getByText(project.name)).toBeInTheDocument(); + expect( + screen.getByText(project.name, { exact: false }), + ).toBeInTheDocument(); + expect( + screen.getByText(project.key, { exact: false }), + ).toBeInTheDocument(); }); }); @@ -88,4 +104,18 @@ describe("ProjectSwitcher", () => { expect(mockOnProjectChange).toHaveBeenCalledWith(mockProjects[1].id); }); + + it("should render skeleton when isLoading is true", () => { + render( + , + ); + + expect(screen.getByTestId("skeleton")).toBeInTheDocument(); + expect(screen.getByTestId("icon-FolderOpen")).toBeInTheDocument(); + expect(screen.queryByTestId("project-select")).not.toBeInTheDocument(); + }); }); diff --git a/apps/customer-portal/webapp/src/components/header/__tests__/SearchBar.test.tsx b/apps/customer-portal/webapp/src/components/common/header/__tests__/SearchBar.test.tsx similarity index 95% rename from apps/customer-portal/webapp/src/components/header/__tests__/SearchBar.test.tsx rename to apps/customer-portal/webapp/src/components/common/header/__tests__/SearchBar.test.tsx index ce9d84bb86..dc407f6cea 100644 --- a/apps/customer-portal/webapp/src/components/header/__tests__/SearchBar.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/__tests__/SearchBar.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import SearchBar from "@/components/header/SearchBar"; +import SearchBar from "@/components/common/header/SearchBar"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/header/__tests__/UserProfile.test.tsx b/apps/customer-portal/webapp/src/components/common/header/__tests__/UserProfile.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/header/__tests__/UserProfile.test.tsx rename to apps/customer-portal/webapp/src/components/common/header/__tests__/UserProfile.test.tsx index dcdaa17a52..6d15b52b53 100644 --- a/apps/customer-portal/webapp/src/components/header/__tests__/UserProfile.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/header/__tests__/UserProfile.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import UserProfile from "@/components/header/UserProfile"; +import UserProfile from "@/components/common/header/UserProfile"; import { mockUser } from "@/models/mockData"; // Mock @wso2/oxygen-ui diff --git a/apps/customer-portal/webapp/src/components/sideNavBar/SideBar.tsx b/apps/customer-portal/webapp/src/components/common/sideNavBar/SideBar.tsx similarity index 97% rename from apps/customer-portal/webapp/src/components/sideNavBar/SideBar.tsx rename to apps/customer-portal/webapp/src/components/common/sideNavBar/SideBar.tsx index 5566f4caf3..864cbcc463 100644 --- a/apps/customer-portal/webapp/src/components/sideNavBar/SideBar.tsx +++ b/apps/customer-portal/webapp/src/components/common/sideNavBar/SideBar.tsx @@ -18,7 +18,7 @@ import { Link, Sidebar } from "@wso2/oxygen-ui"; import { Settings } from "@wso2/oxygen-ui-icons-react"; import { type JSX } from "react"; import { useLocation, useParams, Link as NavigateLink } from "react-router"; -import SubscriptionWidget from "@/components/sideNavBar/SubscriptionWidget"; +import SubscriptionWidget from "@/components/common/sideNavBar/SubscriptionWidget"; import { APP_SHELL_NAV_ITEMS } from "@/constants/appLayoutConstants"; /** diff --git a/apps/customer-portal/webapp/src/components/sideNavBar/SubscriptionWidget.tsx b/apps/customer-portal/webapp/src/components/common/sideNavBar/SubscriptionWidget.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/sideNavBar/SubscriptionWidget.tsx rename to apps/customer-portal/webapp/src/components/common/sideNavBar/SubscriptionWidget.tsx diff --git a/apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SideBar.test.tsx b/apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SideBar.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SideBar.test.tsx rename to apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SideBar.test.tsx index 38397bb33c..9bd75f6b68 100644 --- a/apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SideBar.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SideBar.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi, beforeEach } from "vitest"; -import SideBar from "@/components/sideNavBar/SideBar"; +import SideBar from "@/components/common/sideNavBar/SideBar"; import { APP_SHELL_NAV_ITEMS } from "@/constants/appLayoutConstants"; // Mock @wso2/oxygen-ui @@ -70,7 +70,7 @@ vi.mock("react-router", () => ({ })); // Mock SubscriptionWidget -vi.mock("../SubscriptionWidget", () => ({ +vi.mock("@/components/common/sideNavBar/SubscriptionWidget", () => ({ default: () =>
, })); diff --git a/apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SubscriptionWidget.test.tsx b/apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SubscriptionWidget.test.tsx similarity index 95% rename from apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SubscriptionWidget.test.tsx rename to apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SubscriptionWidget.test.tsx index 3aae260be3..e0a3a32389 100644 --- a/apps/customer-portal/webapp/src/components/sideNavBar/__tests__/SubscriptionWidget.test.tsx +++ b/apps/customer-portal/webapp/src/components/common/sideNavBar/__tests__/SubscriptionWidget.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import SubscriptionWidget from "@/components/sideNavBar/SubscriptionWidget"; +import SubscriptionWidget from "@/components/common/sideNavBar/SubscriptionWidget"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCard.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCard.tsx similarity index 75% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCard.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCard.tsx index 706c0c1d8a..7f3e026cf0 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/ProjectCard.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCard.tsx @@ -15,12 +15,12 @@ // under the License. import { Form } from "@wso2/oxygen-ui"; -import { type JSX } from "react"; +import { useMemo, type JSX } from "react"; import { useNavigate } from "react-router"; -import ProjectCardActions from "@/components/projectCard/ProjectCardActions"; -import ProjectCardBadges from "@/components/projectCard/ProjectCardBadges"; -import ProjectCardInfo from "@/components/projectCard/ProjectCardInfo"; -import ProjectCardStats from "@/components/projectCard/ProjectCardStats"; +import ProjectCardActions from "@/components/projectHub/projectCard/ProjectCardActions"; +import ProjectCardBadges from "@/components/projectHub/projectCard/ProjectCardBadges"; +import ProjectCardInfo from "@/components/projectHub/projectCard/ProjectCardInfo"; +import ProjectCardStats from "@/components/projectHub/projectCard/ProjectCardStats"; import { getMockActiveChats, getMockOpenCases, @@ -80,9 +80,9 @@ export default function ProjectCard({ projectKey, title, subtitle, - status = getMockStatus(), - openCases = getMockOpenCases(), - activeChats = getMockActiveChats(), + status, + openCases, + activeChats, date, onViewDashboard, }: ProjectCardProps): JSX.Element { @@ -105,6 +105,13 @@ export default function ProjectCard({ } }; + const mockStatus = useMemo(() => getMockStatus(), []); + const mockOpenCases = useMemo(() => getMockOpenCases(), []); + const mockActiveChats = useMemo(() => getMockActiveChats(), []); + const resolvedStatus = status ?? mockStatus; + const resolvedOpenCases = openCases ?? mockOpenCases; + const resolvedActiveChats = activeChats ?? mockActiveChats; + return ( {/* project card badges */} - + {/* project card info */} {/* project card stats */} {/* project card actions */} diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCardActions.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardActions.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCardActions.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardActions.tsx diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCardBadges.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardBadges.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCardBadges.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardBadges.tsx diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCardInfo.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardInfo.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCardInfo.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardInfo.tsx diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCardSkeleton.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardSkeleton.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCardSkeleton.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardSkeleton.tsx diff --git a/apps/customer-portal/webapp/src/components/projectCard/ProjectCardStats.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardStats.tsx similarity index 100% rename from apps/customer-portal/webapp/src/components/projectCard/ProjectCardStats.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/ProjectCardStats.tsx diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCard.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCard.test.tsx similarity index 97% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCard.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCard.test.tsx index 81d32a4253..b2289ba470 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCard.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCard.test.tsx @@ -16,7 +16,7 @@ import { render, screen, fireEvent } from "@testing-library/react"; import { describe, expect, it, vi, beforeEach } from "vitest"; -import ProjectCard from "@/components/projectCard/ProjectCard"; +import ProjectCard from "@/components/projectHub/projectCard/ProjectCard"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardActions.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardActions.test.tsx similarity index 94% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardActions.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardActions.test.tsx index abacfe89cc..3f1f578b43 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardActions.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardActions.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import ProjectCardActions from "@/components/projectCard/ProjectCardActions"; +import ProjectCardActions from "@/components/projectHub/projectCard/ProjectCardActions"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardBadges.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardBadges.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardBadges.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardBadges.test.tsx index b63c1a1b3a..a24e3edbf3 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardBadges.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardBadges.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import ProjectCardBadges from "@/components/projectCard/ProjectCardBadges"; +import ProjectCardBadges from "@/components/projectHub/projectCard/ProjectCardBadges"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardInfo.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardInfo.test.tsx similarity index 95% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardInfo.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardInfo.test.tsx index 1d59c0adb4..f70080acfd 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardInfo.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardInfo.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import ProjectCardInfo from "@/components/projectCard/ProjectCardInfo"; +import ProjectCardInfo from "@/components/projectHub/projectCard/ProjectCardInfo"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardSkeleton.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardSkeleton.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardSkeleton.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardSkeleton.test.tsx index a7cb12e40c..f75f098580 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardSkeleton.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardSkeleton.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import ProjectCardSkeleton from "@/components/projectCard/ProjectCardSkeleton"; +import ProjectCardSkeleton from "@/components/projectHub/projectCard/ProjectCardSkeleton"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardStats.test.tsx b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardStats.test.tsx similarity index 96% rename from apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardStats.test.tsx rename to apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardStats.test.tsx index cece2b059c..b88df3a6bc 100644 --- a/apps/customer-portal/webapp/src/components/projectCard/__tests__/ProjectCardStats.test.tsx +++ b/apps/customer-portal/webapp/src/components/projectHub/projectCard/__tests__/ProjectCardStats.test.tsx @@ -16,7 +16,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; -import ProjectCardStats from "@/components/projectCard/ProjectCardStats"; +import ProjectCardStats from "@/components/projectHub/projectCard/ProjectCardStats"; // Mock @wso2/oxygen-ui vi.mock("@wso2/oxygen-ui", () => ({ diff --git a/apps/customer-portal/webapp/src/layouts/AppLayout.tsx b/apps/customer-portal/webapp/src/layouts/AppLayout.tsx index 043f770fbe..3c1016f6e0 100644 --- a/apps/customer-portal/webapp/src/layouts/AppLayout.tsx +++ b/apps/customer-portal/webapp/src/layouts/AppLayout.tsx @@ -17,9 +17,9 @@ import { AppShell, Box, useAppShell } from "@wso2/oxygen-ui"; import { type JSX } from "react"; import { useLocation, Outlet } from "react-router"; -import Footer from "@/components/footer/Footer"; -import Header from "@/components/header/Header"; -import SideBar from "@/components/sideNavBar/SideBar"; +import Footer from "@/components/common/footer/Footer"; +import Header from "@/components/common/header/Header"; +import SideBar from "@/components/common/sideNavBar/SideBar"; /** * AppLayout component. diff --git a/apps/customer-portal/webapp/src/layouts/__tests__/AppLayout.test.tsx b/apps/customer-portal/webapp/src/layouts/__tests__/AppLayout.test.tsx index b4499d681f..386d536217 100644 --- a/apps/customer-portal/webapp/src/layouts/__tests__/AppLayout.test.tsx +++ b/apps/customer-portal/webapp/src/layouts/__tests__/AppLayout.test.tsx @@ -27,7 +27,7 @@ const mockShellActions = { const mockShellState = { sidebarCollapsed: false, - expandedMenus: [], + expandedMenus: {}, }; vi.mock("@wso2/oxygen-ui", () => ({ @@ -65,11 +65,11 @@ vi.mock("react-router", () => ({ })); // Mock child components -vi.mock("@/components/footer/Footer", () => ({ +vi.mock("@/components/common/footer/Footer", () => ({ default: () =>
, })); -vi.mock("@/components/header/Header", () => ({ +vi.mock("@/components/common/header/Header", () => ({ default: ({ onToggleSidebar }: { onToggleSidebar: () => void }) => (
@@ -77,7 +77,7 @@ vi.mock("@/components/header/Header", () => ({ ), })); -vi.mock("@/components/sideNavBar/SideBar", () => ({ +vi.mock("@/components/common/sideNavBar/SideBar", () => ({ default: ({ collapsed, onSelect, onToggleExpand }: any) => (
Collapsed: {collapsed.toString()} diff --git a/apps/customer-portal/webapp/src/pages/ProjectHub.tsx b/apps/customer-portal/webapp/src/pages/ProjectHub.tsx index 43a306aa70..8543e8d956 100644 --- a/apps/customer-portal/webapp/src/pages/ProjectHub.tsx +++ b/apps/customer-portal/webapp/src/pages/ProjectHub.tsx @@ -18,8 +18,8 @@ import { Box, Typography } from "@wso2/oxygen-ui"; import { useEffect, type JSX } from "react"; import useGetProjects from "@/api/useGetProjects"; import { useLogger } from "@/hooks/useLogger"; -import ProjectCard from "@/components/projectCard/ProjectCard"; -import ProjectCardSkeleton from "@/components/projectCard/ProjectCardSkeleton"; +import ProjectCard from "@/components/projectHub/projectCard/ProjectCard"; +import ProjectCardSkeleton from "@/components/projectHub/projectCard/ProjectCardSkeleton"; import { FolderOpen } from "@wso2/oxygen-ui-icons-react"; /** @@ -38,10 +38,22 @@ export default function ProjectHub(): JSX.Element { */ const { data: projectsResponse, + fetchNextPage, + hasNextPage, + isFetchingNextPage, isLoading, isError, } = useGetProjects({}, true); + /** + * Drain all pages if fetch-all flag is set. + */ + useEffect(() => { + if (hasNextPage && !isFetchingNextPage && !isError) { + fetchNextPage(); + } + }, [hasNextPage, isFetchingNextPage, isError, fetchNextPage]); + /** * Get projects from the response. */ diff --git a/apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx b/apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx index e6d965aa10..7de971a1ad 100644 --- a/apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx +++ b/apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx @@ -35,11 +35,11 @@ vi.mock("@wso2/oxygen-ui-icons-react", () => ({ })); // Mock sub-components -vi.mock("@/components/projectCard/ProjectCard", () => ({ +vi.mock("@/components/projectHub/projectCard/ProjectCard", () => ({ default: ({ title }: any) =>
{title}
, })); -vi.mock("@/components/projectCard/ProjectCardSkeleton", () => ({ +vi.mock("@/components/projectHub/projectCard/ProjectCardSkeleton", () => ({ default: () =>
, })); @@ -140,4 +140,22 @@ describe("ProjectHub", () => { ); }); }); + + it("should call fetchNextPage when hasNextPage is true", () => { + const mockFetchNextPage = vi.fn(); + mockUseGetProjects.mockReturnValue({ + isLoading: false, + data: { + pages: [{ projects: mockProjects }], + }, + fetchNextPage: mockFetchNextPage, + hasNextPage: true, + isFetchingNextPage: false, + isError: false, + }); + + render(); + + expect(mockFetchNextPage).toHaveBeenCalled(); + }); });