Skip to content

Commit 8bf4e8f

Browse files
authored
feat(networks): Add list views for VLANs, Fabrics, and Spaces (#5849)
- Created list views for: - Fabrics - VLANs - Spaces - Renamed `subnets` directory to `networks` - Refactored networks directory to follow best practices - Introduced query hooks for - Spaces list - Fabrics list - Renamed "Subnets" in side nav to "Networks" - Moved subnets list URL to `/networks/subnets`
1 parent 3370de9 commit 8bf4e8f

File tree

269 files changed

+1730
-506
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

269 files changed

+1730
-506
lines changed

.github/workflows/pr-lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ jobs:
2929
kvm
3030
machines
3131
networkDiscovery
32+
networks
3233
pools
3334
preferences
3435
racks
3536
settings
3637
store
37-
subnets
3838
tags
3939
utils
4040
zones

cypress/e2e/with-users/base/navigation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ context("Navigation - admin", () => {
109109
{ destinationUrl: "/kvm/lxd", linkLabel: "LXD" },
110110
{ destinationUrl: "/images", linkLabel: "Images" },
111111
{ destinationUrl: "/domains", linkLabel: "DNS" },
112-
{ destinationUrl: "/networks", linkLabel: "Subnets" },
112+
{ destinationUrl: "/networks", linkLabel: "Networks" },
113113
{
114114
destinationUrl: "/settings/configuration/general",
115115
linkLabel: "Settings",
File renamed without changes.
File renamed without changes.

cypress/e2e/with-users/subnets/subnets.spec.ts renamed to cypress/e2e/with-users/networks/subnets.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { generateMAASURL } from "../../utils";
33
context("Subnets", () => {
44
beforeEach(() => {
55
cy.login();
6-
cy.visit(generateMAASURL("/networks?by=fabric"));
6+
cy.visit(generateMAASURL("/networks/subnets?by=fabric"));
77
cy.waitForPageToLoad();
88
cy.viewport("macbook-11");
99
});
1010

1111
it("renders the correct heading", () => {
12-
cy.findByRole("heading", { level: 1 }).contains("Subnets");
12+
cy.findByRole("heading", { level: 1 }).contains("Networks");
1313
});
1414

1515
it("displays the main networking view correctly", () => {
@@ -36,7 +36,7 @@ context("Subnets", () => {
3636
"fabric"
3737
);
3838

39-
cy.url().should("include", generateMAASURL("/networks?by=fabric"));
39+
cy.url().should("include", generateMAASURL("/networks/subnets?by=fabric"));
4040
});
4141

4242
it("allows grouping by fabric and space", () => {
@@ -62,6 +62,6 @@ context("Subnets", () => {
6262
cy.get("tbody tr").first().should("include.text", "space");
6363
});
6464

65-
cy.url().should("include", generateMAASURL("/networks?by=space"));
65+
cy.url().should("include", generateMAASURL("/networks/subnets?by=space"));
6666
});
6767
});

src/app/api/query/fabrics.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useFabrics } from "./fabrics";
2+
3+
import { fabricsResolvers, mockFabrics } from "@/testing/resolvers/fabrics";
4+
import {
5+
renderHookWithProviders,
6+
setupMockServer,
7+
waitFor,
8+
} from "@/testing/utils";
9+
10+
setupMockServer(fabricsResolvers.listFabrics.handler());
11+
12+
describe("useFabrics", () => {
13+
it("should return fabrics data", async () => {
14+
const { result } = renderHookWithProviders(useFabrics);
15+
await waitFor(() => {
16+
expect(result.current.isSuccess).toBe(true);
17+
});
18+
19+
expect(result.current.data).toMatchObject(mockFabrics);
20+
});
21+
});

src/app/api/query/fabrics.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { queryOptionsWithHeaders } from "../utils";
2+
3+
import { useWebsocketAwareQuery } from "./base";
4+
5+
import type {
6+
ListFabricsData,
7+
ListFabricsErrors,
8+
ListFabricsResponses,
9+
} from "@/app/apiclient";
10+
import { listFabrics } from "@/app/apiclient";
11+
import { listFabricsQueryKey } from "@/app/apiclient/@tanstack/react-query.gen";
12+
import type { Options } from "@/app/apiclient/client";
13+
14+
export const useFabrics = (options?: Options<ListFabricsData>) => {
15+
return useWebsocketAwareQuery(
16+
queryOptionsWithHeaders<
17+
ListFabricsResponses,
18+
ListFabricsErrors,
19+
ListFabricsData
20+
>(options, listFabrics, listFabricsQueryKey(options))
21+
);
22+
};

src/app/api/query/spaces.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useSpaces } from "./spaces";
2+
3+
import { mockSpaces, spacesResolvers } from "@/testing/resolvers/spaces";
4+
import {
5+
renderHookWithProviders,
6+
setupMockServer,
7+
waitFor,
8+
} from "@/testing/utils";
9+
10+
setupMockServer(spacesResolvers.listSpaces.handler());
11+
12+
describe("useSpaces", () => {
13+
it("should return spaces data", async () => {
14+
const { result } = renderHookWithProviders(useSpaces);
15+
await waitFor(() => {
16+
expect(result.current.isSuccess).toBe(true);
17+
});
18+
19+
expect(result.current.data).toMatchObject(mockSpaces);
20+
});
21+
});

src/app/api/query/spaces.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { queryOptionsWithHeaders } from "../utils";
2+
3+
import { useWebsocketAwareQuery } from "./base";
4+
5+
import type {
6+
ListSpacesData,
7+
ListSpacesErrors,
8+
ListSpacesResponses,
9+
Options,
10+
} from "@/app/apiclient";
11+
import { listSpaces } from "@/app/apiclient";
12+
import { listSpacesQueryKey } from "@/app/apiclient/@tanstack/react-query.gen";
13+
14+
export const useSpaces = (options?: Options<ListSpacesData>) => {
15+
return useWebsocketAwareQuery(
16+
queryOptionsWithHeaders<
17+
ListSpacesResponses,
18+
ListSpacesErrors,
19+
ListSpacesData
20+
>(options, listSpaces, listSpacesQueryKey(options))
21+
);
22+
};

src/app/base/components/AppSideNavigation/AppSideNavigation.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import { statusActions } from "@/app/store/status";
99
import * as factory from "@/testing/factories";
1010
import { authResolvers } from "@/testing/resolvers/auth";
1111
import {
12-
userEvent,
13-
screen,
14-
waitFor,
15-
within,
1612
renderWithBrowserRouter,
1713
renderWithProviders,
14+
screen,
1815
setupMockServer,
16+
userEvent,
17+
waitFor,
18+
within,
1919
} from "@/testing/utils";
2020

2121
const mockUseNavigate = vi.fn();
@@ -218,7 +218,7 @@ describe("GlobalSideNav", () => {
218218

219219
it("can highlight a url with a query param", async () => {
220220
renderWithProviders(<AppSideNavigation />, {
221-
initialEntries: ["/networks?by=fabric"],
221+
initialEntries: ["/networks/subnets?by=fabric"],
222222
state,
223223
});
224224

@@ -227,7 +227,7 @@ describe("GlobalSideNav", () => {
227227
});
228228
const currentMenuItem = screen.getAllByRole("link", { current: "page" })[0];
229229
expect(currentMenuItem).toBeInTheDocument();
230-
expect(currentMenuItem).toHaveTextContent("Subnets");
230+
expect(currentMenuItem).toHaveTextContent("Networks");
231231
});
232232

233233
it("highlights sub-urls", async () => {

0 commit comments

Comments
 (0)