fixed mobx
This commit is contained in:
parent
0cec8be4cd
commit
c77dd23dd1
@ -1,11 +1,8 @@
|
|||||||
import { Theme } from '@radix-ui/themes';
|
import { Theme } from '@radix-ui/themes';
|
||||||
import '@radix-ui/themes/styles.css';
|
import '@radix-ui/themes/styles.css';
|
||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
|
||||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||||
import queryClient from './api/queryClient';
|
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import MyRoutes from './routes/routes';
|
import MyRoutes from './routes/routes';
|
||||||
import React from 'react';
|
|
||||||
import { appStore } from './stores/AppStore';
|
import { appStore } from './stores/AppStore';
|
||||||
import { Ctx } from './context';
|
import { Ctx } from './context';
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,6 @@ export const axiosBase = axios.create({
|
|||||||
export const axiosAuth = axios.create({
|
export const axiosAuth = axios.create({
|
||||||
baseURL: BASE_URL,
|
baseURL: BASE_URL,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${localStorage.getItem('token')}` // Maybe we will use cookies
|
Authorization: `Bearer ${localStorage.getItem('token')}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { QueryClient } from "@tanstack/react-query";
|
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
|
||||||
defaultOptions: {
|
|
||||||
queries: {
|
|
||||||
retry: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default queryClient;
|
|
||||||
@ -9,7 +9,6 @@ import AddUserToProjectDialog from '../dialogs/AddUserToProjectDialog/AddUserToP
|
|||||||
import CreateTaskDialog from '../dialogs/CreateTaskDialog/CreateTaskDialog';
|
import CreateTaskDialog from '../dialogs/CreateTaskDialog/CreateTaskDialog';
|
||||||
import DeleteProjectDialog from '../dialogs/DeleteProjectDialog/CreateTaskDialog';
|
import DeleteProjectDialog from '../dialogs/DeleteProjectDialog/CreateTaskDialog';
|
||||||
|
|
||||||
// Импортируем наш mobx-store
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
|
||||||
type TCardGroup = {
|
type TCardGroup = {
|
||||||
@ -19,18 +18,15 @@ type TCardGroup = {
|
|||||||
|
|
||||||
|
|
||||||
function CardGroup(props: TCardGroup) {
|
function CardGroup(props: TCardGroup) {
|
||||||
// При монтировании (и при изменении `props.id`) грузим задачи для проекта
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
store.mainStore.fetchTasksForGroup(props.id).catch(console.error);
|
store.mainStore.fetchTasksForGroup(props.id).catch(console.error);
|
||||||
}, [props.id, store.mainStore]);
|
}, [props.id, store.mainStore]);
|
||||||
|
|
||||||
|
|
||||||
// Получаем задачи для данного проекта из стора (или пустой массив, если их нет)
|
|
||||||
const tasks = store.mainStore.tasksByProject.get(props.id) ?? [];
|
const tasks = store.mainStore.tasksByProject.get(props.id) ?? [];
|
||||||
const isLoading = store.mainStore.isLoading; // общее isLoading из стора
|
const isLoading = store.mainStore.isLoading;
|
||||||
|
|
||||||
// Создать задачу
|
|
||||||
const createTask = (taskText: string, date: string) => {
|
const createTask = (taskText: string, date: string) => {
|
||||||
store.mainStore.createTask({
|
store.mainStore.createTask({
|
||||||
title: taskText,
|
title: taskText,
|
||||||
@ -40,7 +36,6 @@ function CardGroup(props: TCardGroup) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Удалить проект (аналог deleteProjectMutation)
|
|
||||||
const deleteGroup = () => {
|
const deleteGroup = () => {
|
||||||
store.mainStore.deleteProject(props.id);
|
store.mainStore.deleteProject(props.id);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,22 +7,17 @@ import CardGroup from '../CardGroup/CardGroup';
|
|||||||
import CreateProjectDialog from '../dialogs/CreateProjectDialog/CreateProjectDialog';
|
import CreateProjectDialog from '../dialogs/CreateProjectDialog/CreateProjectDialog';
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
|
||||||
type TDragResult = any; // или определите, если надо
|
|
||||||
|
|
||||||
function MainBoard() {
|
function MainBoard() {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
// Загрузка проектов при монтировании
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
store.mainStore.fetchProjects().catch(console.error);
|
store.mainStore.fetchProjects().catch(console.error);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const dragEndHandle = (result: TDragResult) => {
|
const dragEndHandle = (result: TDragResult) => {
|
||||||
// Логика перетаскивания, если нужно
|
|
||||||
console.log(result);
|
console.log(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Для кнопки "Create project"
|
|
||||||
const createProject = (newProjectData: any) => {
|
const createProject = (newProjectData: any) => {
|
||||||
store.mainStore.createProject(newProjectData);
|
store.mainStore.createProject(newProjectData);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { Draggable } from '@hello-pangea/dnd';
|
|||||||
import { Badge, Button, Card, Flex, Text } from '@radix-ui/themes';
|
import { Badge, Button, Card, Flex, Text } from '@radix-ui/themes';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
type TTaskCard = {
|
type TTaskCard = {
|
||||||
title?: string;
|
title?: string;
|
||||||
@ -36,10 +35,6 @@ const TaskCard = observer((props: TTaskCard) => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
console.log(`rerendered with`, store.mainStore.tasksByProject.get(2) );
|
console.log(`rerendered with`, store.mainStore.tasksByProject.get(2) );
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(store.mainStore.fakeData)
|
|
||||||
}, [store.mainStore.fakeData])
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable draggableId={props.id || '123'} index={props.index || 0}>
|
<Draggable draggableId={props.id || '123'} index={props.index || 0}>
|
||||||
@ -50,7 +45,6 @@ const TaskCard = observer((props: TTaskCard) => {
|
|||||||
{...provided.draggableProps}
|
{...provided.draggableProps}
|
||||||
{...provided.dragHandleProps}
|
{...provided.dragHandleProps}
|
||||||
>
|
>
|
||||||
<h1>{store.mainStore.fakeData.toString()}</h1>
|
|
||||||
<Flex direction="column" gap="2">
|
<Flex direction="column" gap="2">
|
||||||
<Flex justify={'between'}>
|
<Flex justify={'between'}>
|
||||||
<Text wrap="pretty">{props.title}</Text>
|
<Text wrap="pretty">{props.title}</Text>
|
||||||
@ -83,11 +77,6 @@ const TaskCard = observer((props: TTaskCard) => {
|
|||||||
Completed
|
Completed
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button onClick={() => {
|
|
||||||
store.mainStore.fetchPosts()
|
|
||||||
}}>
|
|
||||||
posts
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { PropsWithChildren, useEffect, useState } from 'react';
|
|||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { Button, Dialog, Flex, Select } from '@radix-ui/themes';
|
import { Button, Dialog, Flex, Select } from '@radix-ui/themes';
|
||||||
|
|
||||||
// Импортируем сторы
|
|
||||||
import { useStore } from '../../../hooks/useStore';
|
import { useStore } from '../../../hooks/useStore';
|
||||||
|
|
||||||
type TAddUserToProjectDialog = {
|
type TAddUserToProjectDialog = {
|
||||||
@ -15,8 +14,7 @@ function AddUserToProjectDialog(props: TAddUserToProjectDialog) {
|
|||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
// При открытии диалога (или при ререндере) можно обновлять список пользователей
|
|
||||||
// (В RTK Query был refetch. Тут можно просто вызвать fetchAllUsers(force=true) если надо всегда свежий список)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
store.authStore.fetchAllUsers();
|
store.authStore.fetchAllUsers();
|
||||||
}, []);
|
}, []);
|
||||||
@ -24,7 +22,6 @@ function AddUserToProjectDialog(props: TAddUserToProjectDialog) {
|
|||||||
const handleAddUser = async () => {
|
const handleAddUser = async () => {
|
||||||
if (selectedUserId) {
|
if (selectedUserId) {
|
||||||
try {
|
try {
|
||||||
// В store.mainStore метод addProjectMember(projectId: string, memberId: string/number)
|
|
||||||
await store.mainStore.addProjectMember(projectId.toString(), selectedUserId.toString());
|
await store.mainStore.addProjectMember(projectId.toString(), selectedUserId.toString());
|
||||||
setSelectedUserId(null);
|
setSelectedUserId(null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { makeAutoObservable, runInAction } from 'mobx';
|
import { makeAutoObservable } from 'mobx';
|
||||||
import { MainStore } from './MainStore';
|
import { MainStore } from './MainStore';
|
||||||
import { AuthStore } from './AuthStore';
|
import { AuthStore } from './AuthStore';
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,13 @@ import { makeAutoObservable, runInAction } from 'mobx';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { AppStore } from './AppStore';
|
import { AppStore } from './AppStore';
|
||||||
|
|
||||||
/**
|
|
||||||
* AuthStore
|
|
||||||
* Хранит логику для авторизации, регистрации и получения всех пользователей.
|
|
||||||
*/
|
|
||||||
export class AuthStore {
|
export class AuthStore {
|
||||||
appStore: AppStore
|
appStore: AppStore
|
||||||
|
|
||||||
// Можно также хранить здесь данные о текущем пользователе, ошибках и т.д.
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
error: string | null = null;
|
error: string | null = null;
|
||||||
|
|
||||||
// Список всех пользователей (если вам нужно его кэшировать)
|
|
||||||
allUsers: any[] = [];
|
allUsers: any[] = [];
|
||||||
|
|
||||||
constructor(appStore:any) {
|
constructor(appStore:any) {
|
||||||
@ -25,9 +20,6 @@ export class AuthStore {
|
|||||||
return localStorage.getItem('token') || '';
|
return localStorage.getItem('token') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Логин: отправляет запрос на сервер и сохраняет токен в localStorage
|
|
||||||
*/
|
|
||||||
async login(credentials: { username: string; password: string }) {
|
async login(credentials: { username: string; password: string }) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -40,7 +32,6 @@ export class AuthStore {
|
|||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
if (response.data.access_token) {
|
if (response.data.access_token) {
|
||||||
localStorage.setItem('token', response.data.access_token);
|
localStorage.setItem('token', response.data.access_token);
|
||||||
// Если нужно перенаправить после логина:
|
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@ -54,9 +45,6 @@ export class AuthStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Регистрация: отправляет запрос на сервер
|
|
||||||
*/
|
|
||||||
async register(credentials: { username: string; password: string }) {
|
async register(credentials: { username: string; password: string }) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -67,7 +55,6 @@ export class AuthStore {
|
|||||||
);
|
);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
// Если регистрация успешна, например, статус 201 – перенаправляем на /login
|
|
||||||
if (response.status === 201) {
|
if (response.status === 201) {
|
||||||
window.location.href = '/login';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
@ -82,11 +69,7 @@ export class AuthStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить всех пользователей
|
|
||||||
*/
|
|
||||||
async fetchAllUsers(force = false) {
|
async fetchAllUsers(force = false) {
|
||||||
// Если уже есть пользователи и не запрошен force, просто возвращаем
|
|
||||||
if (this.allUsers.length && !force) {
|
if (this.allUsers.length && !force) {
|
||||||
return this.allUsers;
|
return this.allUsers;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,40 +2,18 @@ import { makeAutoObservable, runInAction } from 'mobx';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { AppStore } from './AppStore';
|
import { AppStore } from './AppStore';
|
||||||
|
|
||||||
export type Posts = Post[]
|
|
||||||
|
|
||||||
export interface Post {
|
|
||||||
userId: number
|
|
||||||
id: number
|
|
||||||
title: string
|
|
||||||
body: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MainStore
|
|
||||||
* Хранит логику для задач, проектов и участников проектов
|
|
||||||
*/
|
|
||||||
export class MainStore {
|
export class MainStore {
|
||||||
appStore: AppStore
|
appStore: AppStore
|
||||||
|
|
||||||
// ----- Общие поля -----
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
error: string | null = null;
|
error: string | null = null;
|
||||||
|
|
||||||
// ----- Задачи -----
|
|
||||||
tasks: any[] = [];
|
tasks: any[] = [];
|
||||||
// Кэшированный список задач по ID проекта
|
|
||||||
tasksByProject = new Map<string, any[]>();
|
tasksByProject = new Map<string, any[]>();
|
||||||
|
|
||||||
// ----- Проекты -----
|
|
||||||
projects: any[] = [];
|
projects: any[] = [];
|
||||||
// Детальные данные по конкретному проекту (если нужно кэшировать)
|
|
||||||
projectById = new Map<string, any>();
|
projectById = new Map<string, any>();
|
||||||
|
|
||||||
fakeData: Posts = []
|
|
||||||
|
|
||||||
// ----- Участники проекта -----
|
|
||||||
// Если нужно кэшировать участников по проекту
|
|
||||||
projectMembersById = new Map<string, any[]>();
|
projectMembersById = new Map<string, any[]>();
|
||||||
|
|
||||||
constructor(appStore:any) {
|
constructor(appStore:any) {
|
||||||
@ -43,75 +21,18 @@ export class MainStore {
|
|||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить токен из localStorage
|
|
||||||
*/
|
|
||||||
get token() {
|
get token() {
|
||||||
return localStorage.getItem('token') || '';
|
return localStorage.getItem('token') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Заготовка для заголовков (проставляем Bearer токен)
|
|
||||||
*/
|
|
||||||
get headers() {
|
get headers() {
|
||||||
return {
|
return {
|
||||||
Authorization: `Bearer ${this.token}`,
|
Authorization: `Bearer ${this.token}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* ЗАДАЧИ
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить все задачи (кэширование: если уже загружены, второй раз не грузим)
|
|
||||||
*/
|
|
||||||
|
|
||||||
async fetchPosts(){
|
|
||||||
fetch('https://jsonplaceholder.typicode.com/posts?limit=10')
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(json => {
|
|
||||||
|
|
||||||
this.fakeData = json
|
|
||||||
console.log(this.fakeData);
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchTasks(force = false) {
|
|
||||||
|
|
||||||
console.error(`Aboba`);
|
|
||||||
|
|
||||||
if (this.tasks.length && !force) {
|
|
||||||
return this.tasks;
|
|
||||||
}
|
|
||||||
this.isLoading = true;
|
|
||||||
this.error = null;
|
|
||||||
try {
|
|
||||||
const response = await axios.get('http://109.107.166.17:5000/api/tasks', {
|
|
||||||
headers: this.headers,
|
|
||||||
});
|
|
||||||
runInAction(() => {
|
|
||||||
console.log(`This is all tasks`,response.data);
|
|
||||||
|
|
||||||
this.tasks = response.data;
|
|
||||||
this.isLoading = false;
|
|
||||||
});
|
|
||||||
return this.tasks;
|
|
||||||
} catch (error: any) {
|
|
||||||
runInAction(() => {
|
|
||||||
this.error = error?.response?.data?.message || 'Ошибка при загрузке задач';
|
|
||||||
this.isLoading = false;
|
|
||||||
});
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить задачи для конкретного проекта (группы)
|
|
||||||
*/
|
|
||||||
async fetchTasksForGroup(projectId: string, force = false) {
|
async fetchTasksForGroup(projectId: string, force = false) {
|
||||||
if (this.tasksByProject.has(projectId) && !force) {
|
if (this.tasksByProject.has(projectId) && !force) {
|
||||||
return this.tasksByProject.get(projectId);
|
return this.tasksByProject.get(projectId);
|
||||||
@ -129,8 +50,6 @@ export class MainStore {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
console.log(`This is tasks for ${projectId}`,response.data);
|
|
||||||
|
|
||||||
this.tasksByProject.set(projectId, response.data);
|
this.tasksByProject.set(projectId, response.data);
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
});
|
});
|
||||||
@ -144,9 +63,6 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить одну задачу по ID
|
|
||||||
*/
|
|
||||||
async fetchTask(taskId: string) {
|
async fetchTask(taskId: string) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -169,18 +85,17 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Создать задачу
|
|
||||||
*/
|
|
||||||
async createTask(newTask: any) {
|
async createTask(newTask: any) {
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
const response = await axios.post(
|
||||||
'http://109.107.166.17:5000/api/tasks/create',
|
'http://109.107.166.17:5000/api/tasks/create',
|
||||||
newTask,
|
newTask,
|
||||||
{ headers: this.headers },
|
{ headers: this.headers },
|
||||||
);
|
);
|
||||||
// Инвалидируем кэш (чтобы при следующем getTasks() данные были актуальны)
|
const createdTask = response.data;
|
||||||
this.tasks = [];
|
this.tasks.push(createdTask);
|
||||||
|
const oldTasks = this.tasksByProject.get(newTask.projectId) ?? [];
|
||||||
|
this.tasksByProject.set(newTask.projectId, [...oldTasks, createdTask]);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.error = error?.response?.data?.message || 'Ошибка при создании задачи';
|
this.error = error?.response?.data?.message || 'Ошибка при создании задачи';
|
||||||
@ -189,22 +104,25 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Обновить задачу
|
|
||||||
*/
|
|
||||||
async updateTask(task: { id: string; status: string }) {
|
async updateTask(task: { id: string; status: string }) {
|
||||||
try {
|
try {
|
||||||
await axios.patch(
|
const response = await axios.patch(
|
||||||
`http://109.107.166.17:5000/api/tasks/${task.id}`,
|
`http://109.107.166.17:5000/api/tasks/${task.id}`,
|
||||||
{ status: task.status },
|
{ status: task.status },
|
||||||
{ headers: this.headers },
|
{ headers: this.headers },
|
||||||
);
|
);
|
||||||
// Локально обновим статус в массиве tasks
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
const index = this.tasks.findIndex((t) => t.id === task.id);
|
const index = this.tasks.findIndex((t) => t.id === task.id);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.tasks[index].status = task.status;
|
this.tasks[index].status = task.status;
|
||||||
}
|
}
|
||||||
|
const projectId = response.data.project.id;
|
||||||
|
const oldArray = this.tasksByProject.get(projectId) || [];
|
||||||
|
const indexInMap = oldArray.findIndex((t) => t.id === +task.id);
|
||||||
|
if (indexInMap !== -1) {
|
||||||
|
oldArray[indexInMap].status = task.status;
|
||||||
|
this.tasksByProject.set(projectId, [...oldArray]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -214,9 +132,7 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Удалить задачу
|
|
||||||
*/
|
|
||||||
async deleteTask(taskId: string) {
|
async deleteTask(taskId: string) {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`http://109.107.166.17:5000/api/tasks/${taskId}`, {
|
await axios.delete(`http://109.107.166.17:5000/api/tasks/${taskId}`, {
|
||||||
@ -234,15 +150,7 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* ПРОЕКТЫ
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить все проекты текущего пользователя
|
|
||||||
*/
|
|
||||||
async fetchProjects(force = false) {
|
async fetchProjects(force = false) {
|
||||||
if (this.projects.length && !force) {
|
if (this.projects.length && !force) {
|
||||||
return this.projects;
|
return this.projects;
|
||||||
@ -269,11 +177,7 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить данные одного проекта по ID
|
|
||||||
*/
|
|
||||||
async fetchProject(projectId: string) {
|
async fetchProject(projectId: string) {
|
||||||
// Если хотим кэшировать отдельно проекты по id
|
|
||||||
if (this.projectById.has(projectId)) {
|
if (this.projectById.has(projectId)) {
|
||||||
return this.projectById.get(projectId);
|
return this.projectById.get(projectId);
|
||||||
}
|
}
|
||||||
@ -299,18 +203,17 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Создать проект
|
|
||||||
*/
|
|
||||||
async createProject(newProject: any) {
|
async createProject(newProject: any) {
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
const response = await axios.post(
|
||||||
'http://109.107.166.17:5000/api/projects/create',
|
'http://109.107.166.17:5000/api/projects/create',
|
||||||
newProject,
|
newProject,
|
||||||
{ headers: this.headers },
|
{ headers: this.headers },
|
||||||
);
|
);
|
||||||
// Инвалидируем кэш
|
const created = response.data;
|
||||||
this.projects = [];
|
runInAction(() => {
|
||||||
|
this.projects.push(created);
|
||||||
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.error = error?.response?.data?.message || 'Ошибка при создании проекта';
|
this.error = error?.response?.data?.message || 'Ошибка при создании проекта';
|
||||||
@ -319,9 +222,6 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Обновить проект
|
|
||||||
*/
|
|
||||||
async updateProject(id: string, projectData: any) {
|
async updateProject(id: string, projectData: any) {
|
||||||
try {
|
try {
|
||||||
await axios.patch(
|
await axios.patch(
|
||||||
@ -329,7 +229,6 @@ export class MainStore {
|
|||||||
projectData,
|
projectData,
|
||||||
{ headers: this.headers },
|
{ headers: this.headers },
|
||||||
);
|
);
|
||||||
// Можно либо перезагрузить список проектов, либо локально обновить
|
|
||||||
this.fetchProjects(true);
|
this.fetchProjects(true);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -339,9 +238,6 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Удалить проект
|
|
||||||
*/
|
|
||||||
async deleteProject(id: string) {
|
async deleteProject(id: string) {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`http://109.107.166.17:5000/api/projects/${id}`, {
|
await axios.delete(`http://109.107.166.17:5000/api/projects/${id}`, {
|
||||||
@ -359,15 +255,6 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* УЧАСТНИКИ ПРОЕКТА
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Добавить участника в проект
|
|
||||||
*/
|
|
||||||
async addProjectMember(projectId: string, memberId: string) {
|
async addProjectMember(projectId: string, memberId: string) {
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post(
|
||||||
@ -378,7 +265,6 @@ export class MainStore {
|
|||||||
},
|
},
|
||||||
{ headers: this.headers },
|
{ headers: this.headers },
|
||||||
);
|
);
|
||||||
// Инвалидируем список участников
|
|
||||||
this.projectMembersById.delete(projectId);
|
this.projectMembersById.delete(projectId);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -387,10 +273,6 @@ export class MainStore {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить участников проекта
|
|
||||||
*/
|
|
||||||
async fetchProjectMembers(projectId: string, force = false) {
|
async fetchProjectMembers(projectId: string, force = false) {
|
||||||
if (this.projectMembersById.has(projectId) && !force) {
|
if (this.projectMembersById.has(projectId) && !force) {
|
||||||
return this.projectMembersById.get(projectId);
|
return this.projectMembersById.get(projectId);
|
||||||
@ -418,9 +300,6 @@ export class MainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Удалить участника из проекта
|
|
||||||
*/
|
|
||||||
async removeProjectMember(projectId: string, memberId: string) {
|
async removeProjectMember(projectId: string, memberId: string) {
|
||||||
try {
|
try {
|
||||||
await axios.delete(
|
await axios.delete(
|
||||||
@ -430,7 +309,7 @@ export class MainStore {
|
|||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Инвалидируем список участников
|
|
||||||
this.projectMembersById.delete(projectId);
|
this.projectMembersById.delete(projectId);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user