фронт

This commit is contained in:
test 2025-06-09 10:31:14 +05:00
parent eb1f18f53e
commit d67ea17fd7
160 changed files with 2611 additions and 5680 deletions

View file

@ -1,20 +0,0 @@
import { useIpStore } from "../store";
import { useAdminStore } from "../store/adminStore";
import { useEffect } from "react";
import { NetworkService } from "../api/request";
export const useCheckAdmin = () => {
const { ipAddress } = useIpStore()
const { setAdmin } = useAdminStore()
return async () => {
const response = await NetworkService.whoami(ipAddress);
console.log(response.data);
if(response.status == 401){
setAdmin(false)
}
else{
setAdmin(response.data.user.is_admin);
}
}
}

View file

@ -1,104 +0,0 @@
export const processNodeChanges = (changes: any, mainGroups: any) => {
let newData;
changes.forEach((change: any) => {
if (change.type === 'position' && change.position) {
const nodeId = change.id;
if (nodeId === 'g0') {
newData = {
container_id: mainGroups[0].id,
container_x: change.position.x,
container_y: change.position.y,
isOpen: true
};
} else if (nodeId === 'g1') {
newData = {
container_id: mainGroups[1].id,
container_x: change.position.x,
container_y: change.position.y,
isOpen: true
};
}
}
});
return newData;
};
const getLastChanges = (changes: any[]) => {
const latestChanges: { [key: number]: any } = {};
changes.forEach((change) => {
latestChanges[change.container_id] = change;
});
return Object.values(latestChanges);
};
export const autosavePosition = (changeArray: any[], socket: any,) => {
if (changeArray.length > 0) {
const lastChanges = getLastChanges(changeArray);
lastChanges.forEach((change) => {
if (socket && socket.readyState === WebSocket.OPEN && change) {
socket.send(JSON.stringify(change))
console.log('JSON отправлен:', JSON.stringify(change));
console.log('Отправленные данные:', change);
} else {
console.log('WebSocket не открыт или нет данных для отправки');
}
});
}
}
export const resetPosition = (socket: any, setNullPos: (value: boolean) => void, nodes: any[], setNodes: (nodes: any[]) => void) => {
const nullPositions = [
{
container_id: 1,
container_x: 0,
container_y: 0,
isOpen: true
},
{
container_id: 2,
container_x: 500,
container_y: 0,
isOpen: true
},
]
nullPositions.forEach(pos => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(pos))
console.log('JSON отправлен:', JSON.stringify(pos))
console.log('Отправленные данные:', pos)
} else {
console.log('WebSocket не открыт или нет данных для отправки')
}
})
const updatedNodes = nodes.map(node => {
if(node.id=="g0"){
return {
...node,
position: { x: 0, y: 0 },
positionAbsolute: { x: 0, y: 0 }
};
}
if(node.id=="g1"){
return {
...node,
position: { x: 500, y: 0 },
positionAbsolute: { x: 500, y: 0 }
};
}
return node;
});
setNodes(updatedNodes);
setNullPos(false);
}

View file

@ -1,65 +0,0 @@
export const collapseGroup = (sortedGroup: any, nodes: any[]) => {
const nodesMap = new Map<string, any>(nodes.map(node => [node.id, structuredClone(node)]));
Object.entries(sortedGroup).forEach(([groupId, groupData]: any) => {
const groupNode = nodesMap.get(groupId);
if (!groupNode) return;
const clicked = groupData.clicked;
const padding = 20;
const higherOrderNodes = groupData.higherOrder.map((childId: string) => {
const child = nodesMap.get(childId);
if (!child) return null;
const newHeight = clicked ? 60 : child.data.height;
const updatedChild = {
...child,
data: {
...child.data,
visible: !clicked,
style: { ...child.data.style, height: newHeight }
},
measured: {
...child.measured,
height: newHeight + 4,
width: child.data.style.width + 4
}
};
nodesMap.set(childId, updatedChild);
return updatedChild;
}).filter(Boolean);
groupData.lowerOrder.forEach((childId: string) => {
const child = nodesMap.get(childId);
if (child) child.hidden = clicked;
});
let currentY = padding;
higherOrderNodes.forEach((child: any) => {
nodesMap.set(child.id, {
...child,
position: { ...child.position, y: currentY }
});
currentY += child.measured.height + padding;
});
const newGroupHeight = clicked
? currentY
: groupNode.data.height;
nodesMap.set(groupId, {
...groupNode,
data: {
...groupNode.data,
style: { ...groupNode.data.style, height: newGroupHeight }
},
measured: {
...groupNode.measured,
height: newGroupHeight + 4
}
});
});
return Array.from(nodesMap.values());
};

View file

@ -1,37 +0,0 @@
export const groupSort = (groups: any, nodes: any)=>{
const result: {
[key: string]: {
higherOrder: string[];
lowerOrder: string[];
clicked: boolean
};
} = {};
groups.forEach((group: any) => {
const groupId = group.id;
result[groupId] = {
higherOrder: [],
lowerOrder: [],
clicked: group.click
};
const children = nodes.filter((node: any) => node.id.startsWith(`${groupId}_`));
children.forEach((child: any) => {
const childId = child.id;
const parts = childId.split('_');
if (parts.length === 2) {
const higherOrderValue = childId
result[groupId].higherOrder.push(higherOrderValue)
} else {
const lowerOrderValue = childId
result[groupId].lowerOrder.push(lowerOrderValue)
}
});
});
return result
}

View file

@ -1,6 +0,0 @@
export { autosavePosition, processNodeChanges , resetPosition} from './autosavePosition';
export { initNetworkIntData } from './initNetIntData';
export { collapseGroup } from './collapseGroup';
export {groupSort} from './groupSort'
export { updateWifiData } from './updateWifiData';
export {useInitCanvas} from './nodeCreator/inits/initor'

View file

@ -1,60 +0,0 @@
import { ResponseData, Interfaces, MainData, IEdge, NetworkData } from '../../const/types/types'
import { ipsInitor } from './nodeCreator/inits/initIpArray';
export const initNetworkIntData = (mainGroups: ResponseData[]): { interfaces: Interfaces[], edgeData: IEdge[] } => {
const edgeData: IEdge[] = [];
const interfaces: Interfaces[] = [];
if (mainGroups) {
mainGroups.map((el, indx) => {
let nodeData: MainData[] = [];
el.interfaces.map((net, index) => {
let nodeID = `g${indx}_nw${index}`;
let portID = `p-nw${index}`;
let targetId = `${portID}_target-right`;
let sourceId = `${nodeID}-source-left`;
if (indx === 0) {
const edge: IEdge = {
id: `${nodeID}-${portID}`,
source: nodeID,
target: portID,
sourceHandle: sourceId,
targetHandle: targetId,
type: "default",
};
edgeData.push(edge);
}
const network: NetworkData = {
device: net.name,
type: net.type,
mac: net.mac_address,
connection: net.active_connection,
mtu: net.device_mtu,
state: net.device_state,
strength: net.strength
};
const ipArray = ipsInitor(net);
let interfaceData: MainData = {
networkData: network,
ipArrays: ipArray
};
nodeData.push(interfaceData);
});
let j: Interfaces = {
container_x: el.container_x,
container_y: el.container_y,
mainData: nodeData
};
interfaces.push(j);
});
}
return { interfaces, edgeData };
};

View file

@ -1,33 +0,0 @@
type StateType = Record<string, string>;
export const stateMap: StateType = {
'0': "Неизвестно",
'10': "Не обслуживается",
'20': "Недоступно",
'30': "Отключено",
'40': "Подготовка",
'50': "Конфигурация",
'60': "Требуется аутентификация",
'70': "Настройка IP",
'80': "Проверка IP",
'90': "Дополнительные настройки",
'100': "Подключено",
'110': "Отключается",
'120': "Ошибка",
}
export const stateColor: StateType = {
'0': "#7e7e7e",
'10': "#d95454",
'20': "#d95454",
'30': "#d95454",
'40': "",
'50': "",
'60': "",
'70': "",
'80': "",
'90': "",
'100': "#66BB6A",
'110': "",
'120': "",
}

View file

@ -1,19 +0,0 @@
import { useState } from "react";
import { IEdge } from "../../../../const/types/types";
export const useInitEdges = () => {
const [initedEdges, setEdges] = useState<IEdge[]>([])
const setInitEdges = (something: IEdge[]) => {
setEdges((prevEdges) => {
const edges: IEdge[] = []
something.map(edge=>{
edges.push(edge)
})
return [...prevEdges, ...edges]
})
}
return { initedEdges, setInitEdges }
}

View file

@ -1,44 +0,0 @@
import { ResponseIpConf, ResponseNetwork, IpData } from "../../../../const/types/types"
interface IpArray {
route: boolean,
ipData: IpData[]
}
export const ipsInitor = (network: ResponseNetwork) => {
const array: IpArray[] = [
{ route: true, ipData: [] },
{ route: false, ipData: [] },
];
const ipArrayInit = (ip: ResponseIpConf, version: string) => {
const isRouted = ip.routes.length > 0
const newData: IpData = {
ipType: ip.method,
ipAdress: ip.address,
ipGate: ip.gateway,
ipDns: ip.dns,
ipRoutese: ip.routes,
ipVersion: version
};
if (isRouted) {
array[0].ipData.push(newData);
} else {
array[1].ipData.push(newData);
}
}
network.ipv4.configurations.forEach((ip: ResponseIpConf) => {
ipArrayInit(ip, '4')
});
network.ipv6.configurations.forEach((ip: ResponseIpConf) => {
ipArrayInit(ip, '6')
});
const resultArray = array.filter((item) => item.ipData.length > 0);
return resultArray;
}

View file

@ -1,297 +0,0 @@
import { useState } from "react";
import { NodeColors } from "../../../../components/customeNodes/types/colors";
import { stateColor, stateMap } from "../deviceState";
import { Interfaces, NetworkNode, IpNode, PortNode, NodeGroup, NetworkInterface } from "../../../../const/types/types"
export const useInitNodes = () => {
const [initedNodes, setNodes] = useState<(NetworkInterface)[]>([]);
const yGap = 20
interface MainHeight {
x?: number,
y?: number,
height?: number;
}
const findMaxHeight = (data: any[])=>{
const filtred = data.filter((el)=> el.x ===0 || el.x ===1)
if(filtred.length ===0){
return 140
}
const max =filtred.reduce((max, el)=> Math.max(max, el.height), 0)
return max
}
const setInitNodes = (interfaces: Interfaces[]) => {
setNodes(() => {
const networkNodes: NetworkNode[] = []
const portNodes: PortNode[] = []
const ipGroupes: NodeGroup[][] = []
const ipNodes: IpNode[][] = []
const networkGroups: NodeGroup[] = []
let width: number, columnCount: MainHeight[] = []
let widthArr: number[] = []
let heightArr: number[] = []
interfaces.map((b, indexB) => {
const centerX = 20
const centerY = 20
let currentY = centerY;
b.mainData.map((data, networkIndex) => {
data.ipArrays.map((el) => {
if (el.route === true) {
const column = { x: 1 }
columnCount.push(column)
}
else if (el.route === false) {
const column = { x: 0 }
columnCount.push(column)
}
})
if (columnCount.length == 2) {
width = (260 * 2) + 45
}
else {
width = 260 + 35
}
let mainHeight: MainHeight[] = []
data.ipArrays.forEach((ipInfo, groupIndx) => {
if(!ipInfo || !ipInfo.ipData || ipInfo.ipData.length ===0){
return
}
let groupes: NodeGroup[] = []
let nodeCount = ipInfo.ipData.length
let x = 20, y = 150, newX, newY, gap = 0
let height = (140 + 15) * (nodeCount)
if (ipInfo.route) {
newX = width - 260 - 15
const groupHeight = {
x: 1,
height: height
}
mainHeight.push(groupHeight)
}
else {
newX = x
const groupHeight = {
x: 0,
height: height
}
mainHeight.push(groupHeight)
}
const newIpGroupe: NodeGroup = {
id: `g${indexB}_nw${networkIndex}_rx${groupIndx}`,
position: {
x: newX,
y: y
},
data: {
style: {
width: 260,
height: height
}
},
hidden: false,
type: "ipgroup",
parentId: `g${indexB}_nw${networkIndex}`,
extent: 'parent',
draggable: false,
}
let startY = 0
const ipGap = 15
ipInfo.ipData.map((ip, ipIndex) => {
let nodes: IpNode[] = []
const y = startY;
startY += 140 + ipGap;
const newIpNode: IpNode = {
id: `g${indexB}_nw${networkIndex}_rx${groupIndx}_ip${ipIndex}`,
position: {
x: 0,
y: y
},
type: 'ip',
data: {
ipData: {
ipType: ip.ipType,
ipAdress: ip.ipAdress,
ipGate: ip.ipGate,
ipDns: ip.ipDns,
ipRoutese: [],
ipVersion: ip.ipVersion
},
interfaceData:{
device: data.networkData.device,
connection: data.networkData.connection,
},
route: ipInfo.route,
style: {
width: 260,
height: 140,
borderType: "solid",
borderColor: NodeColors["1"],
},
},
hidden: false,
parentId: `g${indexB}_nw${networkIndex}_rx${groupIndx}`,
extent: 'parent',
draggable: false,
}
nodes.push(newIpNode)
ipNodes.push(nodes)
})
groupes.push(newIpGroupe)
ipGroupes.push(groupes)
})
const maxHeight = findMaxHeight(mainHeight);
// const networkNodeHeight = (maxHeight || 0) + 150;
const networkNodeHeight = maxHeight +150
let groupId: string
if (data.networkData.connection === 'unknown') {
groupId = 'cn1'
}
else {
groupId = 'cn0'
}
const y = currentY;
currentY += networkNodeHeight + yGap;
const newNode: NetworkNode = {
id: `g${indexB}_nw${networkIndex}`,
position: {
x: centerX,
y: y
},
type: "network",
data: {
networkData: {
device: data.networkData.device,
type: data.networkData.type,
mac: data.networkData.mac,
mtu: data.networkData.mtu,
state: stateMap[data.networkData.state],
connection: data.networkData.connection,
id: `nw${networkIndex}`,
strength: data.networkData.strength
},
style: {
width: width,
height: networkNodeHeight as number,
borderType: "solid",
borderColor: NodeColors["0"],
backgroundColor: stateColor[data.networkData.state]
},
height: networkNodeHeight,
visible: true
},
parentId: `g${indexB}`,
extent: 'parent',
};
widthArr.push(width)
heightArr.push(networkNodeHeight)
networkNodes.push(newNode)
columnCount = []
let portNodeHeight = 60;
let absoluteY = (currentY - portNodeHeight + 10) - (networkNodeHeight / 2);
if (data.networkData.connection !== 'unknown') {
const portNode: PortNode = {
id: `p-nw${networkIndex}`,
position: {
x: -350,
y: absoluteY,
},
type: 'portNode',
data: {
label: `${data.networkData.connection}`,
id: `p-nw${networkIndex}`,
style: {
width: 260,
height: portNodeHeight,
borderType: "solid",
borderColor: NodeColors["0"],
},
}
}
portNodes.push(portNode)
}
})
const sumHeight = heightArr.reduce((a, c) => a + c, 0);
const maxWidth = Math.max(...widthArr)
let count = b.mainData.length
let groupHeight = sumHeight + (count * 30)
let groupWidth = maxWidth + 40
let label: string;
if (indexB == 0) {
label = 'Активные интерфейсы'
}
else {
label = 'Неактивные интерфейсы'
}
let x = b.container_x
if (indexB > 0 && x === 0) {
x = x + 500
}
if (b.mainData.length > 0) {
const networkGroup: NodeGroup = {
id: `g${indexB}`,
position: {
x: x,
y: b.container_y
},
type: "nodegroup",
data: {
label: label,
id: `g${indexB}`,
height: groupHeight,
style: {
width: groupWidth,
height: groupHeight,
borderType: "solid",
borderColor: NodeColors["0"],
},
},
}
networkGroups.push(networkGroup)
}
heightArr = []
})
return [...networkGroups, ...networkNodes, ...ipGroupes.flat(), ...portNodes, ...ipNodes.flat()];
});
};
return { initedNodes, setInitNodes };
};

View file

@ -1,15 +0,0 @@
import { useInitNodes } from "./initNodes";
import { useInitEdges } from "./initEdges";
import { IEdge, Interfaces } from "../../../../const/types/types";
export const useInitCanvas = () => {
const { initedNodes, setInitNodes } = useInitNodes();
const { initedEdges, setInitEdges } = useInitEdges();
const handleInit = (edgeData: IEdge[], interfaces: Interfaces[])=>{
setInitNodes(interfaces)
setInitEdges(edgeData)
}
return { initedNodes, initedEdges, handleInit };
};

View file

@ -1,21 +0,0 @@
export const updateWifiData = (wifiData: any, nodes: any)=>{
const wifiName = wifiData.name;
const updatedNodes = nodes.map((node: any) => {
if (node.data.networkData && node.data.networkData.device === wifiName) {
return {
...node,
data: {
...node.data,
networkData: {
...node.data.networkData,
strength: wifiData.strength,
},
},
};
}
return node;
});
return updatedNodes
}

View file

@ -1,35 +0,0 @@
export const validateIPAddress = (ip: string) => {
const ipv4Pattern = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const ipv6Pattern = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
return ipv4Pattern.test(ip) || ipv6Pattern.test(ip);
};
export const validateSameSubnet = (ip1: string, ip2: string, ip3: string | string[]): boolean => {
const extractSubnet = (ip: string): string => {
if (typeof ip !== 'string') {
throw new TypeError(`Некорректный формат IP-адреса: ${ip}`);
}
return ip.split('.').slice(0, 3).join('.');
};
const areInSameSubnet = (ip: string, subnet: string): boolean => {
return extractSubnet(ip) === subnet;
};
try {
const subnet1 = extractSubnet(ip1);
const subnet2 = extractSubnet(ip2);
// Проверяем, что IP и шлюз в одной подсети
if (subnet1 !== subnet2) {
return false;
}
// Если DNS — массив, проверяем, что хотя бы один DNS в той же подсети
const dnsArray = Array.isArray(ip3) ? ip3 : [ip3];
return dnsArray.some(dns => areInSameSubnet(dns, subnet1));
} catch (error) {
console.error(error);
return false;
}
};

View file

@ -1,18 +0,0 @@
import { useEffect, useState } from "react";
export const usePageReloadCounter = (): number => {
const [reloadCount, setReloadCount] = useState<number>(() => {
// Инициализируем состояние из sessionStorage или начинаем с 0
const savedCount = sessionStorage.getItem('pageReloadCount');
return savedCount ? parseInt(savedCount, 10) : 0;
});
useEffect(() => {
// Увеличиваем счётчик при каждом монтировании компонента
const newCount = reloadCount + 1;
setReloadCount(newCount);
sessionStorage.setItem('pageReloadCount', newCount.toString());
}, []); // Пустой массив зависимостей означает, что эффект сработает только при монтировании
return reloadCount;
};