diff --git a/apps/web/app/[locale]/timesheet/[memberId]/components/AddTaskModal.tsx b/apps/web/app/[locale]/timesheet/[memberId]/components/AddTaskModal.tsx index 089f36e6d..cfdc306ad 100644 --- a/apps/web/app/[locale]/timesheet/[memberId]/components/AddTaskModal.tsx +++ b/apps/web/app/[locale]/timesheet/[memberId]/components/AddTaskModal.tsx @@ -188,7 +188,6 @@ export function AddTaskModal({ closeModal, isOpen }: IAddTaskModalProps) { className='w-full font-medium dark:text-white' options={activeTeam?.members || []} onChange={(value) => { - console.log(value) updateFormState('employeeId', value) }} renderOption={(option) => ( diff --git a/apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx b/apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx index 1cd5ddd81..66a19e4de 100644 --- a/apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx +++ b/apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx @@ -171,7 +171,7 @@ export function EditTaskModal({ isOpen, closeModal, dataTimesheet }: IEditTaskMo closeModal={closeModal} isOpen={isOpen} showCloseIcon - title={'Edit Task'} + title={t('common.EDIT_TASK')} className="bg-light--theme-light dark:bg-dark--theme-light p-5 rounded-xl w-full md:w-40 md:min-w-[32rem] justify-start h-[auto]" titleClass="font-bold flex justify-start w-full">
diff --git a/apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx b/apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx index 1aea6661d..44dc52055 100644 --- a/apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx +++ b/apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx @@ -8,13 +8,27 @@ export interface IRejectSelectedModalProps { onReject: (reason: string) => void; minReasonLength?: number; maxReasonLength?: number; + selectTimesheetId?: string[]; } +/** + * A modal for rejecting selected timesheet entries. + * + * @param isOpen - If true, show the modal. Otherwise, hide the modal. + * @param closeModal - A function to close the modal. + * @param maxReasonLength - The maximum length of the rejection reason. + * @param onReject - A function to call when the user rejects the selected entries. + * @param minReasonLength - The minimum length of the rejection reason. + * @param selectTimesheetId - The IDs of the timesheet entries to be rejected. + * + * @returns A modal component. + */ export function RejectSelectedModal({ isOpen, closeModal, maxReasonLength, onReject, - minReasonLength + minReasonLength, + selectTimesheetId }: IRejectSelectedModalProps) { const [isSubmitting, setIsSubmitting] = useState(false); const [reason, setReason] = useState(''); diff --git a/apps/web/app/hooks/features/useTimelogFilterOptions.ts b/apps/web/app/hooks/features/useTimelogFilterOptions.ts index 995992ea4..f077a1e8c 100644 --- a/apps/web/app/hooks/features/useTimelogFilterOptions.ts +++ b/apps/web/app/hooks/features/useTimelogFilterOptions.ts @@ -47,16 +47,17 @@ export function useTimelogFilterOptions() { const handleSelectRowByStatusAndDate = (logs: TimesheetLog[], isChecked: boolean) => { setSelectTimesheetId((prev) => { const logIds = logs.map((item) => item.id); - - if (isChecked) { - return [...new Set([...prev, ...logIds])]; - } else { - return prev.filter((id) => !logIds.includes(id)); + if (!isChecked) { + const allSelected = logIds.every(id => prev.includes(id)); + if (allSelected) { + return prev.filter((id) => !logIds.includes(id)); + } else { + return [...new Set([...prev, ...logIds])]; + } } + return [...new Set([...prev, ...logIds])]; }); - } - - + }; React.useEffect(() => { return () => setSelectTimesheetId([]); diff --git a/apps/web/lib/features/integrations/calendar/table-time-sheet.tsx b/apps/web/lib/features/integrations/calendar/table-time-sheet.tsx index 2c73b7deb..96ca5bde5 100644 --- a/apps/web/lib/features/integrations/calendar/table-time-sheet.tsx +++ b/apps/web/lib/features/integrations/calendar/table-time-sheet.tsx @@ -117,6 +117,7 @@ export function DataTableTimeSheet({ data, user }: { data?: GroupedTimesheet[], countID={selectTimesheetId.length} /> { // Pending implementation }} @@ -186,11 +187,16 @@ export function DataTableTimeSheet({ data, user }: { data?: GroupedTimesheet[], handleSelectRowByStatusAndDate(rows, selectTimesheetId.length === 0)} + () => handleSelectRowByStatusAndDate( + rows, + !rows.every(row => selectTimesheetId.includes(row.id)) + ) + } data={rows} status={status} onSort={handleSort} date={plan.date} + selectedIds={selectTimesheetId} /> {rows.map((task) => (
void, data: TimesheetLog[], handleSelectRowByStatusAndDate: (status: string, date: string) => void, - date?: string + date?: string, + selectedIds: string[] + }) => { const { bg, bgOpacity } = statusColor(status); @@ -536,6 +546,7 @@ const HeaderRow = ({ Employee: null, Status: null, }); + const isAllSelected = data.length > 0 && data.every(row => selectedIds.includes(row.id)); const handleSort = (key: string) => { const newOrder = sortState[key] === "ASC" ? "DESC" : "ASC"; @@ -549,6 +560,7 @@ const HeaderRow = ({ className="flex items-center text-[#71717A] font-medium border-b border-t dark:border-gray-600 space-x-4 p-1 h-[60px] w-full" > date && handleSelectRowByStatusAndDate(status, date)} className="w-5 h-5" disabled={!date} @@ -581,7 +593,7 @@ const HeaderRow = ({ currentSort={sortState["Status"]} />
-
+
Time