This commit is contained in:
parent
1672f54e02
commit
c423cf7172
6 changed files with 112 additions and 97 deletions
|
|
@ -76,7 +76,7 @@ export const NetworkInterfaces = ({ startConnection, ws }: Props) => {
|
|||
setHasInited(false)
|
||||
initializationAttempt.current = 0;
|
||||
|
||||
const newSocket = new WebSocket(`ws://${ws}:8001/api/v1`);
|
||||
const newSocket = new WebSocket(`wss://${ws}:8001/api/v1`);
|
||||
|
||||
let connectionTimeout;
|
||||
setSocket(newSocket);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export const DevicesBar = () => {
|
|||
|
||||
const checkWebSocketAvailability = async (ip: string): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
const testSocket = new WebSocket(`ws://${ip}:8001/api/v1`);
|
||||
const testSocket = new WebSocket(`wss://${ip}:8001/api/v1`);
|
||||
const timeout = setTimeout(() => {
|
||||
testSocket.close();
|
||||
resolve(false);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import axios, { AxiosResponse } from "axios";
|
||||
|
||||
const axiosWithoutCredentials = axios.create({
|
||||
baseURL: `http://localhost:8001`,
|
||||
baseURL: `https://localhost:8001`,
|
||||
})
|
||||
|
||||
export class NetworkService {
|
||||
static createAxiosInstance(ipAddress: string) {
|
||||
return axios.create({
|
||||
baseURL: `http://${ipAddress}:8001`,
|
||||
baseURL: `https://${ipAddress}:8001`,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,19 @@ const StatusBadge = styled.span<{ status:string }>`
|
|||
border-radius:4px;
|
||||
`
|
||||
|
||||
const TableScanner = ({devices}:TableScannerProps) => {
|
||||
export const TableScanner = ({ devices }: TableScannerProps) => {
|
||||
const { openModal } = useModalContext();
|
||||
const nameSetting = useNameSetting();
|
||||
const ordersColumns = useOrdersColumns();
|
||||
const disabledColumns = useDisabledColumns();
|
||||
const paginateSetting = usePaginateSetting();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [devicesPerPage, setDevicesPerPage] = useState(paginateSetting);
|
||||
|
||||
useEffect(() => {
|
||||
setDevicesPerPage(paginateSetting);
|
||||
}, [paginateSetting]);
|
||||
|
||||
const openModalNote = (e: React.MouseEvent, device: DeviceUser) => {
|
||||
e.stopPropagation();
|
||||
|
|
@ -81,36 +91,26 @@ const TableScanner = ({devices}:TableScannerProps) => {
|
|||
});
|
||||
};
|
||||
|
||||
// Применение настроек отображения
|
||||
const ordersColumns = useOrdersColumns();
|
||||
const disabledColumns = useDisabledColumns();
|
||||
const columnVisibility = useMemo(() => {
|
||||
return {
|
||||
status: !disabledColumns.includes(ordersColumns.indexOf('Онлайн')),
|
||||
name: !disabledColumns.includes(ordersColumns.indexOf('Имя')),
|
||||
vendor: !disabledColumns.includes(ordersColumns.indexOf('Производитель')),
|
||||
ip: !disabledColumns.includes(ordersColumns.indexOf('IP адрес')),
|
||||
ports: !disabledColumns.includes(ordersColumns.indexOf('Открытые порты')),
|
||||
activity: !disabledColumns.includes(ordersColumns.indexOf('Последняя активность')),
|
||||
note: !disabledColumns.includes(ordersColumns.indexOf('Заметка')),
|
||||
action: !disabledColumns.includes(ordersColumns.indexOf('Действие'))
|
||||
};
|
||||
}, [ordersColumns, disabledColumns]);
|
||||
const sortedColumns = useMemo(() => {
|
||||
return ordersColumns.filter(column =>
|
||||
!disabledColumns.includes(ordersColumns.indexOf(column))
|
||||
);
|
||||
const visibleColumns = useMemo(() => {
|
||||
return ordersColumns
|
||||
.filter(column => !disabledColumns.includes(ordersColumns.indexOf(column)))
|
||||
.map(column => {
|
||||
switch(column) {
|
||||
case 'Онлайн': return 'status';
|
||||
case 'Имя': return 'name';
|
||||
case 'Производитель': return 'vendor';
|
||||
case 'IP адрес': return 'ip';
|
||||
case 'Открытые порты': return 'ports';
|
||||
case 'Последняя активность': return 'activity';
|
||||
case 'Заметка': return 'note';
|
||||
case 'Действие': return 'action';
|
||||
default: return '';
|
||||
}
|
||||
})
|
||||
.filter(Boolean); // Убираем пустые значения
|
||||
}, [ordersColumns, disabledColumns]);
|
||||
|
||||
// Пагинация
|
||||
const paginateSetting = usePaginateSetting();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [devicesPerPage, setDevicesPerPage] = useState(paginateSetting);
|
||||
|
||||
useEffect(() => {
|
||||
setDevicesPerPage(paginateSetting);
|
||||
}, [paginateSetting]);
|
||||
|
||||
const indexOfLastDevice = currentPage * devicesPerPage;
|
||||
const indexOfFirstDevice = indexOfLastDevice - devicesPerPage;
|
||||
const currentDevices = devices.slice(indexOfFirstDevice, indexOfLastDevice);
|
||||
|
|
@ -118,58 +118,75 @@ const TableScanner = ({devices}:TableScannerProps) => {
|
|||
|
||||
const handlePrevPage = () => {
|
||||
if (currentPage > 1) setCurrentPage(currentPage - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextPage = () => {
|
||||
if (currentPage < totalPages) setCurrentPage(currentPage + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const onPageChange = (page: number) => {
|
||||
setCurrentPage(page);
|
||||
};
|
||||
|
||||
// Рендер ячейки таблицы
|
||||
const renderTableCell = (column: string, item: DeviceUser) => {
|
||||
switch (column) {
|
||||
case 'status':
|
||||
return <TableCell key="status"><StatusBadge status={item.status} /></TableCell>;
|
||||
case 'name':
|
||||
return <TableCell key="name">{item.hostname || (nameSetting === 'ip' ? item.ip : 'Неизвестно')}</TableCell>;
|
||||
case 'vendor':
|
||||
return <TableCell key="vendor">{item.vendor}</TableCell>;
|
||||
case 'ip':
|
||||
return <TableCell key="ip">{item.ip}</TableCell>;
|
||||
case 'ports':
|
||||
return <TableCell key="ports">{item.open_ports.join(', ') || '-'}</TableCell>;
|
||||
case 'activity':
|
||||
return <TableCell key="activity">{item.last_seen}</TableCell>;
|
||||
case 'note':
|
||||
return <TableCell key="note">{item.note || '-'}</TableCell>;
|
||||
case 'action':
|
||||
return (
|
||||
<TableCell key="action">
|
||||
<button onClick={(e) => openModalNote(e, item)}>
|
||||
<IconComponent name={buttonNames[16]} width="26" height="26" />
|
||||
</button>
|
||||
</TableCell>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<TableContainer>
|
||||
<StyledTable>
|
||||
<thead>
|
||||
<tr>
|
||||
{columnVisibility.status && <TableHeaderCell></TableHeaderCell>}
|
||||
{columnVisibility.name && <TableHeaderCell>Имя</TableHeaderCell>}
|
||||
{columnVisibility.vendor && <TableHeaderCell>Производитель</TableHeaderCell>}
|
||||
{columnVisibility.ip && <TableHeaderCell>IP адрес</TableHeaderCell>}
|
||||
{columnVisibility.ports && <TableHeaderCell>Открытые порты</TableHeaderCell>}
|
||||
{columnVisibility.activity && <TableHeaderCell>Последняя активность</TableHeaderCell>}
|
||||
{columnVisibility.note && <TableHeaderCell>Заметка</TableHeaderCell>}
|
||||
{columnVisibility.action && <TableHeaderCell></TableHeaderCell>}
|
||||
{visibleColumns.map(column => {
|
||||
switch (column) {
|
||||
case 'status': return <TableHeaderCell key="status"></TableHeaderCell>;
|
||||
case 'name': return <TableHeaderCell key="name">Имя</TableHeaderCell>;
|
||||
case 'vendor': return <TableHeaderCell key="vendor">Производитель</TableHeaderCell>;
|
||||
case 'ip': return <TableHeaderCell key="ip">IP адрес</TableHeaderCell>;
|
||||
case 'ports': return <TableHeaderCell key="ports">Открытые порты</TableHeaderCell>;
|
||||
case 'activity': return <TableHeaderCell key="activity">Последняя активность</TableHeaderCell>;
|
||||
case 'note': return <TableHeaderCell key="note">Заметка</TableHeaderCell>;
|
||||
case 'action': return <TableHeaderCell key="action"></TableHeaderCell>;
|
||||
default: return null;
|
||||
}
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{currentDevices.map((item, i) => (
|
||||
<TableRow key={i}>
|
||||
{columnVisibility.status && (
|
||||
<TableCell><StatusBadge status={item.status} /></TableCell>
|
||||
)}
|
||||
{columnVisibility.name && (
|
||||
<TableCell>
|
||||
{item.hostname || (nameSetting === 'ip' ? item.ip : 'Неизвестно')}
|
||||
</TableCell>
|
||||
)}
|
||||
{columnVisibility.vendor && <TableCell>{item.vendor}</TableCell>}
|
||||
{columnVisibility.ip && <TableCell>{item.ip}</TableCell>}
|
||||
{columnVisibility.ports && (
|
||||
<TableCell>{item.open_ports.join(', ') || '-'}</TableCell>
|
||||
)}
|
||||
{columnVisibility.activity && <TableCell>{item.last_seen}</TableCell>}
|
||||
{columnVisibility.note && <TableCell>{item.note || '-'}</TableCell>}
|
||||
{columnVisibility.action && (
|
||||
<TableCell>
|
||||
<button onClick={(e) => openModalNote(e, item)}>
|
||||
<IconComponent name={buttonNames[16]} width="26" height="26" />
|
||||
</button>
|
||||
</TableCell>
|
||||
)}
|
||||
{currentDevices.map((item, index) => (
|
||||
<TableRow key={index}>
|
||||
{visibleColumns.map(column => renderTableCell(column, item))}
|
||||
</TableRow>
|
||||
))}
|
||||
</tbody>
|
||||
</StyledTable>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Pagination
|
||||
onPageChange={onPageChange}
|
||||
|
|
@ -182,5 +199,3 @@ const TableScanner = ({devices}:TableScannerProps) => {
|
|||
</TableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableScanner;
|
||||
|
|
@ -76,7 +76,7 @@ export const NetworkInterfaces = ({ startConnection, ws }: Props) => {
|
|||
setHasInited(false)
|
||||
initializationAttempt.current = 0;
|
||||
|
||||
const newSocket = new WebSocket(`ws://${ws}:8001/api/v1`);
|
||||
const newSocket = new WebSocket(`wss://${ws}:8001/api/v1`);
|
||||
|
||||
let connectionTimeout;
|
||||
setSocket(newSocket);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export const DevicesBar = () => {
|
|||
|
||||
const checkWebSocketAvailability = async (ip: string): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
const testSocket = new WebSocket(`ws://${ip}:8001/api/v1`);
|
||||
const testSocket = new WebSocket(`wss://${ip}:8001/api/v1`);
|
||||
const timeout = setTimeout(() => {
|
||||
testSocket.close();
|
||||
resolve(false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue