This commit is contained in:
rgrgogu
2026-05-23 11:49:52 +08:00
11 changed files with 243 additions and 270 deletions
@@ -73,7 +73,7 @@ export default function ArchiveTaskListTable() {
const selectionActions = buildSelectionActions({ const selectionActions = buildSelectionActions({
exportConfig, exportConfig,
onRestoreMany: (ids) => setRestoreIds(ids), onBulkRestore: (ids) => setRestoreIds(ids),
getTableInstance: () => tableRefsRef.current.tableInstance, getTableInstance: () => tableRefsRef.current.tableInstance,
}); });
@@ -129,7 +129,7 @@ export default function ArchiveTaskListTable() {
onOpenChange={(v) => !v && setRestoreIds(null)} onOpenChange={(v) => !v && setRestoreIds(null)}
ids={restoreIds ?? []} ids={restoreIds ?? []}
entityLabel="Task List" entityLabel="Task List"
onRestore={(ids) => bulkRestoreTaskLists(ids)} onRestore={({ ids }) => bulkRestoreTaskLists(ids)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -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 { useNavigate, useParams } from "react-router-dom";
import { useAdminTask } from "@/contexts/AdminTaskContext"; import { useAdminTask } from "@/contexts/AdminTaskContext";
@@ -31,7 +31,7 @@ export default function ArchivedTaskTable() {
const { const {
taskList, tasks, attributes, pagination, loading, taskList, tasks, attributes, pagination, loading,
fetchArchivedTasks, fetchTaskList, fetchArchivedTasks, fetchTaskFieldValues,
restoreTask, restoreTask,
bulkRestoreTasks, bulkRestoreTasks,
} = useAdminTask(); } = useAdminTask();
@@ -47,6 +47,11 @@ export default function ArchivedTaskTable() {
tableInstance: null, tableInstance: null,
}); });
useEffect(() => {
fetchTaskList(taskListId);
fetchArchivedTasks(taskListId, { page: 1, limit: 10 });
}, [taskListId]);
const handleRefsReady = (refs) => { const handleRefsReady = (refs) => {
tableRefsRef.current = refs; tableRefsRef.current = refs;
}; };
@@ -82,19 +87,16 @@ export default function ArchivedTaskTable() {
}), [navigate]); }), [navigate]);
const toolbarActions = useMemo(() => buildToolbarActions({ const toolbarActions = useMemo(() => buildToolbarActions({
taskListId, fetchArchivedTasks: handleFetch, taskListId,
navigate, navigate, pagination, exportConfig,
getSort: () => tableRefsRef.current.getSort(),
fetchArchivedTasks: handleFetch,
pagination,
exportConfig,
getFilters: () => tableRefsRef.current.getFilters(), getFilters: () => tableRefsRef.current.getFilters(),
getSort: () => tableRefsRef.current.getSort(),
getTableInstance: () => tableRefsRef.current.tableInstance, getTableInstance: () => tableRefsRef.current.tableInstance,
}), [taskListId, navigate, handleFetch, pagination, exportConfig]); }), [taskListId, navigate, handleFetch, pagination, exportConfig]);
const selectionActions = useMemo(() => buildSelectionActions({ const selectionActions = useMemo(() => buildSelectionActions({
exportConfig, exportConfig,
onRestoreMany: (ids) => setRestoreIds(ids), onBulkRestore: (ids) => setRestoreIds(ids), // ← was onRestoreMany
getTableInstance: () => tableRefsRef.current.tableInstance, getTableInstance: () => tableRefsRef.current.tableInstance,
}), [exportConfig]); }), [exportConfig]);
@@ -182,7 +184,7 @@ export default function ArchivedTaskTable() {
pagination={pagination} pagination={pagination}
loading={loading} loading={loading}
onFetch={handleFetch} onFetch={handleFetch}
onFetchFilterData={() => []} onFetchFilterData={(field) => fetchTaskFieldValues(taskListId, field)}
onRefsReady={handleRefsReady} onRefsReady={handleRefsReady}
renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => ( renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => (
<FilterSheet <FilterSheet
@@ -219,7 +221,7 @@ export default function ArchivedTaskTable() {
onOpenChange={(v) => !v && setRestoreIds(null)} onOpenChange={(v) => !v && setRestoreIds(null)}
ids={restoreIds ?? []} ids={restoreIds ?? []}
entityLabel="Task" entityLabel="Task"
onRestore={(ids) => bulkRestoreTasks(taskListId, ids)} onRestore={({ ids }) => bulkRestoreTasks(taskListId, ids)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -72,12 +72,12 @@ export default function TaskListTable() {
}; };
// ── Export config ───────────────────────────────────────────────────────── // ── Export config ─────────────────────────────────────────────────────────
const exportConfig = { const exportConfig = useMemo(() => ({
allData: taskLists, allData: taskLists,
attributes, attributes,
filename: `${getTimestamp()}_TaskLists`, filename: `${getTimestamp()}_TaskLists`,
sheetName: "Task Lists", sheetName: "Task Lists",
}; }), [taskLists, attributes]);
// ── Row actions ─────────────────────────────────────────────────────────── // ── Row actions ───────────────────────────────────────────────────────────
const rowActions = buildRowActions({ const rowActions = buildRowActions({
@@ -90,6 +90,7 @@ export default function TaskListTable() {
// ── Toolbar ─────────────────────────────────────────────────────────────── // ── Toolbar ───────────────────────────────────────────────────────────────
const toolbarActions = buildToolbarActions({ const toolbarActions = buildToolbarActions({
fetchTaskLists, fetchArchivedTaskLists, pagination, navigate, fetchTaskLists, fetchArchivedTaskLists, pagination, navigate,
exportConfig,
showArchived, showArchived,
onToggleArchived: handleToggleArchived, onToggleArchived: handleToggleArchived,
getFilters: () => tableRefsRef.current.getFilters(), getFilters: () => tableRefsRef.current.getFilters(),
@@ -101,10 +102,8 @@ export default function TaskListTable() {
const selectionActions = buildSelectionActions({ const selectionActions = buildSelectionActions({
exportConfig, exportConfig,
showArchived, showArchived,
onArchive: (row) => setArchiveTarget(row), onBulkArchive: (ids) => setArchiveIds(ids),
onArchiveMany: (ids) => setArchiveIds(ids), onBulkRestore: (ids) => setRestoreIds(ids),
onRestore: (row) => setRestoreTarget(row),
onRestoreMany: (ids) => setRestoreIds(ids),
getTableInstance: () => tableRefsRef.current.tableInstance, getTableInstance: () => tableRefsRef.current.tableInstance,
}); });
@@ -150,7 +149,7 @@ export default function TaskListTable() {
entity={archiveTarget} entity={archiveTarget}
entityLabel="Task List" entityLabel="Task List"
getName={(r) => r?.name} getName={(r) => r?.name}
onArchive={(r) => archiveTaskList(r?.task_list_id)} onArchive={(entity) => archiveTaskList(entity?.task_list_id)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -162,7 +161,7 @@ export default function TaskListTable() {
entity={restoreTarget} entity={restoreTarget}
entityLabel="Task List" entityLabel="Task List"
getName={(r) => r?.name} getName={(r) => r?.name}
onRestore={(r) => restoreTaskList(r?.task_list_id)} onRestore={(entity) => restoreTaskList(entity?.task_list_id)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -173,7 +172,7 @@ export default function TaskListTable() {
onOpenChange={(v) => !v && setArchiveIds(null)} onOpenChange={(v) => !v && setArchiveIds(null)}
ids={archiveIds ?? []} ids={archiveIds ?? []}
entityLabel="Task List" entityLabel="Task List"
onArchive={(ids) => bulkArchiveTaskLists(ids)} onArchive={({ ids }) => bulkArchiveTaskLists(ids)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -184,7 +183,7 @@ export default function TaskListTable() {
onOpenChange={(v) => !v && setRestoreIds(null)} onOpenChange={(v) => !v && setRestoreIds(null)}
ids={restoreIds ?? []} ids={restoreIds ?? []}
entityLabel="Task List" entityLabel="Task List"
onRestore={(ids) => bulkRestoreTaskLists(ids)} onRestore={({ ids }) => bulkRestoreTaskLists(ids)}
loading={loading} loading={loading}
onSuccess={handleSuccess} onSuccess={handleSuccess}
/> />
@@ -1,31 +1,32 @@
import { RotateCcw } from "lucide-react"; import { Download, RotateCcw } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; import { exportTableToExcel } from "@/utils/excel.util";
import { Download } from "lucide-react";
export function buildSelectionActions({ export function buildSelectionActions({
exportConfig, exportConfig,
onRestoreMany, onBulkRestore,
getTableInstance, getTableInstance,
}) { }) {
return [ return [
{ {
key: "export-selected", key: "export-selected",
label: "Export Selected", label: "Export",
icon: <Download className="size-4" />, icon: <Download className="h-3.5 w-3.5" />,
onClick: () => onClick: (rows, table) =>
exportTableToExcel({ exportTableToExcel({
...exportConfig, ...exportConfig,
tableInstance: getTableInstance?.(), selectedRows: rows,
selectedOnly: true, tableInstance: table ?? getTableInstance?.(),
}), }),
}, },
{ {
key: "bulk-restore", key: "restore-selected",
label: "Restore Selected", label: "Restore Selected",
icon: <RotateCcw className="size-4" />, icon: <RotateCcw className="h-3.5 w-3.5" />,
variant: "outline", onClick: (rows) => {
onClick: (selectedRows) => const ids = rows.map((r) => r.task_list_id).filter(Boolean);
onRestoreMany(selectedRows.map((r) => r.task_list_id)), if (!ids.length) return;
onBulkRestore?.(ids);
},
}, },
]; ];
} }
@@ -39,7 +39,7 @@ export function buildSelectionActions({
), ),
className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive",
onClick: (rows) => { 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; if (!ids.length) return;
showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids); showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids);
}, },
@@ -1,34 +1,32 @@
// config/selection.config.jsx import { Download, RotateCcw } from "lucide-react";
import { Download, Archive, Trash2 } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; import { exportTableToExcel } from "@/utils/excel.util";
/** export function buildSelectionActions({
* @param {Object} deps exportConfig,
* @param {Object} deps.exportConfig { allData, attributes, filename, sheetName } onBulkRestore,
* @param {Function} deps.archiveUser Archive handler from useManagement getTableInstance,
* @param {Function} deps.deleteUser Delete handler from useManagement }) {
*/
export function buildSelectionActions({ exportConfig, archiveUser, archiveUsers, getTableInstance }) {
return [ return [
{ {
key: "export-selected", key: "export-selected",
label: "Export", label: "Export",
icon: <Download className="h-3.5 w-3.5" />, icon: <Download className="h-3.5 w-3.5" />,
onClick: (rows, table) => onClick: (rows, table) =>
exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }), exportTableToExcel({
...exportConfig,
selectedRows: rows,
tableInstance: table ?? getTableInstance?.(),
}),
}, },
{ {
key: "archive-selected", key: "restore-selected",
label: "Archive", label: "Restore Selected",
icon: <Archive className="h-3.5 w-3.5" />, icon: <RotateCcw className="h-3.5 w-3.5" />,
className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive",
onClick: (rows) => { onClick: (rows) => {
const ids = rows.map((r) => r.user_id); const ids = rows.map((r) => r.task_id).filter(Boolean);
ids.length === 1 if (!ids.length) return;
? archiveUser(rows[0]) // opens single dialog onBulkRestore?.(ids);
: archiveUsers(ids); // opens bulk dialog
}, },
hidden: (rows) => rows.every((r) => r.status === "archived"),
}, },
]; ];
} }
@@ -1,28 +1,11 @@
// ─── config/toolbar.config.jsx ──────────────────────────────────────────────── import { RefreshCw, Download } from "lucide-react";
import { RefreshCw, Download, Plus, Archive } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; 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({ export function buildToolbarActions({
fetchTasks, fetchArchivedTasks,
taskId, taskListId,
pagination, pagination,
exportConfig, exportConfig,
navigate,
showArchived,
onToggleArchived,
getFilters, getFilters,
getSort, getSort,
getTableInstance, getTableInstance,
@@ -34,12 +17,11 @@ export function buildToolbarActions({
icon: <RefreshCw className="size-4" />, icon: <RefreshCw className="size-4" />,
label: "Refresh", label: "Refresh",
onClick: () => onClick: () =>
fetchTasks(taskId, { fetchArchivedTasks(taskListId, {
page: 1, page: 1,
limit: pagination?.limit ?? 10, limit: pagination?.limit ?? 10,
filters: getFilters?.() ?? [], filters: getFilters?.() ?? [],
sort: getSort?.() ?? [], sort: getSort?.() ?? [],
archived: showArchived,
}), }),
}, },
{ {
@@ -1,34 +1,39 @@
// config/selection.config.jsx import { Download, Archive, RotateCcw } from "lucide-react";
import { Download, Archive, Trash2 } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; import { exportTableToExcel } from "@/utils/excel.util";
/** export function buildSelectionActions({
* @param {Object} deps exportConfig,
* @param {Object} deps.exportConfig { allData, attributes, filename, sheetName } showArchived,
* @param {Function} deps.archiveUser Archive handler from useManagement onBulkArchive,
* @param {Function} deps.deleteUser Delete handler from useManagement onBulkRestore,
*/ getTableInstance,
export function buildSelectionActions({ exportConfig, archiveUser, archiveUsers, getTableInstance }) { }) {
return [ return [
{ {
key: "export-selected", key: "export-selected",
label: "Export", label: "Export",
icon: <Download className="h-3.5 w-3.5" />, icon: <Download className="h-3.5 w-3.5" />,
onClick: (rows, table) => onClick: (rows, table) =>
exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }), exportTableToExcel({
...exportConfig,
selectedRows: rows,
tableInstance: table ?? getTableInstance?.(),
}),
}, },
{ {
key: "archive-selected", key: showArchived ? "restore-selected" : "archive-selected",
label: "Archive", label: showArchived ? "Restore" : "Archive",
icon: <Archive className="h-3.5 w-3.5" />, icon: showArchived ? (
<RotateCcw className="h-3.5 w-3.5" />
) : (
<Archive className="h-3.5 w-3.5" />
),
className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive", className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive",
onClick: (rows) => { onClick: (rows) => {
const ids = rows.map((r) => r.user_id); const ids = rows.map((r) => r.task_id).filter(Boolean);
ids.length === 1 if (!ids.length) return;
? archiveUser(rows[0]) // opens single dialog showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids);
: archiveUsers(ids); // opens bulk dialog
}, },
hidden: (rows) => rows.every((r) => r.status === "archived"),
}, },
]; ];
} }
@@ -1,22 +1,9 @@
// ─── config/toolbar.config.jsx ────────────────────────────────────────────────
import { RefreshCw, Download, Plus, Archive } from "lucide-react"; import { RefreshCw, Download, Plus, Archive } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; 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({ export function buildToolbarActions({
fetchTasks, fetchTasks,
fetchArchivedTasks,
taskListId, taskListId,
pagination, pagination,
exportConfig, exportConfig,
@@ -33,14 +20,15 @@ export function buildToolbarActions({
type: "button", type: "button",
icon: <RefreshCw className="size-4" />, icon: <RefreshCw className="size-4" />,
label: "Refresh", label: "Refresh",
onClick: () => onClick: () => {
fetchTasks(taskId, { const fetcher = showArchived ? fetchArchivedTasks : fetchTasks;
fetcher(taskListId, {
page: 1, page: 1,
limit: pagination?.limit ?? 10, limit: pagination?.limit ?? 10,
filters: getFilters?.() ?? [], filters: getFilters?.() ?? [],
sort: getSort?.() ?? [], sort: getSort?.() ?? [],
archived: showArchived, });
}), },
}, },
{ {
key: "export", key: "export",
@@ -69,7 +57,6 @@ export function buildToolbarActions({
label: showArchived ? "Active Tasks" : "Archived Tasks", label: showArchived ? "Active Tasks" : "Archived Tasks",
variant: "secondary", variant: "secondary",
className: "border border-border", className: "border border-border",
// onClick: onToggleArchived,
onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/archived`), onClick: () => navigate(`/admin/taskList/${taskListId}/tasks/archived`),
}, },
]; ];
@@ -1,24 +1,10 @@
// ─── config/toolbar.config.jsx ──────────────────────────────────────────────── // ─── config/task_list/toolbar.config.jsx ─────────────────────────────────────
import { RefreshCw, Download, Plus, Archive } from "lucide-react"; import { RefreshCw, Download, Plus, Archive } from "lucide-react";
import { exportTableToExcel } from "@/utils/excel.util"; 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({ export function buildToolbarActions({
fetchTasks, fetchTaskLists,
fetchArchivedTaskLists, fetchArchivedTaskLists,
taskListId,
pagination, pagination,
exportConfig, exportConfig,
navigate, navigate,
@@ -34,14 +20,15 @@ export function buildToolbarActions({
type: "button", type: "button",
icon: <RefreshCw className="size-4" />, icon: <RefreshCw className="size-4" />,
label: "Refresh", label: "Refresh",
onClick: () => onClick: () => {
fetchTasks(taskListId, { const fetcher = showArchived ? fetchArchivedTaskLists : fetchTaskLists;
fetcher({
page: 1, page: 1,
limit: pagination?.limit ?? 10, limit: pagination?.limit ?? 10,
filters: getFilters?.() ?? [], filters: getFilters?.() ?? [],
sort: getSort?.() ?? [], sort: getSort?.() ?? [],
archived: showArchived, });
}), },
}, },
{ {
key: "export", key: "export",
@@ -55,7 +42,7 @@ export function buildToolbarActions({
}), }),
}, },
{ {
key: "add-task", key: "add-task-list",
type: "button", type: "button",
icon: <Plus className="size-4" />, icon: <Plus className="size-4" />,
label: "Create Task List", label: "Create Task List",
@@ -64,10 +51,10 @@ export function buildToolbarActions({
onClick: () => navigate(`/admin/taskList/create`), onClick: () => navigate(`/admin/taskList/create`),
}, },
{ {
key: "toggle-archived-task", key: "toggle-archived",
type: "button", type: "button",
icon: <Archive className="size-4" />, icon: <Archive className="size-4" />,
label: showArchived ? "Active Task Lists" : "Archived Task List", label: showArchived ? "Active Task Lists" : "Archived Task Lists",
variant: "secondary", variant: "secondary",
className: "border border-border", className: "border border-border",
onClick: () => navigate("/admin/taskList/archived"), onClick: () => navigate("/admin/taskList/archived"),
@@ -4,6 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom';
import { useAdminTask } from '@/contexts/AdminTaskContext'; import { useAdminTask } from '@/contexts/AdminTaskContext';
import DataTable from '@/components/generic/Table/DataTable'; import DataTable from '@/components/generic/Table/DataTable';
import { FilterSheet } from "@/components/generic/Sheet/FilterSheet";
import { ArchiveDialog } from '@/components/generic/Dialogs/ArchiveDialog'; import { ArchiveDialog } from '@/components/generic/Dialogs/ArchiveDialog';
import { RestoreDialog } from '@/components/generic/Dialogs/RestoreDialog'; import { RestoreDialog } from '@/components/generic/Dialogs/RestoreDialog';
import { Button } from '@/components/ui/button'; 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 { buildToolbarActions } from '@/modules/admin/config/task_list/task/toolbar.config';
import { buildSelectionActions } from '@/modules/admin/config/task_list/task/selection.config'; import { buildSelectionActions } from '@/modules/admin/config/task_list/task/selection.config';
import { buildRowActions } from '@/modules/admin/config/task_list/task/rowActions.config'; import { buildRowActions } from '@/modules/admin/config/task_list/task/rowActions.config';
import { getTimestamp } from '@/utils/timestamp.util';
export default function Tasks() { export default function Tasks() {
const navigate = useNavigate(); 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, navigate,
onArchive: (row) => setArchiveTarget(row), onArchive: (row) => setArchiveTarget(row),
onRestore: (row) => setRestoreTarget(row), onRestore: (row) => setRestoreTarget(row),
showArchived, showArchived,
}), [navigate, showArchived]); });
const toolbarActions = buildToolbarActions({ const toolbarActions = buildToolbarActions({
fetchTasks, fetchArchivedTasks, taskListId, pagination, navigate, fetchTasks, fetchArchivedTasks, taskListId,
pagination, navigate, exportConfig,
showArchived, onToggleArchived: handleToggleArchived, showArchived, onToggleArchived: handleToggleArchived,
getFilters: () => tableRefsRef.current.getFilters(), getFilters: () => tableRefsRef.current.getFilters(),
getSort: () => tableRefsRef.current.getSort(), getSort: () => tableRefsRef.current.getSort(),
getTableInstance: () => tableRefsRef.current.tableInstance,
}); });
// ── Selection ─────────────────────────────────────────────────────────────
const selectionActions = buildSelectionActions({ const selectionActions = buildSelectionActions({
showArchived, showArchived,
onBulkArchive: (ids) => setBulkArchiveIds(ids), onBulkArchive: (ids) => setBulkArchiveIds(ids),
@@ -214,11 +226,21 @@ export default function Tasks() {
pagination={pagination} pagination={pagination}
loading={loading} loading={loading}
onFetch={handleFetch} onFetch={handleFetch}
onFetchFilterData={fetchTaskFieldValues} onFetchFilterData={(field) => fetchTaskFieldValues(taskListId, field)}
toolbarActions={toolbarActions} toolbarActions={toolbarActions}
selectionActions={selectionActions} selectionActions={selectionActions}
columnPinning={columnPinning} columnPinning={columnPinning}
onRefsReady={handleRefsReady} onRefsReady={handleRefsReady}
renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => (
<FilterSheet
open={open}
onOpenChange={onOpenChange}
column={column}
attr={attr}
data={data}
loading={loading}
/>
)}
/> />
{/* ── All Groups Dialog ─────────────────────────────────────────── */} {/* ── All Groups Dialog ─────────────────────────────────────────── */}
@@ -251,11 +273,9 @@ export default function Tasks() {
entity={archiveTarget} entity={archiveTarget}
entityLabel="Task" entityLabel="Task"
getName={(r) => r?.name} getName={(r) => r?.name}
onArchive={async (r) => { onArchive={(entity) => archiveTask(taskListId, entity?.task_id)}
const ok = await archiveTask(taskListId, r?.task_id);
if (ok) { setArchiveTarget(null); afterMutation(); }
}}
loading={loading} loading={loading}
onSuccess={afterMutation}
/> />
{/* ── Single restore ────────────────────────────────────────────── */} {/* ── Single restore ────────────────────────────────────────────── */}
@@ -265,39 +285,31 @@ export default function Tasks() {
entity={restoreTarget} entity={restoreTarget}
entityLabel="Task" entityLabel="Task"
getName={(r) => r?.name} getName={(r) => r?.name}
onRestore={async (r) => { onRestore={(entity) => restoreTask(taskListId, entity?.task_id)}
const ok = await restoreTask(taskListId, r?.task_id);
if (ok) { setRestoreTarget(null); afterMutation(); }
}}
loading={loading} loading={loading}
onSuccess={afterMutation}
/> />
{/* ── Bulk archive ──────────────────────────────────────────────── */} {/* ── Bulk archive ──────────────────────────────────────────────── */}
<ArchiveDialog <ArchiveDialog
open={!!bulkArchiveIds} open={!!bulkArchiveIds}
onOpenChange={(v) => !v && setBulkArchiveIds(null)} onOpenChange={(v) => !v && setBulkArchiveIds(null)}
entity={bulkArchiveIds} ids={bulkArchiveIds ?? []}
entityLabel={`${bulkArchiveIds?.length ?? 0} Task(s)`} entityLabel="Task"
getName={() => `${bulkArchiveIds?.length ?? 0} task(s)`} onArchive={({ ids }) => bulkArchiveTasks(taskListId, ids)}
onArchive={async () => {
const ok = await bulkArchiveTasks(taskListId, bulkArchiveIds);
if (ok) { setBulkArchiveIds(null); afterMutation(); }
}}
loading={loading} loading={loading}
onSuccess={afterMutation}
/> />
{/* ── Bulk restore ──────────────────────────────────────────────── */} {/* ── Bulk restore ──────────────────────────────────────────────── */}
<RestoreDialog <RestoreDialog
open={!!bulkRestoreIds} open={!!bulkRestoreIds}
onOpenChange={(v) => !v && setBulkRestoreIds(null)} onOpenChange={(v) => !v && setBulkRestoreIds(null)}
entity={bulkRestoreIds} ids={bulkRestoreIds ?? []}
entityLabel={`${bulkRestoreIds?.length ?? 0} Task(s)`} entityLabel="Task"
getName={() => `${bulkRestoreIds?.length ?? 0} task(s)`} onRestore={({ ids }) => bulkRestoreTasks(taskListId, ids)}
onRestore={async () => {
const ok = await bulkRestoreTasks(taskListId, bulkRestoreIds);
if (ok) { setBulkRestoreIds(null); afterMutation(); }
}}
loading={loading} loading={loading}
onSuccess={afterMutation}
/> />
</div> </div>