diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml deleted file mode 100644 index 26470a9..0000000 --- a/.forgejo/workflows/release.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Gonets Release Debian Packaging - -on: - workflow_dispatch: - -jobs: - build-and-release: - runs-on: debian - steps: - - name: Checkout main - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: main - - - name: Установка всех необходимых зависимостей для сборки - run: | - sudo apt update - sudo apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make - - - name: Сборка backend - run: | - cd SRV - poetry install - - - name: Сборка frontend - run: | - cd FRONT/BUILD/resources/app - npm install - npm run build - - - name: Build deb package - run: | - dpkg-buildpackage -us -uc -b - - - name: Get version from changelog - id: get_version - run: | - VERSION=$(dpkg-parsechangelog | awk '/^Version:/ {print $2}') - echo "version=$VERSION" >> $GITHUB_OUTPUT - - - name: Create git tag - env: - GIT_PUSH_TOKEN: ${{ secrets.GIT_PUSH_TOKEN }} - run: | - git config --global user.email "ci-bot@example.com" - git config --global user.name "CI Bot" - git tag gonets-${{ steps.get_version.outputs.version }} - git push https://ci-bot:${GIT_PUSH_TOKEN}@${GITEA_SERVER}/${GITEA_REPO}.git gonets-${{ steps.get_version.outputs.version }} - - - name: Create release and upload deb - uses: softprops/action-gh-release@v2 - with: - tag_name: gonets-${{ steps.get_version.outputs.version }} - name: "Gonets ${{ steps.get_version.outputs.version }}" - files: ../*.deb - env: - GITHUB_TOKEN: ${{ secrets.GIT_PUSH_TOKEN }} \ No newline at end of file diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml new file mode 100644 index 0000000..94ea84d --- /dev/null +++ b/.woodpecker/.woodpecker.yml @@ -0,0 +1,20 @@ +when: + event: manual + +steps: + checkout: + image: debian:latest + environment: + FORGEJO_TOKEN: + from_secret: forgejo_token + commands: + # ПОДГОТОВКА ГИТА И КЛОНИРОВАНИЕ GONETS + - apt update + - apt install -y git git-lfs + - git lfs install + - git config --global user.email "s.galanskiy@gossys.dev" + - git config --global user.name "s.galanskiy" + - touch file + - git add . + - git commit -m "commit" + - git push https://$FORGEJO_TOKEN@dev.gossys.dev/s.galanskiy/gonets.git \ No newline at end of file diff --git a/FRONT/BUILD/index.html b/FRONT/BUILD/index.html new file mode 100644 index 0000000..8f4d4d1 --- /dev/null +++ b/FRONT/BUILD/index.html @@ -0,0 +1,13 @@ + +
+ + +
- v 0.0.3
+
+ ГоNets — минимально работоспособный кроссплатформенный продукт (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.
-Возможности:
-Приложение ГоNets является минимально работоспособным кроссплатформенным продуктом (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.
+Программное обеспечение исключительно для ознакомления и домашнего использования.
- Перейти на ГоNets-PRO -Данное приложение умеет:
+- Отображать в графическом виде активные сетевые ресурсы
+- Настраивать сетевые параметры локального и удаленных сетевых ресурсов
+- Отображать и изменять взаимодействие сетевых ресурсов с установленным Клиентом ГоNets
+Программное обеспечение исключительно для ознакомления и домашнего использования.
+Для коммерческого использования приобретите версию ГоNets-PRO (Подробная информация на странице продукта)
+Ссылка на домашнюю страницу:
+ https://gossys.dev/pages/projects/gonets +Инструкции и информация:
+ https://wiki.gossys.dev/ru/gonets +Распространяется под лицензией GosysPUB текущей версии.
+Полный текст актуальной лицензии:
+ https://wiki.gossys.dev/ru/lic/GosysPUB +Разработано и поддерживается ООО «Гибридные Офисные Системы» 2024-2025 г. Все права защищены.
+Узлы не найдены
+Устройства не найдены
) : null} > ); diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx index 77e064c..ebe71a9 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -30,13 +30,13 @@ const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps return ( <>Узлы не найдены
+Устройства не найдены
) : null} > ); diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx index 19ca497..cb816ca 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx @@ -77,7 +77,7 @@ const UserLocate = styled.div<{ loading: boolean, scanInitiated: boolean }>` span { position: absolute; display: inline-block; - background: ${(props) => props.theme.scannerColor}; + background: ${(props) => props.theme.accent}; top: 50%; left: 50%; transform: translate(-50%, -50%); @@ -163,7 +163,7 @@ export default function UserScanner() { return (+ MAC: {device.mac} +
+ +{value?.label || 'Select an option'}
+Версия IP:
+v{data.ipData.ipVersion}
+Метод:
+{typeMap[data.ipData.ipType]}
+IPv{data.ipData.ipVersion}-Addr:
+ {isInput ? ( + handleChange('newIp', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +{data.ipData.ipAdress}
+ )} + +IPv{data.ipData.ipVersion}-GW:
+ {isInput ? ( + handleChange('newGate', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +{data.ipData.ipGate}
+ )} +IPv{data.ipData.ipVersion}-DNS:
+ {isInput ? ( + handleChange('newDns', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +{data.ipData.ipDns.join(', ')}
+ )} +{data.label}
+ + {/*Конфигурация
+MAC:
+{data.networkData.mac}
+MTU:
+{data.networkData.mtu}
+{data.label}
+ + + {data.port && +{data.port}
+ } ++ {error} +
+Пожалуйста, проверьте доступ к адресу и попробуйте снова.
+Вы собираетесь отключиться от сети "{address}". Все активные подключения будут прерваны.
+Интерфейс: {ipData.device}
+--{'>'}
+{ipData.connection}
+Текущий ip: {ipData.currentIp}
+Текущий шлюз: {ipData.currentGate}
+Текущий DNS: {ipData.currentDns}
+Новый ip: {ipData.newIp}
+Новый шлюз: {ipData.newGate}
+Новый DNS: {ipData.newDns}
++ Неверный пароль оператора +
+ )} + +В данном режиме доступа ограничиваются полномочия администратора.
+Это окно можно закрыть, либо оно пропадёт само
+{ipAddress}
+ } + +Перед началом работы необходимо создать пароль оператора приложения
++ Пароли не совпадают! +
+ )} +
+ v 0.0.3
+ГоNets — минимально работоспособный кроссплатформенный продукт (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.
+Возможности:
+Программное обеспечение исключительно для ознакомления и домашнего использования.
+ Перейти на ГоNets-PRO +Узлы не найдены
+ ) : null} + > + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx new file mode 100644 index 0000000..77e064c --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import styled from 'styled-components'; +import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; +import {DeviceUser} from "../../../../../../store/useDeviceStore"; +import TableScanner from "../../../../../UI/tables/TableScanner"; + +const ScanBtn = styled.button` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; + transition: .4s ease; + &:hover{ + transform: scale(1.03); + } +` + +interface ListUsersProps { + loading: boolean; + handleScan: ()=>void; + devices: DeviceUser[]; + scanInitiated: boolean; +} + +const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps) => { + + return ( + <> +Узлы не найдены
+ ) : null} + > + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx new file mode 100644 index 0000000..19ca497 --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx @@ -0,0 +1,191 @@ +import { useIpStore } from "../../../../../store"; +import styled, { keyframes } from "styled-components"; +import { useState } from "react"; +import { NetworkService } from "../../../../../api/request"; +import ListUsers from "./modules/ListUsers"; +import TableUsers from "./modules/TableUsers"; +import DropdownType from "../../../../UI/Dropdown/DropdownType"; +import useNetworkStore from "../../../../../store/useDeviceStore"; + +type Option ={ + value: number, + label: string, +} + +// Анимации +const ring1 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.2; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } +`; + +const ring2 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.15; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } +`; + +const ring3 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.1; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } +`; +const dotAnimation = keyframes` + 0% { content: '.'; } + 33% { content: '..'; } + 66% { content: '...'; } + 100% { content: '.'; } +`; +const pulse = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); } + 50% { transform: translate(-50%, -50%) scale(1.1); } + 100% { transform: translate(-50%, -50%) scale(1); } +`; + +// Стили +const Wrapper = styled.div<{ scanInitiated: boolean, loading: boolean}>` + display: flex; + flex-direction: column; + align-items: center; + justify-content:${({scanInitiated, loading})=>(scanInitiated && !loading ? 'start' : 'center')}; + height: 100%; + width: 100%; + background: ${(props) => props.theme.background}; + padding: 50px; + box-sizing: border-box; + gap: 24px; + transition: justify-content .4s ease; + overflow-y: auto; + overflow-x: hidden; + position: relative; +`; +const TitleWrapper = styled.h2` + position: absolute; + top: 20px; + left: 50%; + transform: translateX(-50%); + font-size: 32px; + width: max-content; +` +const UserLocate = styled.div<{ loading: boolean, scanInitiated: boolean }>` + width: 60px; + height: 60px; + border-radius: 50%; + position: relative; + transition: .4s ease; + transform: ${({scanInitiated,loading})=>(scanInitiated && !loading ? 'scale(0)' : 'scale(1)')}; + span { + position: absolute; + display: inline-block; + background: ${(props) => props.theme.scannerColor}; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 50%; + &.center { + width: 60px; + height: 60px; + animation: ${({ loading }) => (loading ? pulse : "none")} 2s ease infinite; + } + &.ring1 { + opacity: 0.12; + width: 250px; + height: 250px; + animation: ${({ loading }) => (loading ? ring1 : "none")} 4s linear infinite; + } + + &.ring2 { + opacity: 0.08; + width: 400px; + height: 400px; + animation: ${({ loading }) => (loading ? ring2 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.1s" : "0")}; + } + + &.ring3 { + opacity: 0.04; + width: 550px; + height: 550px; + animation: ${({ loading }) => (loading ? ring3 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.2s" : "0")}; + } + } +`; + +const LoadingText = styled.div` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; +`; +const ScanningText = styled.span` + &::after { + content: '.'; + animation: ${dotAnimation} 1.5s infinite; + } +`; + + +export default function UserScanner() { + const { ipAddress } = useIpStore(); + const [loading, setLoading] = useState(false); + const { devices, setDevices } = useNetworkStore(); + const [scanInitiated, setScanInitiated] = useState(devices.length > 0); + + // Сканирование + const handleScan = async () => { + try { + setLoading(true); + setScanInitiated(true); + const res = await NetworkService.scanUser(ipAddress); + console.log(res); + setDevices(res.data.devices || []); + } catch (err) { + console.error("Ошибка сканирования сети:", err); + setDevices([]) + } finally { + setLoading(false); + } + }; + + // Способ отображения + const viewOptions: Option[] = [ + { value: 1, label: 'Таблица' }, + { value: 2, label: 'Список' }, + ]; + const [selectedView, setSelectedView] = useState