import * as React from 'react'; import { Box, Flex, HStack, IconButton, Select, Spacer, Table, Text, Th, Thead, Tooltip, Tr } from '@chakra-ui/react'; import { Download } from '@phosphor-icons/react'; import { CSVLink } from 'react-csv'; import { useTranslation } from 'react-i18next'; import ReactVirtualizedAutoSizer from 'react-virtualized-auto-sizer'; import { FixedSizeList as List } from 'react-window'; import DeviceLogsSearchBar from './DeviceLogsSearchBar'; import { CardBody } from 'components/Containers/Card/CardBody'; import { CardHeader } from 'components/Containers/Card/CardHeader'; import ShownLogsDropdown from 'components/ShownLogsDropdown'; import { useControllerStore } from 'contexts/ControllerSocketProvider/useStore'; import { dateForFilename } from 'helpers/dateFormatting'; const LogsCard = () => { const { t } = useTranslation(); const { availableLogTypes, hiddenLogIds, setHiddenLogIds, logs } = useControllerStore((state) => ({ logs: state.allMessages, availableLogTypes: state.availableLogTypes, hiddenLogIds: state.hiddenLogIds, setHiddenLogIds: state.setHiddenLogIds, })); const [show, setShow] = React.useState<'' | 'connections' | 'statistics' | 'global_statistics'>(''); const [serialNumber, setSerialNumber] = React.useState(''); const onSerialSelect = React.useCallback((serial: string) => setSerialNumber(serial), []); const labels = { DEVICE_CONNECTION: t('common.connected'), DEVICE_DISCONNECTION: t('common.disconnected'), DEVICE_STATISTICS: t('controller.devices.new_statistics'), DEVICE_CONNECTIONS_STATISTICS: t('controller.dashboard.device_dashboard_refresh'), DEVICE_SEARCH_RESULTS: undefined, }; const data = React.useMemo(() => { let arr = logs.filter( ({ data: d }) => d.type === 'DEVICE_CONNECTION' || d.type === 'DEVICE_DISCONNECTION' || d.type === 'DEVICE_STATISTICS', ); if (show === 'connections') { arr = arr.filter( (msg) => msg.type === 'NOTIFICATION' && (msg.data.type === 'DEVICE_CONNECTION' || msg.data.type === 'DEVICE_DISCONNECTION'), ); } else if (show === 'statistics') { arr = arr.filter((msg) => msg.type === 'NOTIFICATION' && msg.data.type === 'DEVICE_STATISTICS'); } else if (show === 'global_statistics') { arr = arr.filter((msg) => msg.type === 'NOTIFICATION' && msg.data.type === 'DEVICE_CONNECTIONS_STATISTICS'); } if (serialNumber.trim().length > 0) { arr = arr.filter( (msg) => msg.data?.serialNumber !== undefined && typeof msg.data.serialNumber === 'string' && msg.data?.serialNumber.includes(serialNumber.trim()), ); } return arr.reverse(); }, [logs, show, serialNumber]); type RowProps = { index: number; style: React.CSSProperties }; const Row = React.useCallback( ({ index, style }: RowProps) => { const msg = data[index]; if (msg) { if (msg.type === 'NOTIFICATION' && msg.data.serialNumber) { return ( {msg.timestamp.toLocaleTimeString()} {msg.data?.serialNumber ?? '-'} {labels[msg.data.type] ?? msg.data.type} {JSON.stringify(msg.data)} ); } } return null; }, [t, data], ); const downloadableLogs = React.useMemo( () => data.map((msg) => ({ timestamp: msg.timestamp.toLocaleString(), serialNumber: msg.data?.serialNumber ?? '-', type: labels[msg.data?.type] ?? msg.data.type, data: JSON.stringify(msg.data), })), [data], ); return ( <> } colorScheme="blue" />
{t('common.time')} {t('inventory.serial_number')} {t('common.type')} {t('analytics.raw_data')}
{({ height, width }) => ( {Row} )}
); }; export default LogsCard;