From f6bccd65736b18bb8b3a6293bbc6670e9f921b1f Mon Sep 17 00:00:00 2001 From: Ugo Palatucci Date: Mon, 22 Jul 2024 18:13:40 +0200 Subject: [PATCH] Use VirtualMachine dynamic extension pages --- .../HorizontalNavbar/HorizontalNavbar.tsx | 43 ++++++++++++++----- .../HorizontalNavbar/utils/useDynamicPages.ts | 33 ++++++++++++++ .../VirtualMachineConfigurationTab.tsx | 2 +- .../console/VirtualMachineConsolePage.tsx | 2 +- .../VirtualMachineDiagnosticTab.tsx | 2 +- .../tabs/events/VirtualMachinePageEvents.tsx | 2 +- .../tabs/metrics/VirtualMachineMetricsTab.tsx | 2 +- .../overview/VirtualMachinesOverviewTab.tsx | 2 +- .../tabs/snapshots/SnapshotListPage.tsx | 2 +- .../tabs/yaml/VirtualMachineYAMLPage.tsx | 4 +- .../virtualmachines/details/utils/types.ts | 5 ++- 11 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 src/utils/components/HorizontalNavbar/utils/useDynamicPages.ts diff --git a/src/utils/components/HorizontalNavbar/HorizontalNavbar.tsx b/src/utils/components/HorizontalNavbar/HorizontalNavbar.tsx index f68aa6297..2bb633a2b 100644 --- a/src/utils/components/HorizontalNavbar/HorizontalNavbar.tsx +++ b/src/utils/components/HorizontalNavbar/HorizontalNavbar.tsx @@ -1,10 +1,13 @@ -import React, { FC, useState } from 'react'; -import { NavLink, Route, Routes, useLocation } from 'react-router-dom-v5-compat'; +import React, { FC, useEffect, useMemo, useState } from 'react'; +import { NavLink, Route, Routes, useLocation, useParams } from 'react-router-dom-v5-compat'; import classNames from 'classnames'; +import { VirtualMachineModel } from 'src/views/dashboard-extensions/utils'; import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt'; +import { isEmpty } from '@kubevirt-utils/utils/utils'; import { Nav, NavList } from '@patternfly/react-core'; +import useDynamicPages from './utils/useDynamicPages'; import { NavPageKubevirt, trimLastHistoryPath } from './utils/utils'; import './horizontal-nav-bar.scss'; @@ -18,20 +21,33 @@ type HorizontalNavbarProps = { const HorizontalNavbar: FC = ({ instanceTypeExpandedSpec, pages, vm }) => { const location = useLocation(); - const initialActiveTab = - pages.find(({ name = '' }) => location?.pathname.includes('/' + name.toLowerCase())) || - pages?.[0]; + const params = useParams(); - const [activeItem, setActiveItem] = useState( - initialActiveTab?.name?.toLowerCase(), + const dynamicPluginPages = useDynamicPages(VirtualMachineModel); + + const allPages = useMemo( + () => [...pages, ...(dynamicPluginPages || [])] as NavPageKubevirt[], + [pages, dynamicPluginPages], ); - const paths = pages.map((page) => page.href); + const paths = allPages.map((page) => page.href); + + useEffect(() => { + const defaultPage = allPages.find(({ href }) => isEmpty(href)); + + const initialActiveTab = + allPages.find(({ href }) => !isEmpty(href) && location?.pathname.includes('/' + href)) || + defaultPage; + + setActiveItem(initialActiveTab?.name?.toLowerCase()); + }, [allPages, location?.pathname]); + + const [activeItem, setActiveItem] = useState(); return ( <> - {pages.map((page) => { + {allPages.map((page) => { const Component = page.component; return ( ( - + )} key={page.href} path={page.href} diff --git a/src/utils/components/HorizontalNavbar/utils/useDynamicPages.ts b/src/utils/components/HorizontalNavbar/utils/useDynamicPages.ts new file mode 100644 index 000000000..52f633598 --- /dev/null +++ b/src/utils/components/HorizontalNavbar/utils/useDynamicPages.ts @@ -0,0 +1,33 @@ +import { useMemo } from 'react'; + +import { + HorizontalNavTab, + isHorizontalNavTab, + K8sModel, + useResolvedExtensions, +} from '@openshift-console/dynamic-plugin-sdk'; + +const useDynamicPages = (model: K8sModel) => { + const [dynamicNavTabExtensions, navTabExtentionsResolved] = + useResolvedExtensions(isHorizontalNavTab); + + return useMemo( + () => + navTabExtentionsResolved + ? dynamicNavTabExtensions + .filter( + (tab) => + tab.properties.model.group === model.apiGroup && + tab.properties.model.version === model.apiVersion && + tab.properties.model.kind === model.kind, + ) + .map((tab) => ({ + ...tab.properties.page, + component: tab.properties.component, + })) + : [], + [dynamicNavTabExtensions, model, navTabExtentionsResolved], + ); +}; + +export default useDynamicPages; diff --git a/src/views/virtualmachines/details/tabs/configuration/VirtualMachineConfigurationTab.tsx b/src/views/virtualmachines/details/tabs/configuration/VirtualMachineConfigurationTab.tsx index 6f7c7cb78..a6c4f50c7 100644 --- a/src/views/virtualmachines/details/tabs/configuration/VirtualMachineConfigurationTab.tsx +++ b/src/views/virtualmachines/details/tabs/configuration/VirtualMachineConfigurationTab.tsx @@ -21,7 +21,7 @@ import { getInnerTabFromPath, includesConfigurationPath, tabs } from './utils/ut import './virtual-machine-configuration-tab.scss'; -const VirtualMachineConfigurationTab: FC = ({ vm: obj }) => { +const VirtualMachineConfigurationTab: FC = ({ obj }) => { const navigate = useNavigate(); const location = useLocation(); diff --git a/src/views/virtualmachines/details/tabs/console/VirtualMachineConsolePage.tsx b/src/views/virtualmachines/details/tabs/console/VirtualMachineConsolePage.tsx index 4804f13b4..dacf12327 100644 --- a/src/views/virtualmachines/details/tabs/console/VirtualMachineConsolePage.tsx +++ b/src/views/virtualmachines/details/tabs/console/VirtualMachineConsolePage.tsx @@ -19,7 +19,7 @@ import { printableVMStatus } from '../../../utils'; import VirtualMachineConsolePageTitle from './components/VirtualMachineConsolePageTitle'; -const VirtualMachineConsolePage: FC = ({ vm }) => { +const VirtualMachineConsolePage: FC = ({ obj: vm }) => { const { t } = useKubevirtTranslation(); const [vmi, vmiLoaded] = useK8sWatchResource({ groupVersionKind: VirtualMachineInstanceModelGroupVersionKind, diff --git a/src/views/virtualmachines/details/tabs/diagnostic/VirtualMachineDiagnosticTab.tsx b/src/views/virtualmachines/details/tabs/diagnostic/VirtualMachineDiagnosticTab.tsx index 1d4cf18eb..d0519f77a 100644 --- a/src/views/virtualmachines/details/tabs/diagnostic/VirtualMachineDiagnosticTab.tsx +++ b/src/views/virtualmachines/details/tabs/diagnostic/VirtualMachineDiagnosticTab.tsx @@ -16,7 +16,7 @@ import VirtualMachineLogViewer from './VirtualMachineLogViewer/VirtualMachineLog import './virtual-machine-diagnostic-tab.scss'; -const VirtualMachineDiagnosticTab: FC = ({ vm }) => { +const VirtualMachineDiagnosticTab: FC = ({ obj: vm }) => { const navigate = useNavigate(); const location = useLocation(); const { t } = useKubevirtTranslation(); diff --git a/src/views/virtualmachines/details/tabs/events/VirtualMachinePageEvents.tsx b/src/views/virtualmachines/details/tabs/events/VirtualMachinePageEvents.tsx index 8a4fa3fbc..b2d5ab000 100644 --- a/src/views/virtualmachines/details/tabs/events/VirtualMachinePageEvents.tsx +++ b/src/views/virtualmachines/details/tabs/events/VirtualMachinePageEvents.tsx @@ -8,7 +8,7 @@ import { NavPageComponentProps } from '@virtualmachines/details/utils/types'; import './VirtualMachinePageEventsTab.scss'; -const VirtualMachinePageEventsTab: FC = ({ vm }) => { +const VirtualMachinePageEventsTab: FC = ({ obj: vm }) => { const { t } = useKubevirtTranslation(); return ( diff --git a/src/views/virtualmachines/details/tabs/metrics/VirtualMachineMetricsTab.tsx b/src/views/virtualmachines/details/tabs/metrics/VirtualMachineMetricsTab.tsx index 6078c015c..ebaf6dfeb 100644 --- a/src/views/virtualmachines/details/tabs/metrics/VirtualMachineMetricsTab.tsx +++ b/src/views/virtualmachines/details/tabs/metrics/VirtualMachineMetricsTab.tsx @@ -17,7 +17,7 @@ import { MetricsTabExpendedSections } from './utils/utils'; import './virtual-machine-metrics-tab.scss'; -const VirtualMachineMetricsTab: FC = ({ vm }) => { +const VirtualMachineMetricsTab: FC = ({ obj: vm }) => { const { t } = useKubevirtTranslation(); const location = useLocation(); const { loaded, pods, vmi } = useVMIAndPodsForVM(vm?.metadata?.name, vm?.metadata?.namespace); diff --git a/src/views/virtualmachines/details/tabs/overview/VirtualMachinesOverviewTab.tsx b/src/views/virtualmachines/details/tabs/overview/VirtualMachinesOverviewTab.tsx index cb7abaf2e..941246264 100644 --- a/src/views/virtualmachines/details/tabs/overview/VirtualMachinesOverviewTab.tsx +++ b/src/views/virtualmachines/details/tabs/overview/VirtualMachinesOverviewTab.tsx @@ -20,7 +20,7 @@ import useVMAlerts from './utils/hook/useVMAlerts'; const VirtualMachinesOverviewTab: FC = ({ instanceTypeExpandedSpec, - vm, + obj: vm, }) => { const vmAlerts = useVMAlerts(vm); const { error, loaded, pods, vmi } = useVMIAndPodsForVM( diff --git a/src/views/virtualmachines/details/tabs/snapshots/SnapshotListPage.tsx b/src/views/virtualmachines/details/tabs/snapshots/SnapshotListPage.tsx index 880e63649..50e7cf96d 100644 --- a/src/views/virtualmachines/details/tabs/snapshots/SnapshotListPage.tsx +++ b/src/views/virtualmachines/details/tabs/snapshots/SnapshotListPage.tsx @@ -14,7 +14,7 @@ import useSnapshotData from './hooks/useSnapshotData'; import './SnapshotListPage.scss'; -const SnapshotListPage: FC = ({ vm }) => { +const SnapshotListPage: FC = ({ obj: vm }) => { const { t } = useKubevirtTranslation(); const { createModal } = useModal(); const { error, loaded, restoresMap, snapshots } = useSnapshotData( diff --git a/src/views/virtualmachines/details/tabs/yaml/VirtualMachineYAMLPage.tsx b/src/views/virtualmachines/details/tabs/yaml/VirtualMachineYAMLPage.tsx index 0452a56ac..a4122b5c8 100644 --- a/src/views/virtualmachines/details/tabs/yaml/VirtualMachineYAMLPage.tsx +++ b/src/views/virtualmachines/details/tabs/yaml/VirtualMachineYAMLPage.tsx @@ -7,7 +7,9 @@ import { NavPageComponentProps } from '@virtualmachines/details/utils/types'; import './virtual-machine-yaml-page.scss'; -const VirtualMachineYAMLPage: FC = ({ vm }) => { +const VirtualMachineYAMLPage: FC = (props) => { + const { obj: vm } = props; + const loading = ( diff --git a/src/views/virtualmachines/details/utils/types.ts b/src/views/virtualmachines/details/utils/types.ts index eb646db4a..0293063b6 100644 --- a/src/views/virtualmachines/details/utils/types.ts +++ b/src/views/virtualmachines/details/utils/types.ts @@ -1,6 +1,9 @@ +import { Params } from 'react-router-dom-v5-compat'; + import { V1VirtualMachine } from '@kubevirt-ui/kubevirt-api/kubevirt'; export type NavPageComponentProps = { instanceTypeExpandedSpec?: V1VirtualMachine; - vm: V1VirtualMachine; + obj: V1VirtualMachine; + params: Params; };