109 lines
No EOL
3.8 KiB
TypeScript
109 lines
No EOL
3.8 KiB
TypeScript
import React from 'react';
|
||
import { DeviceUser } from '../../../store/useDeviceStore';
|
||
|
||
interface TableScannerProps {
|
||
devices: DeviceUser[];
|
||
}
|
||
import styled from 'styled-components';
|
||
import {IconComponent} from "../../../const/buttons/icons";
|
||
import {buttonNames} from "../../../const/buttons/names";
|
||
import {ModalMap} from "../../modalwindows/windowsType";
|
||
import {useModalContext} from "../../../store";
|
||
|
||
const TableContainer = styled.div`
|
||
width: 100%;
|
||
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||
background: ${({ theme }) => theme.primary};
|
||
margin: 24px 0;
|
||
`;
|
||
|
||
const StyledTable = styled.table`
|
||
width: 100%;
|
||
border-collapse: separate;
|
||
border-spacing: 0;
|
||
`;
|
||
|
||
const TableHeaderCell = styled.th<{ sortable?: boolean }>`
|
||
padding: 16px 24px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
color: ${({ theme }) => theme.textSecondary};
|
||
background: ${({ theme }) => theme.primary};
|
||
border-bottom: 1px solid ${({ theme }) => theme.borderColor};
|
||
transition: all 0.2s ease;
|
||
`;
|
||
|
||
const TableRow = styled.tr<{ clickable?: boolean }>`
|
||
transition: all 0.2s ease;
|
||
&:hover {
|
||
background-color: ${({ theme }) => theme.background};
|
||
}
|
||
`;
|
||
|
||
const TableCell = styled.td`
|
||
padding: 16px 24px;
|
||
font-size: 14px;
|
||
color: ${({ theme }) => theme.text};
|
||
border-bottom: 1px solid ${({ theme }) => theme.borderColor};
|
||
transition: all 0.2s ease;
|
||
`;
|
||
|
||
const StatusBadge = styled.span<{ status:string }>`
|
||
width: 10px;
|
||
height: 30px;
|
||
background-color: ${({theme, status}) => (status==='online' ? theme.successColor : theme.offlineColor)};
|
||
display: inline-block;
|
||
border-radius:4px;
|
||
`
|
||
|
||
const TableScanner = ({devices}:TableScannerProps) => {
|
||
const { openModal } = useModalContext();
|
||
|
||
const openModalNote = (e: React.MouseEvent, device:DeviceUser ) => {
|
||
e.stopPropagation();
|
||
openModal(ModalMap['6'], {
|
||
address: device.mac,
|
||
currentNote: device.note || ''
|
||
});
|
||
};
|
||
|
||
return (
|
||
<TableContainer>
|
||
<StyledTable>
|
||
<thead>
|
||
<tr>
|
||
<TableHeaderCell></TableHeaderCell>
|
||
<TableHeaderCell>Имя</TableHeaderCell>
|
||
<TableHeaderCell>Производитель</TableHeaderCell>
|
||
<TableHeaderCell>IP адрес</TableHeaderCell>
|
||
<TableHeaderCell>Открытые порты</TableHeaderCell>
|
||
<TableHeaderCell>Последняя активность</TableHeaderCell>
|
||
<TableHeaderCell>Заметка</TableHeaderCell>
|
||
<TableHeaderCell></TableHeaderCell>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{devices.map((item, i) => (
|
||
<TableRow key={i}>
|
||
<TableCell><StatusBadge status={item.status}></StatusBadge></TableCell>
|
||
<TableCell>{item.hostname || item.ip}</TableCell>
|
||
<TableCell>{item.vendor}</TableCell>
|
||
<TableCell>{item.ip}</TableCell>
|
||
<TableCell>{item.open_ports.join(', ') || '-'}</TableCell>
|
||
<TableCell>{item.last_seen}</TableCell>
|
||
<TableCell>{item.note || '-'}</TableCell>
|
||
<TableCell>
|
||
<span onClick={(e)=>openModalNote(e, item)}>
|
||
<IconComponent name={buttonNames[16]} width="26" height="26" />
|
||
</span>
|
||
</TableCell>
|
||
</TableRow>
|
||
))}
|
||
</tbody>
|
||
</StyledTable>
|
||
</TableContainer>
|
||
);
|
||
};
|
||
|
||
export default TableScanner; |