Skip to content

Commit 53eba88

Browse files
committed
[UI] Query logs using descending and show timestamp per log entry #2892
1 parent 4864863 commit 53eba88

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed

frontend/src/pages/Runs/Details/Logs/index.tsx

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
1+
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import classNames from 'classnames';
44

5-
import { Code, Container, Header, ListEmptyMessage, Loader, TextContent } from 'components';
5+
import { Box, Code, Container, Header, ListEmptyMessage, Loader, TextContent, Toggle } from 'components';
66

77
import { useLazyGetProjectLogsQuery } from 'services/project';
88

9+
import { useLocalStorageState } from '../../../../hooks/useLocalStorageState';
910
import { decodeLogs } from './helpers';
1011

1112
import { IProps } from './types';
@@ -24,6 +25,16 @@ export const Logs: React.FC<IProps> = ({ className, projectName, runName, jobSub
2425
const [logsData, setLogsData] = useState<ILogItem[]>([]);
2526
const [isLoading, setIsLoading] = useState(false);
2627
const [getProjectLogs] = useLazyGetProjectLogsQuery();
28+
const [isEnabledDecoding, setIsEnabledDecoding] = useLocalStorageState('enable-encode-logs', false);
29+
// const [isShowTimestamp, setIsShowTimestamp] = useLocalStorageState('enable-showing-timestamp-logs', false);
30+
31+
const logsForView = useMemo(() => {
32+
if (isEnabledDecoding) {
33+
return decodeLogs(logsData);
34+
}
35+
36+
return logsData;
37+
}, [logsData, isEnabledDecoding]);
2738

2839
const saveScrollPositionByBottom = () => {
2940
if (!codeRef.current) return;
@@ -86,14 +97,14 @@ export const Logs: React.FC<IProps> = ({ className, projectName, runName, jobSub
8697
}, []);
8798

8899
useLayoutEffect(() => {
89-
if (logsData.length && logsData.length <= LIMIT_LOG_ROWS) {
100+
if (logsForView.length && logsForView.length <= LIMIT_LOG_ROWS) {
90101
scrollToBottom();
91102
} else {
92103
restoreScrollPositionByBottom();
93104
}
94105

95-
if (logsData.length) checkNeedMoreLoadingData();
96-
}, [logsData]);
106+
if (logsForView.length) checkNeedMoreLoadingData();
107+
}, [logsForView]);
97108

98109
const onScroll = useCallback<EventListener>(
99110
(event) => {
@@ -103,7 +114,7 @@ export const Logs: React.FC<IProps> = ({ className, projectName, runName, jobSub
103114
getNextLogItems();
104115
}
105116
},
106-
[isLoading, logsData],
117+
[isLoading, logsForView],
107118
);
108119

109120
useEffect(() => {
@@ -127,27 +138,57 @@ export const Logs: React.FC<IProps> = ({ className, projectName, runName, jobSub
127138
<div className={classNames(styles.logs, className)}>
128139
<Container
129140
header={
130-
<Header variant="h2">
131-
<div className={styles.headerContainer}>
132-
{t('projects.run.log')}
133-
<Loader show={isLoading} padding={'n'} className={classNames(styles.loader)} loadingText={''} />
141+
<div className={styles.headerContainer}>
142+
<div className={styles.headerTitle}>
143+
<Header variant="h2">{t('projects.run.log')}</Header>
144+
</div>
145+
146+
<Loader
147+
show={isLoading && Boolean(logsForView.length)}
148+
padding={'n'}
149+
className={styles.loader}
150+
loadingText={''}
151+
/>
152+
153+
<div className={styles.switchers}>
154+
<Box>
155+
<Toggle
156+
onChange={({ detail }) => setIsEnabledDecoding(detail.checked)}
157+
checked={isEnabledDecoding}
158+
>
159+
Decode
160+
</Toggle>
161+
</Box>
162+
163+
{/*<Box>*/}
164+
{/* <Toggle onChange={({ detail }) => setIsShowTimestamp(detail.checked)} checked={isShowTimestamp}>*/}
165+
{/* Show timestamp*/}
166+
{/* </Toggle>*/}
167+
{/*</Box>*/}
134168
</div>
135-
</Header>
169+
</div>
136170
}
137171
>
138172
<TextContent>
139-
{!isLoading && !logsData.length && (
173+
{!isLoading && !logsForView.length && (
140174
<ListEmptyMessage
141175
title={t('projects.run.log_empty_message_title')}
142176
message={t('projects.run.log_empty_message_text')}
143177
/>
144178
)}
145179

146-
<Code className={styles.terminal} ref={codeRef}>
147-
{logsData.map((log, i) => (
148-
<p key={i}>{log.message}</p>
149-
))}
150-
</Code>
180+
{!logsForView.length && <Loader show={isLoading} className={styles.mainLoader} />}
181+
182+
{Boolean(logsForView.length) && (
183+
<Code className={styles.terminal} ref={codeRef}>
184+
{logsForView.map((log, i) => (
185+
<p key={i}>
186+
{/*{isShowTimestamp && <span className={styles.timestamp}>{log.timestamp}</span>}*/}
187+
{log.message}
188+
</p>
189+
))}
190+
</Code>
191+
)}
151192
</TextContent>
152193
</Container>
153194
</div>

frontend/src/pages/Runs/Details/Logs/styles.module.scss

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,33 @@
44
display: flex;
55
gap: 10px;
66
align-items: center;
7+
padding-top: 4px;
8+
9+
.headerTitle {
10+
flex-shrink: 0;
11+
margin-top: -4px;
12+
}
13+
14+
.switchers {
15+
margin-left: auto;
16+
display: flex;
17+
gap: 24px;
18+
}
719
}
820

921
.loader {
1022
position: relative;
11-
top: -2px;
1223
height: 20px;
1324
background-color: rgba(awsui.$color-background-container-content, .8);
1425
color: #6e6e6e;
1526
}
1627

28+
.mainLoader {
29+
margin-top: auto;
30+
margin-bottom: auto;
31+
transform: translateY(-24px);
32+
}
33+
1734
.logs {
1835
display: flex;
1936
flex-direction: column;
@@ -56,10 +73,18 @@
5673
.terminal {
5774
flex-grow: 1;
5875
min-height: 0;
76+
height: 0;
5977
overflow-y: auto;
78+
background-color: awsui.$color-background-layout-main;
6079

6180
p {
6281
padding: 0 !important;
82+
font-size: awsui.$font-size-body-s !important;
83+
line-height: awsui.$line-height-body-s !important;
84+
85+
.timestamp {
86+
padding-right: 8px;
87+
}
6388
}
6489
}
6590

0 commit comments

Comments
 (0)