Skip to content

Commit

Permalink
feat(ui): add delete static IP side panel (#5410)
Browse files Browse the repository at this point in the history
Co-authored-by: Nick De Villiers <[email protected]>
  • Loading branch information
Jay-Topher and ndv99 authored Apr 19, 2024
1 parent ab91890 commit 315f14b
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 1 deletion.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ VITE_APP_BASENAME=${BASENAME}
VITE_APP_VITE_BASENAME=${VITE_BASENAME}
VITE_APP_WEBSOCKET_DEBUG=false
VITE_APP_USABILLA_ID=fd6cf482fbbb
VITE_APP_STATIC_IPS_ENABLED=false
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import AddStaticRouteForm from "../StaticRoutes/AddStaticRouteForm";
import DeleteStaticRouteForm from "../StaticRoutes/DeleteStaticRouteform";
import EditStaticRouteForm from "../StaticRoutes/EditStaticRouteForm";
import DeleteStaticIP from "../SubnetStaticIPs/DeleteStaticIP";

import DeleteSubnet from "./components/DeleteSubnet";
import EditBootArchitectures from "./components/EditBootArchitectures";
Expand All @@ -26,19 +27,24 @@ const FormComponents: Record<
[SubnetActionTypes.DeleteStaticRoute]: DeleteStaticRouteForm,
[SubnetActionTypes.ReserveRange]: ReservedRangeForm,
[SubnetActionTypes.DeleteReservedRange]: ReservedRangeDeleteForm,
[SubnetActionTypes.ReserveStaticIP]: () => null,
[SubnetActionTypes.EditStaticIP]: () => null,
[SubnetActionTypes.DeleteStaticIP]: DeleteStaticIP,
};

const SubnetActionForms = ({
subnetId,
activeForm,
setSidePanelContent,
staticRouteId,
macAddress,
}: SubnetActionProps): JSX.Element => {
const FormComponent = activeForm ? FormComponents[activeForm] : () => null;

return (
<FormComponent
activeForm={activeForm}
macAddress={macAddress}
setSidePanelContent={setSidePanelContent}
staticRouteId={staticRouteId}
subnetId={subnetId}
Expand Down
10 changes: 9 additions & 1 deletion src/app/subnets/views/SubnetDetails/SubnetDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Navigate, Route, Routes } from "react-router-dom";

import StaticRoutes from "./StaticRoutes";
import SubnetDetailsHeader from "./SubnetDetailsHeader";
import SubnetStaticIPs from "./SubnetStaticIPs";
import SubnetSummary from "./SubnetSummary";
import SubnetUsedIPs from "./SubnetUsedIPs";
import Utilisation from "./Utilisation";
Expand Down Expand Up @@ -120,7 +121,14 @@ const SubnetDetails = (): JSX.Element => {
path={getRelativeRoute(urls.subnets.subnet.staticRoutes(null), base)}
/>
<Route
element={<ReservedRanges subnetId={id} />}
element={
<>
{import.meta.env.VITE_APP_STATIC_IPS_ENABLED === "true" && (
<SubnetStaticIPs />
)}
<ReservedRanges subnetId={id} />
</>
}
path={getRelativeRoute(
urls.subnets.subnet.reservedIpAddresses(null),
base
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import DeleteStaticIPs from "./DeleteStaticIP";

import { renderWithBrowserRouter, screen } from "@/testing/utils";

it("renders a delete confirmation form", () => {
renderWithBrowserRouter(
<DeleteStaticIPs
macAddress="91:2a:95:aa:2e:50"
setSidePanelContent={vi.fn()}
/>
);
expect(
screen.getByRole("form", { name: "Delete static IP" })
).toBeInTheDocument();
expect(
screen.getByText(
"Are you sure you want to delete this static IP? This action is permanent and can not be undone."
)
).toBeInTheDocument();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { SubnetActionProps } from "../../types";

import ModelActionForm from "@/app/base/components/ModelActionForm";

type Props = Pick<SubnetActionProps, "setSidePanelContent" | "macAddress">;
const DeleteStaticIP = ({ setSidePanelContent, macAddress }: Props) => {
if (!macAddress) return null;
const handleClose = () => setSidePanelContent(null);
// TODO: Implement onSubmit function and passing IDs when API supports it.
// https://warthogs.atlassian.net/browse/MAASENG-2983
return (
<ModelActionForm
aria-label="Delete static IP"
initialValues={{}}
modelType="static IP"
onCancel={handleClose}
onSubmit={() => {}}
/>
);
};

export default DeleteStaticIP;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./DeleteStaticIP";
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import SubnetStaticIPs from "./SubnetStaticIPs";

import { renderWithBrowserRouter, screen } from "@/testing/utils";

it("renders", () => {
renderWithBrowserRouter(<SubnetStaticIPs />);
expect(
screen.getByRole("heading", { name: "Static IPs" })
).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "Reserve static IP" })
).toBeInTheDocument();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { MainToolbar } from "@canonical/maas-react-components";
import { Button } from "@canonical/react-components";

import { SubnetActionTypes, SubnetDetailsSidePanelViews } from "../constants";

import { useSidePanel } from "@/app/base/side-panel-context";

const SubnetStaticIPs = () => {
const { setSidePanelContent } = useSidePanel();

return (
<>
<MainToolbar>
<MainToolbar.Title>Static IPs</MainToolbar.Title>
<MainToolbar.Controls>
<Button
appearance="positive"
onClick={() =>
setSidePanelContent({
view: SubnetDetailsSidePanelViews[
SubnetActionTypes.ReserveStaticIP
],
})
}
>
Reserve static IP
</Button>
</MainToolbar.Controls>
</MainToolbar>
</>
);
};

export default SubnetStaticIPs;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./SubnetStaticIPs";
9 changes: 9 additions & 0 deletions src/app/subnets/views/SubnetDetails/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const SubnetActionTypes = {
DeleteStaticRoute: "DeleteStaticRoute",
ReserveRange: "ReserveRange",
DeleteReservedRange: "DeleteReservedRange",
ReserveStaticIP: "ReserveStaticIP",
EditStaticIP: "EditStaticIP",
DeleteStaticIP: "DeleteStaticIP",
} as const;
export type SubnetActionType = ValueOf<typeof SubnetActionTypes>;

Expand All @@ -24,6 +27,9 @@ export const subnetActionLabels = {
[SubnetActionTypes.DeleteStaticRoute]: "Delete static route",
[SubnetActionTypes.ReserveRange]: "Reserve range",
[SubnetActionTypes.DeleteReservedRange]: "Delete Reserved Range",
[SubnetActionTypes.ReserveStaticIP]: "Reserve static IP",
[SubnetActionTypes.EditStaticIP]: "Edit static IP",
[SubnetActionTypes.DeleteStaticIP]: "Delete static IP",
} as const;

export const SubnetDetailsSidePanelViews = {
Expand All @@ -44,6 +50,9 @@ export const SubnetDetailsSidePanelViews = {
"",
SubnetActionTypes.DeleteReservedRange,
],
[SubnetActionTypes.ReserveStaticIP]: ["", SubnetActionTypes.ReserveStaticIP],
[SubnetActionTypes.EditStaticIP]: ["", SubnetActionTypes.EditStaticIP],
[SubnetActionTypes.DeleteStaticIP]: ["", SubnetActionTypes.DeleteStaticIP],
} as const;

export type SubnetDetailsSidePanelContent = SidePanelContent<
Expand Down
1 change: 1 addition & 0 deletions src/app/subnets/views/SubnetDetails/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export interface SubnetActionProps {
staticRouteId?: StaticRoute[StaticRouteMeta.PK];
activeForm: SubnetAction;
setSidePanelContent: SetSidePanelContent;
macAddress?: string;
}

0 comments on commit 315f14b

Please sign in to comment.