diff --git a/packages/ui/src/components/JobCard/Details/Details.module.css b/packages/ui/src/components/JobCard/Details/Details.module.css
index d4107131..013faa79 100644
--- a/packages/ui/src/components/JobCard/Details/Details.module.css
+++ b/packages/ui/src/components/JobCard/Details/Details.module.css
@@ -19,10 +19,7 @@
flex: 1;
max-width: calc(100% - 80px);
overflow: hidden;
-}
-
-.tabContent.logs {
- overflow: visible;
+ position: relative;
}
.tabContent :global(.error) {
diff --git a/packages/ui/src/components/JobCard/Details/Details.tsx b/packages/ui/src/components/JobCard/Details/Details.tsx
index 7cd7f32c..0d9afb2e 100644
--- a/packages/ui/src/components/JobCard/Details/Details.tsx
+++ b/packages/ui/src/components/JobCard/Details/Details.tsx
@@ -29,11 +29,7 @@ export const Details = ({ status, job, actions }: DetailsProps) => {
))}
-
diff --git a/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.module.css b/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.module.css
index fbb95b0e..8e2dd65c 100644
--- a/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.module.css
+++ b/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.module.css
@@ -1,37 +1,35 @@
.jobLogs {
- margin: 0 10px 0 0;
- color: #000;
+ margin: 0;
+ overflow: hidden;
position: relative;
- border-radius: 4px;
+ background: #fff;
}
.preWrapper {
- padding: 0 15px;
- padding-top: 20px;
+ padding: 40px 1rem 1rem;
max-height: 100%;
overflow: auto;
height: 330px;
- background: #FFF;
}
-.preWrapper span {
+.preWrapper ol {
display: block;
white-space: pre-wrap;
word-break: break-all;
}
-.preWrapper span i {
- color: #999;
- font-style: normal;
+.preWrapper ol li::marker {
+ color: #a0aec0;
+ content: attr(data-line-number);
}
.preWrapper::-webkit-scrollbar {
- width: 0.35rem;
+ width: 0.5rem;
}
.preWrapper::-webkit-scrollbar-track {
padding: 2px;
- margin-top: 15px;
+ background: rgba(255, 255, 255, 0.2);
}
.preWrapper::-webkit-scrollbar-thumb {
@@ -39,68 +37,43 @@
border-radius: 4px;
}
-.jobLogs:fullscreen .preWrapper {
- height: 100%;
- padding-top: 55px;
- padding-bottom: 10px;
-}
-
-.jobLogs:fullscreen .preWrapper::-webkit-scrollbar {
- width: 0.55rem;
-}
-
.toolbar {
position: absolute;
- top: -30px;
- right: 0px;
- width: 100%;
- background: rgba(255, 255, 255, 0.5);
- padding-bottom: 3px;
- text-align: right;
- z-index: 9;
+ top: 0;
+ left: 15px;
+ right: 15px;
+ background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(4px);
+ padding: 0 0 1rem;
+ margin: 0;
+ list-style: none;
+ text-align: right;
+ z-index: 1;
display: flex;
}
-.jobLogs:fullscreen .toolbar {
- position: fixed;
- top: 0;
- width: 100%;
- padding-bottom: 15px;
+.toolbar > li:first-child {
+ flex: 1;
}
-.toolbar form {
- display: inline-block ;
+.toolbar > li button {
+ height: 100%;
}
-.toolbar button {
- margin-left: 1rem;
- font-size: 1rem;
- padding: 0.65rem;
+.toolbar > li + li {
+ margin-left: 0.5rem;
}
-.toolbar form {
- flex: 1;
- text-align: left;
-}
-
-.toolbar .searchBar {
- padding: 5px 15px;
- border-radius: 4px;
- border-bottom-right-radius: 0;
- border: none;
- outline: none;
- width: 100%;
- box-shadow: none !important;
- border-bottom: 1px solid #e0e7eb;
+.jobLogs:fullscreen .toolbar {
+ position: fixed;
+ padding: 1rem 0;
}
-.jobLogs:fullscreen .toolbar .searchBar {
- padding: 10px 15px;
- font-size: 1.25rem;
+.jobLogs:fullscreen .preWrapper {
+ height: 100%;
+ padding-top: 1rem !important;
}
-.toolbar button svg {
- width: 0.6rem;
- height: 0.6rem;
+.toolbar .searchBar {
+ width: 100%;
}
diff --git a/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.tsx b/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.tsx
index ca6b8807..856d2988 100644
--- a/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.tsx
+++ b/packages/ui/src/components/JobCard/Details/DetailsContent/JobLogs/JobLogs.tsx
@@ -1,11 +1,11 @@
-/* eslint-disable no-console */
-import React, { SyntheticEvent, useEffect, useState, useRef } from 'react';
import { AppJob } from '@bull-board/api/typings/app';
-import { Button } from '../../../Button/Button';
+import React, { SyntheticEvent, useEffect, useRef, useState } from 'react';
+import { useInterval } from '../../../../../hooks/useInterval';
+import { InputField } from '../../../../Form/InputField/InputField';
import { FullscreenIcon } from '../../../../Icons/Fullscreen';
-import { PlayIcon } from '../../../../Icons/Play';
import { PauseIcon } from '../../../../Icons/Pause';
-import { useInterval } from '../../../../../hooks/useInterval';
+import { PlayIcon } from '../../../../Icons/Play';
+import { Button } from '../../../Button/Button';
import s from './JobLogs.module.css';
interface JobLogsProps {
@@ -16,13 +16,13 @@ interface JobLogsProps {
}
interface LogType {
- lineNumber: number;
message: string;
+ lineNumber: number;
}
-const getLogType = ({ message }: LogType) => {
- const msgType = message?.match(/((info|warn|error)?):/i)?.[1] || '';
- return msgType.toLowerCase();
+const getLogType = (log: LogType) => {
+ const msgType = log.message?.match(/((info|warn|error)?):/i)?.[1];
+ return msgType?.toLowerCase();
};
const onClickFullScreen = (el: HTMLElement | null) => async () => {
@@ -34,12 +34,9 @@ const shouldShow = (log: LogType, keyword = '') => {
return !keyword || new RegExp(`${keyword}`, 'i').test(log.message);
};
-const formatLogs = (logs: string[]): LogType[] => {
- return logs.map((message, lineNumber) => ({
- message,
- lineNumber: lineNumber + 1,
- }));
-};
+function formatLogs(logs: string[]) {
+ return logs.map((message, i) => ({ message, lineNumber: i + 1 }));
+}
export const JobLogs = ({ actions, job }: JobLogsProps) => {
const [logs, setLogs] = useState([]);
@@ -73,12 +70,14 @@ export const JobLogs = ({ actions, job }: JobLogsProps) => {
liveLogs ? 2500 : null
);
- const onClickLiveLogsButton = () => {
+ const toggleLiveLogsButton = () => {
setLiveLogs(!liveLogs);
};
const onSearch = (event: SyntheticEvent) => {
- if (!!!event.currentTarget?.value) setKeyword('');
+ if (!event.currentTarget?.value) {
+ setKeyword('');
+ }
};
const onSearchSubmit = (event: SyntheticEvent) => {
@@ -88,36 +87,47 @@ export const JobLogs = ({ actions, job }: JobLogsProps) => {
return (
-
-
+
+ -
+
+
+
{!job.finishedOn && (
-
+ -
+
+
)}
-
-
+
+
+
+
- {logs
- .filter((log) => shouldShow(log, keyword))
- .map((log) => (
-
- {log.lineNumber} {log.message}
-
- ))}
+
+ {logs
+ .filter((log) => shouldShow(log, keyword))
+ .map((log) => (
+ -
+ {log.message}
+
+ ))}
+