Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UX updates for pipeline logs #3295

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/concepts/dashboard/DashboardLogViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof LogViewer>['onScroll'];
height?: number | string;
isTextWrapped?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
ToolbarItem,
Tooltip,
Truncate,
Icon,
} 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';
Expand Down Expand Up @@ -97,6 +97,7 @@
};
}, [dispatchResizeEvent]);

// Scroll to bottom when log refreshes and streaming
React.useEffect(() => {
if (!isPaused && logs) {
if (logViewerRef.current) {
Expand All @@ -105,6 +106,16 @@
}
}, [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<typeof LogViewer>['onScroll'] = ({
scrollOffsetToBottom,
scrollUpdateWasRequested,
Expand Down Expand Up @@ -195,6 +206,8 @@
data = 'No logs available';
}

const rawLogsLink = `${location.origin}/api/k8s/api/v1/namespaces/${namespace}/pods/${podName}/log?container=${containerName}`;

return (
<Stack hasGutter>
<StackItem>
Expand All @@ -208,19 +221,18 @@
isCached={isCached}
isFailedPod={isFailedPod}
isLogsAvailable={podContainers.length !== 1 && !!logs}
onDownload={onDownloadAll}
onDownload={onDownload}
onDownloadAll={onDownloadAll}
rawLogsLink={rawLogsLink}
/>
)}
</StackItem>
<StackItem isFilled id="dashboard-logviewer" style={{ position: 'relative' }}>
{/* -33 to make room for the footer to pop in*/}
<div
style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: -33 }}
style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }}
ref={logsTabRef}
>
{/* 33 for the toolbar, 33 for the footer, and 1 because browser layout calculations sometimes go over by a fraction of a pixel */}
<DashboardLogViewer
height="calc(100% - 75px)"
data={data}
logViewerRef={logViewerRef}
isTextWrapped={isTextWrapped}
Expand Down Expand Up @@ -314,7 +326,7 @@
}}
/>
</ToolbarItem>
{(!podStatus?.completed || isPaused) && (
{!podStatus?.completed && (
<ToolbarItem spacer={{ default: 'spacerNone' }}>
<Button
variant={!logsLoaded ? 'plain' : isPaused ? 'plain' : 'link'}
Expand All @@ -323,16 +335,20 @@
data-testid="logs-pause-refresh-button"
>
{isPaused ? (
<Tooltip content="Resume refreshing">
<PlayIcon />
<Tooltip content="Resume log streaming.">

Check warning on line 338 in frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/runLogs/LogsTab.tsx#L338

Added line #L338 was not covered by tests
<Icon iconSize="md">
<OutlinedPlayCircleIcon />
</Icon>
</Tooltip>
) : !logsLoaded || podStatus?.podInitializing ? (
<Tooltip content="Loading log">
<Spinner size="sm" />
</Tooltip>
) : (
<Tooltip content="Pause refreshing">
<PauseIcon />
<Tooltip content="Pause log streaming.">
<Icon iconSize="md">
<OutlinedPauseCircleIcon />
</Icon>
</Tooltip>
)}
</Button>
Expand Down Expand Up @@ -394,7 +410,7 @@
<DropdownList>
<DropdownItem
isDisabled={!logs}
to={`${location.origin}/api/k8s/api/v1/namespaces/${namespace}/pods/${podName}/log?container=${containerName}`}
to={rawLogsLink}
target="_blank"
rel="noopener noreferrer"
icon={<OutlinedWindowRestoreIcon />}
Expand All @@ -418,19 +434,6 @@
</Toolbar>
)
}
footer={
logsLoaded &&
isPaused &&
!podStatus?.completed && (
<Button
onClick={() => setIsPaused(false)}
isBlock
icon={<OutlinedPlayCircleIcon />}
>
Resume refreshing log
</Button>
)
}
onScroll={onScroll}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type LogsTabStatusProps = {
isFailedPod?: boolean;
loaded: boolean;
onDownload: () => void;
onDownloadAll: () => void;
rawLogsLink: string;
};

const LogsTabStatus: React.FC<LogsTabStatusProps> = ({
Expand All @@ -28,6 +30,8 @@ const LogsTabStatus: React.FC<LogsTabStatusProps> = ({
loaded,
isFailedPod,
onDownload,
onDownloadAll,
rawLogsLink,
}) => {
if (isCached) {
return (
Expand Down Expand Up @@ -85,11 +89,28 @@ const LogsTabStatus: React.FC<LogsTabStatusProps> = ({
>
<p>
The log refreshes every {Math.floor(LOG_REFRESH_RATE / 1000)} seconds and displays the
latest {LOG_TAIL_LINES} lines. To view the full log for this task, you can{' '}
latest {LOG_TAIL_LINES} lines, with exceptionally long lines abridged. To view the full log
for this step,{' '}
<Button
isDisabled={!isLogsAvailable}
variant="link"
component="a"
href={rawLogsLink}
target="_blank"
rel="noopener noreferrer"
isInline
>
view its raw log
</Button>{' '}
or{' '}
<Button isDisabled={!isLogsAvailable} variant="link" isInline onClick={onDownload}>
download all step logs
download
</Button>{' '}
associated with it.
it. To view the full log for this task,{' '}
<Button isDisabled={!isLogsAvailable} variant="link" isInline onClick={onDownloadAll}>
download all of its associated step logs
</Button>
.
</p>
</Alert>
);
Expand Down
Loading