init
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { IServerResponse } from '@/types/common.types';
|
||||
import apiClient from '@/api/api-client';
|
||||
import { API_BASE_URL } from '@/shared/constants';
|
||||
|
||||
import {
|
||||
IMentionMemberSelectOption,
|
||||
IMentionMemberViewModel,
|
||||
IProjectCommentsCreateRequest,
|
||||
} from '@/types/project/projectComments.types';
|
||||
import { toQueryString } from '@/utils/toQueryString';
|
||||
import { IProjectUpdateCommentViewModel } from '@/types/project/project.types';
|
||||
|
||||
const rootUrl = `${API_BASE_URL}/project-comments`;
|
||||
|
||||
export const projectCommentsApiService = {
|
||||
createProjectComment: async (
|
||||
body: IProjectCommentsCreateRequest
|
||||
): Promise<IServerResponse<IProjectCommentsCreateRequest>> => {
|
||||
const url = `${rootUrl}`;
|
||||
const response = await apiClient.post<IServerResponse<IProjectCommentsCreateRequest>>(
|
||||
`${url}`,
|
||||
body
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getMentionMembers: async (
|
||||
projectId: string,
|
||||
index: number,
|
||||
size: number,
|
||||
field: string | null,
|
||||
order: string | null,
|
||||
search: string | null
|
||||
): Promise<IServerResponse<IMentionMemberViewModel[]>> => {
|
||||
const s = encodeURIComponent(search || '');
|
||||
const url = `${rootUrl}/project-members/${projectId}${toQueryString({ index, size, field, order, search: s })}`;
|
||||
const response = await apiClient.get<IServerResponse<IMentionMemberViewModel[]>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getCountByProjectId: async (projectId: string): Promise<IServerResponse<number>> => {
|
||||
const url = `${rootUrl}/${projectId}/comments/count`;
|
||||
const response = await apiClient.get<IServerResponse<number>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getByProjectId: async (
|
||||
projectId: string,
|
||||
isLimit: boolean = false
|
||||
): Promise<IServerResponse<IProjectUpdateCommentViewModel[]>> => {
|
||||
const url = `${rootUrl}/project-comments/${projectId}${toQueryString({ latest: isLimit })}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectUpdateCommentViewModel[]>>(
|
||||
`${url}`
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
deleteComment: async (commentId: string): Promise<IServerResponse<string>> => {
|
||||
const url = `${rootUrl}/delete/${commentId}`;
|
||||
const response = await apiClient.delete<IServerResponse<string>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
import { IServerResponse } from '@/types/common.types';
|
||||
import apiClient from '@/api/api-client';
|
||||
import { API_BASE_URL } from '@/shared/constants';
|
||||
import { toQueryString } from '@/utils/toQueryString';
|
||||
import { IProjectViewModel } from '@/types/project/projectViewModel.types';
|
||||
import { IDeadlineTaskStats } from '@/types/project/projectInsights.types';
|
||||
import {
|
||||
IInsightTasks,
|
||||
IProjectInsightsGetRequest,
|
||||
IProjectLogs,
|
||||
IProjectMemberStats,
|
||||
} from '@/types/project/projectInsights.types';
|
||||
import { ITaskStatusCounts } from '@/types/project/project-insights.types';
|
||||
|
||||
const rootUrl = `${API_BASE_URL}/project-insights`;
|
||||
|
||||
export const projectInsightsApiService = {
|
||||
getProjectInsights: async (id: string): Promise<IServerResponse<IProjectViewModel>> => {
|
||||
const url = `${rootUrl}/${id}/insights`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getProjectOverviewData: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IProjectInsightsGetRequest>> => {
|
||||
const url = `${rootUrl}/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectInsightsGetRequest>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getLastUpdatedTasks: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/last-updated/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IInsightTasks[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getProjectLogs: async (id: string): Promise<IServerResponse<IProjectLogs[]>> => {
|
||||
const url = `${rootUrl}/logs/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectLogs[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getTaskStatusCounts: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<ITaskStatusCounts[]>> => {
|
||||
const url = `${rootUrl}/status-overview/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<ITaskStatusCounts[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getPriorityOverview: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<ITaskStatusCounts[]>> => {
|
||||
const url = `${rootUrl}/priority-overview/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<ITaskStatusCounts[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getOverdueTasks: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/overdue-tasks/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IInsightTasks[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getTasksCompletedEarly: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/early-tasks/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IInsightTasks[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getTasksCompletedLate: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/late-tasks/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IInsightTasks[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getMemberInsightAStats: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IProjectMemberStats>> => {
|
||||
const url = `${rootUrl}/members/stats/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectMemberStats>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getMemberTasks: async (body: any): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/members/tasks`;
|
||||
const response = await apiClient.post<IServerResponse<IInsightTasks[]>>(url, body);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getProjectDeadlineStats: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IDeadlineTaskStats>> => {
|
||||
const url = `${rootUrl}/deadline/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IDeadlineTaskStats>>(url);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getOverloggedTasks: async (
|
||||
id: string,
|
||||
include_archived: boolean
|
||||
): Promise<IServerResponse<IInsightTasks[]>> => {
|
||||
const url = `${rootUrl}/overlogged-tasks/${id}?archived=${include_archived}`;
|
||||
const response = await apiClient.get<IServerResponse<IInsightTasks[]>>(url);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { IServerResponse } from '@/types/common.types';
|
||||
import { API_BASE_URL } from '@/shared/constants';
|
||||
import { IProjectHealth } from '@/types/project/projectHealth.types';
|
||||
import apiClient from '@api/api-client';
|
||||
|
||||
const rootUrl = `${API_BASE_URL}/project-healths`;
|
||||
|
||||
export const projectHealthApiService = {
|
||||
getHealthOptions: async (): Promise<IServerResponse<IProjectHealth[]>> => {
|
||||
const response = await apiClient.get<IServerResponse<IProjectHealth[]>>(rootUrl);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { IServerResponse } from '@/types/common.types';
|
||||
import apiClient from '../../api-client';
|
||||
import { API_BASE_URL } from '@/shared/constants';
|
||||
import { IProjectStatus } from '@/types/project/projectStatus.types';
|
||||
|
||||
const rootUrl = `${API_BASE_URL}/project-statuses`;
|
||||
|
||||
export const projectStatusesApiService = {
|
||||
getStatuses: async (): Promise<IServerResponse<IProjectStatus[]>> => {
|
||||
const response = await apiClient.get<IServerResponse<IProjectStatus[]>>(rootUrl);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
121
worklenz-frontend/src/api/projects/projects.api.service.ts
Normal file
121
worklenz-frontend/src/api/projects/projects.api.service.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { IServerResponse } from '@/types/common.types';
|
||||
import apiClient from '../api-client';
|
||||
import { API_BASE_URL } from '@/shared/constants';
|
||||
import { IProjectOverviewStats, IProjectsViewModel } from '@/types/project/projectsViewModel.types';
|
||||
import { toQueryString } from '@/utils/toQueryString';
|
||||
import { IProjectViewModel } from '@/types/project/projectViewModel.types';
|
||||
import { ITeamMemberOverviewGetResponse } from '@/types/project/project-insights.types';
|
||||
import { IProjectMembersViewModel } from '@/types/projectMember.types';
|
||||
import { IProjectManager } from '@/types/project/projectManager.types';
|
||||
|
||||
const rootUrl = `${API_BASE_URL}/projects`;
|
||||
|
||||
export const projectsApiService = {
|
||||
getProjects: async (
|
||||
index: number,
|
||||
size: number,
|
||||
field: string | null,
|
||||
order: string | null,
|
||||
search: string | null,
|
||||
filter: number | null = null,
|
||||
statuses: string | null = null,
|
||||
categories: string | null = null
|
||||
): Promise<IServerResponse<IProjectsViewModel>> => {
|
||||
const s = encodeURIComponent(search || '');
|
||||
const url = `${rootUrl}${toQueryString({ index, size, field, order, search: s, filter, statuses, categories })}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectsViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getProject: async (id: string): Promise<IServerResponse<IProjectViewModel>> => {
|
||||
const url = `${rootUrl}/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
toggleFavoriteProject: async (id: string): Promise<IServerResponse<IProjectsViewModel>> => {
|
||||
const url = `${rootUrl}/favorite/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectsViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getOverViewById: async (id: string): Promise<IServerResponse<IProjectOverviewStats>> => {
|
||||
const url = `${rootUrl}/overview/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectOverviewStats>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getOverViewMembersById: async (
|
||||
id: string,
|
||||
archived = false
|
||||
): Promise<IServerResponse<ITeamMemberOverviewGetResponse[]>> => {
|
||||
const url = `${rootUrl}/overview-members/${id}?archived=${archived}`;
|
||||
const response = await apiClient.get<IServerResponse<ITeamMemberOverviewGetResponse[]>>(
|
||||
`${url}`
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getMembers: async (
|
||||
id: string,
|
||||
index: number,
|
||||
size: number,
|
||||
field: string | null,
|
||||
order: string | null,
|
||||
search: string | null
|
||||
): Promise<IServerResponse<IProjectMembersViewModel>> => {
|
||||
const s = encodeURIComponent(search || '');
|
||||
const url = `${rootUrl}/members/${id}${toQueryString({ index, size, field, order, search: s })}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectMembersViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
createProject: async (
|
||||
project: IProjectViewModel
|
||||
): Promise<IServerResponse<IProjectViewModel>> => {
|
||||
const url = `${rootUrl}`;
|
||||
const response = await apiClient.post<IServerResponse<IProjectViewModel>>(`${url}`, project);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
updateProject: async (
|
||||
id: string,
|
||||
project: IProjectViewModel
|
||||
): Promise<IServerResponse<IProjectViewModel>> => {
|
||||
const q = toQueryString({ current_project_id: id });
|
||||
const url = `${rootUrl}/${id}${q}`;
|
||||
const response = await apiClient.put<IServerResponse<IProjectViewModel>>(`${url}`, project);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
deleteProject: async (id: string): Promise<IServerResponse<IProjectViewModel>> => {
|
||||
const url = `${rootUrl}/${id}`;
|
||||
const response = await apiClient.delete<IServerResponse<IProjectViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
toggleArchiveProject: async (id: string): Promise<IServerResponse<any>> => {
|
||||
const url = `${rootUrl}/archive/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
toggleArchiveProjectForAll: async (id: string): Promise<IServerResponse<any>> => {
|
||||
const url = `${rootUrl}/archive-all/${id}`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectViewModel>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
updateDefaultTab: async (body: { project_id: string; default_view: string }): Promise<IServerResponse<any>> => {
|
||||
const url = `${rootUrl}/update-pinned-view`;
|
||||
const response = await apiClient.put<IServerResponse<IProjectViewModel>>(`${url}`, body);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getProjectManagers: async (): Promise<IServerResponse<IProjectManager[]>> => {
|
||||
const url = `${API_BASE_URL}/project-managers`;
|
||||
const response = await apiClient.get<IServerResponse<IProjectManager[]>>(`${url}`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
153
worklenz-frontend/src/api/projects/projects.v1.api.service.ts
Normal file
153
worklenz-frontend/src/api/projects/projects.v1.api.service.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
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 } from '../api-client';
|
||||
|
||||
const rootUrl = '/projects';
|
||||
|
||||
export const projectsApi = createApi({
|
||||
reducerPath: 'projectsApi',
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: `${import.meta.env.VITE_API_URL}${API_BASE_URL}`,
|
||||
prepareHeaders: headers => {
|
||||
headers.set('X-CSRF-Token', getCsrfToken() || '');
|
||||
headers.set('Content-Type', 'application/json');
|
||||
},
|
||||
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;
|
||||
Reference in New Issue
Block a user