GonetsDocs/Documentation/Общее описание кода клиентской части.md
2025-10-14 16:19:35 +05:00

11 KiB
Raw Blame History

Общее описание кода клиентской части

Клиент Го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

  1. currentIp-storage (строка): Хранит IP-адрес текущего хоста или "localhost". Пример: "192.168.1.147".

  2. connectedDevices-storage (массив объектов Device): Список подключённых хостов.

    interface Device { number: number; address: string; }
    

    Пример: [{ number: 1, address: "192.168.1.147" }].

  3. menus-storage (массив объектов Menu): Состояние меню (открыто/закрыто, активно/неактивно).

    interface Menu { id: string; isOpen: boolean; isActive?: boolean; }
    

    Пример: [{ id: "menu1", isOpen: true, isActive: true }].

  4. 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" }.

  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".
  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.

  • Интерфейс:

    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", "загрузка данных").