import { Timeline, Typography, Flex, ConfigProvider, Tag, Tooltip, Skeleton, } from '@/shared/antd-imports'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ArrowRightOutlined } from '@/shared/antd-imports'; import { IActivityLog, IActivityLogAttributeTypes, IActivityLogsResponse, } from '@/types/tasks/task-activity-logs-get-request'; import SingleAvatar from '@/components/common/single-avatar/single-avatar'; import { taskActivityLogsApiService } from '@/api/tasks/task-activity-logs.api.service'; import { useAppSelector } from '@/hooks/useAppSelector'; import { calculateTimeGap } from '@/utils/calculate-time-gap'; import { formatDateTimeWithLocale } from '@/utils/format-date-time-with-locale'; import logger from '@/utils/errorLogger'; const TaskDrawerActivityLog = () => { const [activityLogs, setActivityLogs] = useState({}); const [loading, setLoading] = useState(false); const { selectedTaskId, taskFormViewModel } = useAppSelector(state => state.taskDrawerReducer); const { mode: themeMode } = useAppSelector(state => state.themeReducer); const { t } = useTranslation('task-drawer/task-drawer'); useEffect(() => { fetchActivityLogs(); }, [taskFormViewModel]); const fetchActivityLogs = async () => { if (!selectedTaskId) return; setLoading(true); try { const res = await taskActivityLogsApiService.getActivityLogsByTaskId(selectedTaskId); if (res.done) { setActivityLogs(res.body); } } catch (error) { logger.error('Error fetching activity logs', error); } finally { setLoading(false); } }; const renderAttributeType = (activity: IActivityLog) => { const truncateText = (text?: string) => { if (!text) return text; const div = document.createElement('div'); div.innerHTML = text; const plainText = div.textContent || div.innerText || ''; return plainText.length > 28 ? `${plainText.slice(0, 27)}...` : plainText; }; switch (activity.attribute_type) { case IActivityLogAttributeTypes.ASSIGNEES: return ( {truncateText(activity.assigned_user?.name)}   {truncateText(activity.log_type?.toUpperCase())} ); case IActivityLogAttributeTypes.LABEL: return ( {truncateText(activity.label_data?.name)}   {activity.log_type === 'create' ? t('taskActivityLogTab.add') : t('taskActivityLogTab.remove')} ); case IActivityLogAttributeTypes.STATUS: return ( {truncateText(activity.previous_status?.name) || t('taskActivityLogTab.none')}   {truncateText(activity.next_status?.name) || t('taskActivityLogTab.none')} ); case IActivityLogAttributeTypes.PRIORITY: return ( {truncateText(activity.previous_priority?.name) || t('taskActivityLogTab.none')}   {truncateText(activity.next_priority?.name) || t('taskActivityLogTab.none')} ); case IActivityLogAttributeTypes.PHASE: return ( {truncateText(activity.previous_phase?.name) || t('taskActivityLogTab.none')}   {truncateText(activity.next_phase?.name) || t('taskActivityLogTab.none')} ); case IActivityLogAttributeTypes.PROGRESS: return ( {activity.previous || '0'}%   {activity.current || '0'}% ); case IActivityLogAttributeTypes.WEIGHT: return ( {t('taskActivityLogTab.weight')}: {activity.previous || '100'}   {t('taskActivityLogTab.weight')}: {activity.current || '100'} ); default: return ( {truncateText(activity.previous) || t('taskActivityLogTab.none')}   {truncateText(activity.current) || t('taskActivityLogTab.none')} ); } }; useEffect(() => { !loading && fetchActivityLogs(); }, []); return ( {activityLogs.logs?.map((activity, index) => ( {activity.done_by?.name} {activity.log_text} {activity.attribute_type}. {activity.created_at ? calculateTimeGap(activity.created_at) : ''} {renderAttributeType(activity)} ))} {activityLogs.name} {t('taskActivityLogTab.createdTask')} {activityLogs.created_at ? calculateTimeGap(activityLogs.created_at) : ''} ); }; export default TaskDrawerActivityLog;