From 3d00c0af7ef857f55ae592b007745f3cd3bdde7a Mon Sep 17 00:00:00 2001 From: Mason Hu Date: Tue, 30 Jan 2024 16:16:09 +0200 Subject: [PATCH] fix: add dynamic routes for editting storage pool and project configs Signed-off-by: Mason Hu --- src/App.tsx | 24 ++++++++++++----- src/pages/instances/EditInstance.tsx | 27 +++++++++---------- src/pages/networks/EditNetwork.tsx | 2 +- src/pages/profiles/EditProfile.tsx | 27 +++++++++---------- src/pages/projects/CreateProject.tsx | 5 ++-- src/pages/projects/EditProject.tsx | 16 ++++++++--- src/pages/projects/forms/ProjectForm.tsx | 19 ++++++++----- src/pages/storage/CreateStoragePool.tsx | 9 ++++++- src/pages/storage/EditStoragePool.tsx | 23 +++++++++++++--- src/pages/storage/StorageUsedBy.tsx | 2 +- src/pages/storage/StorageVolumeDetail.tsx | 2 +- src/pages/storage/StorageVolumeHeader.tsx | 2 +- src/pages/storage/StorageVolumeNameLink.tsx | 2 +- src/pages/storage/forms/StoragePoolForm.tsx | 12 +++++---- src/pages/storage/forms/StorageVolumeEdit.tsx | 4 +-- tests/projects.spec.ts | 1 - 16 files changed, 114 insertions(+), 63 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 95cecfcc5d..ff50c97924 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -124,7 +124,7 @@ const App: FC = () => { } /> } />} @@ -164,7 +164,7 @@ const App: FC = () => { } /> } />} @@ -204,7 +204,7 @@ const App: FC = () => { } /> } />} @@ -243,6 +243,14 @@ const App: FC = () => { /> } /> + } />} + /> + } + /> } />} @@ -288,15 +296,19 @@ const App: FC = () => { element={} />} /> } />} + /> + } />} /> } />} /> } />} /> = ({ instance }) => { const eventQueue = useEventQueue(); const notify = useNotify(); - const { project, activeSection } = useParams<{ + const { project, section } = useParams<{ project: string; - activeSection?: string; + section?: string; }>(); const queryClient = useQueryClient(); const navigate = useNavigate(); @@ -95,7 +95,7 @@ const EditInstance: FC = ({ instance }) => { const updateFormHeight = () => { updateMaxHeight("form-contents", "p-bottom-controls"); }; - useEffect(updateFormHeight, [notify.notification?.message, activeSection]); + useEffect(updateFormHeight, [notify.notification?.message, section]); useEventListener("resize", updateFormHeight); const formik = useFormik({ @@ -166,7 +166,7 @@ const EditInstance: FC = ({ instance }) => {
= ({ instance }) => { hasDiskError={hasDiskError(formik)} hasNetworkError={hasNetworkError(formik)} /> - + - {(activeSection === slugify(MAIN_CONFIGURATION) || - !activeSection) && ( + {(section === slugify(MAIN_CONFIGURATION) || !section) && ( )} - {activeSection === slugify(DISK_DEVICES) && ( + {section === slugify(DISK_DEVICES) && ( )} - {activeSection === slugify(NETWORK_DEVICES) && ( + {section === slugify(NETWORK_DEVICES) && ( )} - {activeSection === slugify(RESOURCE_LIMITS) && ( + {section === slugify(RESOURCE_LIMITS) && ( )} - {activeSection === slugify(SECURITY_POLICIES) && ( + {section === slugify(SECURITY_POLICIES) && ( )} - {activeSection === slugify(SNAPSHOTS) && ( + {section === slugify(SNAPSHOTS) && ( )} - {activeSection === slugify(CLOUD_INIT) && ( + {section === slugify(CLOUD_INIT) && ( )} - {activeSection === slugify(YAML_CONFIGURATION) && ( + {section === slugify(YAML_CONFIGURATION) && ( void formik.setFieldValue("yaml", yaml)} diff --git a/src/pages/networks/EditNetwork.tsx b/src/pages/networks/EditNetwork.tsx index 51f6e430ba..f4700fe593 100644 --- a/src/pages/networks/EditNetwork.tsx +++ b/src/pages/networks/EditNetwork.tsx @@ -29,7 +29,7 @@ interface Props { const EditNetwork: FC = ({ network, project }) => { const navigate = useNavigate(); const notify = useNotify(); - const { activeSection: section } = useParams<{ activeSection?: string }>(); + const { section } = useParams<{ section?: string }>(); const queryClient = useQueryClient(); const controllerState = useState(null); diff --git a/src/pages/profiles/EditProfile.tsx b/src/pages/profiles/EditProfile.tsx index c5de47bfba..877677ae6e 100644 --- a/src/pages/profiles/EditProfile.tsx +++ b/src/pages/profiles/EditProfile.tsx @@ -75,9 +75,9 @@ interface Props { const EditProfile: FC = ({ profile, featuresProfiles }) => { const notify = useNotify(); - const { project, activeSection } = useParams<{ + const { project, section } = useParams<{ project: string; - activeSection?: string; + section?: string; }>(); const queryClient = useQueryClient(); const navigate = useNavigate(); @@ -90,7 +90,7 @@ const EditProfile: FC = ({ profile, featuresProfiles }) => { const updateFormHeight = () => { updateMaxHeight("form-contents", "p-bottom-controls"); }; - useEffect(updateFormHeight, [notify.notification?.message, activeSection]); + useEffect(updateFormHeight, [notify.notification?.message, section]); useEventListener("resize", updateFormHeight); const ProfileSchema = Yup.object().shape({ @@ -183,45 +183,44 @@ const EditProfile: FC = ({ profile, featuresProfiles }) => { )} - + - {(activeSection === slugify(MAIN_CONFIGURATION) || - !activeSection) && ( + {(section === slugify(MAIN_CONFIGURATION) || !section) && ( )} - {activeSection === slugify(DISK_DEVICES) && ( + {section === slugify(DISK_DEVICES) && ( )} - {activeSection === slugify(NETWORK_DEVICES) && ( + {section === slugify(NETWORK_DEVICES) && ( )} - {activeSection === slugify(RESOURCE_LIMITS) && ( + {section === slugify(RESOURCE_LIMITS) && ( )} - {activeSection === slugify(SECURITY_POLICIES) && ( + {section === slugify(SECURITY_POLICIES) && ( )} - {activeSection === slugify(SNAPSHOTS) && ( + {section === slugify(SNAPSHOTS) && ( )} - {activeSection === slugify(CLOUD_INIT) && ( + {section === slugify(CLOUD_INIT) && ( )} - {activeSection === slugify(YAML_CONFIGURATION) && ( + {section === slugify(YAML_CONFIGURATION) && ( void formik.setFieldValue("yaml", yaml)} diff --git a/src/pages/projects/CreateProject.tsx b/src/pages/projects/CreateProject.tsx index 38ccc46305..4e33ac1c8e 100644 --- a/src/pages/projects/CreateProject.tsx +++ b/src/pages/projects/CreateProject.tsx @@ -39,6 +39,7 @@ import { import ProjectForm from "pages/projects/forms/ProjectForm"; import BaseLayout from "components/BaseLayout"; import FormFooterLayout from "components/forms/FormFooterLayout"; +import { slugify } from "util/slugify"; export type ProjectFormValues = ProjectDetailsFormValues & ProjectResourceLimitsFormValues & @@ -52,7 +53,7 @@ const CreateProject: FC = () => { const notify = useNotify(); const queryClient = useQueryClient(); const controllerState = useState(null); - const [section, setSection] = useState(PROJECT_DETAILS); + const [section, setSection] = useState(slugify(PROJECT_DETAILS)); const ProjectSchema = Yup.object().shape({ name: Yup.string() @@ -119,7 +120,7 @@ const CreateProject: FC = () => { setSection(slugify(newSection))} isEdit={false} /> diff --git a/src/pages/projects/EditProject.tsx b/src/pages/projects/EditProject.tsx index 4dd86b890f..89680754de 100644 --- a/src/pages/projects/EditProject.tsx +++ b/src/pages/projects/EditProject.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useState } from "react"; +import React, { FC, useEffect } from "react"; import { Button, useNotify } from "@canonical/react-components"; import { updateProject } from "api/projects"; import { useQueryClient } from "@tanstack/react-query"; @@ -29,16 +29,19 @@ import ProjectConfigurationHeader from "pages/projects/ProjectConfigurationHeade import { useAuth } from "context/auth"; import CustomLayout from "components/CustomLayout"; import FormFooterLayout from "components/forms/FormFooterLayout"; +import { useNavigate, useParams } from "react-router-dom"; +import { slugify } from "util/slugify"; interface Props { project: LxdProject; } const EditProject: FC = ({ project }) => { + const navigate = useNavigate(); const { isRestricted } = useAuth(); const notify = useNotify(); const queryClient = useQueryClient(); - const [section, setSection] = useState(PROJECT_DETAILS); + const { section } = useParams<{ section?: string }>(); const updateFormHeight = () => { updateMaxHeight("form-contents", "p-bottom-controls"); @@ -100,6 +103,13 @@ const EditProject: FC = ({ project }) => { }; }; + const setSection = (newSection: string) => { + const baseUrl = `/ui/project/${project.name}/configuration`; + newSection === PROJECT_DETAILS + ? navigate(baseUrl) + : navigate(`${baseUrl}/${slugify(newSection)}`); + }; + return ( } @@ -108,7 +118,7 @@ const EditProject: FC = ({ project }) => { diff --git a/src/pages/projects/forms/ProjectForm.tsx b/src/pages/projects/forms/ProjectForm.tsx index 2839458aab..87628c3b4e 100644 --- a/src/pages/projects/forms/ProjectForm.tsx +++ b/src/pages/projects/forms/ProjectForm.tsx @@ -18,6 +18,7 @@ import NetworkRestrictionForm from "pages/projects/forms/NetworkRestrictionForm" import { FormikProps } from "formik/dist/types"; import { LxdProject } from "types/project"; import NotificationRow from "components/NotificationRow"; +import { slugify } from "util/slugify"; interface Props { formik: FormikProps; @@ -34,7 +35,7 @@ const ProjectForm: FC = ({ project, isEdit, }) => { - const [isRestrictionsOpen, setRestrictionsOpen] = useState(false); + const [isRestrictionsOpen, setRestrictionsOpen] = useState(true); const toggleMenu = () => { setRestrictionsOpen((old) => !old); @@ -53,24 +54,28 @@ const ProjectForm: FC = ({ - {section === PROJECT_DETAILS && ( + {section === slugify(PROJECT_DETAILS) && ( )} - {section === RESOURCE_LIMITS && ( + {section === slugify(RESOURCE_LIMITS) && ( )} - {section === CLUSTERS && } - {section === INSTANCES && ( + {section === slugify(CLUSTERS) && ( + + )} + {section === slugify(INSTANCES) && ( )} - {section === DEVICE_USAGE && ( + {section === slugify(DEVICE_USAGE) && ( )} - {section === NETWORKS && } + {section === slugify(NETWORKS) && ( + + )}
diff --git a/src/pages/storage/CreateStoragePool.tsx b/src/pages/storage/CreateStoragePool.tsx index 53be12622c..d0efcd676c 100644 --- a/src/pages/storage/CreateStoragePool.tsx +++ b/src/pages/storage/CreateStoragePool.tsx @@ -17,12 +17,15 @@ import StoragePoolForm, { } from "./forms/StoragePoolForm"; import { useClusterMembers } from "context/useClusterMembers"; import FormFooterLayout from "components/forms/FormFooterLayout"; +import { slugify } from "util/slugify"; +import { MAIN_CONFIGURATION } from "./forms/StoragePoolFormMenu"; const CreateStoragePool: FC = () => { const navigate = useNavigate(); const notify = useNotify(); const queryClient = useQueryClient(); const { project } = useParams<{ project: string }>(); + const [section, setSection] = useState(slugify(MAIN_CONFIGURATION)); const controllerState = useState(null); const { data: clusterMembers = [] } = useClusterMembers(); @@ -80,7 +83,11 @@ const CreateStoragePool: FC = () => { contentClassName="create-storage-pool" > - +