all docs and guides for gonets
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
|
@ -1,75 +1,75 @@
|
||||||
# ПРИЛОЖЕНИЕ ГоNETS Материалы
|
# Курс по использованию ГоNETS
|
||||||
|
|
||||||
При первом запуске ГоNETS необходимо настроить пользователя оператор для дальнейшей работы с приложением.
|
При первом запуске ГоNETS необходимо настроить пользователя оператор для дальнейшей работы с приложением.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
О программе
|
О программе
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Новая страница о программе (на рассмотрении)
|
Новая страница о программе (на рассмотрении)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Основное полотно приложения с текущими сетевыми интерфейсами на системе
|
Основное полотно приложения с текущими сетевыми интерфейсами на системе
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Для комфортного восприятия дальше скриншоты будут в светлой теме, переключить тему можно в левом нижнем углу кликнув на специальную иконку. Поддерживается темная, светлая и системная темы.
|
Для комфортного восприятия дальше скриншоты будут в светлой теме, переключить тему можно в левом нижнем углу кликнув на специальную иконку. Поддерживается темная, светлая и системная темы.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Далее отображается нынешний узел с возможностью подключиться к другому узлу
|
Далее отображается нынешний узел с возможностью подключиться к другому узлу
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Введя данные узел будет подключен и отображаться в левом списке доступных узлов. На следующем скриншоте отображается полотное узла к которому мы подключились
|
Введя данные узел будет подключен и отображаться в левом списке доступных узлов. На следующем скриншоте отображается полотное узла к которому мы подключились
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Окно сканирования узлов в подсети
|
Окно сканирования узлов в подсети
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Список просканированных узлов подсети
|
Список просканированных узлов подсети
|
||||||
|
|
||||||
В виде таблицы
|
В виде таблицы
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Списком
|
Списком
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Возможность добавить заметку к узлу
|
Возможность добавить заметку к узлу
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Сканирование точек доступа Wi-Fi
|
Сканирование точек доступа Wi-Fi
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Просканированные точки доступа Wi-Fi
|
Просканированные точки доступа Wi-Fi
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Изменение IP-адреса у сетевого интерфейса
|
Изменение IP-адреса у сетевого интерфейса
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Предупреждение об необходимости авторизоваться под администратором
|
Предупреждение об необходимости авторизоваться под администратором
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Проверка доступности вводимых данных
|
Проверка доступности вводимых данных
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
44
ПРИЛОЖЕНИЕ ГоNETS Материалы/API.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# API
|
||||||
|
|
||||||
|
Клиентская часть приложения взаимодействует с сервером через HTTPS-запросы и WebSocket-соединение. Большинство запросов могут выполняться с любого подключённого узла (например, https://192.168.1.147:8001/ip/check_ip), за исключением запроса /network/get_hostname, который ограничен локальным хостом (localhost:8001), так как возвращает hostname корневого устройства, с которого запущен клиент.
|
||||||
|
|
||||||
|
Все HTTPS-запросы реализованы в файле /src/api/request.ts. WebSocket-соединение для работы с сетевыми интерфейсами настроено в файле /src/components/workSpace/modules/workModules/networkInterfaces.tsx.
|
||||||
|
|
||||||
|
(По-хорошему настройку WebSocket подключения нужно будет переносить тоже в /src/api, так будет лучше, когда будет писаться больше модулей рабочего пространства)
|
||||||
|
|
||||||
|
Список API-запросов
|
||||||
|
|
||||||
|
1. Проверка доступности IP-адреса
|
||||||
|
- Эндпоинт: https://<host>:8001/ip/check_ip
|
||||||
|
- Описание: Проверяет доступность указанного IP-адреса.
|
||||||
|
2. Сохранение изменений IP-адреса
|
||||||
|
- Эндпоинт: https://<host>:8001/ip/apply_ip
|
||||||
|
- Описание: Применяет изменения конфигурации IP-адреса.
|
||||||
|
3. Получение hostname корневого устройства
|
||||||
|
- Эндпоинт: https://localhost:8001/network/get_hostname
|
||||||
|
- Описание: Возвращает hostname устройства, с которого запущен клиент. Запрос ограничен локальным хостом.
|
||||||
|
4. Регистрация пользователя
|
||||||
|
- Эндпоинт: https://<host>:8001/auth/register
|
||||||
|
- Описание: Создаёт нового пользователя (устанавливает пароль оператора).
|
||||||
|
5. Авторизация пользователя
|
||||||
|
- Эндпоинт: https://<host>:8001/auth/login
|
||||||
|
- Описание: Выполняет вход пользователя, повышая его права до уровня оператора.
|
||||||
|
6. Выход пользователя
|
||||||
|
- Эндпоинт: https://<host>:8001/auth/logout
|
||||||
|
- Описание: Выполняет выход пользователя, снижая его права.
|
||||||
|
7. Проверка прав пользователя
|
||||||
|
- Эндпоинт: https://<host>:8001/auth/me
|
||||||
|
- Описание: Проверяет текущие права авторизованного пользователя.
|
||||||
|
8. Проверка наличия пользователя
|
||||||
|
- Эндпоинт: https://<host>:8001/auth/check_json
|
||||||
|
- Описание: Проверяет, существует ли пользователь на устройстве.
|
||||||
|
|
||||||
|
WebSocket-соединение
|
||||||
|
|
||||||
|
- Эндпоинт: wss://<host>:8001/api/v1
|
||||||
|
- Описание: Устанавливает WebSocket-соединение для получения данных о сетевых интерфейсах в реальном времени. Реализовано в файле /src/components/workSpace/modules/workModules/networkInterfaces.tsx.
|
||||||
|
|
||||||
|
Замечания для разработки и тестирования
|
||||||
|
|
||||||
|
- В режиме разработки (npm run dev) можно переключать протоколы с https на http и с wss на ws, если сервер настроен на поддержку HTTP-запросов.
|
||||||
|
- Убедитесь, что сервер работает в соответствующем режиме (HTTP или HTTPS), чтобы избежать ошибок подключения.
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# ГоNets итог
|
# ГоNets итог
|
||||||
|
|
||||||

|

|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Инструкция по запуску и сборке клиента
|
||||||
|
|
||||||
|
### Общие сведения.
|
||||||
|
|
||||||
|
Клиент приложения ГоNets написан на языке Typescript с использованием фреймворка React. Для более понятного отображения информации была выбрана библиотека ReatFlow, позволяющая легко и просто выстраивать различные графы, схемы, блоки и их связи. Так же, для того, чтобы приложение запускалось как десктопное был выбран метод обёртки собранной (build) версии в облочку Electron.
|
||||||
|
|
||||||
|
### Зависимости клиентской части
|
||||||
|
|
||||||
|
Далее будет представлен список необходимых npm зависимостей для разработки приложения. Уточню, что необходимы они исключительно во время разработки и сборки, собранная версия работает спокойно без них.
|
||||||
|
|
||||||
|
Зависимости при разработки:
|
||||||
|
|
||||||
|
```
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/icons-ic": "^1.2.13",
|
||||||
|
"@iconify/react": "^5.2.0",
|
||||||
|
"@reduxjs/toolkit": "^2.6.0",
|
||||||
|
"@xyflow/react": "^12.3.5",
|
||||||
|
"axios": "^1.7.9",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
|
"react-flow-renderer": "^10.3.17",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
|
"react-router-dom": "^7.0.2",
|
||||||
|
"styled-components": "^6.1.13",
|
||||||
|
"zustand": "^5.0.3"
|
||||||
|
},
|
||||||
|
|
||||||
|
"devDependencies": {
|
||||||
|
"@iconify-json/ic": "^1.2.2",
|
||||||
|
"@types/react": "^18.0.28",
|
||||||
|
"@types/react-dom": "^18.0.11",
|
||||||
|
"@vitejs/plugin-basic-ssl": "^2.0.0",
|
||||||
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
|
"electron": "^34.0.2",
|
||||||
|
"electron-packager": "^17.1.2",
|
||||||
|
"esbuild-wasm": "^0.17.12",
|
||||||
|
"typescript": "^4.9.5",
|
||||||
|
"vite": "^6.3.4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск и сборка
|
||||||
|
|
||||||
|
Для того, чтобы работать с исходным кодом, необходимо склонировать проект с ветки frontend, перейти в директорию `FRONT/DEV/` и выполнить установку зависимостей с помощью `npm install`, возможно потребуется сделать после этого `npm audit --fix` Весь исходный код, находится непосредственно в директории `DEV`, собранная же версия в директории `BUILD`.
|
||||||
|
|
||||||
|
Для сборки приложения и обёртки его в электрон необходимо выполнить команду `npm run package`, далее перейти в созданную после команды директорию `dist`, от туда в `gonets-for-linux-64x/resources/app`, здесь нужно выполнить `npm run build`, в появившейся директории `dist` отредактировать файл `index.html`, таким образом, что везде где стоит `/assets` нужно прописать `./assets`. Проверить запуск приложения, можно прописав в терминале `./gonets` из директории `FRONT/DEV/dist/gonets-for-linux-64x`, где и лежит исполняемвый файл.
|
||||||
|
|
||||||
|
После удачного билда можно переместить всё содержимое `FRONT/DEV/dist/gonets-for-linux-64x/` в `/FRONT/BUILD`
|
||||||
|
|
||||||
|
Дополнительно отмечу, что входной точкой/файлом настройки самого электрона является файл `main.js`
|
||||||
|
|
||||||
|
### Замечания для разработки
|
||||||
|
|
||||||
|
- В dev режиме можно менять https запросы и wss подключение на http и ws соответственно. Меняется это в файлах:
|
||||||
|
- /FRONT/DEV/src/api/request.ts - Здесь основные http запросы
|
||||||
|
- /FRONT/DEV/src/components/workSpace/workModule/networkInterfaces.tsx - Здесь главное WebSocket подключение
|
||||||
|
- Стоит убедиться, что сервер работает в соответствующем режиме (HTTP или HTTPS), чтобы избежать ошибок подключения
|
||||||
199
ПРИЛОЖЕНИЕ ГоNETS Материалы/Инструкция по пользованию.md
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
# Инструкция по пользованию
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
**GoNets** — это приложение для удобного и эффективного управления сетями в Linux с интуитивно понятным графическим интерфейсом. Оно помогает пользователям работать с сетевыми интерфейсами и узлами через визуальные блоки, что упрощает настройку и управление сетью без необходимости использования множества команд в терминале.
|
||||||
|
|
||||||
|
### Основные компоненты приложения:
|
||||||
|
|
||||||
|
- **Клиентская часть**: веб-приложение, использующее современные подходы веб-разработки для отображения сетевых интерфейсов и их связей в виде узлов и соединений. Приложение обёрнуто в Electron, что позволяет запускать приложение как десктопное.
|
||||||
|
- **Серверная часть**: сервис на Python, который взаимодействует с операционной системой через D-Bus и передает данные клиенту через WebSocket.
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
|
1. **Скачивание и установка**:
|
||||||
|
Скачайте DEB-пакет GoNets и установите его на вашу систему Linux. Установка автоматически запустит серверную часть как системный сервис на адресе https://localhost:8001.
|
||||||
|
2. **Запуск клиента**:
|
||||||
|
Запустите клиентскую часть через Electron, которая подключится к серверу и начнёт отображать сетевые интерфейсы.
|
||||||
|
|
||||||
|
## Первы запуск приложения
|
||||||
|
|
||||||
|
### 1\. Настройка пароля администратора
|
||||||
|
|
||||||
|
При первом запуске необходимо создать пароль администратора. Он будет использоваться для доступа к функциям с повышенными правами (например, изменение IP-адресов).
|
||||||
|
|
||||||
|
В окне создания пароля доступны также:
|
||||||
|
|
||||||
|
- Переключение темы интерфейса.
|
||||||
|
- Переход на страницу «О приложении».
|
||||||
|
- Кнопка возврата на корневой узел (если происходит регистрация подключённого узла).
|
||||||
|
|
||||||
|
**Что такое узел?**
|
||||||
|
В контексте GoNets **узел** — это отдельное, подключённое к общей сети и управляемый через приложение. Узел может быть **корневым** (локальный компьютер, с которого запущено приложение) или **подключённым** (удалённая система, подключённая к корневому узлу).
|
||||||
|
|
||||||
|
**Особенности пароля:**
|
||||||
|
|
||||||
|
- У каждого узла (корневого или подключённого) — свой уникальный пароль администратора.
|
||||||
|
- Пример для корневого узла: `securePass2025`
|
||||||
|
- Пример для подключённого узла: \`adminNet123
|
||||||
|
- Если на подключённом узле пароль ещё не задан, система предложит создать его при первом подключении.
|
||||||
|
|
||||||
|
## Интерфейс и работа с приложением
|
||||||
|
|
||||||
|
### 1\. Рабочее пространство
|
||||||
|
|
||||||
|
После успешной настройки пароля открывается стартовое приветственное окно, из которого осуществляется переход к основным модулям приложения. В текущей версии доступен один модуль — **Настройки сети**.
|
||||||
|
|
||||||
|
Рабочее пространство включает два постоянных элемента:
|
||||||
|
|
||||||
|
- **Боковая панель** — основной элемент навигации, доступен во всех разделах приложения.
|
||||||
|
- **Рабочая область** — в ней отображаются модули и интерфейсы, связанные с выбранным разделом.
|
||||||
|
|
||||||
|
#### 1.1 Боковая панель
|
||||||
|
|
||||||
|
Боковая панель размещена слева и предоставляет быстрый доступ к следующим функциям:
|
||||||
|
|
||||||
|
- **Управление узлами** — кнопка с иконкой _Монитора_, открывает меню управления устройствами.
|
||||||
|
- **Смена темы оформления** — переключение между светлой, тёмной и системной темой.
|
||||||
|
- **Профиль пользователя** — отображает текущий уровень доступа (пользователь / администратор) с возможностью смены.
|
||||||
|
- **О программе** — отображает информацию о версии и дате выпуска.
|
||||||
|
|
||||||
|
##### 1.2 Настройки сети
|
||||||
|
|
||||||
|
Этот модуль представляет собой интерактивный холст, на котором в графической форме отображаются сетевые интерфейсы и их связи. Такой подход обеспечивает наглядное и удобное управление сетевой конфигурацией.
|
||||||
|
|
||||||
|
Элементы на холсте можно перемещать для лучшего отображения. Положение элементов будет сохраняться даже при выходе из приложения. Чтобы вернуть все элементы в исходное положение, в хэдере холста нажмите на иконку сброса. Чтобы закрыть холст, нажмите на иконку закрытия и вы попадёте обратно на приветственное окно
|
||||||
|
|
||||||
|
На холсте отображаются следующие элементы:
|
||||||
|
|
||||||
|
1. **Группы интерфейсов**
|
||||||
|
Все сетевые интерфейсы распределяются на две группы: **активные** и **неактивные**.Каждая группа оформлена в виде рамки с заголовком и кнопкой «Скрыть/Показать», позволяющей сворачивать или разворачивать список интерфейсов.
|
||||||
|
2. **Блок сетевого интерфейса**
|
||||||
|
Каждый интерфейс отображается в отдельном блоке, содержащем:
|
||||||
|
- **Заголовок** — название интерфейса, его тип (например, ethernet, wifi или VPN), а также текущий статус, который представлен цветом заголовка интерфейса.
|
||||||
|
- **Конфигурацию** — MAC-адрес и значение MTU.
|
||||||
|
- **Блоки IP-адресов** (опционально) — один или несколько блоков с информацией о назначенных IP-адресах.
|
||||||
|
3. **Блок IP-адреса**Каждый блок IP-адреса включает:
|
||||||
|
- **Заголовок** — указывается метод получения адреса: `DHCP` или `Static`, а также кнопка редактирования.
|
||||||
|
- **Параметры** — строки с IP-адресом, шлюзом и DNS-серверами.
|
||||||
|
- При активации редактирования, строки заменяются на поля ввода. В заголовке блока при этом появляются кнопки подтверждения и отмены изменений.
|
||||||
|
|
||||||
|
### 2\. Управление узлами
|
||||||
|
|
||||||
|
Управление узлами осуществляется через **боковую панель**. Для этого нажмите на иконку _Монитора_ — откроется меню с перечнем доступных устройств.
|
||||||
|
|
||||||
|
В меню узлов отображаются:
|
||||||
|
|
||||||
|
1. **Корневой узел** — локальное устройство, на котором запущено приложение. Его имя берётся из системного `hostname`.
|
||||||
|
2. **Список подключённых узлов** — отображаются в порядке добавления.
|
||||||
|
3. **Кнопка добавления нового узла** — представлена в виде блока с символом "+".
|
||||||
|
|
||||||
|
#### 2.1 Добавление нового узла
|
||||||
|
|
||||||
|
При нажатии на кнопку **"+"** откроется модальное окно, в котором потребуется указать адрес подключаемого устройства.
|
||||||
|
В текущей версии приложения поддерживается подключение только к узлам, находящимся в одной локальной сети с корневым.
|
||||||
|
|
||||||
|
После ввода адреса и подтверждения, приложение попытается установить соединение с выбранным узлом. Если на нём установлено приложение GoNets, соединение будет успешно установлено, и узел появится в списке. В противном случае подключение не состоится, и переключение на данный узел будет невозможно.
|
||||||
|
|
||||||
|
#### 2.2 Пароль администратора на узлах
|
||||||
|
|
||||||
|
При первом переходе на подключённый узел система проверит, задан ли на нём пароль администратора GoNets.
|
||||||
|
Если пароль отсутствует, появится предложение создать его. Этот пароль требуется для выполнения действий с повышенными правами, таких как изменение IP-адресов или управление интерфейсами.
|
||||||
|
|
||||||
|
> **Важно**: проверка пароля выполняется один раз — при первом запуске GoNets на каждом устройстве. Установленный пароль сохраняется на узле и в дальнейшем используется без повторной настройки.
|
||||||
|
|
||||||
|
#### 2.3. Возврат к корневому узлу
|
||||||
|
|
||||||
|
Чтобы вернуться на корневой узел просто нажмите на него в списке узлов, он всегда будет первым.
|
||||||
|
|
||||||
|
### 3\. Права пользователя приложения
|
||||||
|
|
||||||
|
В приложении реализована двухуровневая система прав доступа:
|
||||||
|
|
||||||
|
- **Ограниченные права** — режим по умолчанию при входе в приложение, даже после создания пароля администратора.
|
||||||
|
- **Администраторский доступ** — расширенные права, необходимые для изменения конфигурации сетевых параметров.
|
||||||
|
|
||||||
|
Даже после создания пароля администратора Пользователь попадает в приложение с ограниченными правами.
|
||||||
|
|
||||||
|
#### 3.1 Ограниченный режим
|
||||||
|
|
||||||
|
В ограниченном режиме пользователь может просматривать сетевую конфигурацию, но **не имеет доступа к редактированию IP-адресов** интерфейсов. При попытке изменить параметры IP, шлюза или DNS, будет отображено уведомление о невозможности выполнения действия без прав администратора.
|
||||||
|
|
||||||
|
#### 3.2 Повышение прав до администратора
|
||||||
|
|
||||||
|
Для получения прав администратора:
|
||||||
|
|
||||||
|
1. Нажмите на иконку перечёркнутого щита в **боковой панели**.
|
||||||
|
2. В открывшемся модальном окне введите **администраторский пароль** для текущего узла.
|
||||||
|
Важно: пароль должен соответствовать именно тому узлу, с которым Вы работаете в данный момент.
|
||||||
|
3. После успешного ввода:
|
||||||
|
- Появится уведомление об успешной авторизации. Оно автоматически исчезнет через 3 секунды или может быть закрыто вручную.
|
||||||
|
- Иконка в боковой панели изменится, отображая текущий статус пользователя (администратор или ограниченный доступ).
|
||||||
|
4.
|
||||||
|
|
||||||
|
#### 3.3 Возврат в ограниченный режим
|
||||||
|
|
||||||
|
Чтобы отключить расширенные права:
|
||||||
|
|
||||||
|
1. Снова нажмите на иконку доступа в боковой панели.
|
||||||
|
2. В модальном окне нажмите кнопку **«Ограничить»**.
|
||||||
|
3. После этого права пользователя будут понижены, и доступ к редактированию IP-адресов будет снова ограничен.
|
||||||
|
|
||||||
|
### 4\. Взаимодействие с IP-адресами
|
||||||
|
|
||||||
|
Приложение предоставляет удобный способ управления IP-адресами сетевых интерфейсов. Все изменения доступны **только при наличии административных прав доступа**.
|
||||||
|
|
||||||
|
#### 4.1 Переход в режим редактирования
|
||||||
|
|
||||||
|
Чтобы изменить параметры IP-адреса:
|
||||||
|
|
||||||
|
1. Убедитесь, что Вы находитесь в **режиме администратора**.
|
||||||
|
2. Найдите нужный интерфейс в группе **активных интерфейсов**.
|
||||||
|
3. Нажмите на кнопку с иконкой **карандаша** в заголовке блока IP-адреса.
|
||||||
|
|
||||||
|
После этого строки с параметрами IP-адреса преобразуются в с поля ввода для редактирования:
|
||||||
|
|
||||||
|
- **IP-адрес**
|
||||||
|
- **Шлюз**
|
||||||
|
- **DNS-серверы**
|
||||||
|
|
||||||
|
В заголовке блока IP-Адреса появятся две кнопки: **Подтвердить** и **Отменить изменения**.
|
||||||
|
|
||||||
|
#### 4.2 Требования к данным
|
||||||
|
|
||||||
|
Перед подтверждением убедитесь, что:
|
||||||
|
|
||||||
|
- Указанные IP-адрес, шлюз и DNS-серверы находятся **в одной подсети**.
|
||||||
|
- Все поля заполнены корректно.
|
||||||
|
|
||||||
|
Если данные не соответствуют требованиям, появится предупреждение
|
||||||
|
|
||||||
|
#### 4.3 Проверка и подтверждение изменений
|
||||||
|
|
||||||
|
После ввода корректных данных:
|
||||||
|
|
||||||
|
1. Нажмите кнопку **подтверждения**.
|
||||||
|
2. Отобразится **экран загрузки**, во время которого приложение производит сканирование локальной сети, чтобы:
|
||||||
|
- Проверить доступность указанного IP-адреса.
|
||||||
|
- Убедиться, что адрес **не занят другим устройством**.
|
||||||
|
|
||||||
|
Если IP-адрес уже используется, появится уведомление, и изменения применить не удастся, это уведомление можно будет закрыть.
|
||||||
|
|
||||||
|
Если адрес свободен:
|
||||||
|
|
||||||
|
1. Откроется **модальное окно подтверждения**, в котором отображаются:
|
||||||
|
- **Текущие параметры** IP-адреса.
|
||||||
|
- **Новые параметры**, введённые пользователем.
|
||||||
|
- Здесь Вы можете либо **отменить изменения**, либо **сохранить** их.
|
||||||
|
|
||||||
|
> Обратите внимание: в процессе могут несколько раз отображаться **экраны загрузки** — это нормально. Сервер динамически обрабатывает изменения и проверяет доступность указанных параметров.
|
||||||
|
|
||||||
|
#### 4.4 Изменение адреса подключённого узла
|
||||||
|
|
||||||
|
Если редактирование IP-адреса выполняется **у подключённого узла**, то при успешном применении новый адрес автоматически **обновится в списке узлов** в боковой панели. Это необходимо для корректной работы приложения и исключения путаницы.
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
GoNets значительно упрощает управление сетями в Linux, предоставляя удобный графический интерфейс для работы с сетевыми интерфейсами и узлами. Вы можете легко настраивать IP-адреса, добавлять новые узлы и управлять ими, а также изменять параметры интерфейсов без необходимости использовать командную строку.
|
||||||
|
|
||||||
|
Для получения дополнительной информации и подробных инструкций, пожалуйста, ознакомьтесь с документацией и скриншотами, которые будут добавлены в следующей версии.
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Итерация 1 WIFI SCANNER
|
# Итерация 1 WIFI SCANNER
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
# Общее описание кода клиентской части
|
||||||
|
|
||||||
|
Клиент ГоNets — это одностраничное веб-приложение, разработанное на TypeScript с использованием фреймворка React. Код организован по принципам компонентно-ориентированной архитектуры, разделён на модули и компоненты для упрощения разработки, поддержки и масштабирования. Приложение использует localStorage, библиотеку Zustand и React Context для управления состоянием, а также HTTPS и WebSocket для взаимодействия с сервером.
|
||||||
|
|
||||||
|
### 1\. Входная точка приложения
|
||||||
|
|
||||||
|
Точка входа — файл index.tsx, где инициализируется корневой компонент приложения. Здесь подключаются роутер и компонент модальных окон:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WindowComponent isOpen={isOpen} type={modalType} data={modalData} />
|
||||||
|
<Router />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Приложение оборачивается в провайдеры ThemeProvider и ModalProvider, которые обеспечивают глобальный доступ к темам и модальным окнам:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
root.render(
|
||||||
|
<ThemeProvider>
|
||||||
|
<HashRouter>
|
||||||
|
<ModalProvider>
|
||||||
|
<MainComponent />
|
||||||
|
</ModalProvider>
|
||||||
|
</HashRouter>
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2\. Роутинг
|
||||||
|
|
||||||
|
Роутинг реализован в файле router.tsx с использованием библиотеки react-router-dom. Несмотря на одностраничную природу приложения, роутинг управляет условной загрузкой компонентов в зависимости от конфигурации:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
if (configExists === null) {
|
||||||
|
return <RouterLoader loaderText="Идёт загрузка данных" />;
|
||||||
|
}
|
||||||
|
if (configExists === false) {
|
||||||
|
return <CreateUser />;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<WorkSpace />} />
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3\. Рабочее пространство
|
||||||
|
|
||||||
|
Рабочее пространство (workspace.tsx) — центральная часть приложения, где происходит отрисовка интерфейса и взаимодействие с пользователем. Оно включает:
|
||||||
|
|
||||||
|
- Боковую панель (SideBar) — отвечает за навигацию и управление.
|
||||||
|
- Модули — динамически подключаемые компоненты, отображаемые на основе значения из localStorage.
|
||||||
|
|
||||||
|
Логика отображения модулей:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
return (
|
||||||
|
<Section>
|
||||||
|
<FlowContainer>
|
||||||
|
<SideBar />
|
||||||
|
{workModule === workSpaceNames[1] && <HelloWindow />}
|
||||||
|
{workModule === workSpaceNames[2] && <About from="workSpace" />}
|
||||||
|
{workModule === workSpaceNames[4] && <About from="helloWindow" />}
|
||||||
|
{workModule === workSpaceNames[3] && (
|
||||||
|
<WorkSection>
|
||||||
|
<Header />
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<NetworkInterfaces
|
||||||
|
key={currentWs}
|
||||||
|
startConnection={true}
|
||||||
|
ws={currentWs}
|
||||||
|
/>
|
||||||
|
</ReactFlowProvider>
|
||||||
|
</WorkSection>
|
||||||
|
)}
|
||||||
|
</FlowContainer>
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.1. Модули рабочего пространства
|
||||||
|
|
||||||
|
Рабочее пространство приложения построено с акцентом на модульность, что позволяет разделять функциональность на независимые компоненты. Модули делятся на два типа:
|
||||||
|
|
||||||
|
- Модули приложения (AppModules): Глобальные и информационные модули, отвечающие за общую функциональность и представление данных. Примеры:
|
||||||
|
- HelloWindow — приветственное окно.
|
||||||
|
- About — страница с информацией о приложении.
|
||||||
|
- Рабочие модули: Узкоспециализированные модули, предназначенные для выполнения конкретных задач. На данный момент реализован один такой модуль:
|
||||||
|
- NetworkInterfaces (networkInterfaces.tsx) — управляет сетевыми интерфейсами и визуализацией данных с помощью React Flow. (Более подробно ознакомиться можно в файле “Описание работы модуля сетевых интерфейсов“)
|
||||||
|
|
||||||
|
Модули хранятся в /src/componens/workSpace/workSpaceModules/
|
||||||
|
|
||||||
|
### 4\. Хранилища данных
|
||||||
|
|
||||||
|
Приложение использует localStorage для и библиотеку Zustand с React Context для управления состоянием. Zustand-хранилища синхронизируются с localStorage через persist, а некоторые хранилища управляют временным состоянием без сохранения.
|
||||||
|
|
||||||
|
Все хранилища располагаются в директории /src/store
|
||||||
|
|
||||||
|
#### 4.1. Хранилища в localStorage
|
||||||
|
|
||||||
|
1. currentIp-storage (строка): Хранит IP-адрес текущего хоста или "[localhost](http://localhost)". Пример: "192.168.1.147".
|
||||||
|
2. connectedDevices-storage (массив объектов Device): Список подключённых хостов.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
interface Device { number: number; address: string; }
|
||||||
|
```
|
||||||
|
|
||||||
|
Пример: \[{ number: 1, address: "192.168.1.147" }\].
|
||||||
|
3. menus-storage (массив объектов Menu): Состояние меню (открыто/закрыто, активно/неактивно).
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
interface Menu { id: string; isOpen: boolean; isActive?: boolean; }
|
||||||
|
```
|
||||||
|
|
||||||
|
Пример: \[{ id: "menu1", isOpen: true, isActive: true }\].
|
||||||
|
4. toolBar-storage (объект ToolBar): Состояние боковой панели и текущий активный пункт.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
interface ToolSpace { id: string; isOpen: boolean; isActive?: boolean; }
|
||||||
|
interface ToolBar { toolSpace: ToolSpace[]; current: string; }
|
||||||
|
```
|
||||||
|
|
||||||
|
Пример: { toolSpace: \[{ id: "tool1", isOpen: true, isActive: true }\], current: "tool1" }.
|
||||||
|
5. workSpace-storage (строка): Название активного модуля из /src/const/workSpace/names.ts. Пример: "networkInterfaces".
|
||||||
|
6. theme (строка): Текущая тема приложения ("light", "dark", "system"). Пример: "dark".
|
||||||
|
|
||||||
|
#### 4.2. Zustand-хранилища, связанные с localStorage
|
||||||
|
|
||||||
|
1. useIpStore (currentIp-storage): Управляет IP-адресом хоста.
|
||||||
|
- Методы: setIpAddress(newIp: string).
|
||||||
|
- Пример: "[localhost](http://localhost)".
|
||||||
|
2. useDevicesStore (connectedDevices-storage): Управляет списком устройств.
|
||||||
|
- Методы: addDevice(address: string), deleteDevice(number: number).
|
||||||
|
- Пример: \[{ number: 1, address: "192.168.1.147" }\].
|
||||||
|
3. useMenuStore (menus-storage): Управляет состоянием меню.
|
||||||
|
- Методы: toggleMenu(menuId: string).
|
||||||
|
- Пример: \[{ id: "menu1", isOpen: true, isActive: true }\].
|
||||||
|
4. useToolBarStore (toolBar-storage): Управляет боковой панелью.
|
||||||
|
- Методы: toggleMenu(menuId: string), initialize().
|
||||||
|
- Пример: { toolSpace: \[{ id: "tool1", isOpen: true }\], current: "tool1" }.
|
||||||
|
5. useWorkSpaceStore (workSpace-storage): Хранит активный модуль.
|
||||||
|
- Методы: setWorkModule(newModule: string), initialize().
|
||||||
|
- Пример: "networkInterfaces".
|
||||||
|
|
||||||
|
#### 4.3. Zustand-хранилища (без localStorage)
|
||||||
|
|
||||||
|
1. useAdminStore: Управляет административными правами.
|
||||||
|
- Тип: Булево значение (isAdmin).
|
||||||
|
- Методы: setAdmin(isAdmin: boolean).
|
||||||
|
- Пример: isAdmin: true.
|
||||||
|
2. useGroupStore: Управляет группами нод в React Flow.
|
||||||
|
- Тип: Массив объектов { id: string; click: boolean }.
|
||||||
|
- Методы: setGroups(groups: { id: string; click: boolean }\[\]).
|
||||||
|
- Пример: \[{ id: "group1", click: true }\].
|
||||||
|
3. usePosStore: Хранит флаг для сброса позиций нод в React Flow.
|
||||||
|
- Тип: Булево значение (isNullPos).
|
||||||
|
- Методы: setNullPos(isNullPos: boolean).
|
||||||
|
- Пример: isNullPos: false.
|
||||||
|
4. React Контексты
|
||||||
|
|
||||||
|
#### 4.4. Контекст темы (ThemeProvider)
|
||||||
|
|
||||||
|
- Назначение: Управляет темой приложения ("light", "dark", "system") и её переключением.
|
||||||
|
- Хранилище localStorage: theme.
|
||||||
|
- Интерфейс:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
type ThemeContextType = {
|
||||||
|
theme: "light" | "dark" | "system";
|
||||||
|
toggleTheme: () => void;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- Методы: toggleTheme() — переключает тему в порядке: system → light → dark.
|
||||||
|
- Особенности:
|
||||||
|
- По умолчанию используется "system", подстраивающаяся под prefers-color-scheme.
|
||||||
|
- Интеграция с styled-components для стилизации через StyledTheme и GlobalStyle.
|
||||||
|
- Тема сохраняется в localStorage для восстановления.
|
||||||
|
- Пример: "dark".
|
||||||
|
|
||||||
|
Более подробно о теме можно ознакомиться в файле (Описание работы с темой)
|
||||||
|
|
||||||
|
#### 4.5. Контекст модальных окон (ModalProvider)
|
||||||
|
|
||||||
|
- Назначение: Управляет отображением модальных окон.
|
||||||
|
- Интерфейс:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
interface ModalContextType {
|
||||||
|
isOpen: boolean;
|
||||||
|
modalType: string;
|
||||||
|
modalData: any;
|
||||||
|
openModal: (modalType: string, modalData?: any) => void;
|
||||||
|
closeModal: () => void;
|
||||||
|
closeLoader: () => void;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Методы:
|
||||||
|
- openModal(modalType: string, modalData?: any) — открывает окно с указанным типом и данными.
|
||||||
|
- closeModal() — закрывает окно с перезагрузкой страницы.
|
||||||
|
- closeLoader() — закрывает окно без перезагрузки.
|
||||||
|
- Особенности:
|
||||||
|
- Оборачивает приложение в index.tsx, доступ через useModalContext.
|
||||||
|
- Блокирует прокрутку страницы при открытии окна (overflow: hidden).
|
||||||
|
- Типы окон определены в /src/components/modalwindows/windowsType.ts.
|
||||||
|
- Логика отображения — в /src/components/modalwindows/modalWindow.tsx.
|
||||||
|
- Контейнеры хранятся в /src/components/modalwindows/modalContainers.
|
||||||
|
- Пример: openModal("loader", "загрузка данных").
|
||||||
|
|
@ -0,0 +1,387 @@
|
||||||
|
# Описание работы c сетевыми интерфейсами
|
||||||
|
|
||||||
|
На данный момент главным рабочим модулем приложения является модуль работы с сетевыми интерфейсами. Данный модуль позволяет отображать сетевые интерфейсы хоста в графическом виде и управлять IP адресами интерфейсов. В основе работы модуля лежит достаточно большая библиотека ReactFlow, которая позволяет строить различные графы по средством блоков и связей между ними. Далее для удобства блоки будут называться нодами (node), связи эджами (edge), а само поле ReactFlow холстом
|
||||||
|
|
||||||
|
### 1\. Подключение модуля в рабочее пространство
|
||||||
|
|
||||||
|
Работа модуля начинается с файла /src/components/workSpace/workspace.tsx, здесь в рабочее пространство приложения подключаются сами модули.
|
||||||
|
|
||||||
|
```
|
||||||
|
{workModule === workSpaceNames[3] &&
|
||||||
|
<WorkSection>
|
||||||
|
<Header />
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<NetworkInterfaces
|
||||||
|
key={currentWs}
|
||||||
|
startConnection={true}
|
||||||
|
ws={currentWs}
|
||||||
|
/>
|
||||||
|
</ReactFlowProvider>
|
||||||
|
</WorkSection>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
В данном блоке этого файла подключается модуль сетевых интерфейсов в рабочее пространство. Из localstorage берётся название текущего модуля, который должен быть подключён, в этом случаи это ‘networkInterfaces‘ и по названию определяется необходимый модуль.
|
||||||
|
|
||||||
|
Здесь
|
||||||
|
|
||||||
|
<Header/> - это верхняя панель для управления холстом
|
||||||
|
|
||||||
|
<NetWorkInterfaces/> - Сам компонент работы с сетевыми интерфейсами, в нём пропсы key - ключ компонента, будет равен текущему ip хоста, startConnection - флаг, при передачи которого начинается работа компонента, ws - передача ip текущего хоста для создания WebSocket подключения
|
||||||
|
|
||||||
|
### 2\. Компонент NetworkInterfaces
|
||||||
|
|
||||||
|
Рассмотрение компонента логично начать с обзора его переменных состояния, которых в этом компоненте присутствует немало.
|
||||||
|
|
||||||
|
#### 2.1. Переменные состояния компонента NetworkInterfaces
|
||||||
|
|
||||||
|
1. initializationAttempt
|
||||||
|
- Тип: React.useRef<number>
|
||||||
|
- Описание: Счетчик попыток инициализации данных, хранящийся в useRef. Используется для отслеживания статуса начальной загрузки нод и эджей. Начальное значение — 0. После успешной инициализации устанавливается в 1. Позволяет избежать повторных попыток инициализации или перезагрузки страницы при сбоях.
|
||||||
|
2. requestError
|
||||||
|
- Тип: { status: boolean, message: string }
|
||||||
|
- Описание: Состояние для отслеживания ошибок при установлении WebSocket-соединения или загрузке данных. Содержит флаг status (true, если ошибка произошла) и поле message с текстом ошибки (например, "Соединение с сервером разорвано" или "Превышено время ожидания"). Используется для отображения ошибок через модальное окно.
|
||||||
|
3. { openModal, closeLoader }
|
||||||
|
- Тип: Методы из useModalContext
|
||||||
|
- Описание: Функции, полученные из контекста ModalWindowContext, для управления модальными окнами. openModal открывает модальное окно с указанным типом и параметрами (например, для отображения ошибок или уведомлений о загрузке). closeLoader закрывает экран загрузки после завершения инициализации данных.
|
||||||
|
4. loader
|
||||||
|
- Тип: boolean
|
||||||
|
- Описание: Флаг, управляющий отображением экрана загрузки. Изначально установлен в true, что указывает на процесс загрузки данных. После успешной инициализации нод и эджей устанавливается в false, и экран загрузки скрывается с помощью closeLoader.
|
||||||
|
5. socket
|
||||||
|
- Тип: WebSocket | null
|
||||||
|
- Описание: Состояние для хранения объекта WebSocket, используемого для связи с сервером по адресу ws://192.168.1.147:8001/api/v1. Изначально null. После успешного подключения сохраняет экземпляр WebSocket, позволяя отправлять и получать данные о сетевых интерфейсах.
|
||||||
|
6. data
|
||||||
|
- Тип: ResponseData\[\]
|
||||||
|
- Описание: Массив данных, полученных через WebSocket. Содержит два элемента: данные об активных (activation) и неактивных (deactivation) сетевых интерфейсах. Используется как источник для преобразования в ноды и эджи для отображения на холсте ReactFlow.
|
||||||
|
7. wifiData
|
||||||
|
- Тип: ResponseNetwork | undefined
|
||||||
|
- Описание: Состояние для хранения информации о Wi-Fi интерфейсе, извлеченной из активных данных (activation). Обновляется, если в полученных данных присутствует интерфейс с типом WIFI. Используется для специфической обработки и отображения Wi-Fi нод на холсте.
|
||||||
|
8. hasInited
|
||||||
|
- Тип: boolean
|
||||||
|
- Описание: Флаг, указывающий, были ли данные (ноды и эджи) успешно инициализированы. Изначально false. Устанавливается в true после первичной обработки данных и вызова handleInit из useInitCanvas, чтобы предотвратить повторную инициализацию.
|
||||||
|
9. { initedNodes, initedEdges, handleInit }
|
||||||
|
- Тип: Значения и метод из useInitCanvas
|
||||||
|
- Описание: Данные и функция из пользовательского хука useInitCanvas. initedNodes и initedEdges содержат инициализированные ноды и эджи, подготовленные для отображения на холсте. handleInit выполняет начальную обработку edgeData и interfaces для создания этих структур.
|
||||||
|
10. interfaces
|
||||||
|
- Тип: Interfaces\[\]
|
||||||
|
- Описание: Состояние для хранения преобразованных данных о сетевых интерфейсах, полученных из data с помощью функции initNetworkIntData. Содержит структурированные объекты, описывающие интерфейсы, в формате, удобном для построения нод на холсте ReactFlow.
|
||||||
|
11. edgeData
|
||||||
|
- Тип: IEdge\[\]
|
||||||
|
- Описание: Состояние для хранения преобразованных данных о связях (эджи) между сетевыми интерфейсами, полученных из data с помощью initNetworkIntData. Используется как промежуточный формат перед финальной инициализацией эджей для отображения.
|
||||||
|
12. nodes
|
||||||
|
- Тип: Массив нод для ReactFlow
|
||||||
|
- Описание: Состояние, управляемое хуком useNodesState, для хранения и отображения нод (блоков) на холсте ReactFlow. Инициализируется пустым массивом и заполняется данными из initedNodes после обработки. Обновляется при изменении позиций, групп или Wi-Fi данных.
|
||||||
|
13. edges
|
||||||
|
- Тип: Массив эджей для ReactFlow
|
||||||
|
- Описание: Состояние, управляемое хуком useEdgesState, для хранения и отображения связей (эджей) между нодами на холсте ReactFlow. Изначально пустой массив, заполняется из initedEdges после инициализации и обновляется при добавлении новых связей.
|
||||||
|
14. isPanDisabled
|
||||||
|
- Тип: boolean
|
||||||
|
- Описание: Флаг, полученный из хука usePannableStore, определяющий, отключена ли возможность перемещения (прокрутки) холста ReactFlow. Если true, пользователь не может перемещать холст, что полезно для фиксации вида при определенных действиях.
|
||||||
|
15. changeArray
|
||||||
|
- Тип: any\[\]
|
||||||
|
- Описание: Массив для временного хранения изменений позиций нод, полученных через processNodeChanges. Накапливает данные о перемещениях, которые затем отправляются на сервер через autosavePosition с интервалом в 1 секунду для сохранения позиций.
|
||||||
|
16. groups
|
||||||
|
- Тип: Данные из useGroupStore
|
||||||
|
- Описание: Состояние, полученное из хука useGroupStore, содержащее информацию о группах сетевых интерфейсов (например, активные и неактивные). Используется для сортировки и сворачивания/разворачивания групп нод на холсте с помощью groupSort и collapseGroup.
|
||||||
|
17. { isNullPos, setNullPos }
|
||||||
|
- Тип: Значения и метод из usePosStore
|
||||||
|
- Описание: Состояние и функция из хука usePosStore. isNullPos — флаг, указывающий, нужно ли сбросить позиции нод. setNullPos — метод для управления этим флагом. При активации сбрасывает позиции нод через resetPosition, отправляя запрос по WebSocket.
|
||||||
|
|
||||||
|
#### 2.2. Методы
|
||||||
|
|
||||||
|
Функции и эффекты
|
||||||
|
|
||||||
|
1. Первый useEffect — Подключение к WebSocket
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (startConnection) {
|
||||||
|
openModal(ModalMap['2'], 'Идет загрузка данных');
|
||||||
|
setNodes([]);
|
||||||
|
setEdges([]);
|
||||||
|
setHasInited(false);
|
||||||
|
initializationAttempt.current = 0;
|
||||||
|
const newSocket = new WebSocket(`ws://192.168.1.147:8001/api/v1`);
|
||||||
|
let connectionTimeout;
|
||||||
|
setSocket(newSocket);
|
||||||
|
connectionTimeout = setTimeout(() => {
|
||||||
|
if (newSocket.readyState !== WebSocket.OPEN) {
|
||||||
|
newSocket.close();
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
newSocket.onopen = () => {
|
||||||
|
console.log('WebSocket connection established');
|
||||||
|
};
|
||||||
|
newSocket.onmessage = (event) => {
|
||||||
|
const newData = JSON.parse(event.data);
|
||||||
|
setData(() => [newData.activation, newData.deactivation]);
|
||||||
|
};
|
||||||
|
newSocket.onerror = (error) => {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
};
|
||||||
|
newSocket.onclose = () => {
|
||||||
|
console.log('WebSocket connection closed');
|
||||||
|
setRequestError({ status: true, message: 'Соединение с сервером разорвано' });
|
||||||
|
};
|
||||||
|
return () => {
|
||||||
|
newSocket.close();
|
||||||
|
closeLoader();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [startConnection, ws]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении startConnection или ws.
|
||||||
|
- Логика: Открывает модальное окно загрузки, сбрасывает ноды, эджи и флаги. Создает WebSocket, устанавливает тайм-аут (5 сек) для проверки соединения. Обрабатывает открытие, получение данных, ошибки и закрытие.
|
||||||
|
- Очистка: Закрывает WebSocket и загрузчик.
|
||||||
|
- Цель: Установить связь с сервером и получить данные.
|
||||||
|
2. Второй useEffect — Обработка данных из WebSocket
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (data.length > 0) {
|
||||||
|
const { interfaces: newInterfaces, edgeData: newEdgeData } = initNetworkIntData(data);
|
||||||
|
const activationData = data[0].interfaces;
|
||||||
|
const wifi = activationData.find((el: any) => el.type === 'WIFI');
|
||||||
|
setInterfaces(newInterfaces);
|
||||||
|
setEdgeData(newEdgeData);
|
||||||
|
if (wifi) { setWifi(wifi); }
|
||||||
|
}
|
||||||
|
}, [data]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении data.
|
||||||
|
- Логика: Преобразует data в interfaces и edgeData через initNetworkIntData. Ищет Wi-Fi интерфейс в активных данных, обновляет состояния.
|
||||||
|
- Цель: Подготовить данные для холст.
|
||||||
|
3. Третий useEffect — Инициализация нод и эджей
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (interfaces.length > 0 && !hasInited) {
|
||||||
|
handleInit(edgeData, interfaces);
|
||||||
|
setHasInited(true);
|
||||||
|
}
|
||||||
|
}, [interfaces, edgeData, hasInited]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении interfaces, edgeData, hasInited.
|
||||||
|
- Логика: Если данные есть и инициализация не выполнена, вызывает handleInit для подготовки нод и эджей, затем устанавливает hasInited в true.
|
||||||
|
- Цель: Инициализировать холст.
|
||||||
|
4. Четвертый useEffect — Мониторинг инициализации
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (initializationAttempt.current === 0 && !requestError.status) {
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!initedNodes.some(node => node.id === 'g0_nw0_rx0_ip0')) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
if (initedNodes.length > 0 && initedEdges.length > 0) {
|
||||||
|
setNodes(initedNodes);
|
||||||
|
setEdges(initedEdges);
|
||||||
|
console.log("Ноды и эджи успешно инициализированы");
|
||||||
|
initializationAttempt.current = 1;
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
} else {
|
||||||
|
console.log("Попытка инициализации нод и эджей...");
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
console.error("Ошибка: слишком долгая загрузка данных");
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
setRequestError({ status: true, message: 'Превышено время ожидания' });
|
||||||
|
}, 30000);
|
||||||
|
return () => {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [initedNodes, initedEdges, requestError]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении initedNodes, initedEdges, requestError.
|
||||||
|
- Логика: Проверяет каждую секунду наличие инициализированных данных. Через 500 мс проверяет ключевую ноду; если нет — перезагрузка. При успехе обновляет nodes, edges, логирует, останавливает проверки. Тайм-аут (30 сек) фиксирует ошибку.
|
||||||
|
- Очистка: Удаляет интервал и тайм-аут.
|
||||||
|
- Цель: Гарантировать успешную инициализацию.
|
||||||
|
5. Пятый useEffect — Обновление счетчика попыток
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (nodes.length === 0) {
|
||||||
|
initializationAttempt.current = 0;
|
||||||
|
} else {
|
||||||
|
initializationAttempt.current = 1;
|
||||||
|
}
|
||||||
|
}, [nodes]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении nodes.
|
||||||
|
- Логика: Сбрасывает initializationAttempt в 0, если нод нет, иначе устанавливает 1.
|
||||||
|
- Цель: Отслеживать состояние инициализации.
|
||||||
|
6. Шестой useEffect — Управление загрузчиком
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (nodes.length > 0 && loader == true) {
|
||||||
|
setLoader(false);
|
||||||
|
closeLoader();
|
||||||
|
}
|
||||||
|
}, [nodes, loader]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении nodes, loader.
|
||||||
|
- Логика: Если ноды есть и загрузчик активен, скрывает его.
|
||||||
|
- Цель: Убрать экран загрузки после рендера.
|
||||||
|
7. Функция onEdgesChange
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
const onEdgesChange = useCallback(
|
||||||
|
(changes: any) => setEdges((eds) => applyEdgeChanges(changes, eds)),
|
||||||
|
[setEdges]
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Тип: useCallback
|
||||||
|
- Вход: changes — массив изменений эджей.
|
||||||
|
- Логика: Применяет изменения к эджам через applyEdgeChanges, обновляет edges.
|
||||||
|
- Цель: Обработать изменения связей.
|
||||||
|
8. Функция onConnect
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
const onConnect = useCallback(
|
||||||
|
(connection: any) => setEdges((eds) => addEdge(connection, eds)),
|
||||||
|
[setEdges]
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Тип: useCallback
|
||||||
|
- Вход: connection — объект новой связи.
|
||||||
|
- Логика: Добавляет связь через addEdge, обновляет edges.
|
||||||
|
- Цель: Создавать новые связи на холсте.
|
||||||
|
9. Функция handleNodesChange
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
const handleNodesChange = (changes: any) => {
|
||||||
|
onNodesChange(changes);
|
||||||
|
const newData = processNodeChanges(changes, data);
|
||||||
|
if (newData) {
|
||||||
|
setChangeArray((prevArray) => [...prevArray, newData]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- Вход: changes — массив изменений нод.
|
||||||
|
- Логика: Обновляет ноды через onNodesChange, извлекает изменения позиций через processNodeChanges, добавляет в changeArray.
|
||||||
|
- Цель: Отслеживать перемещения нод.
|
||||||
|
10. Седьмой useEffect — Автосохранение позиций
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (socket && socket.readyState === WebSocket.OPEN) {
|
||||||
|
autosavePosition(changeArray, socket);
|
||||||
|
}
|
||||||
|
setChangeArray([]);
|
||||||
|
}, 1000);
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
}, [changeArray, socket]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении changeArray, socket.
|
||||||
|
- Логика: Каждую секунду отправляет изменения позиций через autosavePosition, очищает changeArray.
|
||||||
|
- Очистка: Удаляет интервал.
|
||||||
|
- Цель: Сохранять позиции на сервере.
|
||||||
|
11. Восьмой useEffect — Обработка групп
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
const sortedGroups = groupSort(groups, nodes);
|
||||||
|
setNodes(collapseGroup(sortedGroups, nodes));
|
||||||
|
}, [groups]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении groups.
|
||||||
|
- Логика: Сортирует ноды по группам через groupSort, сворачивает/разворачивает через collapseGroup, обновляет nodes.
|
||||||
|
- Цель: Организовать ноды по группам.
|
||||||
|
12. Девятый useEffect — Обновление Wi-Fi
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (wifiData) {
|
||||||
|
setNodes(updateWifiData(wifiData, nodes));
|
||||||
|
}
|
||||||
|
}, [wifiData]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении wifiData.
|
||||||
|
- Логика: Обновляет ноды с учетом Wi-Fi через updateWifiData.
|
||||||
|
- Цель: Отобразить Wi-Fi данные.
|
||||||
|
13. Десятый useEffect — Обработка ошибок
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (requestError.status) {
|
||||||
|
setTimeout(() => {
|
||||||
|
openModal(ModalMap['3'], { message: requestError.message });
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}, [requestError]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении requestError.
|
||||||
|
- Логика: При ошибке через 1 сек открывает модальное окно с сообщением.
|
||||||
|
- Цель: Уведомить об ошибках.
|
||||||
|
14. Одиннадцатый useEffect — Сброс позиций
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
useEffect(() => {
|
||||||
|
if (isNullPos) {
|
||||||
|
if (socket && socket.readyState === WebSocket.OPEN) {
|
||||||
|
resetPosition(socket, setNullPos, nodes, setNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isNullPos]);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Условие: Срабатывает при изменении isNullPos.
|
||||||
|
- Логика: При истинном isNullPos сбрасывает позиции через resetPosition, обновляет ноды.
|
||||||
|
- Цель: Вернуть исходные позиции.
|
||||||
|
|
||||||
|
#### 2.3. Рендеринг
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ReactFlow
|
||||||
|
nodes={nodes}
|
||||||
|
edges={edges}
|
||||||
|
onNodesChange={handleNodesChange}
|
||||||
|
onEdgesChange={onEdgesChange}
|
||||||
|
onConnect={onConnect}
|
||||||
|
style={{ background: '#F7F9FB' }}
|
||||||
|
minZoom={0}
|
||||||
|
maxZoom={4}
|
||||||
|
fitView
|
||||||
|
fitViewOptions={{ padding: 0.1 }}
|
||||||
|
attributionPosition="bottom-left"
|
||||||
|
snapToGrid
|
||||||
|
snapGrid={[20, 20]}
|
||||||
|
panOnDrag={!isPanDisabled}
|
||||||
|
nodeTypes={nodeTypes}
|
||||||
|
proOptions={proOptions}
|
||||||
|
>
|
||||||
|
<Background gap={20} size={1} bgColor={theme.background} />
|
||||||
|
<Controls fitViewOptions={{ padding: 0.1 }} />
|
||||||
|
</ReactFlow>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Компонент: ReactFlow рендерит холст.
|
||||||
|
- Параметры: Ноды, эджи, обработчики, фон, зум (0–4), сетка (20x20), перетаскивание по isPanDisabled, кастомные ноды.
|
||||||
|
- Дочерние: Background (сетка), Controls (кнопки для управления зумом).
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Сервер от меня
|
# Сервер от меня
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
# Структура исходного кода клиентской части
|
||||||
|
|
||||||
|
### Структура исходного кода клиенсткой части
|
||||||
|
|
||||||
|
```
|
||||||
|
FRONT/
|
||||||
|
BUILD/ # Сближенная версия приложения
|
||||||
|
DEV/ # Исходный код приложения
|
||||||
|
assets/
|
||||||
|
icon.png # Иконка для самого приложения
|
||||||
|
public/
|
||||||
|
assets/
|
||||||
|
images/ # SVG-иконки и изображения для UI
|
||||||
|
back1.svg
|
||||||
|
bigLogo.svg
|
||||||
|
bukvi.svg
|
||||||
|
cancel.svg
|
||||||
|
check.svg
|
||||||
|
edit.svg
|
||||||
|
ethernet.svg
|
||||||
|
gossys.png
|
||||||
|
logo.svg
|
||||||
|
signal.svg
|
||||||
|
vite.svg
|
||||||
|
vpn.svg
|
||||||
|
wifi.svg
|
||||||
|
src/ # Основной исходный код приложения
|
||||||
|
api/
|
||||||
|
request.ts # Функции для HTTP-запросов
|
||||||
|
assets/
|
||||||
|
css/ # Стили приложения
|
||||||
|
flow.css # Стили для React Flow
|
||||||
|
index.css # Глобальные стили приложения
|
||||||
|
components/
|
||||||
|
customeNodes/ # Кастомные ноды для React Flow
|
||||||
|
nodes/
|
||||||
|
baseForm/ # Базовые формы нод
|
||||||
|
circle/
|
||||||
|
circleNode.tsx # Компонент ноды в форме круга
|
||||||
|
style.ts
|
||||||
|
default/
|
||||||
|
defaultNode.tsx # Компонент ноды по умолчанию
|
||||||
|
style.ts
|
||||||
|
diamond/
|
||||||
|
diamondNode.tsx # Компонент ноды в форме ромба
|
||||||
|
style.ts
|
||||||
|
paralelogram/
|
||||||
|
paralelogramNode.tsx # Компонент ноды в форме параллелограмма
|
||||||
|
style.ts
|
||||||
|
pill/
|
||||||
|
pillNode.tsx # Компонент ноды в форме таблетки
|
||||||
|
style.ts
|
||||||
|
networkInterface/ # Ноды для представления сетевых интерфейсов
|
||||||
|
ipGroup/
|
||||||
|
ipGroup.tsx # Компонент ноды групп IP-адресов
|
||||||
|
style.ts
|
||||||
|
ipNode/
|
||||||
|
ipNode.tsx # Компонент ноды IP-адреса
|
||||||
|
style.ts
|
||||||
|
networkGroup/
|
||||||
|
nodeGroup.tsx # Компонент ноды групп сетевых интерфейсов
|
||||||
|
style.ts
|
||||||
|
networkNode/
|
||||||
|
networkNode.tsx # Компонент ноды сетевого интерфейса
|
||||||
|
style.ts
|
||||||
|
portNode/
|
||||||
|
portNode.tsx # Компонент ноды порта
|
||||||
|
style.ts
|
||||||
|
index.ts
|
||||||
|
types/
|
||||||
|
colors.ts # Константы цветов для нод
|
||||||
|
types.ts # Общие типы для нод
|
||||||
|
modalwindows/
|
||||||
|
modalContainers/ # Контейнеры для модальных окон
|
||||||
|
addDevice.tsx
|
||||||
|
connectionError.tsx
|
||||||
|
ipConfirm.tsx
|
||||||
|
rightsConfirm.tsx
|
||||||
|
index.ts
|
||||||
|
modal.tsx # Базовый компонент модального окна
|
||||||
|
modalWindow.tsx # Основной компонент для рендеринга модальных окон
|
||||||
|
style.ts # Стили для модальных окон
|
||||||
|
windowsType.ts # Типы для модальных окон
|
||||||
|
UI/ # Общие UI-компоненты
|
||||||
|
buttons/
|
||||||
|
mainButton.tsx # Основная кнопка приложения
|
||||||
|
quitButton.tsx # Кнопка выхода
|
||||||
|
toggletheme.tsx # Кнопка переключения темы
|
||||||
|
inputs/
|
||||||
|
input.tsx # Компонент поля ввода
|
||||||
|
animDot.tsx # Анимированная точка
|
||||||
|
loader.tsx # Компонент загрузки
|
||||||
|
routerLoader.tsx # Лоадер для маршрутизации
|
||||||
|
signalSvg.tsx # SVG-компонент для индикатора сигнала
|
||||||
|
workSpace/ # Компоненты рабочего пространства
|
||||||
|
modules/
|
||||||
|
appModules/ # Общие модули приложения
|
||||||
|
about.tsx # Страница/компонент "О программе"
|
||||||
|
header.tsx # Компонент хэдера
|
||||||
|
helloWindow.tsx # Приветственное окно
|
||||||
|
workModules/
|
||||||
|
networkInterfaces.tsx # Модуль для управления сетевыми интерфейсами
|
||||||
|
sideBar/ # Боковая панель
|
||||||
|
toolBar/
|
||||||
|
toolBar-button.tsx # Компонент кнопки панели инструментов
|
||||||
|
toolBar.tsx # Панель инструментов
|
||||||
|
toolSpace/
|
||||||
|
devicesBar.tsx # Меню управление подключённых хостов
|
||||||
|
toolSpace.tsx # Компонент пространства инструментов
|
||||||
|
sideBar.tsx # Основной компонент боковой панели
|
||||||
|
workSpace.tsx # Основной компонент рабочего пространства
|
||||||
|
register.tsx # Компонент регистрации пользователя(создания пароля)
|
||||||
|
const/ # Константы и конфигурации
|
||||||
|
buttons/
|
||||||
|
icons.tsx # Иконки для кнопок
|
||||||
|
names.ts # Названия кнопок
|
||||||
|
menus/
|
||||||
|
othersMenus/
|
||||||
|
data.ts # Данные для прочих меню
|
||||||
|
names.ts # Названия прочих меню
|
||||||
|
sideBar/
|
||||||
|
components.tsx # Компоненты для боковой панели
|
||||||
|
data.ts # Данные для боковой панели
|
||||||
|
icons.tsx # Иконки боковой панели
|
||||||
|
names.ts # Названия пунктов боковой панели
|
||||||
|
modals/
|
||||||
|
names.ts # Названия модальных окон
|
||||||
|
theme/
|
||||||
|
globalStyles.ts # Глобальные стили темы
|
||||||
|
icons.tsx # Иконки для темы
|
||||||
|
names.ts # Названия тем
|
||||||
|
theme.ts # Конфигурация темы
|
||||||
|
types/
|
||||||
|
types.ts # Общие типы приложения
|
||||||
|
workspace/
|
||||||
|
names.ts # Названия для рабочего пространства
|
||||||
|
hooks/
|
||||||
|
useMenu.ts # Хук для управления меню
|
||||||
|
useToolBar.ts # Хук для управления панелью инструментов
|
||||||
|
store/
|
||||||
|
adminStore.ts # Хранилище для админских данных
|
||||||
|
devicesStore.ts # Хранилище для данных об подключённых хостах
|
||||||
|
flowStore.ts # Хранилище для React Flow
|
||||||
|
groupStore.ts # Хранилище для групп нод
|
||||||
|
index.ts # Экспорт всех хранилищ
|
||||||
|
ipStore.ts # Хранилище для IP-адресов
|
||||||
|
menusStore.ts # Хранилище для меню
|
||||||
|
modalContext.tsx # Контекст для управления модальными окнами
|
||||||
|
pannableStore.ts # Хранилище для перемещения холста
|
||||||
|
posStore.ts # Хранилище для позиций нод
|
||||||
|
themeContext.tsx # Контекст для управления темой
|
||||||
|
toolBarStore.ts # Хранилище для панели инструментов
|
||||||
|
workSpaceStore.ts # Хранилище для рабочего пространства
|
||||||
|
utils/ # Утилитарные функции
|
||||||
|
nodeController/ # Утилиты для управления узлами
|
||||||
|
nodeCreator/
|
||||||
|
inits/
|
||||||
|
initEdges.ts # Инициализация связей (эджей)
|
||||||
|
initIpArray.ts # Инициализация массива IP-адресов
|
||||||
|
initNodes.ts # Инициализация нод
|
||||||
|
initor.ts # Общий инициализатор
|
||||||
|
autosavePosition.ts # Автосохранение позиций нод
|
||||||
|
collapseGroup.ts # Сворачивание групп нод
|
||||||
|
groupSort.ts # Сортировка групп
|
||||||
|
index.ts # Экспорт утилит
|
||||||
|
initNetIntData.ts # Инициализация данных сетевых интерфейсов
|
||||||
|
updateWifiData.ts # Обновление данных Wi-Fi
|
||||||
|
validator.ts # Валидация данных
|
||||||
|
checkAdmin.ts # Проверка прав администратора
|
||||||
|
pageReloads.ts # Утилиты для управления перезагрузкой страниц
|
||||||
|
electron.d.ts # Типы для Electron
|
||||||
|
router.tsx # Маршрутизация (React Router)
|
||||||
|
.gitignore
|
||||||
|
eslint.config.js
|
||||||
|
index.html # Главный HTML-файл
|
||||||
|
index.tsx # Точка входа для React-приложения
|
||||||
|
main.js # Главный файл для Electron
|
||||||
|
package-lock.json
|
||||||
|
package.json
|
||||||
|
preload.js # Preload-скрипт для Electron
|
||||||
|
tsconfig.app.json
|
||||||
|
tsconfig.json
|
||||||
|
tsconfig.node.json
|
||||||
|
vite-env.d.ts
|
||||||
|
vite.config.ts
|
||||||
|
yarn.lock
|
||||||
|
```
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Схема общей структуры клиентской части
|
# Схема общей структуры клиентской части
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Схема общей структуры сервера
|
# Схема общей структуры сервера
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Зависимости сервера (AGPL Нету):
|
### Зависимости сервера (AGPL Нету):
|
||||||
|
|
||||||
|
|
|
||||||