This commit is contained in:
chamikaJ
2025-04-17 18:28:54 +05:30
parent f583291d8a
commit 8825b0410a
2837 changed files with 241385 additions and 127578 deletions

View File

@@ -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;
},
};

View File

@@ -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;
},
};

View File

@@ -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;
},
};

View File

@@ -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;
},
};

View 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;
},
};

View 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;