muryshev commited on
Commit
4f9f661
·
1 Parent(s): d6b9145
src/App.tsx CHANGED
@@ -3,31 +3,58 @@ import { Routes, Route, BrowserRouter as Router, Navigate } from "react-router-d
3
  import Navbar from '@/components/common/navbar/Navbar';
4
  import Page from "@/components/pages/main/Page";
5
  import Logs from "@/components/pages/logsPage/Logs";
6
- import Vectorization from "./components/pages/vectorizationPage/Vectorization";
7
  import { pdfjs } from "react-pdf";
8
- import LLMConfigList from "./components/pages/llmConfigs/LlmConfigList";
9
- import LlmPromptList from "./components/pages/llmPrompts/LlmPromptList";
 
 
10
 
11
  pdfjs.GlobalWorkerOptions.workerSrc = new URL(
12
  "pdfjs-dist/build/pdf.worker.min.mjs",
13
  import.meta.url
14
  ).toString();
15
 
16
- function App() {
 
 
 
 
 
 
17
  return (
18
  <Router>
19
- <Navbar />
 
20
  <Routes>
21
- {/* <Route path="" element={<Page />} /> */}
22
- <Route path="/logs" element={<Logs />} />
23
- {/* <Route path="/test" element={<TestPage />} /> */}
24
- <Route path="/docs" element={<Vectorization />} />
25
- <Route path="/llmconfig" element={<LLMConfigList />} />
26
- <Route path="/llmprompt" element={<LlmPromptList />} />
27
- {/* <Route path="/" element={<Navigate to="/logs" />} /> */}
 
 
 
 
 
 
 
 
 
 
 
28
  </Routes>
 
29
  </Router>
30
  );
31
  }
32
 
33
- export default App;
 
 
 
 
 
 
 
3
  import Navbar from '@/components/common/navbar/Navbar';
4
  import Page from "@/components/pages/main/Page";
5
  import Logs from "@/components/pages/logsPage/Logs";
6
+ import Vectorization from "@/components/pages/vectorizationPage/Vectorization";
7
  import { pdfjs } from "react-pdf";
8
+ import LLMConfigList from "@/components/pages/llmConfigs/LlmConfigList";
9
+ import LlmPromptList from "@/components/pages/llmPrompts/LlmPromptList";
10
+ import LoginPage from "@/components/pages/auth/Login";
11
+ import { AuthProvider, useAuth } from "@/context/AuthContext";
12
 
13
  pdfjs.GlobalWorkerOptions.workerSrc = new URL(
14
  "pdfjs-dist/build/pdf.worker.min.mjs",
15
  import.meta.url
16
  ).toString();
17
 
18
+ const App: React.FC = () => {
19
+ const { isAuthenticated } = useAuth();
20
+
21
+ const PrivateRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => {
22
+ return isAuthenticated ? <>{children}</> : <Navigate to="/login" />;
23
+ };
24
+
25
  return (
26
  <Router>
27
+ <Navbar/>
28
+ <div className="app-content">
29
  <Routes>
30
+ <Route path="/login" element={<LoginPage />} />
31
+ <Route path="/logs" element={
32
+ <PrivateRoute>
33
+ <Logs />
34
+ </PrivateRoute>} />
35
+ <Route path="/docs" element={
36
+ <PrivateRoute>
37
+ <Vectorization />
38
+ </PrivateRoute>} />
39
+ <Route path="/llmconfig" element={
40
+ <PrivateRoute>
41
+ <LLMConfigList />
42
+ </PrivateRoute>
43
+ } />
44
+ <Route path="/llmprompt" element={
45
+ <PrivateRoute>
46
+ <LlmPromptList />
47
+ </PrivateRoute>} />
48
  </Routes>
49
+ </div>
50
  </Router>
51
  );
52
  }
53
 
54
+ const RootApp: React.FC = () => (
55
+ <AuthProvider>
56
+ <App />
57
+ </AuthProvider>
58
+ );
59
+
60
+ export default RootApp;
src/api/auth/authApi.ts ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { query } from '@/shared/api/query';
2
+ import { AuthResponse, LoginRequest } from './types';
3
+
4
+ export const login = async (data: LoginRequest): Promise<AuthResponse> => {
5
+ const response = await query<AuthResponse>({
6
+ url: '/auth/login',
7
+ method: 'post',
8
+ data,
9
+ });
10
+ if ('error' in response) {
11
+ throw new Error(`Ошибка авторизации: ${response.error.status}`);
12
+ }
13
+ return response.data;
14
+ };
src/api/auth/hooks.ts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from 'react';
2
+ import { useMutation } from '@tanstack/react-query';
3
+ import { login } from './authApi';
4
+ import { LoginRequest } from './types';
5
+
6
+ export const useAuth = () => {
7
+
8
+ const loginMutation = useMutation({
9
+ mutationFn: (data: LoginRequest) => login(data),
10
+ onSuccess: (data) => {
11
+ console.log(data)
12
+ return data;
13
+ },
14
+ onError: (error) => {
15
+ console.error('Login Error:', error);
16
+ },
17
+ });
18
+
19
+ return {
20
+ login: loginMutation.mutateAsync,
21
+ isLoading: loginMutation.isPending,
22
+ error: loginMutation.error,
23
+ };
24
+ };
src/api/auth/types.ts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ export interface LoginRequest {
2
+ username: string;
3
+ password: string;
4
+ }
5
+
6
+ export interface AuthResponse {
7
+ access_token: string;
8
+ token_type: string;
9
+ }
src/components/common/navbar/Navbar.tsx CHANGED
@@ -1,43 +1,65 @@
1
  import React from 'react';
2
- import { NavLink } from 'react-router-dom';
3
  import './Navbar.scss';
 
4
 
5
  const Navbar: React.FC = () => {
 
 
 
 
 
 
 
 
6
  return (
7
  <nav className="navbar">
8
  <ul>
9
- <li>
10
- <NavLink
11
- to="/logs"
12
- className={({ isActive }) => (isActive ? 'active' : '')}
13
- >
14
- Логи
15
- </NavLink>
16
- </li>
17
- <li>
18
- <NavLink
19
- to="/docs"
20
- className={({ isActive }) => (isActive ? 'active' : '')}
21
- >
22
- Датасеты
23
- </NavLink>
24
- </li>
25
- <li>
26
- <NavLink
27
- to="/llmconfig"
28
- className={({ isActive }) => (isActive ? 'active' : '')}
29
- >
30
- Настройки LLM
31
- </NavLink>
32
- </li>
33
- <li>
34
- <NavLink
35
- to="/llmprompt"
36
- className={({ isActive }) => (isActive ? 'active' : '')}
37
- >
38
- Системные промпты
39
- </NavLink>
40
- </li>
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  </ul>
42
  </nav>
43
  );
 
1
  import React from 'react';
2
+ import { NavLink, useNavigate } from 'react-router-dom';
3
  import './Navbar.scss';
4
+ import { useAuth } from '@/context/AuthContext';
5
 
6
  const Navbar: React.FC = () => {
7
+ const { isAuthenticated, logout } = useAuth();
8
+ const navigate = useNavigate();
9
+
10
+ const handleLogout = () => {
11
+ logout();
12
+ navigate('/login');
13
+ };
14
+
15
  return (
16
  <nav className="navbar">
17
  <ul>
18
+ {isAuthenticated ? (
19
+ <>
20
+ <li>
21
+ <NavLink
22
+ to="/logs"
23
+ className={({ isActive }) => (isActive ? 'active' : '')}
24
+ >
25
+ Логи
26
+ </NavLink>
27
+ </li>
28
+ <li>
29
+ <NavLink
30
+ to="/docs"
31
+ className={({ isActive }) => (isActive ? 'active' : '')}
32
+ >
33
+ Датасеты
34
+ </NavLink>
35
+ </li>
36
+ <li>
37
+ <NavLink
38
+ to="/llmconfig"
39
+ className={({ isActive }) => (isActive ? 'active' : '')}
40
+ >
41
+ Настройки LLM
42
+ </NavLink>
43
+ </li>
44
+ <li>
45
+ <NavLink
46
+ to="/llmprompt"
47
+ className={({ isActive }) => (isActive ? 'active' : '')}
48
+ >
49
+ Системные промпты
50
+ </NavLink>
51
+ </li>
52
+ <li>
53
+ <button onClick={handleLogout}>Выход</button>
54
+ </li>
55
+ </>
56
+ ) : (
57
+ <li>
58
+ <NavLink to="/login" className={({ isActive }) => (isActive ? 'active' : '')}>
59
+ Вход
60
+ </NavLink>
61
+ </li>
62
+ )}
63
  </ul>
64
  </nav>
65
  );
src/components/pages/auth/Login.scss ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .login-page {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ height: 100vh;
7
+ background-color: #f5f5f5;
8
+
9
+ h2 {
10
+ margin-bottom: 20px;
11
+ font-size: 24px;
12
+ color: #333;
13
+ }
14
+
15
+ form {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: 15px;
19
+ width: 300px;
20
+ padding: 20px;
21
+ background-color: white;
22
+ border-radius: 8px;
23
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
24
+
25
+ div {
26
+ display: flex;
27
+ flex-direction: column;
28
+
29
+ label {
30
+ margin-bottom: 5px;
31
+ font-size: 14px;
32
+ color: #555;
33
+ }
34
+
35
+ input {
36
+ padding: 8px;
37
+ font-size: 16px;
38
+ border: 1px solid #ddd;
39
+ border-radius: 4px;
40
+ outline: none;
41
+
42
+ &:focus {
43
+ border-color: #28a745;
44
+ }
45
+ }
46
+ }
47
+
48
+ .error {
49
+ color: #dc3545;
50
+ font-size: 14px;
51
+ text-align: center;
52
+ }
53
+
54
+ button {
55
+ padding: 10px;
56
+ font-size: 16px;
57
+ background-color: #28a745;
58
+ color: white;
59
+ border: none;
60
+ border-radius: 4px;
61
+ cursor: pointer;
62
+
63
+ &:hover {
64
+ background-color: #218838;
65
+ }
66
+
67
+ &:disabled {
68
+ background-color: #6c757d;
69
+ cursor: not-allowed;
70
+ }
71
+ }
72
+ }
73
+ }
src/components/pages/auth/Login.tsx ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+ import './Login.scss';
4
+ import { useAuth } from '@/context/AuthContext';
5
+
6
+ const LoginPage: React.FC = () => {
7
+ const [username, setUsername] = useState('');
8
+ const [password, setPassword] = useState('');
9
+ const { login, isLoading, error } = useAuth();
10
+ const navigate = useNavigate();
11
+
12
+ const handleSubmit = async (e: React.FormEvent) => {
13
+ e.preventDefault();
14
+ try {
15
+ await login({ username, password });
16
+ navigate('/logs', { replace: true });
17
+ } catch {
18
+ // Ошибка уже логируется в хуке
19
+ }
20
+ };
21
+
22
+ return (
23
+ <div className="login-page">
24
+ <h2>Вход в админку</h2>
25
+ <form onSubmit={handleSubmit}>
26
+ <div>
27
+ <label>Логин:</label>
28
+ <input
29
+ type="text"
30
+ value={username}
31
+ onChange={(e) => setUsername(e.target.value)}
32
+ />
33
+ </div>
34
+ <div>
35
+ <label>Пароль:</label>
36
+ <input
37
+ type="password"
38
+ value={password}
39
+ onChange={(e) => setPassword(e.target.value)}
40
+ />
41
+ </div>
42
+ {error && <p className="error">Неверный логин или пароль</p>}
43
+ <button type="submit" disabled={isLoading}>
44
+ {isLoading ? 'Вход...' : 'Войти'}
45
+ </button>
46
+ </form>
47
+ </div>
48
+ );
49
+ };
50
+
51
+ export default LoginPage;
src/components/pages/llmConfigs/LlmConfigList.tsx CHANGED
@@ -4,7 +4,7 @@ import { GoTrash, GoStar, GoStarFill } from 'react-icons/go';
4
  import { useQuery } from '@tanstack/react-query';
5
  import { useLLMConfigs, } from "@/api/llmConfigs/hooks";
6
  import { LLMConfig } from "@/api/llmConfigs/types";
7
- import './LlmConfigList.scss';
8
  import LLMConfigModal from './LlmConfigModal';
9
  import { fetchDefaultLLMConfig } from '@/api/llmConfigs/llmConfigApi';
10
 
 
4
  import { useQuery } from '@tanstack/react-query';
5
  import { useLLMConfigs, } from "@/api/llmConfigs/hooks";
6
  import { LLMConfig } from "@/api/llmConfigs/types";
7
+ import './LLMConfigList.scss';
8
  import LLMConfigModal from './LlmConfigModal';
9
  import { fetchDefaultLLMConfig } from '@/api/llmConfigs/llmConfigApi';
10
 
src/components/pages/llmConfigs/LlmConfigModal.tsx CHANGED
@@ -4,7 +4,7 @@ import { GoX } from 'react-icons/go';
4
  import { LLMConfig } from '@/api/llmConfigs/types';
5
  import { useQuery } from '@tanstack/react-query';
6
  import { fetchLLMConfigById, fetchDefaultLLMConfig } from '@/api/llmConfigs/llmConfigApi';
7
- import './LlmConfigModal.scss';
8
 
9
  interface LLMConfigModalProps {
10
  isOpen: boolean;
 
4
  import { LLMConfig } from '@/api/llmConfigs/types';
5
  import { useQuery } from '@tanstack/react-query';
6
  import { fetchLLMConfigById, fetchDefaultLLMConfig } from '@/api/llmConfigs/llmConfigApi';
7
+ import './LLMConfigModal.scss';
8
 
9
  interface LLMConfigModalProps {
10
  isOpen: boolean;
src/context/AuthContext.tsx ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
2
+ import { useMutation } from '@tanstack/react-query';
3
+ import { login } from '@/api/auth/authApi';
4
+ import { LoginRequest } from '@/api/auth/types';
5
+
6
+ interface AuthContextType {
7
+ isAuthenticated: boolean;
8
+ login: (data: LoginRequest) => Promise<void>;
9
+ logout: () => void;
10
+ isLoading: boolean;
11
+ error: Error | null;
12
+ }
13
+
14
+ const AuthContext = createContext<AuthContextType | undefined>(undefined);
15
+
16
+ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
17
+ const [isAuthenticated, setIsAuthenticated] = useState<boolean>(() => {
18
+ // Инициализируем состояние сразу из localStorage
19
+ return !!localStorage.getItem('authToken');
20
+ });
21
+
22
+ const loginMutation = useMutation({
23
+ mutationFn: (data: LoginRequest) => login(data),
24
+ onSuccess: (data) => {
25
+ localStorage.setItem('authToken', data.access_token);
26
+ setIsAuthenticated(true);
27
+ },
28
+ onError: (error) => {
29
+ console.error('Login Error:', error);
30
+ },
31
+ });
32
+
33
+ const loginHandler = async (data: LoginRequest) => {
34
+ await loginMutation.mutateAsync(data);
35
+ };
36
+
37
+ const logout = () => {
38
+ localStorage.removeItem('authToken');
39
+ setIsAuthenticated(false);
40
+ };
41
+
42
+ return (
43
+ <AuthContext.Provider
44
+ value={{
45
+ isAuthenticated,
46
+ login: loginHandler,
47
+ logout,
48
+ isLoading: loginMutation.isPending,
49
+ error: loginMutation.error,
50
+ }}
51
+ >
52
+ {children}
53
+ </AuthContext.Provider>
54
+ );
55
+ };
56
+
57
+ export const useAuth = () => {
58
+ const context = useContext(AuthContext);
59
+ if (!context) {
60
+ throw new Error('useAuth must be used within an AuthProvider');
61
+ }
62
+ return context;
63
+ };
src/index.scss CHANGED
@@ -1,4 +1,4 @@
1
- @import "@fontsource/fira-mono";
2
 
3
  :root {
4
  --font-body: Arial, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
 
1
+ @use "@fontsource/fira-mono";
2
 
3
  :root {
4
  --font-body: Arial, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
src/main.tsx CHANGED
@@ -3,7 +3,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
  import { Provider } from "react-redux";
4
  import { store } from "./store/index.js";
5
  import Modal from 'react-modal';
6
- import App from "./App";
7
  import "./index.scss";
8
 
9
  export const queryClient = new QueryClient();
@@ -11,7 +11,7 @@ export const queryClient = new QueryClient();
11
  createRoot(document.getElementById("root")!).render(
12
  <QueryClientProvider client={queryClient}>
13
  <Provider store={store}>
14
- <App />
15
  </Provider>
16
  </QueryClientProvider>
17
  );
 
3
  import { Provider } from "react-redux";
4
  import { store } from "./store/index.js";
5
  import Modal from 'react-modal';
6
+ import RootApp from "./App";
7
  import "./index.scss";
8
 
9
  export const queryClient = new QueryClient();
 
11
  createRoot(document.getElementById("root")!).render(
12
  <QueryClientProvider client={queryClient}>
13
  <Provider store={store}>
14
+ <RootApp />
15
  </Provider>
16
  </QueryClientProvider>
17
  );
src/shared/api/query.ts CHANGED
@@ -1,23 +1,14 @@
1
- import axios, {
2
- AxiosError,
3
- AxiosRequestConfig,
4
- AxiosResponse,
5
- AxiosResponseHeaders,
6
- InternalAxiosRequestConfig,
7
- RawAxiosResponseHeaders,
8
- ResponseType,
9
- } from "axios";
10
-
11
- import { apiBaseUrl } from "../constants";
12
- import { queryClient } from "@/main";
13
 
14
  export interface IAxiosParams {
15
- method: AxiosRequestConfig["method"];
16
  url: string;
17
- params?: AxiosRequestConfig["params"];
18
- data?: AxiosRequestConfig["data"];
19
- headers?: AxiosRequestConfig["headers"];
20
- responseType?: ResponseType | undefined;
21
  notCauseError?: boolean;
22
  signal?: AbortSignal;
23
  }
@@ -26,50 +17,47 @@ export interface IQueryErrorResponse {
26
  error: {
27
  status: unknown;
28
  data: unknown;
29
- headers?: RawAxiosResponseHeaders | AxiosResponseHeaders;
30
  notCauseError?: boolean;
31
  };
32
  }
33
 
34
  export interface GenericIdentityFn<Type> {
35
  data: Type;
36
- headers?: RawAxiosResponseHeaders | AxiosResponseHeaders;
37
  }
38
 
39
- /**
40
- * Инстанс аксиоса
41
- */
42
  export const instance = axios.create({
43
- baseURL: apiBaseUrl ? `${apiBaseUrl}` : "",
44
  timeout: 600000,
45
  });
46
 
47
- /**
48
- * Интерцептор на запрос
49
- */
50
  const requestInterceptors = (req: InternalAxiosRequestConfig) => {
 
 
 
 
 
51
  return req;
52
  };
53
 
54
- /**
55
- * Интерцептор на успешный ответ сервера
56
- */
57
  const successInterceptors = (response: AxiosResponse) => response;
58
 
59
- /**
60
- * Интерцептор на ошибку сервера
61
- */
62
  const errorInterceptors = async (error: AxiosError) => {
63
  const message = error.message;
64
- if (!axios.isCancel(error) && !message.includes("409")) {
65
- alert(`${message} Произошла ошибка`);
66
- }
67
 
68
- if (message.includes("409")) {
69
- console.log("409");
70
- queryClient.invalidateQueries({ queryKey: ["processing"] });
 
 
 
 
 
 
 
 
71
  }
72
-
73
  return Promise.reject(error);
74
  };
75
 
@@ -84,38 +72,25 @@ export const query = async <T>(
84
  const requestSignal = signal || controller.signal;
85
 
86
  try {
87
- console.log("Попытка отправки запроса");
88
  const result = await instance({
89
  url: `${baseUrl}${url}`,
90
  signal: requestSignal,
91
  ...requestOptions,
92
  });
93
- console.log("Запрос отправлен, результат:", result);
94
  return { data: result.data as T, headers: result.headers };
95
  } catch (axiosError) {
96
  if (axios.isCancel(axiosError)) {
97
- console.log("Запрос отменен");
98
- return {
99
- error: {
100
- status: "Cancelled",
101
- data: "Request was cancelled",
102
- notCauseError: true,
103
- },
104
- };
105
  }
106
  const err = axiosError as AxiosError;
107
- console.log("Ошибка при отправке запроса");
108
-
109
- return {
110
- error: {
111
- status: err.response?.status,
112
- data: err.response?.data,
113
- headers: err.response?.headers,
114
- },
115
- };
116
  } finally {
117
  if (!signal) {
118
  controller.abort();
119
  }
120
  }
121
- };
 
1
+ import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
2
+ import { apiBaseUrl } from '../constants';
3
+ import { queryClient } from '@/main';
 
 
 
 
 
 
 
 
 
4
 
5
  export interface IAxiosParams {
6
+ method: AxiosRequestConfig['method'];
7
  url: string;
8
+ params?: AxiosRequestConfig['params'];
9
+ data?: AxiosRequestConfig['data'];
10
+ headers?: AxiosRequestConfig['headers'];
11
+ responseType?: AxiosRequestConfig['responseType'];
12
  notCauseError?: boolean;
13
  signal?: AbortSignal;
14
  }
 
17
  error: {
18
  status: unknown;
19
  data: unknown;
20
+ headers?: AxiosResponse['headers'];
21
  notCauseError?: boolean;
22
  };
23
  }
24
 
25
  export interface GenericIdentityFn<Type> {
26
  data: Type;
27
+ headers?: AxiosResponse['headers'];
28
  }
29
 
 
 
 
30
  export const instance = axios.create({
31
+ baseURL: apiBaseUrl ? `${apiBaseUrl}` : '',
32
  timeout: 600000,
33
  });
34
 
 
 
 
35
  const requestInterceptors = (req: InternalAxiosRequestConfig) => {
36
+ // Добавляем jwt токен для всех маршрутов
37
+ const token = localStorage.getItem('authToken');
38
+ if (token) {
39
+ req.headers.Authorization = `Bearer ${token}`;
40
+ }
41
  return req;
42
  };
43
 
 
 
 
44
  const successInterceptors = (response: AxiosResponse) => response;
45
 
 
 
 
46
  const errorInterceptors = async (error: AxiosError) => {
47
  const message = error.message;
 
 
 
48
 
49
+ if (message.includes('409')) {
50
+ console.log('409');
51
+ queryClient.invalidateQueries({ queryKey: ['processing'] });
52
+ }
53
+ if (error.response?.status === 401) {
54
+ localStorage.removeItem('authToken');
55
+ window.location.href = '/login'; // Редирект на логин при 401
56
+ } else {
57
+ if (!axios.isCancel(error) && !message.includes('409')) {
58
+ alert(`${message} Произошла ошибка`);
59
+ }
60
  }
 
61
  return Promise.reject(error);
62
  };
63
 
 
72
  const requestSignal = signal || controller.signal;
73
 
74
  try {
75
+ console.log('Попытка отправки запроса');
76
  const result = await instance({
77
  url: `${baseUrl}${url}`,
78
  signal: requestSignal,
79
  ...requestOptions,
80
  });
81
+ console.log('Запрос отправлен, результат:', result);
82
  return { data: result.data as T, headers: result.headers };
83
  } catch (axiosError) {
84
  if (axios.isCancel(axiosError)) {
85
+ console.log('Запрос отменен');
86
+ return { error: { status: 'Cancelled', data: 'Request was cancelled', notCauseError: true } };
 
 
 
 
 
 
87
  }
88
  const err = axiosError as AxiosError;
89
+ console.log('Ошибка при отправке запроса');
90
+ return { error: { status: err.response?.status, data: err.response?.data, headers: err.response?.headers } };
 
 
 
 
 
 
 
91
  } finally {
92
  if (!signal) {
93
  controller.abort();
94
  }
95
  }
96
+ };
tsconfig.tsbuildinfo CHANGED
@@ -1 +1 @@
1
- {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/documents/documentsapi.ts","./src/api/documents/hooks.ts","./src/api/documents/types.ts","./src/api/predictions/hooks.ts","./src/api/predictions/predictionsapi.ts","./src/api/predictions/types.ts","./src/components/generics/button/button.interface.ts","./src/components/generics/button/button.tsx","./src/components/generics/collapse/collapse.inreface.ts","./src/components/generics/collapse/collapse.tsx","./src/components/generics/dropdown/dropdown.interface.ts","./src/components/generics/dropdown/dropdown.tsx","./src/components/generics/editable/editable.interface.ts","./src/components/generics/editable/editable.tsx","./src/components/generics/input/input.interface.ts","./src/components/generics/input/input.tsx","./src/components/generics/loading/loading.tsx","./src/components/generics/modal/modal.interface.ts","./src/components/generics/modal/modal.tsx","./src/components/generics/sizechanger/sizechanger.tsx","./src/components/generics/sizechanger/sizechangerprops.ts","./src/components/generics/spinner/spinner.tsx","./src/components/generics/tag/tag.interface.ts","./src/components/generics/tag/tag.tsx","./src/components/generics/textarea/textarea.interface.ts","./src/components/generics/textarea/textarea.tsx","./src/components/generics/toggle/toggle.interface.ts","./src/components/generics/toggle/toggle.tsx","./src/components/generics/tooltip/tooltip.interface.ts","./src/components/generics/tooltip/tooltip.tsx","./src/components/pages/documentspage/documents.tsx","./src/components/pages/logspage/logs.tsx","./src/components/pages/main/page.tsx","./src/components/pages/vectorizationpage/vectorization.tsx","./src/components/views/abbreviationblock/abbreviationblock.interface.ts","./src/components/views/abbreviationblock/abbreviationsblock.tsx","./src/components/views/comment/comment.tsx","./src/components/views/comment/commentprops.ts","./src/components/views/documents/adddocuimentform/adddocumentform.interface.ts","./src/components/views/documents/adddocuimentform/adddocumentform.tsx","./src/components/views/documents/createdatasetform/createdatasetform.interface.ts","./src/components/views/documents/createdatasetform/createdatasetform.tsx","./src/components/views/documents/docslist/docslist.interface.ts","./src/components/views/documents/docslist/docslist.tsx","./src/components/views/llmanswer/llmanswer.tsx","./src/components/views/llmanswer/llmanswerprops.ts","./src/components/views/loginform/loginform.tsx","./src/components/views/pagination/pagination.tsx","./src/components/views/requesttextarea/requesttextarea.tsx","./src/components/views/requesttextarea/requesttextareaprops.ts","./src/components/views/search/documentmodal/documentmodal.tsx","./src/components/views/search/documentmodal/pdfviewer.tsx","./src/components/views/search/groupresults/groupresults.tsx","./src/components/views/search/groupresults/groupresultsprops.ts","./src/components/views/search/rocksnnresults/rocksnnresults.tsx","./src/components/views/search/rocksnnresults/rocksnnresultsprops.ts","./src/components/views/search/searchresults/searchresults.tsx","./src/components/views/search/searchresults/searchresultsprops.ts","./src/components/views/search/searchresultsitem/searchresultsitem.tsx","./src/components/views/search/searchresultsitem/searchresultsitemprops.ts","./src/components/views/search/segmentationresults/segmentationresult.tsx","./src/components/views/search/segmentationresults/segmentationsearch.ts","./src/components/views/search/staffresultsitem/staffresultsitem.tsx","./src/components/views/search/staffresultsitem/staffresultsitemprops.ts","./src/shared/constants.ts","./src/shared/types.ts","./src/shared/api/query.ts","./src/shared/hooks/useabbreviations/reducer.ts","./src/shared/hooks/useabbreviations/types.ts","./src/shared/hooks/useabbreviations/useabbreviation.ts","./src/shared/hooks/useauth/reducer.ts","./src/shared/hooks/useauth/types.ts","./src/shared/hooks/useauth/useauth.ts","./src/shared/utils/customparse.ts","./src/shared/utils/downloadexcel.ts","./src/shared/utils/downloadfile.ts","./src/shared/utils/escaperegexp.ts","./src/shared/utils/gettimezoneoffset.ts","./src/shared/utils/highlightmatches.ts","./src/shared/utils/parsedocumnetsinllmanswer.ts","./src/store/hooks.ts","./src/store/index.ts","./src/store/types.ts"],"version":"5.7.3"}
 
1
+ {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/auth/authapi.ts","./src/api/auth/hooks.ts","./src/api/auth/types.ts","./src/api/documents/documentsapi.ts","./src/api/documents/hooks.ts","./src/api/documents/types.ts","./src/api/llmconfigs/hooks.ts","./src/api/llmconfigs/llmconfigapi.ts","./src/api/llmconfigs/types.ts","./src/api/llmprompts/hooks.ts","./src/api/llmprompts/llmpromptapi.ts","./src/api/llmprompts/types.ts","./src/api/predictions/hooks.ts","./src/api/predictions/predictionsapi.ts","./src/api/predictions/types.ts","./src/components/common/navbar/navbar.tsx","./src/components/generics/button/button.interface.ts","./src/components/generics/button/button.tsx","./src/components/generics/collapse/collapse.inreface.ts","./src/components/generics/collapse/collapse.tsx","./src/components/generics/dropdown/dropdown.interface.ts","./src/components/generics/dropdown/dropdown.tsx","./src/components/generics/editable/editable.interface.ts","./src/components/generics/editable/editable.tsx","./src/components/generics/input/input.interface.ts","./src/components/generics/input/input.tsx","./src/components/generics/loading/loading.tsx","./src/components/generics/modal/modal.interface.ts","./src/components/generics/modal/modal.tsx","./src/components/generics/sizechanger/sizechanger.tsx","./src/components/generics/sizechanger/sizechangerprops.ts","./src/components/generics/spinner/spinner.tsx","./src/components/generics/tag/tag.interface.ts","./src/components/generics/tag/tag.tsx","./src/components/generics/textarea/textarea.interface.ts","./src/components/generics/textarea/textarea.tsx","./src/components/generics/toggle/toggle.interface.ts","./src/components/generics/toggle/toggle.tsx","./src/components/generics/tooltip/tooltip.interface.ts","./src/components/generics/tooltip/tooltip.tsx","./src/components/pages/auth/login.tsx","./src/components/pages/documentspage/documents.tsx","./src/components/pages/llmconfigs/llmconfiglist.tsx","./src/components/pages/llmconfigs/llmconfigmodal.tsx","./src/components/pages/llmprompts/llmpromptlist.tsx","./src/components/pages/llmprompts/llmpromptmodal.tsx","./src/components/pages/logspage/logs.tsx","./src/components/pages/main/page.tsx","./src/components/pages/vectorizationpage/vectorization.tsx","./src/components/views/abbreviationblock/abbreviationblock.interface.ts","./src/components/views/abbreviationblock/abbreviationsblock.tsx","./src/components/views/comment/comment.tsx","./src/components/views/comment/commentprops.ts","./src/components/views/documents/adddocuimentform/adddocumentform.interface.ts","./src/components/views/documents/adddocuimentform/adddocumentform.tsx","./src/components/views/documents/createdatasetform/createdatasetform.interface.ts","./src/components/views/documents/createdatasetform/createdatasetform.tsx","./src/components/views/documents/docslist/docslist.interface.ts","./src/components/views/documents/docslist/docslist.tsx","./src/components/views/llmanswer/llmanswer.tsx","./src/components/views/llmanswer/llmanswerprops.ts","./src/components/views/loginform/loginform.tsx","./src/components/views/pagination/pagination.tsx","./src/components/views/requesttextarea/requesttextarea.tsx","./src/components/views/requesttextarea/requesttextareaprops.ts","./src/components/views/search/documentmodal/documentmodal.tsx","./src/components/views/search/documentmodal/pdfviewer.tsx","./src/components/views/search/groupresults/groupresults.tsx","./src/components/views/search/groupresults/groupresultsprops.ts","./src/components/views/search/rocksnnresults/rocksnnresults.tsx","./src/components/views/search/rocksnnresults/rocksnnresultsprops.ts","./src/components/views/search/searchresults/searchresults.tsx","./src/components/views/search/searchresults/searchresultsprops.ts","./src/components/views/search/searchresultsitem/searchresultsitem.tsx","./src/components/views/search/searchresultsitem/searchresultsitemprops.ts","./src/components/views/search/segmentationresults/segmentationresult.tsx","./src/components/views/search/segmentationresults/segmentationsearch.ts","./src/components/views/search/staffresultsitem/staffresultsitem.tsx","./src/components/views/search/staffresultsitem/staffresultsitemprops.ts","./src/context/authcontext.tsx","./src/shared/constants.ts","./src/shared/types.ts","./src/shared/api/query.ts","./src/shared/hooks/useabbreviations/reducer.ts","./src/shared/hooks/useabbreviations/types.ts","./src/shared/hooks/useabbreviations/useabbreviation.ts","./src/shared/hooks/useauth/reducer.ts","./src/shared/hooks/useauth/types.ts","./src/shared/hooks/useauth/useauth.ts","./src/shared/utils/customparse.ts","./src/shared/utils/downloadexcel.ts","./src/shared/utils/downloadfile.ts","./src/shared/utils/escaperegexp.ts","./src/shared/utils/gettimezoneoffset.ts","./src/shared/utils/highlightmatches.ts","./src/shared/utils/parsedocumnetsinllmanswer.ts","./src/store/hooks.ts","./src/store/index.ts","./src/store/types.ts"],"version":"5.7.3"}