feat(localization): add timer conflict handling and update translations
- Introduced a new hook `useTaskTimerWithConflictCheck` to manage timer conflicts, prompting users when a timer is already running for a different task. - Updated localization files for Albanian, German, English, Spanish, Portuguese, and Chinese to include new translation keys related to timer conflict handling and cancellation. - Refactored components to utilize the new timer hook, enhancing user experience by preventing overlapping timers.
This commit is contained in:
94
worklenz-frontend/src/hooks/useTaskTimerWithConflictCheck.ts
Normal file
94
worklenz-frontend/src/hooks/useTaskTimerWithConflictCheck.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Modal } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSocket } from '@/socket/socketContext';
|
||||
import { SocketEvents } from '@/shared/socket-events';
|
||||
import { taskTimeLogsApiService } from '@/api/tasks/task-time-logs.api.service';
|
||||
import { useTaskTimer } from './useTaskTimer';
|
||||
|
||||
interface ConflictingTimer {
|
||||
task_id: string;
|
||||
task_name: string;
|
||||
project_name: string;
|
||||
}
|
||||
|
||||
export const useTaskTimerWithConflictCheck = (taskId: string, timerStartTime: string | null) => {
|
||||
const { socket } = useSocket();
|
||||
const { t: tTable } = useTranslation('task-list-table');
|
||||
const { t: tCommon } = useTranslation('common');
|
||||
|
||||
// Ensure timerStartTime is a number or null, as required by useTaskTimer
|
||||
const parsedTimerStartTime = typeof timerStartTime === 'string' && timerStartTime !== null
|
||||
? Number(timerStartTime)
|
||||
: timerStartTime;
|
||||
|
||||
const originalHook = useTaskTimer(taskId, parsedTimerStartTime as number | null);
|
||||
const [isCheckingConflict, setIsCheckingConflict] = useState(false);
|
||||
|
||||
const checkForConflictingTimers = useCallback(async () => {
|
||||
try {
|
||||
const response = await taskTimeLogsApiService.getRunningTimers();
|
||||
const runningTimers = response.body || [];
|
||||
|
||||
// Find conflicting timer (running timer for a different task)
|
||||
const conflictingTimer = runningTimers.find((timer: ConflictingTimer) =>
|
||||
timer.task_id !== taskId
|
||||
);
|
||||
|
||||
return conflictingTimer;
|
||||
} catch (error) {
|
||||
console.error('Error checking for conflicting timers:', error);
|
||||
return null;
|
||||
}
|
||||
}, [taskId]);
|
||||
|
||||
const handleStartTimerWithConflictCheck = useCallback(async () => {
|
||||
if (isCheckingConflict) return;
|
||||
|
||||
setIsCheckingConflict(true);
|
||||
|
||||
try {
|
||||
const conflictingTimer = await checkForConflictingTimers();
|
||||
|
||||
if (conflictingTimer) {
|
||||
Modal.confirm({
|
||||
title: tTable('timer.conflictTitle'),
|
||||
content: tTable('timer.conflictMessage', {
|
||||
taskName: conflictingTimer.task_name,
|
||||
projectName: conflictingTimer.project_name
|
||||
}),
|
||||
okText: tTable('timer.stopAndStart'),
|
||||
cancelText: tCommon('cancel'),
|
||||
onOk: () => {
|
||||
// Stop the conflicting timer
|
||||
if (socket) {
|
||||
socket.emit(SocketEvents.TASK_TIMER_STOP.toString(), JSON.stringify({
|
||||
task_id: conflictingTimer.task_id
|
||||
}));
|
||||
}
|
||||
|
||||
// Start the new timer after a short delay
|
||||
setTimeout(() => {
|
||||
originalHook.handleStartTimer();
|
||||
}, 100);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// No conflict, start timer directly
|
||||
originalHook.handleStartTimer();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error handling timer start with conflict check:', error);
|
||||
// Fallback to original behavior
|
||||
originalHook.handleStartTimer();
|
||||
} finally {
|
||||
setIsCheckingConflict(false);
|
||||
}
|
||||
}, [isCheckingConflict, checkForConflictingTimers, tTable, tCommon, socket, originalHook]);
|
||||
|
||||
return {
|
||||
...originalHook,
|
||||
handleStartTimer: handleStartTimerWithConflictCheck,
|
||||
isCheckingConflict,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user