From 421bdfdbacf1e7640c0fe7f98fd5deffba64cc70 Mon Sep 17 00:00:00 2001 From: Juntao Wang Date: Thu, 3 Oct 2024 11:19:24 -0400 Subject: [PATCH] UX updates for pipeline logs --- .../concepts/dashboard/DashboardLogViewer.tsx | 2 +- .../pipelineRun/runLogs/LogsTab.tsx | 415 +++++++++--------- .../pipelineRun/runLogs/LogsTabStatus.tsx | 27 +- 3 files changed, 226 insertions(+), 218 deletions(-) diff --git a/frontend/src/concepts/dashboard/DashboardLogViewer.tsx b/frontend/src/concepts/dashboard/DashboardLogViewer.tsx index d57fdc2428..bccd877da1 100644 --- a/frontend/src/concepts/dashboard/DashboardLogViewer.tsx +++ b/frontend/src/concepts/dashboard/DashboardLogViewer.tsx @@ -5,7 +5,7 @@ const DashboardLogViewer: React.FC<{ data: string; logViewerRef: React.MutableRefObject<{ scrollToBottom: () => void } | undefined>; toolbar: JSX.Element | boolean; - footer: JSX.Element | false; + footer?: JSX.Element | false; onScroll: React.ComponentProps['onScroll']; height?: number | string; isTextWrapped?: boolean; diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx index 869395a99c..dfa9b62986 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx @@ -18,15 +18,14 @@ import { Tooltip, Truncate, } from '@patternfly/react-core'; -import { OutlinedPlayCircleIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-play-circle-icon'; -import { PauseIcon } from '@patternfly/react-icons/dist/esm/icons/pause-icon'; -import { PlayIcon } from '@patternfly/react-icons/dist/esm/icons/play-icon'; import { DownloadIcon } from '@patternfly/react-icons/dist/esm/icons/download-icon'; import { LogViewer, LogViewerSearch } from '@patternfly/react-log-viewer'; import { CompressIcon, EllipsisVIcon, ExpandIcon, + OutlinedPauseCircleIcon, + OutlinedPlayCircleIcon, OutlinedWindowRestoreIcon, } from '@patternfly/react-icons'; import DashboardLogViewer from '~/concepts/dashboard/DashboardLogViewer'; @@ -97,6 +96,7 @@ const LogsTab: React.FC = ({ task, isCached }) => { }; }, [dispatchResizeEvent]); + // Scroll to bottom when log refreshes and streaming React.useEffect(() => { if (!isPaused && logs) { if (logViewerRef.current) { @@ -105,6 +105,16 @@ const LogsTab: React.FC = ({ task, isCached }) => { } }, [isPaused, logs]); + React.useEffect(() => { + const logWindowElement = document.querySelector( + '#dashboard-logviewer .pf-v5-c-log-viewer__main', + ); + if (logWindowElement) { + logWindowElement.addEventListener('mousedown', () => setIsPaused(true)); + } + return logWindowElement?.removeEventListener('mousedown', () => setIsPaused(true)); + }, []); + const onScroll: React.ComponentProps['onScroll'] = ({ scrollOffsetToBottom, scrollUpdateWasRequested, @@ -195,6 +205,8 @@ const LogsTab: React.FC = ({ task, isCached }) => { data = 'No logs available'; } + const rawLogsLink = `${location.origin}/api/k8s/api/v1/namespaces/${namespace}/pods/${podName}/log?container=${containerName}`; + return ( @@ -208,232 +220,207 @@ const LogsTab: React.FC = ({ task, isCached }) => { isCached={isCached} isFailedPod={isFailedPod} isLogsAvailable={podContainers.length !== 1 && !!logs} - onDownload={onDownloadAll} + onDownload={onDownload} + onDownloadAll={onDownloadAll} + rawLogsLink={rawLogsLink} /> )} - {/* -33 to make room for the footer to pop in*/} -
- {/* 33 for the toolbar, 33 for the footer, and 1 because browser layout calculations sometimes go over by a fraction of a pixel */} - - - - {!showSearchbar && ( - - setOpen(false)} - onOpenChange={(isOpen: boolean) => setOpen(isOpen)} - toggle={(toggleRef) => ( - setOpen(!open)} - isExpanded={open} - > - key.name === containerName)?.name ?? - 'Select container...' - } - className="truncate-no-min-width" - /> - - )} - shouldFocusToggleOnSelect - > - {defaultContainerName && ( - <> - - - onChange(defaultContainerName)} - > - {defaultContainerName} - - - - - - )} - - - {podContainers - .filter( - (podContainer) => podContainer.name !== defaultContainerName, - ) - .map((container) => ( - { - onChange(container.name); - }} - > - {container.name} - - ))} - - - - - )} - - { - if (!podStatus?.completed && logsLoaded) { - setIsPaused(true); - } - }} - placeholder="Search" - minSearchChars={0} - expandableInput={{ - isExpanded: showSearchbar, - onToggleExpand, - toggleAriaLabel: 'Expandable search input toggle', - }} - /> - - {(!podStatus?.completed || isPaused) && ( - - - - )} - - - - setIsTextWrapped(value)} - /> - - - {downloading && } - {podContainers.length <= 1 ? ( - Download current step log
}> - - ) - } - onScroll={onScroll} - /> - + )} + + { + if (!podStatus?.completed && logsLoaded) { + setIsPaused(true); + } + }} + placeholder="Search" + minSearchChars={0} + expandableInput={{ + isExpanded: showSearchbar, + onToggleExpand, + toggleAriaLabel: 'Expandable search input toggle', + }} + /> + + {!podStatus?.completed && ( + + + + )} + + + + setIsTextWrapped(value)} + /> + + + {downloading && } + {podContainers.length <= 1 ? ( + Download current step log}> + {' '} + or{' '} {' '} - associated with it. + it. To view the full log for this task,{' '} + + .

);