11 KiB
Общее описание кода клиентской части
Клиент ГоNets — это одностраничное веб-приложение, разработанное на TypeScript с использованием фреймворка React. Код организован по принципам компонентно-ориентированной архитектуры, разделён на модули и компоненты для упрощения разработки, поддержки и масштабирования. Приложение использует localStorage, библиотеку Zustand и React Context для управления состоянием, а также HTTPS и WebSocket для взаимодействия с сервером.
1. Входная точка приложения
Точка входа — файл index.tsx, где инициализируется корневой компонент приложения. Здесь подключаются роутер и компонент модальных окон:
return (
<>
<WindowComponent isOpen={isOpen} type={modalType} data={modalData} />
<Router />
</>
);
Приложение оборачивается в провайдеры ThemeProvider и ModalProvider, которые обеспечивают глобальный доступ к темам и модальным окнам:
root.render(
<ThemeProvider>
<HashRouter>
<ModalProvider>
<MainComponent />
</ModalProvider>
</HashRouter>
</ThemeProvider>
);
2. Роутинг
Роутинг реализован в файле router.tsx с использованием библиотеки react-router-dom. Несмотря на одностраничную природу приложения, роутинг управляет условной загрузкой компонентов в зависимости от конфигурации:
if (configExists === null) {
return <RouterLoader loaderText="Идёт загрузка данных" />;
}
if (configExists === false) {
return <CreateUser />;
}
return (
<Routes>
<Route path="/" element={<WorkSpace />} />
</Routes>
);
3. Рабочее пространство
Рабочее пространство (workspace.tsx) — центральная часть приложения, где происходит отрисовка интерфейса и взаимодействие с пользователем. Оно включает:
- Боковую панель (SideBar) — отвечает за навигацию и управление.
- Модули — динамически подключаемые компоненты, отображаемые на основе значения из localStorage.
Логика отображения модулей:
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
-
currentIp-storage (строка): Хранит IP-адрес текущего хоста или "localhost". Пример: "192.168.1.147".
-
connectedDevices-storage (массив объектов Device): Список подключённых хостов.
interface Device { number: number; address: string; }Пример: [{ number: 1, address: "192.168.1.147" }].
-
menus-storage (массив объектов Menu): Состояние меню (открыто/закрыто, активно/неактивно).
interface Menu { id: string; isOpen: boolean; isActive?: boolean; }Пример: [{ id: "menu1", isOpen: true, isActive: true }].
-
toolBar-storage (объект ToolBar): Состояние боковой панели и текущий активный пункт.
interface ToolSpace { id: string; isOpen: boolean; isActive?: boolean; } interface ToolBar { toolSpace: ToolSpace[]; current: string; }Пример: { toolSpace: [{ id: "tool1", isOpen: true, isActive: true }], current: "tool1" }.
-
workSpace-storage (строка): Название активного модуля из /src/const/workSpace/names.ts. Пример: "networkInterfaces".
-
theme (строка): Текущая тема приложения ("light", "dark", "system"). Пример: "dark".
4.2. Zustand-хранилища, связанные с localStorage
- useIpStore (currentIp-storage): Управляет IP-адресом хоста.
- Методы: setIpAddress(newIp: string).
- Пример: "localhost".
- useDevicesStore (connectedDevices-storage): Управляет списком устройств.
- Методы: addDevice(address: string), deleteDevice(number: number).
- Пример: [{ number: 1, address: "192.168.1.147" }].
- useMenuStore (menus-storage): Управляет состоянием меню.
- Методы: toggleMenu(menuId: string).
- Пример: [{ id: "menu1", isOpen: true, isActive: true }].
- useToolBarStore (toolBar-storage): Управляет боковой панелью.
- Методы: toggleMenu(menuId: string), initialize().
- Пример: { toolSpace: [{ id: "tool1", isOpen: true }], current: "tool1" }.
- useWorkSpaceStore (workSpace-storage): Хранит активный модуль.
- Методы: setWorkModule(newModule: string), initialize().
- Пример: "networkInterfaces".
4.3. Zustand-хранилища (без localStorage)
- useAdminStore: Управляет административными правами.
- Тип: Булево значение (isAdmin).
- Методы: setAdmin(isAdmin: boolean).
- Пример: isAdmin: true.
- useGroupStore: Управляет группами нод в React Flow.
- Тип: Массив объектов { id: string; click: boolean }.
- Методы: setGroups(groups: { id: string; click: boolean }[]).
- Пример: [{ id: "group1", click: true }].
- usePosStore: Хранит флаг для сброса позиций нод в React Flow.
- Тип: Булево значение (isNullPos).
- Методы: setNullPos(isNullPos: boolean).
- Пример: isNullPos: false.
- React Контексты
4.4. Контекст темы (ThemeProvider)
-
Назначение: Управляет темой приложения ("light", "dark", "system") и её переключением.
-
Хранилище localStorage: theme.
-
Интерфейс:
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)
-
Назначение: Управляет отображением модальных окон.
-
Интерфейс:
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", "загрузка данных").