From 8a97f84fd6e23ca7ec76f660db464be3f724d085 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Date: Thu, 20 Jun 2024 17:06:49 -0400 Subject: [PATCH] Fix side panel sizing, scrolling, and contents --- frontend/src/app/App.scss | 6 + .../pipeline/PipelineDetails.tsx | 259 +++++++++--------- .../pipeline/SelectedTaskDrawerContent.tsx | 7 +- .../pipelineRun/PipelineRunDetails.tsx | 18 +- .../pipelineRun/PipelineRunDetailsTabs.tsx | 130 +++++---- .../PipelineRunDrawerRightContent.tsx | 4 +- .../pipelineRunJob/PipelineRunJobDetails.tsx | 18 +- .../concepts/topology/PipelineTopology.tsx | 2 +- .../topology/PipelineVisualizationSurface.tsx | 19 +- 9 files changed, 225 insertions(+), 238 deletions(-) diff --git a/frontend/src/app/App.scss b/frontend/src/app/App.scss index 60c55f9db1..3e4dd89d26 100644 --- a/frontend/src/app/App.scss +++ b/frontend/src/app/App.scss @@ -41,6 +41,12 @@ body, inset-inline-start: 12px; } } + .pf-topology-container { + overflow-y: hidden; + .pf-v5-c-drawer__panel.pf-m-resizable { + min-width: 350px; + } + } } // specificity targeting form elements to override --pf-v5-global--FontSize--md diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipeline/PipelineDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipeline/PipelineDetails.tsx index c0c6bc6cae..a96c62d4ec 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipeline/PipelineDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipeline/PipelineDetails.tsx @@ -3,11 +3,9 @@ import { useNavigate, useParams } from 'react-router-dom'; import { Breadcrumb, BreadcrumbItem, - Drawer, - DrawerContent, - DrawerContentBody, Flex, FlexItem, + PageSection, Tab, TabContent, TabContentBody, @@ -82,91 +80,89 @@ const PipelineDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath }) = ); } - const panelContent = selectedNode ? ( -
Hello world
- ) : null; - // setSelectedId(null)} - // />) : null; - - return ( <> - - {breadcrumbPath()} - - {/* TODO: Remove the custom className after upgrading to PFv6 */} - - - - {/* TODO: Remove the custom className after upgrading to PFv6 */} - - - - } - title={ - + {breadcrumbPath()} + + {/* TODO: Remove the custom className after upgrading to PFv6 */} + + + + {/* TODO: Remove the custom className after upgrading to PFv6 */} + + + + } + title={ + + } + {...(pipelineVersion && { + description: ( + + ), + })} + empty={false} + loaded={isLoaded} + headerAction={ + isPipelineVersionLoaded && ( + + + + navigate( + routePipelineDetailsNamespace( + namespace, + version.pipeline_id, + version.pipeline_version_id, + ), + ) + } /> - } - {...(pipelineVersion && { - description: ( - + + {isLoaded && ( + setDeletionOpen(true)} + pipeline={pipeline} + pipelineVersion={pipelineVersion} /> - ), - })} - empty={false} - loaded={isLoaded} - headerAction={ - isPipelineVersionLoaded && ( - - - - navigate( - routePipelineDetailsNamespace( - namespace, - version.pipeline_id, - version.pipeline_version_id, - ), - ) - } - /> - - - {isLoaded && ( - setDeletionOpen(true)} - pipeline={pipeline} - pipelineVersion={pipelineVersion} - /> - )} - - - ) - } - > + )} + + + ) + } + > + + + { setActiveTabKey(tabIndex); @@ -181,7 +177,6 @@ const PipelineDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath }) = aria-label="Pipeline Graph Tab" tabContentId={`tabContent-${PipelineDetailsTab.GRAPH}`} /> - Summary} @@ -191,7 +186,6 @@ const PipelineDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath }) = - Pipeline spec} @@ -200,52 +194,55 @@ const PipelineDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath }) = tabContentId={`tabContent-${PipelineDetailsTab.YAML}`} /> -
- - -
-
+ + + + + + + + {pipeline && ( = ({ t } return ( - + {task.name} {task.type === 'artifact' ? 'Artifact details' : ''} diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx index 5c3a185f8a..ddecfb44e1 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx @@ -2,8 +2,6 @@ import * as React from 'react'; import { Breadcrumb, BreadcrumbItem, - Drawer, - DrawerContent, EmptyState, EmptyStateIcon, EmptyStateVariant, @@ -96,10 +94,10 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath, const runType = run?.storage_state === StorageStateKF.ARCHIVED ? PipelineRunType.ARCHIVED : undefined; - const panelContent = selectedId ? ( + const panelContent = selectedNode ? ( <PipelineRunDrawerRightContent - task={selectedNode?.data.pipelineTask} - upstreamTaskName={selectedNode?.runAfterTasks?.[0]} + task={selectedNode.data.pipelineTask} + upstreamTaskName={selectedNode.runAfterTasks?.[0]} onClose={() => setSelectedId(null)} executions={executions} /> @@ -163,21 +161,15 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath, graphContent={ <PipelineTopology nodes={nodes} - sidePanel={panelContent} selectedIds={selectedId ? [selectedId] : []} onSelectionChange={(ids) => { - const firstId = ids[0]; - if (ids.length === 0) { - setSelectedId(null); - } else if (nodes.find((node) => node.id === firstId)) { - setSelectedId(firstId); - } + setSelectedId(ids.length ? ids[0] : null); }} + sidePanel={panelContent} /> } /> </ApplicationsPage> - <DeletePipelineRunsModal type={PipelineRunType.ARCHIVED} toDeleteResources={deleting && run ? [run] : []} diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx index 908cd4525a..00d588ec58 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx @@ -1,6 +1,15 @@ import React from 'react'; -import { Tabs, Tab, TabTitleText, TabContentBody, TabContent } from '@patternfly/react-core'; +import { + Tabs, + Tab, + TabTitleText, + TabContentBody, + TabContent, + PageSection, + FlexItem, + Flex, +} from '@patternfly/react-core'; import PipelineDetailsYAML from '~/concepts/pipelines/content/pipelinesDetails/PipelineDetailsYAML'; import { @@ -32,62 +41,71 @@ export const PipelineRunDetailsTabs: React.FC<PipelineRunDetailsTabsProps> = ({ const isJob = run && isPipelineRunJob(run); return ( - <> - <Tabs - activeKey={activeKey} - onSelect={(_, eventKey) => setActiveKey(eventKey)} - aria-label="Pipeline run details tabs" + <PageSection + isFilled + padding={{ default: 'noPadding' }} + style={{ flexBasis: 0, overflowY: 'hidden' }} + > + <Flex + direction={{ default: 'column' }} + style={{ height: '100%' }} + spaceItems={{ default: 'spaceItemsNone' }} > - <Tab - eventKey={DetailsTabKey.Graph} - tabContentId={DetailsTabKey.Graph} - title={<TabTitleText>Graph</TabTitleText>} - aria-label="Run graph tab" - data-testid="pipeline-run-tab-graph" - /> - - <Tab - eventKey={DetailsTabKey.Details} - title={<TabTitleText>Details</TabTitleText>} - aria-label="Run details tab" - data-testid="pipeline-run-tab-details" - > - <TabContentBody hasPadding> - <PipelineRunTabDetails workflowName={run?.display_name} run={run} /> - </TabContentBody> - </Tab> - - {!isJob && pipelineSpec && ( - <Tab + <FlexItem> + <Tabs + activeKey={activeKey} + onSelect={(_, eventKey) => setActiveKey(eventKey)} + aria-label="Pipeline run details tabs" + > + <Tab + eventKey={DetailsTabKey.Graph} + tabContentId={DetailsTabKey.Graph} + title={<TabTitleText>Graph</TabTitleText>} + aria-label="Run graph tab" + data-testid="pipeline-run-tab-graph" + /> + <Tab + eventKey={DetailsTabKey.Details} + title={<TabTitleText>Details</TabTitleText>} + aria-label="Run details tab" + data-testid="pipeline-run-tab-details" + > + <TabContentBody hasPadding> + <PipelineRunTabDetails workflowName={run?.display_name} run={run} /> + </TabContentBody> + </Tab> + {!isJob && pipelineSpec && ( + <Tab + eventKey={DetailsTabKey.Spec} + tabContentId={DetailsTabKey.Spec} + title={<TabTitleText>Pipeline spec</TabTitleText>} + aria-label="Run spec tab" + data-testid="pipeline-run-tab-spec" + /> + )} + </Tabs> + </FlexItem> + <FlexItem flex={{ default: 'flex_1' }} style={{ overflowY: 'hidden' }}> + <TabContent + id={DetailsTabKey.Graph} + eventKey={DetailsTabKey.Graph} + className="pf-v5-u-h-100" + hidden={activeKey !== DetailsTabKey.Graph} + > + <TabContentBody className="pf-v5-u-h-100">{graphContent}</TabContentBody> + </TabContent> + <TabContent + id={DetailsTabKey.Spec} eventKey={DetailsTabKey.Spec} - tabContentId={DetailsTabKey.Spec} - title={<TabTitleText>Pipeline spec</TabTitleText>} - aria-label="Run spec tab" - data-testid="pipeline-run-tab-spec" - /> - )} - </Tabs> - - <div style={{ flex: 1 }} hidden={activeKey !== DetailsTabKey.Graph}> - <TabContent - id={DetailsTabKey.Graph} - eventKey={DetailsTabKey.Graph} - className="pf-v5-u-h-100" - > - <TabContentBody className="pf-v5-u-h-100">{graphContent}</TabContentBody> - </TabContent> - </div> - - <TabContent - id={DetailsTabKey.Spec} - eventKey={DetailsTabKey.Spec} - hidden={activeKey !== DetailsTabKey.Spec} - style={{ flex: 1 }} - > - <TabContentBody className="pf-v5-u-h-100" hasPadding> - <PipelineDetailsYAML filename={run?.display_name} content={pipelineSpec} /> - </TabContentBody> - </TabContent> - </> + hidden={activeKey !== DetailsTabKey.Spec} + style={{ flex: 1 }} + > + <TabContentBody className="pf-v5-u-h-100" hasPadding> + <PipelineDetailsYAML filename={run?.display_name} content={pipelineSpec} /> + </TabContentBody> + </TabContent> + </FlexItem> + </Flex> + </PageSection> ); }; diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDrawerRightContent.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDrawerRightContent.tsx index cc9b916457..87fb500b60 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDrawerRightContent.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDrawerRightContent.tsx @@ -33,10 +33,8 @@ const PipelineRunDrawerRightContent: React.FC<PipelineRunDrawerRightContentProps return ( <DrawerPanelContent - isResizable - widths={{ default: 'width_33', lg: 'width_50' }} - minSize="500px" data-testid="pipeline-run-drawer-right-content" + style={{ height: '100%', overflowY: 'auto' }} > {task.type === 'artifact' ? ( <ArtifactNodeDrawerContent diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx index 77cf8ee130..ee0a22b007 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx @@ -2,8 +2,6 @@ import * as React from 'react'; import { Breadcrumb, BreadcrumbItem, - Drawer, - DrawerContent, EmptyState, EmptyStateIcon, EmptyStateVariant, @@ -51,8 +49,6 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ [selectedId, nodes], ); - const getFirstNode = (firstId: string) => nodes.find((n) => n.id === firstId)?.data?.pipelineTask; - const loaded = versionLoaded && jobLoaded; const error = versionError || jobError; @@ -76,9 +72,9 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ ); } - const panelContent = selectedId ? ( + const panelContent = selectedNode ? ( <SelectedTaskDrawerContent - task={selectedNode?.data.pipelineTask} + task={selectedNode.data.pipelineTask} onClose={() => setSelectedId(null)} /> ) : null; @@ -128,21 +124,15 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ graphContent={ <PipelineTopology nodes={nodes} - sidePanel={panelContent} selectedIds={selectedId ? [selectedId] : []} onSelectionChange={(ids) => { - const firstId = ids[0]; - if (ids.length === 0) { - setSelectedId(null); - } else if (getFirstNode(firstId)) { - setSelectedId(firstId); - } + setSelectedId(ids.length ? ids[0] : null); }} + sidePanel={panelContent} /> } /> </ApplicationsPage> - <DeletePipelineRunsModal type={PipelineRunType.SCHEDULED} toDeleteResources={deleting && job ? [job] : []} diff --git a/frontend/src/concepts/topology/PipelineTopology.tsx b/frontend/src/concepts/topology/PipelineTopology.tsx index def7635ffb..2cd2807b97 100644 --- a/frontend/src/concepts/topology/PipelineTopology.tsx +++ b/frontend/src/concepts/topology/PipelineTopology.tsx @@ -53,7 +53,7 @@ const PipelineTopology: React.FC<PipelineTopologyProps> = ({ return ( <VisualizationProvider controller={controller}> - <PipelineVisualizationSurface sidePanel={sidePanel} nodes={nodes} selectedIds={selectedIds} /> + <PipelineVisualizationSurface nodes={nodes} selectedIds={selectedIds} sidePanel={sidePanel} /> </VisualizationProvider> ); }; diff --git a/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx b/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx index 16602db058..488b579ba6 100644 --- a/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx +++ b/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx @@ -22,7 +22,6 @@ import { } from '@patternfly/react-core'; import { ExclamationCircleIcon } from '@patternfly/react-icons'; import { NODE_HEIGHT, NODE_WIDTH } from './const'; -import SelectedTaskDrawerContent from '../pipelines/content/pipelinesDetails/pipeline/SelectedTaskDrawerContent'; type PipelineVisualizationSurfaceProps = { nodes: PipelineNodeModel[]; @@ -42,12 +41,11 @@ const PipelineVisualizationSurface: React.FC<PipelineVisualizationSurfaceProps> let resizeTimeout: NodeJS.Timeout | null; if (selectedIds?.[0]) { - const selectedNode = controller?.getNodeById(selectedIds[0]); + const selectedNode = controller.getNodeById(selectedIds[0]); if (selectedNode) { // Use a timeout in order to allow the side panel to be shown and window size recomputed resizeTimeout = setTimeout(() => { - console.log(`======= Pan Node into view for: `, selectedNode.getLabel()); - controller?.getGraph().panIntoView(selectedNode, { offset: 20, minimumVisible: 100 }); + controller.getGraph().panIntoView(selectedNode, { offset: 20, minimumVisible: 100 }); resizeTimeout = null; }, 500); } @@ -153,14 +151,6 @@ const PipelineVisualizationSurface: React.FC<PipelineVisualizationSurfaceProps> ); } - const topologySideBar = ( - <TopologySideBar className="topology-example-sidebar" show={selectedIds?.length! > 0}> - {sidePanel} - </TopologySideBar> - ); - - console.log(sidePanel); - return ( <TopologyView controlBar={ @@ -192,8 +182,9 @@ const PipelineVisualizationSurface: React.FC<PipelineVisualizationSurfaceProps> })} /> } - sideBarOpen={!!selectedIds?.[0]} - sideBar={topologySideBar} + sideBarOpen={!!sidePanel} + sideBarResizable + sideBar={<TopologySideBar resizable>{sidePanel}</TopologySideBar>} > <VisualizationSurface state={{ selectedIds }} /> </TopologyView>