Files
2025-11-02 10:08:56 +01:00

134 lines
3.2 KiB
TypeScript

import { baseApi } from "@/store/api/baseApi";
import { Todo } from "@/store/models/Todo.model";
import { TodoStatus } from "@/constants/todoStatusEnum";
import { PriorityStatus } from "@/constants/priorityStatusEnum";
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";
interface CreateTodoPayload {
title: string;
task: string;
status: TodoStatus;
priority: PriorityStatus;
dueDate: Date;
createdById: string;
assigneeIds: string[];
}
export interface TodosQueryParams {
page?: number;
limit?: number;
search?: string;
statuses?: TodoStatus[];
priorities?: PriorityStatus[];
sortBy?: "title" | "dueDate" | "status" | "priority" | "createdAt";
sortDir?: TableSortDirection;
assigneeUserId?: string;
teamOfManagerId?: string;
}
export interface PaginatedTodos {
items: Todo[];
total: number;
page: number;
limit: number;
}
const normalizeSortDir = (dir?: TableSortDirection) => {
return dir
? dir === TableSortDirection.DESCENDING
? "desc"
: "asc"
: undefined;
};
const buildTodoParams = (params?: TodosQueryParams) => {
if (!params) return {};
const {
page,
limit,
search,
statuses,
priorities,
sortBy,
sortDir,
assigneeUserId,
teamOfManagerId,
} = params;
return {
...(page !== undefined && { page }),
...(limit !== undefined && { limit }),
...(search && { search }),
...(Array.isArray(statuses) &&
statuses.length && {
statuses: statuses.join(","),
}),
...(Array.isArray(priorities) &&
priorities.length && {
priorities: priorities.join(","),
}),
...(sortBy && { sortBy }),
...(sortDir && { sortDir: normalizeSortDir(sortDir) }),
...(assigneeUserId && { assigneeUserId }),
...(teamOfManagerId && { teamOfManagerId }),
};
};
export const todosApi = baseApi.injectEndpoints({
overrideExisting: false,
endpoints: (builder) => ({
getTodosByUser: builder.query<Todo[], string>({
query: (userId) => ({ url: `/todos/user/${userId}` }),
providesTags: (result) => [
"Todos",
...(result ?? []).map(({ id }) => ({ type: "Todos", id } as const)),
],
}),
getTodos: builder.query<PaginatedTodos, TodosQueryParams | undefined>({
query: (params) => ({ url: "/todos", params: buildTodoParams(params) }),
providesTags: (result, _error, _arg) => [
"Todos",
...(result?.items ?? []).map(
({ id }) => ({ type: "Todos", id } as const)
),
],
}),
createTodo: builder.mutation<Todo, CreateTodoPayload>({
query: (data) => ({
url: "/todos",
method: "POST",
body: data,
}),
invalidatesTags: ["Todos"],
}),
updateTodo: builder.mutation<Todo, Partial<Todo>>({
query: (todo) => ({
url: `/todos/${todo.id}`,
method: "PUT",
body: todo,
}),
invalidatesTags: ["Todos"],
}),
deleteTodo: builder.mutation<void, string>({
query: (id) => ({
url: `/todos/${id}`,
method: "DELETE",
}),
invalidatesTags: ["Todos"],
}),
}),
});
export const {
useGetTodosByUserQuery,
useGetTodosQuery,
useCreateTodoMutation,
useUpdateTodoMutation,
useDeleteTodoMutation,
} = todosApi;