diff --git a/src/app/subnets/components/ReservedRangeDeleteForm/ReservedRangeDeleteForm.tsx b/src/app/subnets/components/ReservedRangeDeleteForm/ReservedRangeDeleteForm.tsx index 71c10f1b9b..32eacee519 100644 --- a/src/app/subnets/components/ReservedRangeDeleteForm/ReservedRangeDeleteForm.tsx +++ b/src/app/subnets/components/ReservedRangeDeleteForm/ReservedRangeDeleteForm.tsx @@ -1,18 +1,14 @@ import { useDispatch, useSelector } from "react-redux"; import ModelActionForm from "@/app/base/components/ModelActionForm"; -import { - useSidePanel, - type SetSidePanelContent, -} from "@/app/base/side-panel-context"; +import { useSidePanel } from "@/app/base/side-panel-context"; import { ipRangeActions } from "@/app/store/iprange"; import ipRangeSelectors from "@/app/store/iprange/selectors"; +import type { VLANActionFormProps } from "@/app/subnets/views/VLANDetails/VLANActionForms/VLANActionForms"; -type Props = { - setActiveForm: SetSidePanelContent; -}; - -const ReservedRangeDeleteForm = ({ setActiveForm }: Props) => { +const ReservedRangeDeleteForm = ({ + setSidePanelContent, +}: Pick) => { const dispatch = useDispatch(); const { sidePanelContent } = useSidePanel(); const saved = useSelector(ipRangeSelectors.saved); @@ -32,7 +28,7 @@ const ReservedRangeDeleteForm = ({ setActiveForm }: Props) => { initialValues={{}} message="Ensure all in-use IP addresses are registered in MAAS before releasing this range to avoid potential collisions. Are you sure you want to remove this IP range?" modelType="IP range" - onCancel={() => setActiveForm(null)} + onCancel={() => setSidePanelContent(null)} onSubmit={() => { dispatch(ipRangeActions.delete(ipRangeId)); }} diff --git a/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.test.tsx b/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.test.tsx index 77e89fdb8a..86e9efb20d 100644 --- a/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.test.tsx +++ b/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.test.tsx @@ -45,7 +45,10 @@ describe("ReservedRangeForm", () => { - + ); @@ -59,7 +62,7 @@ describe("ReservedRangeForm", () => { - + ); @@ -73,7 +76,10 @@ describe("ReservedRangeForm", () => { - + ); @@ -98,7 +104,10 @@ describe("ReservedRangeForm", () => { - + ); @@ -119,8 +128,8 @@ describe("ReservedRangeForm", () => { > @@ -159,7 +168,10 @@ describe("ReservedRangeForm", () => { - + ); @@ -189,7 +201,10 @@ describe("ReservedRangeForm", () => { - + ); @@ -222,7 +237,7 @@ describe("ReservedRangeForm", () => { > @@ -233,10 +248,13 @@ describe("ReservedRangeForm", () => { }); it("displays an error when start and end IP addresses are not provided", async () => { - renderWithBrowserRouter(, { - state, - route: "/machines", - }); + renderWithBrowserRouter( + , + { + state, + route: "/machines", + } + ); await userEvent.click( screen.getByRole("textbox", { name: Labels.StartIp }) ); diff --git a/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.tsx b/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.tsx index 54b28b560e..7241ca8d59 100644 --- a/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.tsx +++ b/src/app/subnets/components/ReservedRangeForm/ReservedRangeForm.tsx @@ -21,8 +21,8 @@ import { isId } from "@/app/utils"; type Props = { createType?: IPRangeType; ipRangeId?: IPRange[IPRangeMeta.PK] | null; - setActiveForm: SetSidePanelContent; - id?: Subnet[SubnetMeta.PK] | null; + setSidePanelContent: SetSidePanelContent; + subnetId?: Subnet[SubnetMeta.PK] | null; }; export type FormValues = { @@ -48,8 +48,8 @@ const Schema = Yup.object().shape({ const ReservedRangeForm = ({ createType, ipRangeId, - setActiveForm, - id, + setSidePanelContent, + subnetId, ...props }: Props): JSX.Element | null => { const dispatch = useDispatch(); @@ -69,7 +69,7 @@ const ReservedRangeForm = ({ const errors = useSelector(ipRangeSelectors.errors); const cleanup = useCallback(() => ipRangeActions.cleanup(), []); const isEditing = isId(computedIpRangeId); - const onClose = () => setActiveForm(null); + const onClose = () => setSidePanelContent(null); let computedCreateType = createType; if (!createType) { computedCreateType = @@ -115,7 +115,7 @@ const ReservedRangeForm = ({ if (!isEditing && computedCreateType) { dispatch( ipRangeActions.create({ - subnet: id, + subnet: subnetId, type: computedCreateType, ...values, }) diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.test.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.test.tsx index 4b9a875c6d..462e188a34 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.test.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.test.tsx @@ -36,7 +36,10 @@ it("dispatches a correct action on add static route form submit", async () => { render( - + ); diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.tsx index ce8d42b6aa..04b5e54d85 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/AddStaticRouteForm/AddStaticRouteForm.tsx @@ -38,23 +38,23 @@ const addStaticRouteSchema = Yup.object().shape({ }); export type Props = { - id: Subnet[SubnetMeta.PK]; - setActiveForm: SetSidePanelContent; + subnetId: Subnet[SubnetMeta.PK]; + setSidePanelContent: SetSidePanelContent; }; const AddStaticRouteForm = ({ - id, - setActiveForm, + subnetId, + setSidePanelContent, }: Props): JSX.Element | null => { const staticRouteErrors = useSelector(staticRouteSelectors.errors); const saving = useSelector(staticRouteSelectors.saving); const saved = useSelector(staticRouteSelectors.saved); const dispatch = useDispatch(); - const handleClose = () => setActiveForm(null); + const handleClose = () => setSidePanelContent(null); const staticRoutesLoading = useSelector(staticRouteSelectors.loading); const subnetsLoading = useSelector(subnetSelectors.loading); const loading = staticRoutesLoading || subnetsLoading; const source = useSelector((state: RootState) => - subnetSelectors.getById(state, id) + subnetSelectors.getById(state, subnetId) ); useFetchActions([subnetActions.fetch]); @@ -69,7 +69,7 @@ const AddStaticRouteForm = ({ cleanup={staticRouteActions.cleanup} errors={staticRouteErrors} initialValues={{ - source: id, + source: subnetId, gateway_ip: "", destination: "", metric: "0", @@ -84,7 +84,7 @@ const AddStaticRouteForm = ({ dispatch(staticRouteActions.cleanup()); dispatch( staticRouteActions.create({ - source: id, + source: subnetId, gateway_ip, destination: toFormikNumber(destination) as number, metric: toFormikNumber(metric), diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.test.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.test.tsx index 86f4fc5f7d..d6abdf5516 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.test.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.test.tsx @@ -33,7 +33,7 @@ state = factory.rootState({ it("renders", () => { renderWithBrowserRouter( , { state } @@ -46,7 +46,7 @@ it("dispatches the correct action to delete a static route", async () => { const store = mockStore(state); renderWithBrowserRouter( , { store } diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.tsx index ba1b121359..2b032b99b9 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/DeleteStaticRouteform/DeleteStaticRouteForm.tsx @@ -11,10 +11,13 @@ import type { type Props = { staticRouteId?: StaticRoute[StaticRouteMeta.PK]; - setActiveForm: SetSidePanelContent; + setSidePanelContent: SetSidePanelContent; }; -const DeleteStaticRouteForm = ({ staticRouteId, setActiveForm }: Props) => { +const DeleteStaticRouteForm = ({ + staticRouteId, + setSidePanelContent, +}: Props) => { const dispatch = useDispatch(); const saved = useSelector(staticRouteSelectors.saved); const saving = useSelector(staticRouteSelectors.saving); @@ -27,12 +30,12 @@ const DeleteStaticRouteForm = ({ staticRouteId, setActiveForm }: Props) => { aria-label="Confirm static route deletion" initialValues={{}} modelType="static route" - onCancel={() => setActiveForm(null)} + onCancel={() => setSidePanelContent(null)} onSubmit={() => { dispatch(staticRouteActions.delete(staticRouteId)); }} onSuccess={() => { - setActiveForm(null); + setSidePanelContent(null); }} saved={saved} saving={saving} diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.test.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.test.tsx index c05b90804d..ac7a8e7f08 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.test.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.test.tsx @@ -28,7 +28,7 @@ it("displays loading text on load", async () => { render( - + ); @@ -70,7 +70,7 @@ it("dispatches a correct action on edit static route form submit", async () => { diff --git a/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.tsx b/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.tsx index 50886b46a6..3f3e91bb5c 100644 --- a/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.tsx +++ b/src/app/subnets/views/SubnetDetails/StaticRoutes/EditStaticRouteForm/EditStaticRouteForm.tsx @@ -40,17 +40,17 @@ const editStaticRouteSchema = Yup.object().shape({ export type Props = { staticRouteId?: StaticRoute[StaticRouteMeta.PK]; - setActiveForm: SetSidePanelContent; + setSidePanelContent: SetSidePanelContent; }; const EditStaticRouteForm = ({ staticRouteId, - setActiveForm, + setSidePanelContent, }: Props): JSX.Element | null => { const staticRouteErrors = useSelector(staticRouteSelectors.errors); const saving = useSelector(staticRouteSelectors.saving); const saved = useSelector(staticRouteSelectors.saved); const dispatch = useDispatch(); - const handleClose = () => setActiveForm(null); + const handleClose = () => setSidePanelContent(null); const staticRoutesLoading = useSelector(staticRouteSelectors.loading); const subnetsLoading = useSelector(subnetSelectors.loading); const loading = staticRoutesLoading || subnetsLoading; diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/SubnetActionForms.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/SubnetActionForms.tsx index e135bb3020..7364d1f9bf 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/SubnetActionForms.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/SubnetActionForms.tsx @@ -16,7 +16,7 @@ import type { const FormComponents: Record< SubnetAction, - ({ activeForm, setActiveForm }: SubnetActionProps) => JSX.Element | null + ({ activeForm, setSidePanelContent }: SubnetActionProps) => JSX.Element | null > = { [SubnetActionTypes.MapSubnet]: MapSubnet, [SubnetActionTypes.EditBootArchitectures]: EditBootArchitectures, @@ -29,9 +29,9 @@ const FormComponents: Record< }; const SubnetActionForms = ({ - id, + subnetId, activeForm, - setActiveForm, + setSidePanelContent, staticRouteId, }: SubnetActionProps): JSX.Element => { const FormComponent = activeForm ? FormComponents[activeForm] : () => null; @@ -39,9 +39,9 @@ const SubnetActionForms = ({ return ( ); }; diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.test.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.test.tsx index 767f163b60..e84c364b52 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.test.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.test.tsx @@ -55,7 +55,7 @@ it("displays a correct error message for a subnet with IPs obtained through DHCP render( - + ); @@ -80,7 +80,7 @@ it("displays a message if DHCP is disabled on the VLAN", () => { render( - + ); @@ -105,7 +105,7 @@ it("does not display a message if DHCP is enabled on the VLAN", () => { render( - + ); @@ -131,7 +131,7 @@ it("dispatches an action to load vlans and subnets if not loaded", () => { render( - + ); @@ -156,7 +156,7 @@ it("dispatches a delete action on submit", async () => { render( - + ); @@ -185,7 +185,9 @@ it("redirects on save", async () => { } + element={ + + } path={urls.subnets.subnet.index({ id: subnetId })} /> @@ -205,7 +207,9 @@ it("redirects on save", async () => { } + element={ + + } path={urls.subnets.subnet.index({ id: subnetId })} /> diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.tsx index 86c061e996..cdb4e7346f 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/DeleteSubnet/DeleteSubnet.tsx @@ -12,16 +12,16 @@ import subnetURLs from "@/app/subnets/urls"; import type { SubnetActionProps } from "@/app/subnets/views/SubnetDetails/types"; export const DeleteSubnet = ({ - id, - setActiveForm, + subnetId, + setSidePanelContent, }: Omit): JSX.Element | null => { const dispatch = useDispatch(); const errors = useSelector(subnetSelectors.errors); const saving = useSelector(subnetSelectors.saving); const saved = useSelector(subnetSelectors.saved); - const handleClose = () => setActiveForm(null); - const canBeDeleted = useCanBeDeleted(id); - const dhcpEnabled = useIsDHCPEnabled(id); + const handleClose = () => setSidePanelContent(null); + const canBeDeleted = useCanBeDeleted(subnetId); + const dhcpEnabled = useIsDHCPEnabled(subnetId); useFetchActions([subnetActions.fetch]); @@ -38,7 +38,7 @@ export const DeleteSubnet = ({ initialValues={{}} onCancel={handleClose} onSubmit={() => { - dispatch(subnetActions.delete(id)); + dispatch(subnetActions.delete(subnetId)); }} saved={saved} savedRedirect={subnetURLs.index} diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.test.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.test.tsx index d5a1599b3e..925ade1786 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.test.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.test.tsx @@ -23,7 +23,7 @@ it("shows a spinner while data is loading", () => { render( - + ); @@ -52,7 +52,10 @@ it("initialises form data correctly", () => { render( - + ); @@ -84,7 +87,10 @@ it("can update the arches to disable", async () => { render( - + ); @@ -120,7 +126,10 @@ it("can dispatch an action to update subnet's disabled boot architectures", asyn render( - + ); diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.tsx index 839e0bed51..8139732e4c 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/EditBootArchitectures/EditBootArchitectures.tsx @@ -25,15 +25,15 @@ const Schema = Yup.object().shape({ }); export const EditBootArchitectures = ({ - id, - setActiveForm, + subnetId, + setSidePanelContent, }: Omit): JSX.Element | null => { const dispatch = useDispatch(); const architecturesLoading = useSelector( knownBootArchitecturesSelectors.loading ); const subnet = useSelector((state: RootState) => - subnetSelectors.getById(state, id) + subnetSelectors.getById(state, subnetId) ); const errors = useSelector(subnetSelectors.errors); const saved = useSelector(subnetSelectors.saved); @@ -50,7 +50,7 @@ export const EditBootArchitectures = ({ ); } - const closeForm = () => setActiveForm(null); + const closeForm = () => setSidePanelContent(null); return ( cleanup={cleanup} diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.test.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.test.tsx index c3183eb2e6..6fc437b3ca 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.test.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.test.tsx @@ -18,7 +18,7 @@ it("shows a spinner while subnet is loading", () => { render( - + ); @@ -35,7 +35,7 @@ it("shows an error if the subnet is IPv6", () => { render( - + ); @@ -55,7 +55,7 @@ it("can map an IPv4 subnet", async () => { render( - + ); diff --git a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.tsx b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.tsx index 3bfc5d89a3..928b527b9f 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetActionForms/components/MapSubnet/MapSubnet.tsx @@ -14,19 +14,19 @@ import subnetSelectors from "@/app/store/subnet/selectors"; import type { SubnetActionProps } from "@/app/subnets/views/SubnetDetails/types"; export const MapSubnet = ({ - id, - setActiveForm, + subnetId, + setSidePanelContent, }: Omit): JSX.Element | null => { const dispatch = useDispatch(); const cleanup = useCallback(() => subnetActions.cleanup(), []); const subnet = useSelector((state: RootState) => - subnetSelectors.getById(state, id) + subnetSelectors.getById(state, subnetId) ); const scanError = useSelector((state: RootState) => - subnetSelectors.eventErrorsForSubnets(state, id, "scan") + subnetSelectors.eventErrorsForSubnets(state, subnetId, "scan") )[0]?.error; const scanning = useSelector((state: RootState) => - subnetSelectors.getStatusForSubnet(state, id, "scanning") + subnetSelectors.getStatusForSubnet(state, subnetId, "scanning") ); const [scanned, resetScanned] = useCycled(!scanning); const saved = scanned && !scanError; @@ -39,7 +39,7 @@ export const MapSubnet = ({ ); } - const closeForm = () => setActiveForm(null); + const closeForm = () => setSidePanelContent(null); const isIPv4 = subnet.version === 4; return ( @@ -50,7 +50,7 @@ export const MapSubnet = ({ onSubmit={() => { resetScanned(); dispatch(cleanup()); - dispatch(subnetActions.scan(id)); + dispatch(subnetActions.scan(subnetId)); }} onSuccess={closeForm} saved={saved} diff --git a/src/app/subnets/views/SubnetDetails/SubnetDetails.tsx b/src/app/subnets/views/SubnetDetails/SubnetDetails.tsx index 5ad62f121f..7bd20aec4a 100644 --- a/src/app/subnets/views/SubnetDetails/SubnetDetails.tsx +++ b/src/app/subnets/views/SubnetDetails/SubnetDetails.tsx @@ -87,8 +87,8 @@ const SubnetDetails = (): JSX.Element => { activeForm ? ( ) : null diff --git a/src/app/subnets/views/SubnetDetails/types.ts b/src/app/subnets/views/SubnetDetails/types.ts index 4cbc3f9432..185e522067 100644 --- a/src/app/subnets/views/SubnetDetails/types.ts +++ b/src/app/subnets/views/SubnetDetails/types.ts @@ -10,8 +10,8 @@ import type { Subnet, SubnetMeta } from "@/app/store/subnet/types"; export type SubnetAction = keyof typeof SubnetActionTypes; export interface SubnetActionProps { - id: Subnet[SubnetMeta.PK]; + subnetId: Subnet[SubnetMeta.PK]; staticRouteId?: StaticRoute[StaticRouteMeta.PK]; activeForm: SubnetAction; - setActiveForm: SetSidePanelContent; + setSidePanelContent: SetSidePanelContent; } diff --git a/src/app/subnets/views/VLANDetails/VLANActionForms/VLANActionForms.tsx b/src/app/subnets/views/VLANDetails/VLANActionForms/VLANActionForms.tsx index cf7beb0238..6117b9812e 100644 --- a/src/app/subnets/views/VLANDetails/VLANActionForms/VLANActionForms.tsx +++ b/src/app/subnets/views/VLANDetails/VLANActionForms/VLANActionForms.tsx @@ -1,28 +1,44 @@ import type { SetSidePanelContent } from "@/app/base/side-panel-context"; +import type { Subnet, SubnetMeta } from "@/app/store/subnet/types"; +import type { VLAN, VLANMeta } from "@/app/store/vlan/types"; import ReservedRangeDeleteForm from "@/app/subnets/components/ReservedRangeDeleteForm"; import ReservedRangeForm from "@/app/subnets/components/ReservedRangeForm"; import VLANDeleteForm from "@/app/subnets/views/VLANDetails/VLANDeleteForm"; -import { VLANActionTypes } from "@/app/subnets/views/VLANDetails/constants"; import type { VLANActionType } from "@/app/subnets/views/VLANDetails/constants"; +import { VLANActionTypes } from "@/app/subnets/views/VLANDetails/constants"; + +const actionForms = { + [VLANActionTypes.DeleteVLAN]: VLANDeleteForm, + [VLANActionTypes.ReserveRange]: ReservedRangeForm, + [VLANActionTypes.DeleteReservedRange]: ReservedRangeDeleteForm, +}; -type VLANActionFormProps = { - id: number; +export type VLANActionFormProps = { + subnetId?: Subnet[SubnetMeta.PK]; + vlanId: VLAN[VLANMeta.PK]; activeForm: VLANActionType; setSidePanelContent: SetSidePanelContent; }; const VLANActionForms = ({ - id, activeForm, setSidePanelContent, + subnetId, + vlanId, }: VLANActionFormProps) => { - return activeForm === VLANActionTypes.DeleteVLAN ? ( - setSidePanelContent(null)} id={id} /> - ) : activeForm === VLANActionTypes.ReserveRange ? ( - - ) : activeForm === VLANActionTypes.DeleteReservedRange ? ( - - ) : null; + const ActionForm = actionForms[activeForm]; + + if (!ActionForm) { + return null; + } + + return ( + + ); }; export default VLANActionForms; diff --git a/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.test.tsx b/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.test.tsx index e6679bf59a..e76fdd170a 100644 --- a/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.test.tsx +++ b/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.test.tsx @@ -29,7 +29,7 @@ it("does not allow deletion if the VLAN is the default VLAN in its fabric", () = render( - + ); @@ -60,7 +60,7 @@ it("displays a delete confirmation if the VLAN is not the default for its fabric render( - + ); @@ -89,7 +89,7 @@ it("deletes the VLAN when confirmed", async () => { render( - + ); diff --git a/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.tsx b/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.tsx index 5de223f487..07d1a2c517 100644 --- a/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.tsx +++ b/src/app/subnets/views/VLANDetails/VLANDeleteForm/VLANDeleteForm.tsx @@ -3,6 +3,8 @@ import { useCallback } from "react"; import { Notification } from "@canonical/react-components"; import { useDispatch, useSelector } from "react-redux"; +import type { VLANActionFormProps } from "../VLANActionForms/VLANActionForms"; + import FabricLink from "@/app/base/components/FabricLink"; import FormikForm from "@/app/base/components/FormikForm"; import type { EmptyObject } from "@/app/base/types"; @@ -10,19 +12,19 @@ import fabricSelectors from "@/app/store/fabric/selectors"; import type { RootState } from "@/app/store/root/types"; import { vlanActions } from "@/app/store/vlan"; import vlanSelectors from "@/app/store/vlan/selectors"; -import type { VLAN, VLANMeta } from "@/app/store/vlan/types"; import subnetURLs from "@/app/subnets/urls"; import { isId } from "@/app/utils"; -type Props = { - closeForm: () => void; - id?: VLAN[VLANMeta.PK] | null; -}; - -const VLANDeleteForm = ({ closeForm, id }: Props): JSX.Element | null => { +const VLANDeleteForm = ({ + setSidePanelContent, + vlanId, +}: Pick< + VLANActionFormProps, + "setSidePanelContent" | "vlanId" +>): JSX.Element | null => { const dispatch = useDispatch(); const vlan = useSelector((state: RootState) => - vlanSelectors.getById(state, id) + vlanSelectors.getById(state, vlanId) ); const fabric = useSelector((state: RootState) => fabricSelectors.getById(state, vlan?.fabric) @@ -32,7 +34,7 @@ const VLANDeleteForm = ({ closeForm, id }: Props): JSX.Element | null => { const saving = useSelector(vlanSelectors.saving); const cleanup = useCallback(() => vlanActions.cleanup(), []); - if (!isId(id) || !vlan || !fabric) { + if (!isId(vlanId) || !vlan || !fabric) { return null; } @@ -42,11 +44,12 @@ const VLANDeleteForm = ({ closeForm, id }: Props): JSX.Element | null => { cleanup={cleanup} errors={errors} initialValues={{}} - onCancel={closeForm} + onCancel={() => setSidePanelContent(null)} onSubmit={() => { dispatch(cleanup()); - dispatch(vlanActions.delete(id)); + dispatch(vlanActions.delete(vlanId)); }} + onSuccess={() => setSidePanelContent(null)} saved={saved} savedRedirect={subnetURLs.index} saving={saving} diff --git a/src/app/subnets/views/VLANDetails/VLANDetails.tsx b/src/app/subnets/views/VLANDetails/VLANDetails.tsx index cc8f03458e..967acc2fdb 100644 --- a/src/app/subnets/views/VLANDetails/VLANDetails.tsx +++ b/src/app/subnets/views/VLANDetails/VLANDetails.tsx @@ -89,8 +89,8 @@ const VLANDetails = (): JSX.Element => { activeForm ? ( ) : null