Skip to content

Commit 2e7832d

Browse files
authored
feat: add reload button to logs (#839)
1 parent b26e631 commit 2e7832d

File tree

5 files changed

+64
-28
lines changed

5 files changed

+64
-28
lines changed

src/assets/icons/download-01.svg

Lines changed: 1 addition & 1 deletion
Loading

src/components/logs/enhanced-log-viewer.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import { useLogPageInput } from "./use-logpage-input";
1212

1313
interface EnhancedLogsViewerProps {
1414
logs: LogEntryInternal[];
15+
reloadLogs: () => void;
1516
itemsPerPage?: number; // Optional prop for items per page
1617
}
1718

1819
const DEFAULT_ITEMS_PER_PAGE = 100;
1920

2021
export function EnhancedLogsViewer({
2122
logs,
23+
reloadLogs,
2224
itemsPerPage = DEFAULT_ITEMS_PER_PAGE
2325
}: EnhancedLogsViewerProps) {
2426
const [currentPage, setCurrentPageState] = useState(1);
@@ -117,6 +119,7 @@ export function EnhancedLogsViewer({
117119
logLevel={selectedLogLevel}
118120
setLogLevel={setSelectedLogLevel}
119121
onSearchChange={setSearchQuery}
122+
onReload={reloadLogs}
120123
onCopyAll={handleCopyAllLogs}
121124
onDownload={handleDownloadLogs}
122125
searchQuery={searchQuery}
@@ -139,6 +142,7 @@ export function EnhancedLogsViewer({
139142
logLevel={selectedLogLevel}
140143
setLogLevel={setSelectedLogLevel}
141144
onSearchChange={setSearchQuery}
145+
onReload={reloadLogs}
142146
onCopyAll={handleCopyAllLogs}
143147
onDownload={handleDownloadLogs}
144148
searchQuery={searchQuery}

src/components/logs/toolbar.tsx

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import Copy from "@/assets/icons/copy.svg?react";
22
import Download from "@/assets/icons/download-01.svg?react";
33
import ArrowLeft from "@/assets/icons/arrow-left.svg?react";
4+
import Refresh from "@/assets/icons/refresh.svg?react";
45
import { Button } from "@zenml-io/react-component-library/components/server";
56
import { SearchField } from "../SearchField";
67
import { LogLevelSelect } from "./log-level-select";
78
import { LoggingLevel } from "@/types/logs";
89
import { Dispatch, SetStateAction } from "react";
10+
import {
11+
Tooltip,
12+
TooltipContent,
13+
TooltipProvider,
14+
TooltipTrigger
15+
} from "@zenml-io/react-component-library";
916

1017
interface LogToolbarProps {
1118
onSearchChange: (searchTerm: string) => void;
1219

20+
onReload: () => void;
1321
onCopyAll: () => void;
1422
onDownload: () => void;
1523
// Search-related props from useLogSearch hook
@@ -25,6 +33,7 @@ interface LogToolbarProps {
2533

2634
export function LogToolbar({
2735
onSearchChange,
36+
onReload,
2837
onCopyAll,
2938
onDownload,
3039
searchQuery = "",
@@ -83,33 +92,56 @@ export function LogToolbar({
8392
</div>
8493

8594
{/* Right side - Action Buttons */}
86-
<div className="flex items-center gap-2">
87-
<Button
88-
size="md"
89-
emphasis="subtle"
90-
intent="secondary"
91-
onClick={onCopyAll}
92-
title="Copy all displayed logs"
93-
className="bg-theme-surface-primary"
94-
>
95-
<Copy className="mr-1 h-4 w-4 fill-theme-text-secondary" />
96-
Copy All
97-
</Button>
95+
<TooltipProvider>
96+
<div className="flex items-center gap-2">
97+
<LogIconButton
98+
icon={<Refresh className="h-4 w-4 fill-theme-text-primary" />}
99+
tooltip="Reload logs"
100+
onClick={onReload}
101+
/>
98102

99-
<Button
100-
size="md"
101-
emphasis="subtle"
102-
intent="secondary"
103-
onClick={onDownload}
104-
title="Download logs as file"
105-
className="bg-theme-surface-primary"
106-
>
107-
<Download className="mr-1 h-5 w-5 fill-theme-text-tertiary" />
108-
Download
109-
</Button>
110-
</div>
103+
<LogIconButton
104+
icon={<Copy className="h-4 w-4 fill-theme-text-primary" />}
105+
tooltip="Copy all displayed logs"
106+
onClick={onCopyAll}
107+
/>
108+
109+
<LogIconButton
110+
icon={<Download className="h-4 w-4 fill-theme-text-primary" />}
111+
tooltip="Download logs as file"
112+
onClick={onDownload}
113+
/>
114+
</div>
115+
</TooltipProvider>
111116
</div>
112117
</div>
113118
</>
114119
);
115120
}
121+
122+
function LogIconButton({
123+
icon,
124+
tooltip,
125+
onClick
126+
}: {
127+
icon: React.ReactNode;
128+
tooltip: string;
129+
onClick: () => void;
130+
}) {
131+
return (
132+
<Tooltip delayDuration={200}>
133+
<TooltipTrigger>
134+
<Button
135+
size="md"
136+
emphasis="subtle"
137+
intent="secondary"
138+
onClick={onClick}
139+
className="flex aspect-square items-center justify-center bg-theme-surface-primary p-0"
140+
>
141+
{icon}
142+
</Button>
143+
</TooltipTrigger>
144+
<TooltipContent>{tooltip}</TooltipContent>
145+
</Tooltip>
146+
);
147+
}

src/components/runs/detail-tabs/LogTab/logs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function LogDisplay({ selectedSource, runId }: LogTabContentProps) {
8888

8989
return (
9090
<div className="h-full w-full">
91-
<EnhancedLogsViewer logs={parsedLogs} />
91+
<EnhancedLogsViewer logs={parsedLogs} reloadLogs={() => runLogs.refetch()} />
9292
</div>
9393
);
9494
}

src/components/steps/step-sheet/LogsTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type Props = {
1111
};
1212

1313
export function StepLogsTab({ stepId }: Props) {
14-
const { data, isPending, isError, error } = useStepLogs({ stepId });
14+
const { data, isPending, isError, error, refetch } = useStepLogs({ stepId });
1515

1616
const parsedLogs = useMemo(() => {
1717
if (!data) return [];
@@ -37,7 +37,7 @@ export function StepLogsTab({ stepId }: Props) {
3737

3838
return (
3939
<div className="space-y-5">
40-
<EnhancedLogsViewer logs={parsedLogs} />
40+
<EnhancedLogsViewer logs={parsedLogs} reloadLogs={refetch} />
4141
</div>
4242
);
4343
}

0 commit comments

Comments
 (0)