mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
Merge branch 'main' of https://github.com/rgrgogu/new_starr_app
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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 }) => (
|
||||
<FilterSheet
|
||||
@@ -219,7 +221,7 @@ export default function ArchivedTaskTable() {
|
||||
onOpenChange={(v) => !v && setRestoreIds(null)}
|
||||
ids={restoreIds ?? []}
|
||||
entityLabel="Task"
|
||||
onRestore={(ids) => bulkRestoreTasks(taskListId, ids)}
|
||||
onRestore={({ ids }) => bulkRestoreTasks(taskListId, ids)}
|
||||
loading={loading}
|
||||
onSuccess={handleSuccess}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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: <Download className="size-4" />,
|
||||
onClick: () =>
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
onClick: (rows, table) =>
|
||||
exportTableToExcel({
|
||||
...exportConfig,
|
||||
tableInstance: getTableInstance?.(),
|
||||
selectedOnly: true,
|
||||
selectedRows: rows,
|
||||
tableInstance: table ?? getTableInstance?.(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "bulk-restore",
|
||||
key: "restore-selected",
|
||||
label: "Restore Selected",
|
||||
icon: <RotateCcw className="size-4" />,
|
||||
variant: "outline",
|
||||
onClick: (selectedRows) =>
|
||||
onRestoreMany(selectedRows.map((r) => r.task_list_id)),
|
||||
icon: <RotateCcw className="h-3.5 w-3.5" />,
|
||||
onClick: (rows) => {
|
||||
const ids = rows.map((r) => r.task_list_id).filter(Boolean);
|
||||
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",
|
||||
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);
|
||||
},
|
||||
|
||||
@@ -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 }) {
|
||||
export function buildSelectionActions({
|
||||
exportConfig,
|
||||
onBulkRestore,
|
||||
getTableInstance,
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
key: "export-selected",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
onClick: (rows, table) =>
|
||||
exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }),
|
||||
exportTableToExcel({
|
||||
...exportConfig,
|
||||
selectedRows: rows,
|
||||
tableInstance: table ?? getTableInstance?.(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "archive-selected",
|
||||
label: "Archive",
|
||||
icon: <Archive className="h-3.5 w-3.5" />,
|
||||
className: "text-destructive border-destructive/40 hover:bg-destructive/10 hover:text-destructive",
|
||||
key: "restore-selected",
|
||||
label: "Restore Selected",
|
||||
icon: <RotateCcw className="h-3.5 w-3.5" />,
|
||||
onClick: (rows) => {
|
||||
const ids = rows.map((r) => r.user_id);
|
||||
ids.length === 1
|
||||
? archiveUser(rows[0]) // opens single dialog
|
||||
: archiveUsers(ids); // opens bulk dialog
|
||||
const ids = rows.map((r) => r.task_id).filter(Boolean);
|
||||
if (!ids.length) return;
|
||||
onBulkRestore?.(ids);
|
||||
},
|
||||
hidden: (rows) => rows.every((r) => r.status === "archived"),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -1,28 +1,11 @@
|
||||
// ─── 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,
|
||||
fetchArchivedTasks,
|
||||
taskListId,
|
||||
pagination,
|
||||
exportConfig,
|
||||
navigate,
|
||||
showArchived,
|
||||
onToggleArchived,
|
||||
getFilters,
|
||||
getSort,
|
||||
getTableInstance,
|
||||
@@ -34,12 +17,11 @@ export function buildToolbarActions({
|
||||
icon: <RefreshCw className="size-4" />,
|
||||
label: "Refresh",
|
||||
onClick: () =>
|
||||
fetchTasks(taskId, {
|
||||
fetchArchivedTasks(taskListId, {
|
||||
page: 1,
|
||||
limit: pagination?.limit ?? 10,
|
||||
filters: getFilters?.() ?? [],
|
||||
sort: getSort?.() ?? [],
|
||||
archived: showArchived,
|
||||
}),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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 }) {
|
||||
export function buildSelectionActions({
|
||||
exportConfig,
|
||||
showArchived,
|
||||
onBulkArchive,
|
||||
onBulkRestore,
|
||||
getTableInstance,
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
key: "export-selected",
|
||||
label: "Export",
|
||||
icon: <Download className="h-3.5 w-3.5" />,
|
||||
onClick: (rows, table) =>
|
||||
exportTableToExcel({ ...exportConfig, selectedRows: rows, tableInstance: table ?? getTableInstance() }),
|
||||
exportTableToExcel({
|
||||
...exportConfig,
|
||||
selectedRows: rows,
|
||||
tableInstance: table ?? getTableInstance?.(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "archive-selected",
|
||||
label: "Archive",
|
||||
icon: <Archive className="h-3.5 w-3.5" />,
|
||||
key: showArchived ? "restore-selected" : "archive-selected",
|
||||
label: showArchived ? "Restore" : "Archive",
|
||||
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",
|
||||
onClick: (rows) => {
|
||||
const ids = rows.map((r) => r.user_id);
|
||||
ids.length === 1
|
||||
? archiveUser(rows[0]) // opens single dialog
|
||||
: archiveUsers(ids); // opens bulk dialog
|
||||
const ids = rows.map((r) => r.task_id).filter(Boolean);
|
||||
if (!ids.length) return;
|
||||
showArchived ? onBulkRestore?.(ids) : onBulkArchive?.(ids);
|
||||
},
|
||||
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 { 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,
|
||||
fetchArchivedTasks,
|
||||
taskListId,
|
||||
pagination,
|
||||
exportConfig,
|
||||
@@ -33,14 +20,15 @@ export function buildToolbarActions({
|
||||
type: "button",
|
||||
icon: <RefreshCw className="size-4" />,
|
||||
label: "Refresh",
|
||||
onClick: () =>
|
||||
fetchTasks(taskId, {
|
||||
onClick: () => {
|
||||
const fetcher = showArchived ? fetchArchivedTasks : fetchTasks;
|
||||
fetcher(taskListId, {
|
||||
page: 1,
|
||||
limit: pagination?.limit ?? 10,
|
||||
filters: getFilters?.() ?? [],
|
||||
sort: getSort?.() ?? [],
|
||||
archived: showArchived,
|
||||
}),
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "export",
|
||||
@@ -69,7 +57,6 @@ export function buildToolbarActions({
|
||||
label: showArchived ? "Active Tasks" : "Archived Tasks",
|
||||
variant: "secondary",
|
||||
className: "border border-border",
|
||||
// onClick: onToggleArchived,
|
||||
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 { 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: <RefreshCw className="size-4" />,
|
||||
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: <Plus className="size-4" />,
|
||||
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: <Archive className="size-4" />,
|
||||
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"),
|
||||
|
||||
@@ -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 }) => (
|
||||
<FilterSheet
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
column={column}
|
||||
attr={attr}
|
||||
data={data}
|
||||
loading={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 ──────────────────────────────────────────────── */}
|
||||
<ArchiveDialog
|
||||
open={!!bulkArchiveIds}
|
||||
onOpenChange={(v) => !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 ──────────────────────────────────────────────── */}
|
||||
<RestoreDialog
|
||||
open={!!bulkRestoreIds}
|
||||
onOpenChange={(v) => !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}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user