feat: add swagger docs
ci-front / build (push) Successful in 2m26s

This commit is contained in:
2026-04-04 02:44:36 +03:00
parent 065b5492ef
commit 691e1fced5
5 changed files with 215 additions and 7 deletions
@@ -0,0 +1,78 @@
import { apiClient } from "@/shared/api/axios.instance";
import type {
AgentInfo,
TokenCreate,
TokenUser,
LogEntry,
LogFilters,
InsertLogRequest,
InsertLogsRequest,
} from "../types/agent.types";
class AgentApiService {
private readonly basePath = "/agents";
private readonly authBasePath = "/auth";
private readonly logsBasePath = "/logs";
async getAgents(): Promise<AgentInfo[]> {
const response = await apiClient.get<AgentInfo[]>(this.basePath);
return response.data;
}
async getUsers(): Promise<TokenUser[]> {
const response = await apiClient.get<TokenUser[]>(`${this.authBasePath}/tokens`);
return response.data;
}
async createUser(data: TokenCreate): Promise<void> {
await apiClient.post(`${this.authBasePath}/token`, data);
}
async deleteUser(login: string): Promise<void> {
await apiClient.delete(`${this.authBasePath}/tokens/${login}`);
}
async deleteMyAccount(): Promise<void> {
await apiClient.delete(`${this.authBasePath}/token`);
}
async searchLogs(filters?: LogFilters): Promise<LogEntry[]> {
const response = await apiClient.get<LogEntry[]>(this.logsBasePath, {
params: {
level: filters?.level,
service: filters?.service,
agent: filters?.agent,
date_from: filters?.date_from,
date_to: filters?.date_to,
limit: filters?.limit ?? 100,
offset: filters?.offset ?? 0,
},
});
return response.data;
}
async insertLog(entry: InsertLogRequest): Promise<void> {
await apiClient.post(this.logsBasePath, entry);
}
async insertLogsBatch(data: InsertLogsRequest): Promise<void> {
await apiClient.post(`${this.logsBasePath}/batch`, data);
}
async getDistinctAgents(): Promise<string[]> {
const response = await apiClient.get<string[]>(`${this.logsBasePath}/agents`);
return response.data;
}
async getDistinctLevels(): Promise<string[]> {
const response = await apiClient.get<string[]>(`${this.logsBasePath}/levels`);
return response.data;
}
async getDistinctServices(): Promise<string[]> {
const response = await apiClient.get<string[]>(`${this.logsBasePath}/services`);
return response.data;
}
}
export const agentApiService = new AgentApiService();
@@ -0,0 +1,36 @@
import { useState, useEffect, useCallback } from "react";
import { agentApiService } from "../api/agent.api.service";
import type { AgentInfo } from "../types/agent.types";
interface UseAgentsResult {
agents: AgentInfo[];
isLoading: boolean;
error: string | null;
refetch: () => Promise<void>;
}
export function useAgents(): UseAgentsResult {
const [agents, setAgents] = useState<AgentInfo[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchAgents = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const data = await agentApiService.getAgents();
setAgents(data);
} catch (err) {
const message = err instanceof Error ? err.message : "Failed to fetch agents";
setError(message);
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
fetchAgents();
}, [fetchAgents]);
return { agents, isLoading, error, refetch: fetchAgents };
}
+18
View File
@@ -0,0 +1,18 @@
export { SSHAgentForm } from "./ui/SSHAgentForm";
export type { SSHAgentConfig, ExtraField } from "./ui/SSHAgentForm";
export { useAgents } from "./hooks/useAgents.hook";
export { agentApiService } from "./api/agent.api.service";
export type {
AgentInfo,
LoginRequest,
LoginResponse,
TokenCreate,
TokenUser,
LogEntry,
InsertLogRequest,
InsertLogsRequest,
LogFilters,
} from "./types/agent.types";
@@ -0,0 +1,71 @@
export interface AgentInfo {
label: string;
services: string[];
token: string;
}
export interface LoginRequest {
login: string;
password: string;
}
export interface LoginResponse {
last_name: string;
login: string;
name: string;
permission_admin: boolean;
permission_manage_agent: boolean;
permission_view: boolean;
token: string;
}
export interface TokenCreate {
login: string;
name: string;
last_name: string;
password: string;
permission_admin?: boolean;
permission_manage_agent?: boolean;
permission_view?: boolean;
}
export interface TokenUser {
id: number;
login: string;
name: string;
last_name: string;
permission_admin: boolean;
permission_manage_agent: boolean;
permission_view: boolean;
token: string;
}
export interface LogEntry {
agent: string;
level: string;
message: string;
service: string;
timestamp: string;
}
export interface InsertLogRequest {
agent: string;
level: string;
message: string;
service: string;
timestamp?: string;
}
export interface InsertLogsRequest {
logs: InsertLogRequest[];
}
export interface LogFilters {
level?: string;
service?: string;
agent?: string;
date_from?: string;
date_to?: string;
limit?: number;
offset?: number;
}
+12 -7
View File
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { SSHAgentForm } from "../modules/agent/ui/SSHAgentForm";
import { agentApiService } from "../modules/agent/api/agent.api.service";
import { FiPlusCircle, FiSend } from "react-icons/fi";
interface SSHAgentConfig {
@@ -66,18 +67,22 @@ export const AddAgentsPage: React.FC = () => {
setSubmitError(null);
try {
// Получаем текущих агентов для проверки подключения
const currentAgents = await agentApiService.getAgents();
console.log("Current agents:", currentAgents);
// TODO: Реальный API вызов для развертывания агентов
console.log("Deploying agents:", agents);
// Имитация задержки API
await new Promise((resolve) => setTimeout(resolve, 1500));
// Пока выводим список подключенных агентов
setSubmitMessage(
`Успешно отправлено ${agents.length} сервер(ов) на развертывание`,
`Успешно подключено ${currentAgents.length} агент(ов). Серверы: ${agents.length}`,
);
setAgents([createEmptyAgentConfig()]);
} catch (error) {
setSubmitError("Ошибка при развертывании на серверах");
setSubmitError(
error instanceof Error
? error.message
: "Ошибка при подключении к серверам",
);
} finally {
setIsSubmitting(false);
}