109 lines
3.8 KiB
TypeScript
109 lines
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;
|