diff --git a/src/modules/admin/components/task/ArchiveTaskListTable.jsx b/src/modules/admin/components/task/ArchiveTaskListTable.jsx index 64ac1d1..a9bd6f7 100644 --- a/src/modules/admin/components/task/ArchiveTaskListTable.jsx +++ b/src/modules/admin/components/task/ArchiveTaskListTable.jsx @@ -73,7 +73,7 @@ export default function ArchiveTaskListTable() { const selectionActions = buildSelectionActions({ exportConfig, - onRestoreMany: (ids) => setRestoreIds(ids), + onBulkRestore: (ids) => setRestoreIds(ids), getTableInstance: () => tableRefsRef.current.tableInstance, }); @@ -129,7 +129,7 @@ export default function ArchiveTaskListTable() { onOpenChange={(v) => !v && setRestoreIds(null)} ids={restoreIds ?? []} entityLabel="Task List" - onRestore={(ids) => bulkRestoreTaskLists(ids)} + onRestore={({ ids }) => bulkRestoreTaskLists(ids)} loading={loading} onSuccess={handleSuccess} /> diff --git a/src/modules/admin/components/task/ArchiveTaskTable.jsx b/src/modules/admin/components/task/ArchiveTaskTable.jsx index 22d3ea6..1969ed6 100644 --- a/src/modules/admin/components/task/ArchiveTaskTable.jsx +++ b/src/modules/admin/components/task/ArchiveTaskTable.jsx @@ -1,4 +1,4 @@ -import { useMemo, useRef, useState, useCallback } from "react"; +import { useMemo, useRef, useState, useCallback, useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { useAdminTask } from "@/contexts/AdminTaskContext"; @@ -31,7 +31,7 @@ export default function ArchivedTaskTable() { const { taskList, tasks, attributes, pagination, loading, - fetchArchivedTasks, + fetchTaskList, fetchArchivedTasks, fetchTaskFieldValues, restoreTask, bulkRestoreTasks, } = useAdminTask(); @@ -47,6 +47,11 @@ export default function ArchivedTaskTable() { tableInstance: null, }); + useEffect(() => { + fetchTaskList(taskListId); + fetchArchivedTasks(taskListId, { page: 1, limit: 10 }); + }, [taskListId]); + const handleRefsReady = (refs) => { tableRefsRef.current = refs; }; @@ -82,19 +87,16 @@ export default function ArchivedTaskTable() { }), [navigate]); const toolbarActions = useMemo(() => buildToolbarActions({ - taskListId, - navigate, - getSort: () => tableRefsRef.current.getSort(), - fetchArchivedTasks: handleFetch, - pagination, - exportConfig, + fetchArchivedTasks: handleFetch, taskListId, + navigate, pagination, exportConfig, getFilters: () => tableRefsRef.current.getFilters(), + getSort: () => tableRefsRef.current.getSort(), getTableInstance: () => tableRefsRef.current.tableInstance, }), [taskListId, navigate, handleFetch, pagination, exportConfig]); const selectionActions = useMemo(() => buildSelectionActions({ exportConfig, - onRestoreMany: (ids) => setRestoreIds(ids), + onBulkRestore: (ids) => setRestoreIds(ids), // ← was onRestoreMany getTableInstance: () => tableRefsRef.current.tableInstance, }), [exportConfig]); @@ -182,7 +184,7 @@ export default function ArchivedTaskTable() { pagination={pagination} loading={loading} onFetch={handleFetch} - onFetchFilterData={() => []} + onFetchFilterData={(field) => fetchTaskFieldValues(taskListId, field)} onRefsReady={handleRefsReady} renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => ( !v && setRestoreIds(null)} ids={restoreIds ?? []} entityLabel="Task" - onRestore={(ids) => bulkRestoreTasks(taskListId, ids)} + onRestore={({ ids }) => bulkRestoreTasks(taskListId, ids)} loading={loading} onSuccess={handleSuccess} /> diff --git a/src/modules/admin/components/task/TaskListTable.jsx b/src/modules/admin/components/task/TaskListTable.jsx index 03847a8..ffd9205 100644 --- a/src/modules/admin/components/task/TaskListTable.jsx +++ b/src/modules/admin/components/task/TaskListTable.jsx @@ -72,12 +72,12 @@ export default function TaskListTable() { }; // ── Export config ───────────────────────────────────────────────────────── - const exportConfig = { + const exportConfig = useMemo(() => ({ allData: taskLists, attributes, filename: `${getTimestamp()}_TaskLists`, sheetName: "Task Lists", - }; + }), [taskLists, attributes]); // ── Row actions ─────────────────────────────────────────────────────────── const rowActions = buildRowActions({ @@ -90,6 +90,7 @@ export default function TaskListTable() { // ── Toolbar ─────────────────────────────────────────────────────────────── const toolbarActions = buildToolbarActions({ fetchTaskLists, fetchArchivedTaskLists, pagination, navigate, + exportConfig, showArchived, onToggleArchived: handleToggleArchived, getFilters: () => tableRefsRef.current.getFilters(), @@ -101,10 +102,8 @@ export default function TaskListTable() { const selectionActions = buildSelectionActions({ exportConfig, showArchived, - onArchive: (row) => setArchiveTarget(row), - onArchiveMany: (ids) => setArchiveIds(ids), - onRestore: (row) => setRestoreTarget(row), - onRestoreMany: (ids) => setRestoreIds(ids), + onBulkArchive: (ids) => setArchiveIds(ids), + onBulkRestore: (ids) => setRestoreIds(ids), getTableInstance: () => tableRefsRef.current.tableInstance, }); @@ -150,7 +149,7 @@ export default function TaskListTable() { entity={archiveTarget} entityLabel="Task List" getName={(r) => r?.name} - onArchive={(r) => archiveTaskList(r?.task_list_id)} + onArchive={(entity) => archiveTaskList(entity?.task_list_id)} loading={loading} onSuccess={handleSuccess} /> @@ -162,7 +161,7 @@ export default function TaskListTable() { entity={restoreTarget} entityLabel="Task List" getName={(r) => r?.name} - onRestore={(r) => restoreTaskList(r?.task_list_id)} + onRestore={(entity) => restoreTaskList(entity?.task_list_id)} loading={loading} onSuccess={handleSuccess} /> @@ -173,7 +172,7 @@ export default function TaskListTable() { onOpenChange={(v) => !v && setArchiveIds(null)} ids={archiveIds ?? []} entityLabel="Task List" - onArchive={(ids) => bulkArchiveTaskLists(ids)} + onArchive={({ ids }) => bulkArchiveTaskLists(ids)} loading={loading} onSuccess={handleSuccess} /> @@ -184,7 +183,7 @@ export default function TaskListTable() { onOpenChange={(v) => !v && setRestoreIds(null)} ids={restoreIds ?? []} entityLabel="Task List" - onRestore={(ids) => bulkRestoreTaskLists(ids)} + onRestore={({ ids }) => bulkRestoreTaskLists(ids)} loading={loading} onSuccess={handleSuccess} /> diff --git a/src/modules/admin/config/task_list/archive/selection.config.jsx b/src/modules/admin/config/task_list/archive/selection.config.jsx index 11bd773..3053a1a 100644 --- a/src/modules/admin/config/task_list/archive/selection.config.jsx +++ b/src/modules/admin/config/task_list/archive/selection.config.jsx @@ -1,31 +1,32 @@ -import { RotateCcw } from "lucide-react"; +import { Download, RotateCcw } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -import { Download } from "lucide-react"; export function buildSelectionActions({ exportConfig, - onRestoreMany, + onBulkRestore, getTableInstance, }) { return [ { key: "export-selected", - label: "Export Selected", - icon: , - onClick: () => + label: "Export", + icon: , + onClick: (rows, table) => exportTableToExcel({ ...exportConfig, - tableInstance: getTableInstance?.(), - selectedOnly: true, + selectedRows: rows, + tableInstance: table ?? getTableInstance?.(), }), }, { - key: "bulk-restore", + key: "restore-selected", label: "Restore Selected", - icon: , - variant: "outline", - onClick: (selectedRows) => - onRestoreMany(selectedRows.map((r) => r.task_list_id)), + icon: , + onClick: (rows) => { + const ids = rows.map((r) => r.task_list_id).filter(Boolean); + if (!ids.length) return; + onBulkRestore?.(ids); + }, }, ]; } \ No newline at end of file diff --git a/src/modules/admin/config/task_list/selection.config.jsx b/src/modules/admin/config/task_list/selection.config.jsx index 3543fe2..47b32a4 100644 --- a/src/modules/admin/config/task_list/selection.config.jsx +++ b/src/modules/admin/config/task_list/selection.config.jsx @@ -39,7 +39,7 @@ export function buildSelectionActions({ ), className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", onClick: (rows) => { - const ids = rows.map((r) => r.task_id).filter(Boolean); + const ids = rows.map((r) => r.task_list_id).filter(Boolean); if (!ids.length) return; showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids); }, diff --git a/src/modules/admin/config/task_list/task/archive/selection.config.jsx b/src/modules/admin/config/task_list/task/archive/selection.config.jsx index af85009..3d9938d 100644 --- a/src/modules/admin/config/task_list/task/archive/selection.config.jsx +++ b/src/modules/admin/config/task_list/task/archive/selection.config.jsx @@ -1,34 +1,32 @@ -// config/selection.config.jsx -import { Download, Archive, Trash2 } from "lucide-react"; +import { Download, RotateCcw } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -/** - * @param {Object} deps - * @param {Object} deps.exportConfig { allData, attributes, filename, sheetName } - * @param {Function} deps.archiveUser Archive handler from useManagement - * @param {Function} deps.deleteUser Delete handler from useManagement - */ -export function buildSelectionActions({ exportConfig, archiveUser, archiveUsers, getTableInstance }) { - return [ - { - key: "export-selected", - label: "Export", - icon: , - onClick: (rows, table) => - exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }), - }, - { - key: "archive-selected", - label: "Archive", - icon: , - className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", - onClick: (rows) => { - const ids = rows.map((r) => r.user_id); - ids.length === 1 - ? archiveUser(rows[0]) // opens single dialog - : archiveUsers(ids); // opens bulk dialog - }, - hidden: (rows) => rows.every((r) => r.status === "archived"), - }, - ]; +export function buildSelectionActions({ + exportConfig, + onBulkRestore, + getTableInstance, +}) { + return [ + { + key: "export-selected", + label: "Export", + icon: , + onClick: (rows, table) => + exportTableToExcel({ + ...exportConfig, + selectedRows: rows, + tableInstance: table ?? getTableInstance?.(), + }), + }, + { + key: "restore-selected", + label: "Restore Selected", + icon: , + onClick: (rows) => { + const ids = rows.map((r) => r.task_id).filter(Boolean); + if (!ids.length) return; + onBulkRestore?.(ids); + }, + }, + ]; } \ No newline at end of file diff --git a/src/modules/admin/config/task_list/task/archive/toolbar.config.jsx b/src/modules/admin/config/task_list/task/archive/toolbar.config.jsx index a85b670..131935e 100644 --- a/src/modules/admin/config/task_list/task/archive/toolbar.config.jsx +++ b/src/modules/admin/config/task_list/task/archive/toolbar.config.jsx @@ -1,57 +1,39 @@ -// ─── config/toolbar.config.jsx ──────────────────────────────────────────────── -import { RefreshCw, Download, Plus, Archive } from "lucide-react"; +import { RefreshCw, Download } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -/** - * @param {Object} deps - * @param {Function} deps.fetchTasks - * @param {string} deps.taskId - * @param {Object} deps.pagination - * @param {Object} deps.exportConfig - * @param {Function} deps.navigate - * @param {boolean} deps.showArchived - * @param {Function} deps.onToggleArchived - * @param {Function} deps.getFilters - * @param {Function} deps.getSort - * @param {Function} deps.getTableInstance - */ export function buildToolbarActions({ - fetchTasks, - taskId, - pagination, - exportConfig, - navigate, - showArchived, - onToggleArchived, - getFilters, - getSort, - getTableInstance, + fetchArchivedTasks, + taskListId, + pagination, + exportConfig, + getFilters, + getSort, + getTableInstance, }) { - return [ - { - key: "refresh", - type: "button", - icon: , - label: "Refresh", - onClick: () => - fetchTasks(taskId, { - page: 1, - limit: pagination?.limit ?? 10, - filters: getFilters?.() ?? [], - sort: getSort?.() ?? [], - archived: showArchived, - }), - }, - { - key: "export", - type: "button", - icon: , - label: "Export", - onClick: (table) => - exportTableToExcel({ - ...exportConfig, - tableInstance: table ?? getTableInstance?.(), - }), - }, - ]; + return [ + { + key: "refresh", + type: "button", + icon: , + label: "Refresh", + onClick: () => + fetchArchivedTasks(taskListId, { + page: 1, + limit: pagination?.limit ?? 10, + filters: getFilters?.() ?? [], + sort: getSort?.() ?? [], + }), + }, + { + key: "export", + type: "button", + icon: , + label: "Export", + onClick: (table) => + exportTableToExcel({ + ...exportConfig, + tableInstance: table ?? getTableInstance?.(), + }), + }, + ]; } \ No newline at end of file diff --git a/src/modules/admin/config/task_list/task/selection.config.jsx b/src/modules/admin/config/task_list/task/selection.config.jsx index af85009..b43e466 100644 --- a/src/modules/admin/config/task_list/task/selection.config.jsx +++ b/src/modules/admin/config/task_list/task/selection.config.jsx @@ -1,34 +1,39 @@ -// config/selection.config.jsx -import { Download, Archive, Trash2 } from "lucide-react"; +import { Download, Archive, RotateCcw } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -/** - * @param {Object} deps - * @param {Object} deps.exportConfig { allData, attributes, filename, sheetName } - * @param {Function} deps.archiveUser Archive handler from useManagement - * @param {Function} deps.deleteUser Delete handler from useManagement - */ -export function buildSelectionActions({ exportConfig, archiveUser, archiveUsers, getTableInstance }) { - return [ - { - key: "export-selected", - label: "Export", - icon: , - onClick: (rows, table) => - exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }), - }, - { - key: "archive-selected", - label: "Archive", - icon: , - className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", - onClick: (rows) => { - const ids = rows.map((r) => r.user_id); - ids.length === 1 - ? archiveUser(rows[0]) // opens single dialog - : archiveUsers(ids); // opens bulk dialog - }, - hidden: (rows) => rows.every((r) => r.status === "archived"), - }, - ]; +export function buildSelectionActions({ + exportConfig, + showArchived, + onBulkArchive, + onBulkRestore, + getTableInstance, +}) { + return [ + { + key: "export-selected", + label: "Export", + icon: , + onClick: (rows, table) => + exportTableToExcel({ + ...exportConfig, + selectedRows: rows, + tableInstance: table ?? getTableInstance?.(), + }), + }, + { + key: showArchived ? "restore-selected" : "archive-selected", + label: showArchived ? "Restore" : "Archive", + icon: showArchived ? ( + + ) : ( + + ), + className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", + onClick: (rows) => { + const ids = rows.map((r) => r.task_id).filter(Boolean); + if (!ids.length) return; + showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids); + }, + }, + ]; } \ No newline at end of file diff --git a/src/modules/admin/config/task_list/task/toolbar.config.jsx b/src/modules/admin/config/task_list/task/toolbar.config.jsx index 9103bca..3700598 100644 --- a/src/modules/admin/config/task_list/task/toolbar.config.jsx +++ b/src/modules/admin/config/task_list/task/toolbar.config.jsx @@ -1,76 +1,63 @@ -// ─── config/toolbar.config.jsx ──────────────────────────────────────────────── import { RefreshCw, Download, Plus, Archive } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -/** - * @param {Object} deps - * @param {Function} deps.fetchTasks - * @param {string} deps.taskListId - * @param {Object} deps.pagination - * @param {Object} deps.exportConfig - * @param {Function} deps.navigate - * @param {boolean} deps.showArchived - * @param {Function} deps.onToggleArchived - * @param {Function} deps.getFilters - * @param {Function} deps.getSort - * @param {Function} deps.getTableInstance - */ export function buildToolbarActions({ - fetchTasks, - taskListId, - pagination, - exportConfig, - navigate, - showArchived, - onToggleArchived, - getFilters, - getSort, - getTableInstance, + fetchTasks, + fetchArchivedTasks, + taskListId, + pagination, + exportConfig, + navigate, + showArchived, + onToggleArchived, + getFilters, + getSort, + getTableInstance, }) { - return [ - { - key: "refresh", - type: "button", - icon: , - label: "Refresh", - onClick: () => - fetchTasks(taskId, { - page: 1, - limit: pagination?.limit ?? 10, - filters: getFilters?.() ?? [], - sort: getSort?.() ?? [], - archived: showArchived, - }), - }, - { - key: "export", - type: "button", - icon: , - label: "Export", - onClick: (table) => - exportTableToExcel({ - ...exportConfig, - tableInstance: table ?? getTableInstance?.(), - }), - }, - { - key: "add-task", - type: "button", - icon: , - label: "Create Task", - variant: "default", - className: "text-primary-foreground", - onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/create`), - }, - { - key: "toggle-archived-task", - type: "button", - icon: , - label: showArchived ? "Active Tasks" : "Archived Tasks", - variant: "secondary", - className: "border border-border", - // onClick: onToggleArchived, - onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/archived`), - }, - ]; + return [ + { + key: "refresh", + type: "button", + icon: , + label: "Refresh", + onClick: () => { + const fetcher = showArchived ? fetchArchivedTasks : fetchTasks; + fetcher(taskListId, { + page: 1, + limit: pagination?.limit ?? 10, + filters: getFilters?.() ?? [], + sort: getSort?.() ?? [], + }); + }, + }, + { + key: "export", + type: "button", + icon: , + label: "Export", + onClick: (table) => + exportTableToExcel({ + ...exportConfig, + tableInstance: table ?? getTableInstance?.(), + }), + }, + { + key: "add-task", + type: "button", + icon: , + label: "Create Task", + variant: "default", + className: "text-primary-foreground", + onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/create`), + }, + { + key: "toggle-archived-task", + type: "button", + icon: , + label: showArchived ? "Active Tasks" : "Archived Tasks", + variant: "secondary", + className: "border border-border", + onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/archived`), + }, + ]; } \ No newline at end of file diff --git a/src/modules/admin/config/task_list/toolbar.config.jsx b/src/modules/admin/config/task_list/toolbar.config.jsx index e4e608f..3305c07 100644 --- a/src/modules/admin/config/task_list/toolbar.config.jsx +++ b/src/modules/admin/config/task_list/toolbar.config.jsx @@ -1,24 +1,10 @@ -// ─── config/toolbar.config.jsx ──────────────────────────────────────────────── +// ─── config/task_list/toolbar.config.jsx ───────────────────────────────────── import { RefreshCw, Download, Plus, Archive } from "lucide-react"; import { exportTableToExcel } from "@/utils/excel.util"; -/** - * @param {Object} deps - * @param {Function} deps.fetchTasks - * @param {string} deps.taskListId - * @param {Object} deps.pagination - * @param {Object} deps.exportConfig - * @param {Function} deps.navigate - * @param {boolean} deps.showArchived - * @param {Function} deps.onToggleArchived - * @param {Function} deps.getFilters - * @param {Function} deps.getSort - * @param {Function} deps.getTableInstance - */ export function buildToolbarActions({ - fetchTasks, + fetchTaskLists, fetchArchivedTaskLists, - taskListId, pagination, exportConfig, navigate, @@ -34,14 +20,15 @@ export function buildToolbarActions({ type: "button", icon: , label: "Refresh", - onClick: () => - fetchTasks(taskListId, { + onClick: () => { + const fetcher = showArchived ? fetchArchivedTaskLists : fetchTaskLists; + fetcher({ page: 1, limit: pagination?.limit ?? 10, filters: getFilters?.() ?? [], sort: getSort?.() ?? [], - archived: showArchived, - }), + }); + }, }, { key: "export", @@ -55,7 +42,7 @@ export function buildToolbarActions({ }), }, { - key: "add-task", + key: "add-task-list", type: "button", icon: , label: "Create Task List", @@ -64,10 +51,10 @@ export function buildToolbarActions({ onClick: () => navigate(`/admin/taskList/create`), }, { - key: "toggle-archived-task", + key: "toggle-archived", type: "button", icon: , - label: showArchived ? "Active Task Lists" : "Archived Task List", + label: showArchived ? "Active Task Lists" : "Archived Task Lists", variant: "secondary", className: "border border-border", onClick: () => navigate("/admin/taskList/archived"), diff --git a/src/modules/admin/pages/task_list/task/Tasks.jsx b/src/modules/admin/pages/task_list/task/Tasks.jsx index 0a3c4c1..638b70f 100644 --- a/src/modules/admin/pages/task_list/task/Tasks.jsx +++ b/src/modules/admin/pages/task_list/task/Tasks.jsx @@ -4,6 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { useAdminTask } from '@/contexts/AdminTaskContext'; import DataTable from '@/components/generic/Table/DataTable'; +import { FilterSheet } from "@/components/generic/Sheet/FilterSheet"; import { ArchiveDialog } from '@/components/generic/Dialogs/ArchiveDialog'; import { RestoreDialog } from '@/components/generic/Dialogs/RestoreDialog'; import { Button } from '@/components/ui/button'; @@ -23,6 +24,7 @@ import { buildDataColumns, columnPinning } from '@/modules/admin/config/task_lis import { buildToolbarActions } from '@/modules/admin/config/task_list/task/toolbar.config'; import { buildSelectionActions } from '@/modules/admin/config/task_list/task/selection.config'; import { buildRowActions } from '@/modules/admin/config/task_list/task/rowActions.config'; +import { getTimestamp } from '@/utils/timestamp.util'; export default function Tasks() { const navigate = useNavigate(); @@ -81,20 +83,30 @@ export default function Tasks() { }); }; - const rowActions = useMemo(() => buildRowActions({ + const exportConfig = useMemo(() => ({ + allData: tasks, + attributes, + filename: `${getTimestamp()}_Tasks`, + sheetName: "Tasks", + }), [tasks, attributes]); + + const rowActions = buildRowActions({ navigate, onArchive: (row) => setArchiveTarget(row), onRestore: (row) => setRestoreTarget(row), showArchived, - }), [navigate, showArchived]); + }); const toolbarActions = buildToolbarActions({ - fetchTasks, fetchArchivedTasks, taskListId, pagination, navigate, + fetchTasks, fetchArchivedTasks, taskListId, + pagination, navigate, exportConfig, showArchived, onToggleArchived: handleToggleArchived, getFilters: () => tableRefsRef.current.getFilters(), getSort: () => tableRefsRef.current.getSort(), + getTableInstance: () => tableRefsRef.current.tableInstance, }); + // ── Selection ───────────────────────────────────────────────────────────── const selectionActions = buildSelectionActions({ showArchived, onBulkArchive: (ids) => setBulkArchiveIds(ids), @@ -214,11 +226,21 @@ export default function Tasks() { pagination={pagination} loading={loading} onFetch={handleFetch} - onFetchFilterData={fetchTaskFieldValues} + onFetchFilterData={(field) => fetchTaskFieldValues(taskListId, field)} toolbarActions={toolbarActions} selectionActions={selectionActions} columnPinning={columnPinning} onRefsReady={handleRefsReady} + renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => ( + + )} /> {/* ── All Groups Dialog ─────────────────────────────────────────── */} @@ -251,11 +273,9 @@ export default function Tasks() { entity={archiveTarget} entityLabel="Task" getName={(r) => r?.name} - onArchive={async (r) => { - const ok = await archiveTask(taskListId, r?.task_id); - if (ok) { setArchiveTarget(null); afterMutation(); } - }} + onArchive={(entity) => archiveTask(taskListId, entity?.task_id)} loading={loading} + onSuccess={afterMutation} /> {/* ── Single restore ────────────────────────────────────────────── */} @@ -265,39 +285,31 @@ export default function Tasks() { entity={restoreTarget} entityLabel="Task" getName={(r) => r?.name} - onRestore={async (r) => { - const ok = await restoreTask(taskListId, r?.task_id); - if (ok) { setRestoreTarget(null); afterMutation(); } - }} + onRestore={(entity) => restoreTask(taskListId, entity?.task_id)} loading={loading} + onSuccess={afterMutation} /> {/* ── Bulk archive ──────────────────────────────────────────────── */} !v && setBulkArchiveIds(null)} - entity={bulkArchiveIds} - entityLabel={`${bulkArchiveIds?.length ?? 0} Task(s)`} - getName={() => `${bulkArchiveIds?.length ?? 0} task(s)`} - onArchive={async () => { - const ok = await bulkArchiveTasks(taskListId, bulkArchiveIds); - if (ok) { setBulkArchiveIds(null); afterMutation(); } - }} + ids={bulkArchiveIds ?? []} + entityLabel="Task" + onArchive={({ ids }) => bulkArchiveTasks(taskListId, ids)} loading={loading} + onSuccess={afterMutation} /> {/* ── Bulk restore ──────────────────────────────────────────────── */} !v && setBulkRestoreIds(null)} - entity={bulkRestoreIds} - entityLabel={`${bulkRestoreIds?.length ?? 0} Task(s)`} - getName={() => `${bulkRestoreIds?.length ?? 0} task(s)`} - onRestore={async () => { - const ok = await bulkRestoreTasks(taskListId, bulkRestoreIds); - if (ok) { setBulkRestoreIds(null); afterMutation(); } - }} + ids={bulkRestoreIds ?? []} + entityLabel="Task" + onRestore={({ ids }) => bulkRestoreTasks(taskListId, ids)} loading={loading} + onSuccess={afterMutation} />