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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user