UI tweaks (#800)

* style: placeholder for progress value

* style: rundown menu

* style: extracted rundown takes whole screen

* style: tweaks to rundown indicators

* feat: allow exporting info

* style: indicate action
This commit is contained in:
Carlos Valente
2024-03-03 20:42:36 +01:00
committed by GitHub
parent 0c31438e44
commit 8196ea584d
20 changed files with 166 additions and 87 deletions
@@ -34,6 +34,7 @@ $inner-padding: 1rem;
display: flex;
flex-direction: column;
gap: 1rem;
color: $ui-white;
}
.paragraph {
@@ -1,50 +0,0 @@
$info-gray: $secondary-text-gray;
$info-hover: $section-white;
.log {
font-size: $inner-section-text-size;
overflow-y: auto;
user-select: text;
min-height: 10vh;
max-height: 40vh;
}
.logEntry {
display: flex;
&.INFO {
color: $info-gray;
}
&.WARN {
color: $warning-orange;
}
&.ERROR {
color: $error-red;
}
&:hover {
color: $info-hover;
}
.time {
width: 4.5em;
}
.origin {
width: 6em;
}
.msg {
flex: 1;
}
}
.buttonBar {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
justify-content: flex-start;
padding-bottom: 0.5rem;
}
@@ -1,122 +0,0 @@
import { useCallback, useState } from 'react';
import { Button } from '@chakra-ui/react';
import { LogOrigin } from 'ontime-types';
import { clearLogs, useLogData } from '../../../../common/stores/logger';
import style from './Log.module.scss';
export default function Log() {
const { logs: logData } = useLogData();
const [showClient, setShowClient] = useState(true);
const [showServer, setShowServer] = useState(true);
const [showRx, setShowRx] = useState(true);
const [showTx, setShowTx] = useState(true);
const [showPlayback, setShowPlayback] = useState(true);
const [showUser, setShowUser] = useState(true);
const matchers: LogOrigin[] = [];
if (showUser) {
matchers.push(LogOrigin.User);
}
if (showClient) {
matchers.push(LogOrigin.Client);
}
if (showServer) {
matchers.push(LogOrigin.Server);
}
if (showRx) {
matchers.push(LogOrigin.Rx);
}
if (showTx) {
matchers.push(LogOrigin.Tx);
}
if (showPlayback) {
matchers.push(LogOrigin.Playback);
}
const filteredData = logData.filter((entry) => matchers.some((match) => entry.origin === match));
const disableOthers = useCallback((toEnable: LogOrigin) => {
toEnable === LogOrigin.User ? setShowUser(true) : setShowUser(false);
toEnable === LogOrigin.Client ? setShowClient(true) : setShowClient(false);
toEnable === LogOrigin.Server ? setShowServer(true) : setShowServer(false);
toEnable === LogOrigin.Rx ? setShowRx(true) : setShowRx(false);
toEnable === LogOrigin.Tx ? setShowTx(true) : setShowTx(false);
toEnable === LogOrigin.Playback ? setShowPlayback(true) : setShowPlayback(false);
}, []);
return (
<>
<div className={style.buttonBar}>
<Button
variant={showUser ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowUser((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.User)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.User}
</Button>
<Button
variant={showClient ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowClient((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.Client)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.Client}
</Button>
<Button
variant={showServer ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowServer((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.Server)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.Server}
</Button>
<Button
variant={showPlayback ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowPlayback((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.Playback)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.Playback}
</Button>
<Button
variant={showRx ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowRx((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.Rx)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.Rx}
</Button>
<Button
variant={showTx ? 'ontime-filled' : 'ontime-subtle'}
size='sm'
onClick={() => setShowTx((s) => !s)}
onAuxClick={() => disableOthers(LogOrigin.Tx)}
onContextMenu={(e) => e.preventDefault()}
>
{LogOrigin.Tx}
</Button>
<Button variant='ontime-outlined' size='sm' onClick={clearLogs}>
Clear
</Button>
</div>
<ul className={style.log}>
{filteredData.map((logEntry) => (
<li key={logEntry.id} className={`${style.logEntry} ${style[logEntry.level]} `}>
<span className={style.time}>{logEntry.time}</span>
<span className={style.origin}>{logEntry.origin}</span>
<span className={style.msg}>{logEntry.text}</span>
</li>
))}
</ul>
</>
);
}
@@ -0,0 +1,3 @@
.iconRotate {
transform: rotate(45deg);
}
@@ -0,0 +1,35 @@
import { MouseEvent } from 'react';
import { Button } from '@chakra-ui/react';
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
import { handleLinks } from '../../../../common/utils/linkUtils';
import Log from '../../../log/Log';
import * as Panel from '../PanelUtils';
import style from './LogExport.module.scss';
export default function LogExport() {
const extract = (event: MouseEvent) => {
handleLinks(event, 'log');
};
return (
<Panel.Section>
<Panel.Card>
<Panel.SubHeader>
Network log
<Button
variant='ontime-subtle'
size='sm'
rightIcon={<IoArrowUp className={style.iconRotate} />}
onClick={extract}
>
Extract
</Button>
</Panel.SubHeader>
<Panel.Divider />
<Log />
</Panel.Card>
</Panel.Section>
);
}
@@ -1,6 +1,6 @@
import * as Panel from '../PanelUtils';
import Log from './Log';
import LogExport from './LogExport';
import InfoNif from './NetworkInterfaces';
export default function LogPanel() {
@@ -8,19 +8,10 @@ export default function LogPanel() {
<>
<Panel.Header>Application log</Panel.Header>
<Panel.Section>
<Panel.SubHeader>Available networks</Panel.SubHeader>
<Panel.Card>
<Panel.Paragraph>Ontime is streaming on the following network interfaces</Panel.Paragraph>
<InfoNif />
</Panel.Card>
</Panel.Section>
<Panel.Section>
<Panel.SubHeader>Network log</Panel.SubHeader>
<Panel.Card>
<Log />
</Panel.Card>
<Panel.Paragraph>Ontime is streaming on the following network interfaces</Panel.Paragraph>
</Panel.Section>
<InfoNif />
<LogExport />
</>
);
}