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,221 @@
import { TabsProps, Tabs, Button } from 'antd';
import Drawer from 'antd/es/drawer';
import { InputRef } from 'antd/es/input';
import { useTranslation } from 'react-i18next';
import { useEffect, useRef, useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import { useAppSelector } from '@/hooks/useAppSelector';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import {
setSelectedTaskId,
setShowTaskDrawer,
setTaskFormViewModel,
setTaskSubscribers,
setTimeLogEditing,
} from '@/features/task-drawer/task-drawer.slice';
import './task-drawer.css';
import TaskDrawerHeader from './task-drawer-header/task-drawer-header';
import TaskDrawerActivityLog from './shared/activity-log/task-drawer-activity-log';
import TaskDrawerInfoTab from './shared/info-tab/task-drawer-info-tab';
import TaskDrawerTimeLog from './shared/time-log/task-drawer-time-log';
import TimeLogForm from './shared/time-log/time-log-form';
import { DEFAULT_TASK_NAME } from '@/shared/constants';
import useTaskDrawerUrlSync from '@/hooks/useTaskDrawerUrlSync';
import InfoTabFooter from './shared/info-tab/info-tab-footer';
import { Flex } from 'antd';
const TaskDrawer = () => {
const { t } = useTranslation('task-drawer/task-drawer');
const [activeTab, setActiveTab] = useState<string>('info');
const [refreshTimeLogTrigger, setRefreshTimeLogTrigger] = useState(0);
const { showTaskDrawer, timeLogEditing } = useAppSelector(state => state.taskDrawerReducer);
const taskNameInputRef = useRef<InputRef>(null);
const isClosingManually = useRef(false);
// Use the custom hook to sync the task drawer state with the URL
const { clearTaskFromUrl } = useTaskDrawerUrlSync();
useEffect(() => {
if (taskNameInputRef.current?.input?.value === DEFAULT_TASK_NAME) {
taskNameInputRef.current.focus();
}
}, [showTaskDrawer]);
const dispatch = useAppDispatch();
const handleOnClose = () => {
// Set flag to indicate we're manually closing the drawer
isClosingManually.current = true;
setActiveTab('info');
// Explicitly clear the task parameter from URL
clearTaskFromUrl();
// Update the Redux state
dispatch(setShowTaskDrawer(false));
dispatch(setSelectedTaskId(null));
dispatch(setTaskFormViewModel({}));
dispatch(setTaskSubscribers([]));
// Reset the flag after a short delay
setTimeout(() => {
isClosingManually.current = false;
}, 100);
};
const handleTabChange = (key: string) => {
setActiveTab(key);
};
const handleCancelTimeLog = () => {
dispatch(
setTimeLogEditing({
isEditing: false,
logBeingEdited: null,
})
);
};
const handleAddTimeLog = () => {
dispatch(
setTimeLogEditing({
isEditing: true,
logBeingEdited: null,
})
);
};
// Function to trigger a refresh of the time log list
const refreshTimeLogs = () => {
setRefreshTimeLogTrigger(prev => prev + 1);
};
const handleTimeLogSubmitSuccess = () => {
// Close the form
handleCancelTimeLog();
// Trigger refresh of time logs
refreshTimeLogs();
};
const tabItems: TabsProps['items'] = [
{
key: 'info',
label: t('taskInfoTab.title'),
children: <TaskDrawerInfoTab t={t} />,
},
{
key: 'timeLog',
label: t('taskTimeLogTab.title'),
children: <TaskDrawerTimeLog t={t} refreshTrigger={refreshTimeLogTrigger} />,
},
{
key: 'activityLog',
label: t('taskActivityLogTab.title'),
children: <TaskDrawerActivityLog />,
},
];
// Render the appropriate footer based on the active tab
const renderFooter = () => {
if (activeTab === 'info') {
return <InfoTabFooter />;
} else if (activeTab === 'timeLog') {
if (timeLogEditing.isEditing) {
return (
<TimeLogForm
onCancel={handleCancelTimeLog}
onSubmitSuccess={handleTimeLogSubmitSuccess}
initialValues={timeLogEditing.logBeingEdited || undefined}
mode={timeLogEditing.logBeingEdited ? 'edit' : 'create'}
/>
);
} else {
return (
<Flex justify="center" style={{ width: '100%', padding: '16px 0 0' }}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAddTimeLog}
style={{ width: '100%' }}
>
Add new time log
</Button>
</Flex>
);
}
}
return null;
};
// Create conditional footer styles based on active tab
const getFooterStyle = () => {
const baseStyle = {
padding: '0 24px 16px',
width: '100%',
height: 'auto',
boxSizing: 'border-box' as const,
};
if (activeTab === 'timeLog') {
return {
...baseStyle,
overflow: 'visible', // Remove scrolling for timeLog tab
};
}
return {
...baseStyle,
overflow: 'hidden',
};
};
// Get conditional body style
const getBodyStyle = () => {
const baseStyle = {
padding: '24px',
overflow: 'auto'
};
if (activeTab === 'timeLog' && timeLogEditing.isEditing) {
return {
...baseStyle,
height: 'calc(100% - 220px)', // More space for the timeLog form
};
}
return {
...baseStyle,
height: 'calc(100% - 180px)',
};
};
const drawerProps = {
open: showTaskDrawer,
onClose: handleOnClose,
width: 720,
style: { justifyContent: 'space-between' },
destroyOnClose: true,
title: <TaskDrawerHeader inputRef={taskNameInputRef} t={t} />,
footer: renderFooter(),
bodyStyle: getBodyStyle(),
footerStyle: getFooterStyle(),
};
return (
<Drawer {...drawerProps}>
<Tabs
type="card"
items={tabItems}
destroyInactiveTabPane
onChange={handleTabChange}
activeKey={activeTab}
/>
</Drawer>
);
};
export default TaskDrawer;