UserTasksPage.tsx
2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Workflow user-tasks list page.
//
// Fetches pending human tasks from the embedded workflow engine
// and renders them in a DataTable. Clicking a row navigates to
// the task detail page where the user can complete the task.
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { workflow } from '@/api/client'
import type { UserTaskSummary } from '@/types/api'
import { PageHeader } from '@/components/PageHeader'
import { Loading } from '@/components/Loading'
import { ErrorBox } from '@/components/ErrorBox'
import { DataTable, type Column } from '@/components/DataTable'
import { useT } from '@/i18n/LocaleContext'
export function UserTasksPage() {
const t = useT()
const navigate = useNavigate()
const [rows, setRows] = useState<UserTaskSummary[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
workflow
.listTasks()
.then(setRows)
.catch((e: unknown) => setError(e instanceof Error ? e : new Error(String(e))))
.finally(() => setLoading(false))
}, [])
const columns: Column<UserTaskSummary>[] = [
{
header: 'Task Name',
key: 'taskName',
render: (r) => (
<button
className="text-brand-600 hover:underline"
onClick={() => navigate(`/workflow/tasks/${r.taskId}`)}
>
{r.taskName}
</button>
),
},
{ header: 'Process', key: 'processDefinitionKey' },
{ header: 'Form Key', key: 'formKey', render: (r) => r.formKey ?? '\u2014' },
{ header: 'Created', key: 'createTime' },
{ header: 'Assignee', key: 'assignee', render: (r) => r.assignee ?? '\u2014' },
]
return (
<div>
<PageHeader
title={t('page.tasks.title')}
subtitle={t('page.tasks.subtitle')}
/>
{loading && <Loading />}
{error && <ErrorBox error={error} />}
{!loading && !error && (
<DataTable
rows={rows}
columns={columns}
rowKey={(r) => r.taskId}
empty={<div className="p-6 text-sm text-slate-400">No pending tasks</div>}
/>
)}
</div>
)
}