← Back to team overview

sts-sponsors team mailing list archive

[Merge] ~jonesogolo/maas-site-manager:1526-add-empty-states-to-regions-table into maas-site-manager:main

 

Jones Ogolo has proposed merging ~jonesogolo/maas-site-manager:1526-add-empty-states-to-regions-table into maas-site-manager:main.

Commit message:
Display an empty caption when there's no table data

Requested reviews:
  MAAS Lander (maas-lander): unittests
  MAAS Committers (maas-committers)

For more details, see:
https://code.launchpad.net/~jonesogolo/maas-site-manager/+git/maas-site-manager/+merge/440258

Added empty state for regions table. This component displays when there are no regions available.
-- 
Your team MAAS Committers is requested to review the proposed merge of ~jonesogolo/maas-site-manager:1526-add-empty-states-to-regions-table into maas-site-manager:main.
diff --git a/frontend/src/App.scss b/frontend/src/App.scss
index 7948b24..307e428 100644
--- a/frontend/src/App.scss
+++ b/frontend/src/App.scss
@@ -62,3 +62,4 @@
 @import "@/components/base/CopyButton/CopyButton.scss";
 @import "@/components/base/TablePagination/TablePagination.scss";
 @import "@/components/base/PaginationBar/PaginationBar.scss";
+@import "@/components/NoRegions/NoRegions.scss";
diff --git a/frontend/src/components/NoRegions/NoRegions.test.tsx b/frontend/src/components/NoRegions/NoRegions.test.tsx
new file mode 100644
index 0000000..2824a99
--- /dev/null
+++ b/frontend/src/components/NoRegions/NoRegions.test.tsx
@@ -0,0 +1,90 @@
+import NoRegions from "./NoRegions";
+
+import urls from "@/api/urls";
+import { enrollmentRequestFactory } from "@/mocks/factories";
+import { createMockGetEnrollmentRequestsResolver } from "@/mocks/resolvers";
+import { createMockGetServer } from "@/mocks/server";
+import { renderWithMemoryRouter, screen, waitFor } from "@/test-utils";
+
+describe("open enrollment requests available", () => {
+  const enrollmentRequests = enrollmentRequestFactory.buildList(2);
+  const mockServer = createMockGetServer(
+    urls.enrollmentRequests,
+    createMockGetEnrollmentRequestsResolver(enrollmentRequests),
+  );
+
+  beforeAll(() => {
+    mockServer.listen();
+  });
+  afterEach(() => {
+    mockServer.resetHandlers();
+  });
+  afterAll(() => {
+    mockServer.close();
+  });
+
+  it("should display 'no enrolled regions' text", () => {
+    renderWithMemoryRouter(<NoRegions />);
+
+    expect(screen.getByText(/no enroled maas regions/i)).toBeInTheDocument();
+  });
+  it("should display link to enrollment docs", () => {
+    renderWithMemoryRouter(<NoRegions />);
+
+    expect(
+      screen.getByRole("link", { name: /learn more about the enrolment process in the documentation\./i }),
+    ).toBeInTheDocument();
+  });
+
+  it("should display a link to the request page if there are open requests", async () => {
+    renderWithMemoryRouter(<NoRegions />);
+
+    await waitFor(() =>
+      expect(
+        screen.getByRole("link", {
+          name: /go to requests page/i,
+        }),
+      ).toBeInTheDocument(),
+    );
+  });
+});
+
+describe("no open enrollment requests available", () => {
+  const enrollmentRequests = enrollmentRequestFactory.buildList(0);
+  const mockServer = createMockGetServer(
+    urls.enrollmentRequests,
+    createMockGetEnrollmentRequestsResolver(enrollmentRequests),
+  );
+
+  beforeAll(() => {
+    mockServer.listen();
+  });
+  afterEach(() => {
+    mockServer.resetHandlers();
+  });
+  afterAll(() => {
+    mockServer.close();
+  });
+
+  it("should display a link to the tokens page", async () => {
+    renderWithMemoryRouter(<NoRegions />);
+
+    await waitFor(() =>
+      expect(
+        screen.getByRole("link", {
+          name: /go to tokens page/i,
+        }),
+      ).toBeInTheDocument(),
+    );
+  });
+
+  it("should display a link to enrollment process docs", () => {
+    renderWithMemoryRouter(<NoRegions />);
+
+    expect(
+      screen.getByRole("link", {
+        name: new RegExp("Learn more about the enrolment process in the documentation.", "i"),
+      }),
+    ).toBeInTheDocument();
+  });
+});
diff --git a/frontend/src/components/NoRegions/NoRegions.tsx b/frontend/src/components/NoRegions/NoRegions.tsx
new file mode 100644
index 0000000..083e20c
--- /dev/null
+++ b/frontend/src/components/NoRegions/NoRegions.tsx
@@ -0,0 +1,48 @@
+import { useState } from "react";
+
+import { Link } from "react-router-dom";
+
+import ExternalLink from "../ExternalLink";
+import TableCaption from "../TableCaption";
+
+import docsUrls from "@/base/docsUrls";
+import { useRequestsQuery } from "@/hooks/api";
+
+const NoRegions = () => {
+  const [size] = useState(50);
+  const [page] = useState(0);
+  const { data, isLoading } = useRequestsQuery({ page: `${page}`, size: `${size}` });
+
+  return (
+    <TableCaption>
+      <TableCaption.Title>No enroled MAAS regions</TableCaption.Title>
+      {!isLoading && data!.total > 0 ? (
+        <TableCaption.Description>
+          You have <strong>{data?.total} open enrolment requests, </strong>inspect them in the Requests page.
+          <br />
+          <ExternalLink to={docsUrls.enrollmentRequest}>
+            Learn more about the enrolment process in the documentation.
+          </ExternalLink>
+          <br />
+          <Link className="p-button--positive no-region__action-link" to="/requests">
+            Go to Requests Page
+          </Link>
+        </TableCaption.Description>
+      ) : (
+        <TableCaption.Description>
+          To enrol follow the steps in the Tokens page.
+          <br />
+          <ExternalLink to={docsUrls.enrollmentRequest}>
+            Learn more about the enrolment process in the documentation.
+          </ExternalLink>
+          <br />
+          <Link className="p-button--positive no-region__action-link" to="/tokens">
+            Go to Tokens page
+          </Link>
+        </TableCaption.Description>
+      )}
+    </TableCaption>
+  );
+};
+
+export default NoRegions;
diff --git a/frontend/src/components/NoRegions/_NoRegions.scss b/frontend/src/components/NoRegions/_NoRegions.scss
new file mode 100644
index 0000000..87b645e
--- /dev/null
+++ b/frontend/src/components/NoRegions/_NoRegions.scss
@@ -0,0 +1,3 @@
+caption .no-region__action-link {
+  margin-top: $spv--medium;
+}
\ No newline at end of file
diff --git a/frontend/src/components/NoRegions/index.ts b/frontend/src/components/NoRegions/index.ts
new file mode 100644
index 0000000..3722da9
--- /dev/null
+++ b/frontend/src/components/NoRegions/index.ts
@@ -0,0 +1 @@
+export { default } from "./NoRegions";
diff --git a/frontend/src/components/SitesList/SitesTable/SitesTable.tsx b/frontend/src/components/SitesList/SitesTable/SitesTable.tsx
index 5b9b1b4..e73b97a 100644
--- a/frontend/src/components/SitesList/SitesTable/SitesTable.tsx
+++ b/frontend/src/components/SitesList/SitesTable/SitesTable.tsx
@@ -9,6 +9,7 @@ import ConnectionInfo from "./ConnectionInfo/ConnectionInfo";
 import SitesTableControls from "./SitesTableControls/SitesTableControls";
 
 import type { SitesQueryResult } from "@/api/types";
+import NoRegions from "@/components/NoRegions";
 import { isDev } from "@/constants";
 import { useAppContext } from "@/context";
 import type { UseSitesQueryResult } from "@/hooks/api";
@@ -242,6 +243,8 @@ const SitesTable = ({
         </thead>
         {isLoading && !isFetchedAfterMount ? (
           <caption>Loading...</caption>
+        ) : table.getRowModel().rows.length < 1 ? (
+          <NoRegions />
         ) : (
           <tbody>
             {table.getRowModel().rows.map((row) => {