feat(tasks): optimize task retrieval and performance metrics logging

- Updated `getList` and `getTasksOnly` methods to skip expensive progress calculations by default, enhancing performance.
- Introduced logging for performance metrics, including method execution times and warnings for deprecated methods.
- Added new `getTaskProgressStatus` endpoint to provide basic progress stats without heavy calculations.
- Implemented performance optimizations in the frontend, including lazy loading and improved rendering for task rows.
- Enhanced task management slice with reset actions for better state management.
- Added localization support for task management messages in multiple languages.
This commit is contained in:
chamiakJ
2025-06-26 12:26:50 +05:30
parent 345b8500cd
commit 3d1cb29a67
21 changed files with 866 additions and 216 deletions

View File

@@ -14,15 +14,28 @@ export const getCsrfToken = (): string | null => {
// Function to refresh CSRF token from server
export const refreshCsrfToken = async (): Promise<string | null> => {
try {
// Make a GET request to the server to get a fresh CSRF token
const response = await axios.get(`${config.apiUrl}/csrf-token`, { withCredentials: true });
const tokenStart = performance.now();
console.log('[CSRF] Starting CSRF token refresh...');
// Make a GET request to the server to get a fresh CSRF token with timeout
const response = await axios.get(`${config.apiUrl}/csrf-token`, {
withCredentials: true,
timeout: 10000 // 10 second timeout for CSRF token requests
});
const tokenEnd = performance.now();
console.log(`[CSRF] CSRF token refresh completed in ${(tokenEnd - tokenStart).toFixed(2)}ms`);
if (response.data && response.data.token) {
csrfToken = response.data.token;
console.log('[CSRF] CSRF token successfully refreshed');
return csrfToken;
} else {
console.warn('[CSRF] No token in response:', response.data);
}
return null;
} catch (error) {
console.error('Failed to refresh CSRF token:', error);
console.error('[CSRF] Failed to refresh CSRF token:', error);
return null;
}
};
@@ -37,25 +50,36 @@ export const initializeCsrfToken = async (): Promise<void> => {
const apiClient = axios.create({
baseURL: config.apiUrl,
withCredentials: true,
timeout: 30000, // 30 second timeout to prevent hanging requests
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
// Request interceptor
// Request interceptor with performance optimization
apiClient.interceptors.request.use(
async config => {
const requestStart = performance.now();
// Ensure we have a CSRF token before making requests
if (!csrfToken) {
console.log('[API CLIENT] No CSRF token, fetching...');
const tokenStart = performance.now();
await refreshCsrfToken();
const tokenEnd = performance.now();
console.log(`[API CLIENT] CSRF token fetch took ${(tokenEnd - tokenStart).toFixed(2)}ms`);
}
if (csrfToken) {
config.headers['X-CSRF-Token'] = csrfToken;
} else {
console.warn('No CSRF token available');
console.warn('No CSRF token available after refresh attempt');
}
const requestEnd = performance.now();
console.log(`[API CLIENT] Request interceptor took ${(requestEnd - requestStart).toFixed(2)}ms`);
return config;
},
error => Promise.reject(error)

View File

@@ -28,6 +28,7 @@ export interface ITaskListConfigV2 {
parent_task?: string;
group?: string;
isSubtasksInclude: boolean;
include_empty?: string; // Include empty groups in response
}
export interface ITaskListV3Response {
@@ -137,7 +138,7 @@ export const tasksApiService = {
},
getTaskListV3: async (config: ITaskListConfigV2): Promise<IServerResponse<ITaskListV3Response>> => {
const q = toQueryString(config);
const q = toQueryString({ ...config, include_empty: "true" });
const response = await apiClient.get(`${rootUrl}/list/v3/${config.id}${q}`);
return response.data;
},
@@ -146,4 +147,16 @@ export const tasksApiService = {
const response = await apiClient.post(`${rootUrl}/refresh-progress/${projectId}`);
return response.data;
},
getTaskProgressStatus: async (projectId: string): Promise<IServerResponse<{
projectId: string;
totalTasks: number;
completedTasks: number;
avgProgress: number;
lastUpdated: string;
completionPercentage: number;
}>> => {
const response = await apiClient.get(`${rootUrl}/progress-status/${projectId}`);
return response.data;
},
};