Files
worklenz/worklenz-frontend/src/api/projects/projects.v1.api.service.ts
chamikaJ 65af5f659e refactor(build): remove Gruntfile and transition to npm scripts for build process
- Deleted Gruntfile.js to streamline the build process.
- Updated package.json to include new npm scripts for build, clean, and watch tasks.
- Added dependencies for concurrent execution and CSRF token management.
- Integrated csrf-sync for improved CSRF protection in the application.
- Refactored app and API client to utilize the new CSRF token management approach.
2025-05-30 10:56:19 +05:30

164 lines
5.0 KiB
TypeScript

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { API_BASE_URL } from '@/shared/constants';
import { IProjectViewModel } from '@/types/project/projectViewModel.types';
import { IProjectCategory } from '@/types/project/projectCategory.types';
import { IProjectsViewModel } from '@/types/project/projectsViewModel.types';
import { IServerResponse } from '@/types/common.types';
import { IProjectMembersViewModel } from '@/types/projectMember.types';
import { getCsrfToken, refreshCsrfToken } from '../api-client';
import config from '@/config/env';
const rootUrl = '/projects';
export const projectsApi = createApi({
reducerPath: 'projectsApi',
baseQuery: fetchBaseQuery({
baseUrl: `${config.apiUrl}${API_BASE_URL}`,
prepareHeaders: async headers => {
// Get CSRF token, refresh if needed
let token = getCsrfToken();
if (!token) {
token = await refreshCsrfToken();
}
if (token) {
headers.set('X-CSRF-Token', token);
}
headers.set('Content-Type', 'application/json');
return headers;
},
credentials: 'include',
}),
tagTypes: ['Projects', 'ProjectCategories', 'ProjectMembers'],
endpoints: builder => ({
getProjects: builder.query<
IServerResponse<IProjectsViewModel>,
{
index: number;
size: number;
field: string | null;
order: string | null;
search: string | null;
filter: number | null;
statuses: string | null;
categories: string | null;
}
>({
query: ({ index, size, field, order, search, filter, statuses, categories }) => {
const params = new URLSearchParams({
index: index.toString(),
size: size.toString(),
field: field || '',
order: order || '',
search: search || '',
filter: filter?.toString() || '',
statuses: statuses || '',
categories: categories || '',
});
return `${rootUrl}?${params.toString()}`;
},
providesTags: result => [{ type: 'Projects', id: 'LIST' }],
}),
getProject: builder.query<IServerResponse<IProjectViewModel>, string>({
query: id => `${rootUrl}/${id}`,
providesTags: (result, error, id) => [{ type: 'Projects', id }],
}),
createProject: builder.mutation<IServerResponse<IProjectViewModel>, IProjectViewModel>({
query: project => ({
url: rootUrl,
method: 'POST',
body: project,
}),
invalidatesTags: [{ type: 'Projects', id: 'LIST' }],
}),
updateProject: builder.mutation<
IServerResponse<IProjectViewModel>,
{ id: string; project: IProjectViewModel }
>({
query: ({ id, project }) => ({
url: `${rootUrl}/${id}`,
method: 'PUT',
body: project,
}),
invalidatesTags: (result, error, { id }) => [{ type: 'Projects', id }],
}),
deleteProject: builder.mutation<IServerResponse<IProjectViewModel>, string>({
query: id => ({
url: `${rootUrl}/${id}`,
method: 'DELETE',
}),
invalidatesTags: [{ type: 'Projects', id: 'LIST' }],
}),
toggleFavoriteProject: builder.mutation<IServerResponse<IProjectsViewModel>, string>({
query: id => ({
url: `${rootUrl}/favorite/${id}`,
method: 'GET',
}),
invalidatesTags: (result, error, id) => [{ type: 'Projects', id }],
}),
toggleArchiveProject: builder.mutation<IServerResponse<any>, string>({
query: id => ({
url: `${rootUrl}/archive/${id}`,
method: 'GET',
}),
invalidatesTags: [{ type: 'Projects', id: 'LIST' }],
}),
toggleArchiveProjectForAll: builder.mutation<IServerResponse<any>, string>({
query: id => ({
url: `${rootUrl}/archive-all/${id}`,
method: 'GET',
}),
invalidatesTags: [{ type: 'Projects', id: 'LIST' }],
}),
getProjectCategories: builder.query<IProjectCategory[], void>({
query: () => `${rootUrl}/categories`,
providesTags: ['ProjectCategories'],
}),
getProjectMembers: builder.query<
IServerResponse<IProjectMembersViewModel>,
{
id: string;
index: number;
size: number;
field: string | null;
order: string | null;
search: string | null;
}
>({
query: ({ id, index, size, field, order, search }) => {
const params = new URLSearchParams({
index: index.toString(),
size: size.toString(),
field: field || '',
order: order || '',
search: search || '',
});
return `${rootUrl}/members/${id}?${params.toString()}`;
},
providesTags: (result, error, { id }) => [{ type: 'ProjectMembers', id }],
}),
}),
});
export const {
useGetProjectsQuery,
useGetProjectQuery,
useCreateProjectMutation,
useUpdateProjectMutation,
useDeleteProjectMutation,
useToggleFavoriteProjectMutation,
useToggleArchiveProjectMutation,
useToggleArchiveProjectForAllMutation,
useGetProjectCategoriesQuery,
useGetProjectMembersQuery,
} = projectsApi;