Исправление бага с таблицей
Some checks failed
ci/woodpecker/manual/woodpecker Pipeline failed

This commit is contained in:
test 2025-07-04 15:16:50 +05:00
parent 1672f54e02
commit c423cf7172
6 changed files with 112 additions and 97 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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`,
});
}

View file

@ -69,41 +69,13 @@ 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 openModalNote = (e: React.MouseEvent, device:DeviceUser ) => {
e.stopPropagation();
openModal(ModalMap['6'], {
address: device.mac,
currentNote: device.note || ''
});
};
// Применение настроек отображения
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))
);
}, [ordersColumns, disabledColumns]);
// Пагинация
const paginateSetting = usePaginateSetting();
const [currentPage, setCurrentPage] = useState(1);
const [devicesPerPage, setDevicesPerPage] = useState(paginateSetting);
@ -111,65 +83,110 @@ const TableScanner = ({devices}:TableScannerProps) => {
setDevicesPerPage(paginateSetting);
}, [paginateSetting]);
const openModalNote = (e: React.MouseEvent, device: DeviceUser) => {
e.stopPropagation();
openModal(ModalMap['6'], {
address: device.mac,
currentNote: device.note || ''
});
};
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 indexOfLastDevice = currentPage * devicesPerPage;
const indexOfFirstDevice = indexOfLastDevice - devicesPerPage;
const currentDevices = devices.slice(indexOfFirstDevice, indexOfLastDevice);
const totalPages = Math.ceil(devices.length / devicesPerPage);
const handlePrevPage = () => {
if(currentPage > 1) setCurrentPage(currentPage - 1);
}
if (currentPage > 1) setCurrentPage(currentPage - 1);
};
const handleNextPage = () => {
if(currentPage < totalPages) setCurrentPage(currentPage + 1);
}
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;

View file

@ -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);

View file

@ -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);