lamassu-server/new-lamassu-admin/src/pages/Logs/MachineLogs.jsx
2025-05-12 09:45:43 +01:00

168 lines
4.3 KiB
JavaScript

import { useQuery, gql } from '@apollo/client'
import * as R from 'ramda'
import React, { useState } from 'react'
import LogsDowloaderPopover from 'src/components/LogsDownloaderPopper.jsx'
import Title from 'src/components/Title.jsx'
import Sidebar from 'src/components/layout/Sidebar.jsx'
import { Info3, H4 } from 'src/components/typography/index.jsx'
import {
Table,
TableHead,
TableRow,
TableHeader,
TableBody,
TableCell
} from 'src/components/table/index.js'
import { formatDate } from 'src/utils/timezones.js'
import classes from './Logs.module.css'
const GET_MACHINES = gql`
{
machines {
name
deviceId
}
}
`
const NUM_LOG_RESULTS = 500
const GET_MACHINE_LOGS_CSV = gql`
query MachineLogs(
$deviceId: ID!
$limit: Int
$from: DateTimeISO
$until: DateTimeISO
$timezone: String
) {
machineLogsCsv(
deviceId: $deviceId
limit: $limit
from: $from
until: $until
timezone: $timezone
)
}
`
const GET_MACHINE_LOGS = gql`
query MachineLogs(
$deviceId: ID!
$limit: Int
$from: DateTimeISO
$until: DateTimeISO
) {
machineLogs(
deviceId: $deviceId
limit: $limit
from: $from
until: $until
) {
logLevel
id
timestamp
message
}
}
`
const GET_DATA = gql`
query getData {
config
}
`
const Logs = () => {
const [selected, setSelected] = useState(null)
const [saveMessage, setSaveMessage] = useState(null)
const deviceId = selected?.deviceId
const { data: machineResponse, loading: machinesLoading } =
useQuery(GET_MACHINES)
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
const timezone = R.path(['config', 'locale_timezone'], configResponse)
const { data: logsResponse, loading: logsLoading } = useQuery(
GET_MACHINE_LOGS,
{
variables: { deviceId, limit: NUM_LOG_RESULTS },
skip: !selected,
onCompleted: () => setSaveMessage('')
}
)
if (machineResponse?.machines?.length && !selected) {
setSelected(machineResponse?.machines[0])
}
const isSelected = it => {
return R.path(['deviceId'])(selected) === it.deviceId
}
const loading = machinesLoading || configLoading || logsLoading
return (
<>
<div className={classes.titleWrapper}>
<div className={classes.titleAndButtonsContainer}>
<Title>Machine logs</Title>
{logsResponse && (
<div className={classes.buttonsWrapper}>
<LogsDowloaderPopover
title="Download logs"
name={selected.name}
query={GET_MACHINE_LOGS_CSV}
args={{ deviceId, timezone }}
getLogs={logs => R.path(['machineLogsCsv'])(logs)}
timezone={timezone}
/>
<Info3>{saveMessage}</Info3>
</div>
)}
</div>
</div>
<div className={classes.wrapper}>
<Sidebar
displayName={it => it.name}
data={machineResponse?.machines || []}
isSelected={isSelected}
onClick={setSelected}
/>
<div className={classes.tableWrapper}>
<Table className={classes.table}>
<TableHead>
<TableRow header>
<TableHeader className={classes.dateColumn}>Date</TableHeader>
<TableHeader className={classes.levelColumn}>Level</TableHeader>
<TableHeader className={classes.fillColumn} />
</TableRow>
</TableHead>
<TableBody>
{logsResponse &&
logsResponse.machineLogs.map((log, idx) => (
<TableRow key={idx} size="sm">
<TableCell>
{timezone &&
formatDate(log.timestamp, timezone, 'yyyy-MM-dd HH:mm')}
</TableCell>
<TableCell>{log.logLevel}</TableCell>
<TableCell>{log.message}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{loading && <H4>{'Loading...'}</H4>}
{!loading && !logsResponse?.machineLogs?.length && (
<H4>{'No activity so far'}</H4>
)}
</div>
</div>
</>
)
}
export default Logs