Skip to content

Commit

Permalink
Feat: #156 일정 수정 모달 일정 정보 변경 기능 구현 (#160)
Browse files Browse the repository at this point in the history
* Feat: #156 일정 정보 수정 API를 위한 React Query 기능 추가

* Feat: #156 일정 정보 수정 API를 위한 MSW 기능 추가

* Feat: #156 일정 정보 수정 기능 구현
  • Loading branch information
Seok93 authored Sep 26, 2024
1 parent 40ccd8e commit 54dd298
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/components/modal/task/UpdateModalTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
useReadAssignees,
useReadStatusTasks,
useReadTaskFiles,
useUpdateTaskInfo,
} from '@hooks/query/useTaskQuery';
import { useReadProjectUserRoleList } from '@hooks/query/useProjectQuery';
import { findUserByProject } from '@services/projectService';
Expand Down Expand Up @@ -55,6 +56,7 @@ export default function UpdateModalTask({ project, taskId, onClose: handleClose
const { assigneeList, isAssigneeLoading } = useReadAssignees(projectId, taskId);
const { taskFileList, isTaskFileLoading } = useReadTaskFiles(projectId, taskId);

const { mutate: updateTaskInfoMutate } = useUpdateTaskInfo(projectId, taskId);
const { mutate: addAssigneeMutate } = useAddAssignee(projectId, taskId);
const { mutate: deleteAssigneeMutate } = useDeleteAssignee(projectId, taskId);

Expand Down Expand Up @@ -128,10 +130,8 @@ export default function UpdateModalTask({ project, taskId, onClose: handleClose
return <Spinner />;
}

// ToDo: 일정 수정 API 작업시 추가할 것
const handleFormSubmit: SubmitHandler<TaskInfoForm> = async (data) => {
console.log('수정 폼 제출');
console.log(data);
const handleFormSubmit: SubmitHandler<TaskInfoForm> = async (formData) => {
updateTaskInfoMutate(formData);
handleClose();
};
return (
Expand Down
23 changes: 21 additions & 2 deletions src/hooks/query/useTaskQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {
findAssignees,
findTaskFiles,
findTaskList,
updateTaskInfo,
updateTaskOrder,
} from '@services/taskService';
import useToast from '@hooks/useToast';

import type { User } from '@/types/UserType';
import type { Project } from '@/types/ProjectType';
import type { Task, TaskCreationForm, TaskListWithStatus, TaskOrder } from '@/types/TaskType';
import type { Task, TaskCreationForm, TaskInfoForm, TaskListWithStatus, TaskOrder } from '@/types/TaskType';

function getTaskNameList(taskList: TaskListWithStatus[], excludedTaskName?: Task['name']) {
const taskNameList = taskList
Expand All @@ -24,7 +25,7 @@ function getTaskNameList(taskList: TaskListWithStatus[], excludedTaskName?: Task
return excludedTaskName ? taskNameList.filter((taskName) => taskName !== excludedTaskName) : taskNameList;
}

// Todo: Task Query UD로직 작성하기
// Todo: Task Query D로직 작성하기
// 일정 생성
export function useCreateStatusTask(projectId: Project['projectId']) {
const { toastSuccess } = useToast();
Expand Down Expand Up @@ -138,6 +139,24 @@ export function useReadTaskFiles(projectId: Project['projectId'], taskId: Task['
return { taskFileList, isTaskFileLoading, taskFileError, isTaskFileError };
}

// 일정 정보 수정
export function useUpdateTaskInfo(projectId: Project['projectId'], taskId: Task['taskId']) {
const { toastError, toastSuccess } = useToast();
const queryClient = useQueryClient();
const queryKey = ['projects', projectId, 'tasks'];

const mutation = useMutation({
mutationFn: (formData: TaskInfoForm) => updateTaskInfo(projectId, taskId, formData),
onError: () => toastError('일정 정보 수정에 실패 했습니다. 잠시후 다시 시도해주세요.'),
onSuccess: () => {
toastSuccess('일정 정보를 수정 했습니다.');
queryClient.invalidateQueries({ queryKey });
},
});

return mutation;
}

// 일정 수행자 추가
export function useAddAssignee(projectId: Project['projectId'], taskId: Task['taskId']) {
const { toastError, toastSuccess } = useToast();
Expand Down
29 changes: 28 additions & 1 deletion src/mocks/services/taskServiceHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { getRoleHash, getStatusHash, getTaskHash, getUserHash } from '@mocks/mockHash';

import type { UserWithRole } from '@/types/UserType';
import type { TaskAssigneeForm, TaskCreationForm, TaskOrderForm } from '@/types/TaskType';
import type { TaskAssigneeForm, TaskCreationForm, TaskInfoForm, TaskOrderForm } from '@/types/TaskType';

const BASE_URL = import.meta.env.VITE_BASE_URL;

Expand Down Expand Up @@ -122,6 +122,33 @@ const taskServiceHandler = [
if (fileList.length === 0) return HttpResponse.json([]);
return HttpResponse.json(fileList.length === 0 ? [] : fileList);
}),
// 일정 정보 수정 API
http.patch(`${BASE_URL}/project/:projectId/task/:taskId`, async ({ request, params }) => {
const accessToken = request.headers.get('Authorization');
const { projectId, taskId } = params;
const taskInfoData = (await request.json()) as TaskInfoForm;
taskInfoData.statusId = Number(taskInfoData.statusId);

if (!accessToken) return new HttpResponse(null, { status: 401 });

// ToDo: JWT의 userId 정보를 가져와 프로젝트 권한 확인이 필요.
const project = PROJECT_DUMMY.find((project) => project.projectId === Number(projectId));
if (!project) return new HttpResponse(null, { status: 404 });

const statuses = STATUS_DUMMY.filter((status) => status.projectId === project.projectId);
if (statuses.length === 0) return new HttpResponse(null, { status: 404 });

const task = TASK_DUMMY.find((task) => task.taskId === Number(taskId));
if (!task) return new HttpResponse(null, { status: 404 });

const isIncludedTask = statuses.map((status) => status.statusId).includes(task.statusId);
if (!isIncludedTask) return new HttpResponse(null, { status: 404 });

const index = TASK_DUMMY.findIndex((task) => task.taskId === Number(taskId));
if (index !== -1) TASK_DUMMY[index] = { ...TASK_DUMMY[index], ...taskInfoData };

return new HttpResponse(null, { status: 200 });
}),
// 일정 수행자 추가 API
http.post(`${BASE_URL}/project/:projectId/task/:taskId/assignee`, async ({ request, params }) => {
const accessToken = request.headers.get('Authorization');
Expand Down
22 changes: 21 additions & 1 deletion src/services/taskService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { AxiosRequestConfig } from 'axios';
import type { TaskFile } from '@/types/FileType';
import type { Project } from '@/types/ProjectType';
import type { User, UserWithRole } from '@/types/UserType';
import type { Task, TaskCreationForm, TaskListWithStatus, TaskOrderForm } from '@/types/TaskType';
import type { Task, TaskCreationForm, TaskInfoForm, TaskListWithStatus, TaskOrderForm } from '@/types/TaskType';

/**
* 프로젝트에 속한 모든 일정 목록 조회 API
Expand Down Expand Up @@ -90,6 +90,26 @@ export async function findTaskFiles(
return authAxios.get<TaskFile[]>(`/project/${projectId}/task/${taskId}/attachment`, axiosConfig);
}

/**
* 일정 정보 수정 API
*
* @export
* @async
* @param {Project['projectId']} projectId - 프로젝트 ID
* @param {Task['taskId']} taskId - 일정 ID
* @param {TaskInfoForm} formData - 일정 수정 정보 객체
* @param {AxiosRequestConfig} [axiosConfig={}] - axios 요청 옵션 설정 객체
* @returns {Promise<AxiosResponse<void>>}
*/
export async function updateTaskInfo(
projectId: Project['projectId'],
taskId: Task['taskId'],
formData: TaskInfoForm,
axiosConfig: AxiosRequestConfig = {},
) {
return authAxios.patch(`/project/${projectId}/task/${taskId}`, formData, axiosConfig);
}

/**
* 일정 수행자 추가 API
*
Expand Down

0 comments on commit 54dd298

Please sign in to comment.