diff --git a/src/nmstate-types/react-resize-panel.d.ts b/src/nmstate-types/react-resize-panel.d.ts new file mode 100644 index 00000000..a35a1cf2 --- /dev/null +++ b/src/nmstate-types/react-resize-panel.d.ts @@ -0,0 +1 @@ +declare module 'react-resize-panel'; diff --git a/src/utils/components/PolicyForm/PolicyWizard/PolicyWizard.scss b/src/utils/components/PolicyForm/PolicyWizard/PolicyWizard.scss index 9b987bd6..e69de29b 100644 --- a/src/utils/components/PolicyForm/PolicyWizard/PolicyWizard.scss +++ b/src/utils/components/PolicyForm/PolicyWizard/PolicyWizard.scss @@ -1,5 +0,0 @@ -.nmstate-policy-wizard { - .pf-v6-c-wizard__main-body { - padding-left: 0; - } -} diff --git a/src/views/nodenetworkconfiguration/Topology.tsx b/src/views/nodenetworkconfiguration/Topology.tsx index 90430b84..e88059c8 100644 --- a/src/views/nodenetworkconfiguration/Topology.tsx +++ b/src/views/nodenetworkconfiguration/Topology.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useMemo, useState } from 'react'; import { useHistory } from 'react-router'; import { NodeModelGroupVersionKind } from 'src/console-models/NodeModel'; - +import './components/TopologySidebar/TopologySidebar.scss'; import { IoK8sApiCoreV1Node } from '@kubevirt-ui/kubevirt-api/kubernetes/models'; import { V1beta1NodeNetworkConfigurationEnactment, @@ -37,23 +37,24 @@ import { filterPolicyAppliedNodes } from '@utils/resources/policies/utils'; import TopologyLegend from './components/TopologyLegend/TopologyLegend'; import { SELECTED_ID_QUERY_PARAM } from './components/TopologySidebar/constants'; +import TopologyDrawer from './components/TopologySidebar/InterfaceDrawer/TopologyDrawer'; import { creatingPolicySignal } from './components/TopologySidebar/CreatePolicyDrawer'; -import TopologySidebar from './components/TopologySidebar/TopologySidebar'; import TopologyToolbar from './components/TopologyToolbar/TopologyToolbar'; import { GRAPH_POSITIONING_EVENT, NODE_POSITIONING_EVENT } from './utils/constants'; import { componentFactory, layoutFactory } from './utils/factory'; import { restoreNodePositions, saveNodePositions } from './utils/position'; import { transformDataToTopologyModel } from './utils/utils'; +import CustomDrawer from './components/TopologySidebar/CustomDrawer'; const Topology: FC = () => { useSignals(); const [visualization, setVisualization] = useState(null); + const [isOpen, setIsOpen] = useState(false); const [selectedNodeFilters, setSelectedNodeFilters] = useState([]); const history = useHistory(); const queryParams = useQueryParams(); - const [nodes] = useK8sWatchResource({ groupVersionKind: NodeModelGroupVersionKind, isList: true, @@ -134,7 +135,10 @@ const Topology: FC = () => { creatingPolicySignal.value, creatingPolicyNodesNames, ]); - + const handleCloseDrawer = (isOpen: boolean) => { + history.push({ search: '' }); + setIsOpen(isOpen); + }; if (statesError && statesError?.response?.status === 403) return ( <> @@ -147,47 +151,53 @@ const Topology: FC = () => { return ( - } - viewToolbar={ - - } - controlBar={ - { - const scale = visualization.getGraph().getScale(); - visualization.getGraph().setScale(scale * 1.1); - }), - zoomOutCallback: action(() => { - const scale = visualization.getGraph().getScale(); - visualization.getGraph().setScale(scale * 0.9); - }), - fitToScreenCallback: action(() => { - visualization.getGraph().fit(40); - }), - resetViewCallback: action(() => { - visualization.getGraph().reset(); - visualization.getGraph().layout(); - }), - })} - /> - } + history.push({ search: '' })} />} > - - } - hasAutoWidth - triggerRef={() => document.getElementById('legend') as HTMLButtonElement} - /> - + + } + controlBar={ + { + const scale = visualization.getGraph().getScale(); + visualization.getGraph().setScale(scale * 1.1); + }), + zoomOutCallback: action(() => { + const scale = visualization.getGraph().getScale(); + visualization.getGraph().setScale(scale * 0.9); + }), + fitToScreenCallback: action(() => { + visualization.getGraph().fit(40); + }), + resetViewCallback: action(() => { + visualization.getGraph().reset(); + visualization.getGraph().layout(); + }), + })} + /> + } + > + + } + hasAutoWidth + triggerRef={() => document.getElementById('legend') as HTMLButtonElement} + /> + + ); }; diff --git a/src/views/nodenetworkconfiguration/components/TopologySidebar/CreatePolicyDrawer.tsx b/src/views/nodenetworkconfiguration/components/TopologySidebar/CreatePolicyDrawer.tsx index 43d31ac1..18722d92 100644 --- a/src/views/nodenetworkconfiguration/components/TopologySidebar/CreatePolicyDrawer.tsx +++ b/src/views/nodenetworkconfiguration/components/TopologySidebar/CreatePolicyDrawer.tsx @@ -18,7 +18,7 @@ import { import { logCreationFailed, logNMStateEvent, logNNCPCreated } from '@utils/telemetry/telemetry'; type CreatePolicyDrawerProps = { - onClose?: () => void; + onClose?: (b: boolean) => void; onSuccess?: (message: string) => void; physicalNetworkName?: string; resetPolicyWizard: () => void; @@ -89,7 +89,7 @@ const CreatePolicyDrawer: FC = ({ const closeDrawer = () => { creatingPolicySignal.value = null; - onClose(); + onClose(true); }; return ( diff --git a/src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx b/src/views/nodenetworkconfiguration/components/TopologySidebar/CustomDrawer.tsx similarity index 94% rename from src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx rename to src/views/nodenetworkconfiguration/components/TopologySidebar/CustomDrawer.tsx index 0fb0acaa..67df6542 100644 --- a/src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx +++ b/src/views/nodenetworkconfiguration/components/TopologySidebar/CustomDrawer.tsx @@ -17,7 +17,7 @@ type DrawerProps = { onSuccess?: (message: string) => void; }; -const Drawer: FC = ({ states, onClose, onSuccess }) => { +const CustomDrawer: FC = ({ states, onClose, onSuccess }) => { const params = useQueryParams(); const [resetKey, setResetKey] = useState(0); @@ -57,4 +57,4 @@ const Drawer: FC = ({ states, onClose, onSuccess }) => { return null; }; -export default Drawer; +export default CustomDrawer; diff --git a/src/views/nodenetworkconfiguration/components/TopologySidebar/InterfaceDrawer/TopologyDrawer.tsx b/src/views/nodenetworkconfiguration/components/TopologySidebar/InterfaceDrawer/TopologyDrawer.tsx new file mode 100644 index 00000000..fdce5c9e --- /dev/null +++ b/src/views/nodenetworkconfiguration/components/TopologySidebar/InterfaceDrawer/TopologyDrawer.tsx @@ -0,0 +1,50 @@ +import React, { FC, ReactNode } from 'react'; +import { + Drawer, + DrawerContent, + DrawerContentBody, + DrawerPanelContent, + DrawerPanelBody, + Button, +} from '@patternfly/react-core'; +import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; + +type Props = { + isOpen: boolean; + onClose: (b: boolean) => void; + panel: ReactNode; + children: ReactNode; +}; + +const TopologyDrawer: FC = ({ isOpen, onClose, panel, children }) => ( + + + + + {isOpen && panel} + + + } + > + {children} + + +); + +export default TopologyDrawer; diff --git a/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.scss b/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.scss index 302172f9..97e97cad 100644 --- a/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.scss +++ b/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.scss @@ -22,6 +22,10 @@ } } +.nmstate-policy-wizard .pf-v6-c-wizard__main-body { + padding: 20px; +} + .pf-topology-side-bar.nmstate-topology__sidebar.big-sidebar { @media (min-width: 768px) { max-width: 100%; diff --git a/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.tsx b/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.tsx index a91bc2dc..30d580c1 100644 --- a/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.tsx +++ b/src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.tsx @@ -1,7 +1,6 @@ import React, { FC, useState } from 'react'; import { useHistory } from 'react-router'; import classNames from 'classnames'; - import { V1beta1NodeNetworkState } from '@kubevirt-ui/kubevirt-api/nmstate'; import { Alert, AlertActionCloseButton, AlertVariant } from '@patternfly/react-core'; import { TopologySideBar } from '@patternfly/react-topology'; @@ -9,8 +8,7 @@ import { isEmpty } from '@utils/helpers'; import useQueryParams from '@utils/hooks/useQueryParams'; import { CREATE_POLICY_QUERY_PARAM, SELECTED_ID_QUERY_PARAM } from './constants'; -import Drawer from './Drawer'; - +import CustomDrawer from './CustomDrawer'; import './TopologySidebar.scss'; type TopologySidebarProps = { @@ -34,7 +32,6 @@ const TopologySidebar: FC = ({ states }) => { return (
@@ -48,7 +45,7 @@ const TopologySidebar: FC = ({ states }) => { />
)} - +
); diff --git a/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.scss b/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.scss index 2be899b8..1e1103d0 100644 --- a/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.scss +++ b/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.scss @@ -1,5 +1,6 @@ .pf-v6-c-toolbar__group.pf-topology-view__view-toolbar { width: 100%; + padding-left: 200px; .pf-v6-c-toolbar { width: 100%; } @@ -10,6 +11,7 @@ div[id^='pf-topology-view-'] { } .topology-toolbar { + width: 100%; padding: var(--pf-t--global--spacer--md) 0; &__content { padding: 0 var(--pf-t--global--spacer--md); diff --git a/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.tsx b/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.tsx index cd5972d8..3d8b2109 100644 --- a/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.tsx +++ b/src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.tsx @@ -2,7 +2,6 @@ import React, { Dispatch, FC, SetStateAction } from 'react'; import { useHistory } from 'react-router'; import { useNavigate } from 'react-router-dom-v5-compat'; import NodeNetworkConfigurationPolicyModel from 'src/console-models/NodeNetworkConfigurationPolicyModel'; - import { NodeNetworkConfigurationPolicyModelRef, NodeNetworkStateModelRef } from '@models'; import { ListPageCreateDropdown } from '@openshift-console/dynamic-plugin-sdk'; import { @@ -16,25 +15,26 @@ import { import { ListIcon } from '@patternfly/react-icons'; import { getResourceUrl } from '@utils/helpers'; import { useNMStateTranslation } from '@utils/hooks/useNMStateTranslation'; - import { CREATE_POLICY_QUERY_PARAM } from '../TopologySidebar/constants'; - import TopologyToolbarFilter from './TopologyToolbarFilter'; - import './TopologyToolbar.scss'; type TopologyToolbarProps = { selectedNodeFilters: string[]; setSelectedNodeFilters: Dispatch>; nodeNames: string[]; + onOpen: (b: boolean) => void; }; -const TopologyButton: FC = (props) => { +const TopologyToolbar: FC = ({ + setSelectedNodeFilters, + onOpen, + nodeNames, + selectedNodeFilters, +}) => { const { t } = useNMStateTranslation(); const navigate = useNavigate(); - const setSelectedNodeFilters = props.setSelectedNodeFilters; const history = useHistory(); - const createItems = { form: t('From Form'), yaml: t('With YAML'), @@ -46,10 +46,12 @@ const TopologyButton: FC = (props) => { }); const newParams = new URLSearchParams({ [CREATE_POLICY_QUERY_PARAM]: 'true' }); - - return type === 'form' - ? history.push({ search: newParams.toString() }) - : history.push(`${baseURL}~new`); + if (type === 'form') { + onOpen(true); + return history.push({ search: newParams.toString() }); + } else { + return history.push(`${baseURL}~new`); + } }; return ( @@ -66,7 +68,11 @@ const TopologyButton: FC = (props) => { > {t('Create')} - + @@ -83,4 +89,4 @@ const TopologyButton: FC = (props) => { ); }; -export default TopologyButton; +export default TopologyToolbar;