@baack-software/baack-ts-tasks 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +158 -2
- package/dist/activity.d.ts +20 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +75 -0
- package/dist/activity.js.map +1 -0
- package/dist/blockers.d.ts +28 -0
- package/dist/blockers.d.ts.map +1 -0
- package/dist/blockers.js +134 -0
- package/dist/blockers.js.map +1 -0
- package/dist/conflicts.d.ts +50 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +73 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/draft.d.ts +45 -0
- package/dist/draft.d.ts.map +1 -0
- package/dist/draft.js +155 -0
- package/dist/draft.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/react/TaskActivity.d.ts +15 -0
- package/dist/react/TaskActivity.d.ts.map +1 -0
- package/dist/react/TaskActivity.js +60 -0
- package/dist/react/TaskActivity.js.map +1 -0
- package/dist/react/TaskBoard.d.ts +38 -0
- package/dist/react/TaskBoard.d.ts.map +1 -0
- package/dist/react/TaskBoard.js +85 -0
- package/dist/react/TaskBoard.js.map +1 -0
- package/dist/react/TaskConflicts.d.ts +26 -0
- package/dist/react/TaskConflicts.d.ts.map +1 -0
- package/dist/react/TaskConflicts.js +87 -0
- package/dist/react/TaskConflicts.js.map +1 -0
- package/dist/react/TaskCreateForm.d.ts +13 -0
- package/dist/react/TaskCreateForm.d.ts.map +1 -0
- package/dist/react/TaskCreateForm.js +68 -0
- package/dist/react/TaskCreateForm.js.map +1 -0
- package/dist/react/TaskEditor.d.ts +33 -0
- package/dist/react/TaskEditor.d.ts.map +1 -0
- package/dist/react/TaskEditor.js +172 -0
- package/dist/react/TaskEditor.js.map +1 -0
- package/dist/react/TaskFilters.d.ts +15 -0
- package/dist/react/TaskFilters.d.ts.map +1 -0
- package/dist/react/TaskFilters.js +48 -0
- package/dist/react/TaskFilters.js.map +1 -0
- package/dist/react/TaskView.d.ts +30 -0
- package/dist/react/TaskView.d.ts.map +1 -0
- package/dist/react/TaskView.js +108 -0
- package/dist/react/TaskView.js.map +1 -0
- package/dist/react/TasksAbout.d.ts +24 -0
- package/dist/react/TasksAbout.d.ts.map +1 -0
- package/dist/react/TasksAbout.js +82 -0
- package/dist/react/TasksAbout.js.map +1 -0
- package/dist/react/copy.d.ts +154 -0
- package/dist/react/copy.d.ts.map +1 -0
- package/dist/react/copy.js +173 -0
- package/dist/react/copy.js.map +1 -0
- package/dist/react/fields.d.ts +36 -0
- package/dist/react/fields.d.ts.map +1 -0
- package/dist/react/fields.js +21 -0
- package/dist/react/fields.js.map +1 -0
- package/dist/react/hooks.d.ts +9 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +31 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/parts.d.ts +55 -0
- package/dist/react/parts.d.ts.map +1 -0
- package/dist/react/parts.js +92 -0
- package/dist/react/parts.js.map +1 -0
- package/dist/react/ui/alert.d.ts +11 -0
- package/dist/react/ui/alert.d.ts.map +1 -0
- package/dist/react/ui/alert.js +29 -0
- package/dist/react/ui/alert.js.map +1 -0
- package/dist/react/ui/avatar.d.ts +12 -0
- package/dist/react/ui/avatar.d.ts.map +1 -0
- package/dist/react/ui/avatar.js +24 -0
- package/dist/react/ui/avatar.js.map +1 -0
- package/dist/react/ui/badge.d.ts +10 -0
- package/dist/react/ui/badge.d.ts.map +1 -0
- package/dist/react/ui/badge.js +26 -0
- package/dist/react/ui/badge.js.map +1 -0
- package/dist/react/ui/button.d.ts +11 -0
- package/dist/react/ui/button.d.ts.map +1 -0
- package/dist/react/ui/button.js +37 -0
- package/dist/react/ui/button.js.map +1 -0
- package/dist/react/ui/card.d.ts +12 -0
- package/dist/react/ui/card.d.ts.map +1 -0
- package/dist/react/ui/card.js +26 -0
- package/dist/react/ui/card.js.map +1 -0
- package/dist/react/ui/input.d.ts +4 -0
- package/dist/react/ui/input.d.ts.map +1 -0
- package/dist/react/ui/input.js +8 -0
- package/dist/react/ui/input.js.map +1 -0
- package/dist/react/ui/label.d.ts +5 -0
- package/dist/react/ui/label.d.ts.map +1 -0
- package/dist/react/ui/label.js +10 -0
- package/dist/react/ui/label.js.map +1 -0
- package/dist/react/ui/radio-group.d.ts +6 -0
- package/dist/react/ui/radio-group.d.ts.map +1 -0
- package/dist/react/ui/radio-group.js +12 -0
- package/dist/react/ui/radio-group.js.map +1 -0
- package/dist/react/ui/select.d.ts +16 -0
- package/dist/react/ui/select.d.ts.map +1 -0
- package/dist/react/ui/select.js +37 -0
- package/dist/react/ui/select.js.map +1 -0
- package/dist/react/ui/separator.d.ts +5 -0
- package/dist/react/ui/separator.d.ts.map +1 -0
- package/dist/react/ui/separator.js +10 -0
- package/dist/react/ui/separator.js.map +1 -0
- package/dist/react/ui/sheet.d.ts +15 -0
- package/dist/react/ui/sheet.d.ts.map +1 -0
- package/dist/react/ui/sheet.js +38 -0
- package/dist/react/ui/sheet.js.map +1 -0
- package/dist/react/ui/skeleton.d.ts +3 -0
- package/dist/react/ui/skeleton.d.ts.map +1 -0
- package/dist/react/ui/skeleton.js +7 -0
- package/dist/react/ui/skeleton.js.map +1 -0
- package/dist/react/ui/table.d.ts +11 -0
- package/dist/react/ui/table.d.ts.map +1 -0
- package/dist/react/ui/table.js +29 -0
- package/dist/react/ui/table.js.map +1 -0
- package/dist/react/ui/tabs.d.ts +12 -0
- package/dist/react/ui/tabs.d.ts.map +1 -0
- package/dist/react/ui/tabs.js +31 -0
- package/dist/react/ui/tabs.js.map +1 -0
- package/dist/react/ui/textarea.d.ts +4 -0
- package/dist/react/ui/textarea.d.ts.map +1 -0
- package/dist/react/ui/textarea.js +8 -0
- package/dist/react/ui/textarea.js.map +1 -0
- package/dist/react/ui/toggle-group.d.ts +11 -0
- package/dist/react/ui/toggle-group.d.ts.map +1 -0
- package/dist/react/ui/toggle-group.js +25 -0
- package/dist/react/ui/toggle-group.js.map +1 -0
- package/dist/react/ui/toggle.d.ts +10 -0
- package/dist/react/ui/toggle.d.ts.map +1 -0
- package/dist/react/ui/toggle.js +27 -0
- package/dist/react/ui/toggle.js.map +1 -0
- package/dist/refs.d.ts +16 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +43 -0
- package/dist/refs.js.map +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +4 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/recipes.d.ts +39 -0
- package/dist/server/recipes.d.ts.map +1 -0
- package/dist/server/recipes.js +81 -0
- package/dist/server/recipes.js.map +1 -0
- package/dist/server/webhooks.d.ts +135 -0
- package/dist/server/webhooks.d.ts.map +1 -0
- package/dist/server/webhooks.js +243 -0
- package/dist/server/webhooks.js.map +1 -0
- package/dist/store.d.ts +124 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +443 -0
- package/dist/store.js.map +1 -0
- package/dist/task-client.d.ts +137 -0
- package/dist/task-client.d.ts.map +1 -0
- package/dist/task-client.js +271 -0
- package/dist/task-client.js.map +1 -0
- package/dist/tasks.d.ts +84 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +208 -0
- package/dist/tasks.js.map +1 -0
- package/dist/time.d.ts +15 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +34 -0
- package/dist/time.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +101 -4
- package/src/activity.ts +86 -0
- package/src/blockers.ts +134 -0
- package/src/conflicts.ts +115 -0
- package/src/draft.ts +162 -0
- package/src/errors.ts +40 -0
- package/src/index.ts +10 -0
- package/src/react/TaskActivity.tsx +187 -0
- package/src/react/TaskBoard.tsx +264 -0
- package/src/react/TaskConflicts.tsx +217 -0
- package/src/react/TaskCreateForm.tsx +165 -0
- package/src/react/TaskEditor.tsx +485 -0
- package/src/react/TaskFilters.tsx +122 -0
- package/src/react/TaskView.tsx +291 -0
- package/src/react/TasksAbout.tsx +226 -0
- package/src/react/copy.tsx +253 -0
- package/src/react/fields.tsx +104 -0
- package/src/react/hooks.ts +41 -0
- package/src/react/index.ts +12 -0
- package/src/react/parts.tsx +176 -0
- package/src/react/ui/README.md +6 -0
- package/src/react/ui/alert.tsx +75 -0
- package/src/react/ui/avatar.tsx +109 -0
- package/src/react/ui/badge.tsx +48 -0
- package/src/react/ui/button.tsx +66 -0
- package/src/react/ui/card.tsx +102 -0
- package/src/react/ui/input.tsx +18 -0
- package/src/react/ui/label.tsx +23 -0
- package/src/react/ui/radio-group.tsx +41 -0
- package/src/react/ui/select.tsx +189 -0
- package/src/react/ui/separator.tsx +27 -0
- package/src/react/ui/sheet.tsx +145 -0
- package/src/react/ui/skeleton.tsx +13 -0
- package/src/react/ui/table.tsx +113 -0
- package/src/react/ui/tabs.tsx +89 -0
- package/src/react/ui/textarea.tsx +17 -0
- package/src/react/ui/toggle-group.tsx +89 -0
- package/src/react/ui/toggle.tsx +44 -0
- package/src/refs.ts +49 -0
- package/src/server/index.ts +3 -0
- package/src/server/recipes.ts +107 -0
- package/src/server/webhooks.ts +369 -0
- package/src/store.ts +538 -0
- package/src/task-client.ts +373 -0
- package/src/tasks.ts +263 -0
- package/src/time.ts +35 -0
- package/src/types.ts +101 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
import { cn } from 'cn';
|
|
4
|
+
import { lookupFrom, openBlockers } from "../blockers.js";
|
|
5
|
+
import { groupByStage, groupByWorkflow, groupTasks, isOverdue, NONE_KEY, } from "../tasks.js";
|
|
6
|
+
import { parseTimestamp } from "../time.js";
|
|
7
|
+
import { priorityCopy, statusCopy, useCopy } from "./copy.js";
|
|
8
|
+
import { BlockedBadge, DueDate, nameOf, PersonAvatar, PriorityBadge, StatusBadge } from "./parts.js";
|
|
9
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./ui/table.js";
|
|
10
|
+
function useBlocked(directory) {
|
|
11
|
+
const lookup = lookupFrom(directory.tasks);
|
|
12
|
+
return (task) => openBlockers(task, lookup);
|
|
13
|
+
}
|
|
14
|
+
/** A task as a board card: priority, blocked, title, due date and assignee. Opens the task when chosen. */
|
|
15
|
+
export function TaskCard({ task, directory, selected, blockedBy, onOpen, id, now, }) {
|
|
16
|
+
const copy = useCopy();
|
|
17
|
+
const ids = useId();
|
|
18
|
+
const assignee = task.assignee ? { urn: task.assignee.urn, name: nameOf(directory, task.assignee) } : null;
|
|
19
|
+
const blockedTitle = blockedBy.map((urn) => copy('blocked_by', { name: nameOf(directory, { urn }) })).join(', ');
|
|
20
|
+
// The title names the card; the rest describes it, so screen readers hear the title first and the details after.
|
|
21
|
+
const details = [
|
|
22
|
+
copy(priorityCopy(task.priority)),
|
|
23
|
+
dueLabel(task, copy, now),
|
|
24
|
+
assignee ? `${copy('field_assignee')}: ${assignee.name}` : copy('option_unassigned'),
|
|
25
|
+
blockedTitle,
|
|
26
|
+
]
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.join(', ');
|
|
29
|
+
return (_jsxs("button", { type: "button", id: id, onClick: () => onOpen(task), "aria-current": selected ? 'true' : undefined, "aria-labelledby": `${ids}-title`, "aria-describedby": `${ids}-details`, className: cn('border-border bg-card hover:border-primary focus-visible:outline-primary w-full rounded-lg border p-2.5', 'text-left transition-colors focus-visible:outline-2', selected && 'border-primary ring-primary/30 ring-2'), children: [_jsxs("span", { "aria-hidden": "true", className: "flex flex-wrap items-center gap-1.5", children: [_jsx(PriorityBadge, { priority: task.priority }), blockedBy.length > 0 && _jsx(BlockedBadge, { title: blockedTitle })] }), _jsx("span", { id: `${ids}-title`, className: "mt-1.5 block text-[13px] leading-snug font-medium", children: task.title }), _jsxs("span", { "aria-hidden": "true", className: "mt-2 flex items-center justify-between gap-1", children: [_jsx(DueDate, { task: task, ...(now ? { now } : {}) }), _jsx(PersonAvatar, { person: assignee })] }), _jsx("span", { id: `${ids}-details`, className: "sr-only", children: details })] }));
|
|
30
|
+
}
|
|
31
|
+
/** The due date as words, for a screen reader: "Due 12 Oct, overdue", or "No due date". */
|
|
32
|
+
function dueLabel(task, copy, now) {
|
|
33
|
+
const due = parseTimestamp(task.dueTimestamp);
|
|
34
|
+
if (!due)
|
|
35
|
+
return copy('due_none');
|
|
36
|
+
const text = `${copy('field_due')} ${due.toLocaleDateString(undefined, { day: 'numeric', month: 'short' })}`;
|
|
37
|
+
return isOverdue(task, now) ? `${text}, ${copy('due_overdue')}` : text;
|
|
38
|
+
}
|
|
39
|
+
/** Tasks in columns by status, priority, assignee, project, workflow or workflow stage, each with its count. */
|
|
40
|
+
export function TaskBoard({ tasks, directory, selected, onOpen, itemId, now, groupBy = 'status', sort, hideEmpty = ['UNDEFINED'], workflow, }) {
|
|
41
|
+
const copy = useCopy();
|
|
42
|
+
const ids = useId();
|
|
43
|
+
const blocked = useBlocked(directory);
|
|
44
|
+
const grouped = groupBy === 'workflowStage' && workflow
|
|
45
|
+
? groupByStage(tasks, workflow)
|
|
46
|
+
: groupBy === 'workflow'
|
|
47
|
+
? groupByWorkflow(tasks, directory.workflows ?? [])
|
|
48
|
+
: groupTasks(tasks, groupBy);
|
|
49
|
+
const groups = [...grouped].filter(([key, group]) => group.length > 0 || !hideEmpty.includes(key));
|
|
50
|
+
const columnName = (key) => {
|
|
51
|
+
switch (groupBy) {
|
|
52
|
+
case 'status':
|
|
53
|
+
return copy(statusCopy(key));
|
|
54
|
+
case 'priority':
|
|
55
|
+
return copy(priorityCopy(key));
|
|
56
|
+
case 'assignee':
|
|
57
|
+
return key === NONE_KEY ? copy('option_unassigned') : nameOf(directory, { urn: key });
|
|
58
|
+
case 'project':
|
|
59
|
+
return key === NONE_KEY ? copy('option_no_project') : nameOf(directory, { urn: key });
|
|
60
|
+
case 'workflow':
|
|
61
|
+
return key === NONE_KEY
|
|
62
|
+
? copy('option_no_workflow')
|
|
63
|
+
: (directory.workflows?.find((w) => w.urn === key)?.name ?? nameOf(directory, { urn: key }));
|
|
64
|
+
case 'workflowStage':
|
|
65
|
+
return key === NONE_KEY ? copy('option_no_stage') : nameOf(directory, { urn: key });
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return (_jsx("div", { className: "relative grid auto-cols-[minmax(15rem,1fr)] grid-flow-col gap-3 overflow-x-auto pb-2", children: groups.map(([key, group], index) => {
|
|
69
|
+
const sorted = sort ? [...group].sort(sort) : group;
|
|
70
|
+
const name = columnName(key);
|
|
71
|
+
const count = group.length === 1 ? copy('tasks_count_one') : copy('tasks_count', { count: group.length });
|
|
72
|
+
return (_jsxs("section", { "aria-labelledby": `${ids}-column-${index}`, className: "bg-muted/50 rounded-xl p-2", children: [_jsxs("h3", { id: `${ids}-column-${index}`, "aria-label": `${name}, ${count}`, className: "text-muted-foreground mb-2 flex items-center justify-between px-1 text-xs font-semibold tracking-wide uppercase", children: [name, _jsx("span", { className: "bg-background text-foreground rounded-full px-1.5 text-[11px] tabular-nums", children: group.length })] }), _jsx("ul", { className: "space-y-2", children: sorted.map((task) => (_jsx("li", { children: _jsx(TaskCard, { task: task, directory: directory, selected: task.urn === selected, blockedBy: blocked(task), onOpen: onOpen, ...(itemId ? { id: itemId(task.urn) } : {}), ...(now ? { now } : {}) }) }, task.urn))) })] }, key));
|
|
73
|
+
}) }));
|
|
74
|
+
}
|
|
75
|
+
/** Tasks as table rows: title, status, priority, assignee, project and due date. The title opens the task. */
|
|
76
|
+
export function TaskTable({ tasks, directory, selected, onOpen, itemId, now }) {
|
|
77
|
+
const copy = useCopy();
|
|
78
|
+
const blocked = useBlocked(directory);
|
|
79
|
+
return (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: copy('field_title') }), _jsx(TableHead, { children: copy('field_status') }), _jsx(TableHead, { children: copy('field_priority') }), _jsx(TableHead, { children: copy('field_assignee') }), _jsx(TableHead, { children: copy('field_project') }), _jsx(TableHead, { children: copy('field_due') })] }) }), _jsx(TableBody, { children: tasks.map((task) => {
|
|
80
|
+
const assignee = task.assignee ? { urn: task.assignee.urn, name: nameOf(directory, task.assignee) } : null;
|
|
81
|
+
const blockers = blocked(task);
|
|
82
|
+
return (_jsxs(TableRow, { "data-state": task.urn === selected ? 'selected' : undefined, children: [_jsxs(TableCell, { className: "max-w-80 whitespace-normal", children: [_jsx("button", { type: "button", ...(itemId ? { id: itemId(task.urn) } : {}), onClick: () => onOpen(task), "aria-current": task.urn === selected ? 'true' : undefined, className: "hover:text-primary text-left font-medium hover:underline", children: task.title }), blockers.length > 0 && (_jsx("span", { className: "ml-2", children: _jsx(BlockedBadge, {}) }))] }), _jsx(TableCell, { children: _jsx(StatusBadge, { status: task.status }) }), _jsx(TableCell, { children: _jsx(PriorityBadge, { priority: task.priority }) }), _jsx(TableCell, { children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(PersonAvatar, { person: assignee }), _jsx("span", { className: cn(!assignee && 'text-muted-foreground'), children: assignee?.name ?? copy('option_unassigned') })] }) }), _jsx(TableCell, { className: cn(!task.project && 'text-muted-foreground'), children: task.project ? nameOf(directory, task.project) : copy('option_no_project') }), _jsx(TableCell, { children: _jsx(DueDate, { task: task, ...(now ? { now } : {}) }) })] }, task.urn));
|
|
83
|
+
}) })] }));
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=TaskBoard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskBoard.js","sourceRoot":"","sources":["../../src/react/TaskBoard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ConflictChoices, TaskConflict, TaskField } from '../conflicts.ts';
|
|
2
|
+
import type { TaskListField } from '../types.ts';
|
|
3
|
+
import { type TaskCopyName } from './copy.tsx';
|
|
4
|
+
import { type TaskDirectory } from './parts.tsx';
|
|
5
|
+
/** The copy name of a field's label. */
|
|
6
|
+
export declare const fieldCopy: (field: TaskField | TaskListField) => TaskCopyName;
|
|
7
|
+
export interface TaskConflictsProps {
|
|
8
|
+
conflicts: readonly TaskConflict[];
|
|
9
|
+
directory: TaskDirectory;
|
|
10
|
+
/** Saves with the choices made. Fields left on "keep mine" are saved again; "use theirs" drops the change. */
|
|
11
|
+
onResolve: (choices: ConflictChoices) => void;
|
|
12
|
+
/** Keeps everything the other person saved, dropping this person's conflicting changes. */
|
|
13
|
+
onDiscard: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Shown when someone else changed the same fields while this person was editing: each field with both values, and a
|
|
17
|
+
* choice to keep mine or use theirs. Takes focus when it appears.
|
|
18
|
+
*/
|
|
19
|
+
export declare function TaskConflicts({ conflicts, directory, onResolve, onDiscard }: TaskConflictsProps): import("react").JSX.Element;
|
|
20
|
+
export interface ChangedElsewhereProps {
|
|
21
|
+
fields: readonly (TaskField | TaskListField)[];
|
|
22
|
+
onDismiss?: (() => void) | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** A note that someone else changed other fields while this person was editing, which were kept. */
|
|
25
|
+
export declare function ChangedElsewhere({ fields, onDismiss }: ChangedElsewhereProps): import("react").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=TaskConflicts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskConflicts.d.ts","sourceRoot":"","sources":["../../src/react/TaskConflicts.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAkB,MAAM,iBAAiB,CAAC;AAEhG,OAAO,KAAK,EAAO,aAAa,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAqC,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAuBzD,wCAAwC;AACxC,eAAO,MAAM,SAAS,GAAI,OAAO,SAAS,GAAG,aAAa,KAAG,YAAiC,CAAC;AAE/F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,YAAY,EAAE,CAAC;IACnC,SAAS,EAAE,aAAa,CAAC;IACzB,8GAA8G;IAC9G,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,2FAA2F;IAC3F,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BA4F/F;AAuDD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,CAAC,SAAS,GAAG,aAAa,CAAC,EAAE,CAAC;IAC/C,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACtC;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,qBAAqB,+BAgB5E"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
3
|
+
import { TriangleAlert } from 'lucide-react';
|
|
4
|
+
import { cn } from 'cn';
|
|
5
|
+
import { parseTimestamp } from "../time.js";
|
|
6
|
+
import { priorityCopy, statusCopy, useCopy } from "./copy.js";
|
|
7
|
+
import { nameOf } from "./parts.js";
|
|
8
|
+
import { Alert, AlertDescription } from "./ui/alert.js";
|
|
9
|
+
import { Button } from "./ui/button.js";
|
|
10
|
+
import { Label } from "./ui/label.js";
|
|
11
|
+
import { RadioGroup, RadioGroupItem } from "./ui/radio-group.js";
|
|
12
|
+
const FIELD_COPY = {
|
|
13
|
+
title: 'field_title',
|
|
14
|
+
description: 'field_description',
|
|
15
|
+
status: 'field_status',
|
|
16
|
+
priority: 'field_priority',
|
|
17
|
+
dueTimestamp: 'field_due',
|
|
18
|
+
assignee: 'field_assignee',
|
|
19
|
+
project: 'field_project',
|
|
20
|
+
workflowStage: 'field_stage',
|
|
21
|
+
blockedBy: 'blockers_heading',
|
|
22
|
+
blocking: 'field_blocking',
|
|
23
|
+
associatedTasks: 'related_heading',
|
|
24
|
+
associatedEntities: 'related_heading',
|
|
25
|
+
associatedIdentities: 'related_heading',
|
|
26
|
+
associatedCompanies: 'related_heading',
|
|
27
|
+
};
|
|
28
|
+
/** The copy name of a field's label. */
|
|
29
|
+
export const fieldCopy = (field) => FIELD_COPY[field];
|
|
30
|
+
/**
|
|
31
|
+
* Shown when someone else changed the same fields while this person was editing: each field with both values, and a
|
|
32
|
+
* choice to keep mine or use theirs. Takes focus when it appears.
|
|
33
|
+
*/
|
|
34
|
+
export function TaskConflicts({ conflicts, directory, onResolve, onDiscard }) {
|
|
35
|
+
const copy = useCopy();
|
|
36
|
+
const ids = useId();
|
|
37
|
+
const heading = useRef(null);
|
|
38
|
+
const [choices, setChoices] = useState({});
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
setChoices({});
|
|
41
|
+
heading.current?.focus();
|
|
42
|
+
}, [conflicts]);
|
|
43
|
+
return (_jsxs("section", { role: "alertdialog", "aria-labelledby": `${ids}-heading`, "aria-describedby": `${ids}-intro`, className: "grid gap-3 rounded-lg border border-amber-500/50 bg-amber-500/5 p-3", children: [_jsxs("div", { className: "grid gap-1", children: [_jsxs("h3", { id: `${ids}-heading`, ref: heading, tabIndex: -1, className: "flex items-center gap-1.5 text-sm font-semibold outline-none", children: [_jsx(TriangleAlert, { "aria-hidden": "true", className: "size-4 text-amber-600 dark:text-amber-400" }), copy('conflict_heading')] }), _jsx("p", { id: `${ids}-intro`, className: "text-muted-foreground text-sm", children: copy('conflict_intro') })] }), conflicts.map((conflict) => {
|
|
44
|
+
const id = `${ids}-${conflict.field}`;
|
|
45
|
+
const choice = choices[conflict.field] ?? 'mine';
|
|
46
|
+
return (_jsxs("div", { className: "grid gap-1.5", children: [_jsx("p", { id: id, className: "text-xs font-semibold tracking-wide uppercase", children: copy(fieldCopy(conflict.field)) }), _jsx(RadioGroup, { "aria-labelledby": id, value: choice, onValueChange: (value) => setChoices({ ...choices, [conflict.field]: value }), className: "gap-1.5", children: ['mine', 'theirs'].map((side) => (_jsxs(Label, { htmlFor: `${id}-${side}`, className: cn('bg-card items-start gap-2.5 rounded-md border p-2 font-normal', choice === side && 'border-primary'), children: [_jsx(RadioGroupItem, { id: `${id}-${side}`, value: side, "aria-labelledby": `${id}-${side}-label`, "aria-describedby": `${id}-${side}-value`, className: "mt-0.5" }), _jsxs("span", { className: "grid min-w-0 gap-0.5", children: [_jsx("span", { id: `${id}-${side}-label`, className: "font-medium", children: copy(side === 'mine' ? 'conflict_mine' : 'conflict_theirs') }), _jsx(FieldValue, { id: `${id}-${side}-value`, field: conflict.field, value: conflict[side], directory: directory })] })] }, side))) })] }, conflict.field));
|
|
47
|
+
}), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { size: "sm", onClick: () => onResolve(choices), children: copy('conflict_save') }), _jsx(Button, { size: "sm", variant: "ghost", onClick: onDiscard, children: copy('conflict_discard') })] })] }));
|
|
48
|
+
}
|
|
49
|
+
/** A field's value as the reader would say it: names for references, labels for status and priority. */
|
|
50
|
+
function FieldValue({ id, field, value, directory, }) {
|
|
51
|
+
const copy = useCopy();
|
|
52
|
+
const empty = value == null || value === '';
|
|
53
|
+
let text;
|
|
54
|
+
switch (field) {
|
|
55
|
+
case 'status':
|
|
56
|
+
text = empty ? copy('value_empty') : copy(statusCopy(value));
|
|
57
|
+
break;
|
|
58
|
+
case 'priority':
|
|
59
|
+
text = empty ? copy('value_empty') : copy(priorityCopy(value));
|
|
60
|
+
break;
|
|
61
|
+
case 'assignee':
|
|
62
|
+
text = empty ? copy('option_unassigned') : nameOf(directory, value);
|
|
63
|
+
break;
|
|
64
|
+
case 'project':
|
|
65
|
+
text = empty ? copy('option_no_project') : nameOf(directory, value);
|
|
66
|
+
break;
|
|
67
|
+
case 'workflowStage':
|
|
68
|
+
text = empty ? copy('value_empty') : nameOf(directory, value);
|
|
69
|
+
break;
|
|
70
|
+
case 'dueTimestamp': {
|
|
71
|
+
const due = parseTimestamp(value);
|
|
72
|
+
text = due ? due.toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' }) : copy('due_none');
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
text = empty ? copy('value_empty') : value;
|
|
77
|
+
}
|
|
78
|
+
return (_jsx("span", { id: id, className: cn('text-muted-foreground text-sm break-words', field === 'description' && 'max-h-32 overflow-y-auto whitespace-pre-wrap', empty && 'italic'), children: text }));
|
|
79
|
+
}
|
|
80
|
+
/** A note that someone else changed other fields while this person was editing, which were kept. */
|
|
81
|
+
export function ChangedElsewhere({ fields, onDismiss }) {
|
|
82
|
+
const copy = useCopy();
|
|
83
|
+
const names = [...new Set(fields.map((field) => copy(fieldCopy(field))))];
|
|
84
|
+
const list = new Intl.ListFormat(undefined, { type: 'conjunction' }).format(names);
|
|
85
|
+
return (_jsx(Alert, { children: _jsxs(AlertDescription, { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("span", { children: copy('changed_elsewhere', { fields: list }) }), onDismiss && (_jsx(Button, { size: "xs", variant: "ghost", onClick: onDismiss, children: copy('changed_elsewhere_dismiss') }))] }) }));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=TaskConflicts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskConflicts.js","sourceRoot":"","sources":["../../src/react/TaskConflicts.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DraftInput } from '../draft.ts';
|
|
2
|
+
import { type TaskDirectory } from './parts.tsx';
|
|
3
|
+
export type NewTask = Omit<DraftInput, 'owner'>;
|
|
4
|
+
export interface TaskCreateFormProps {
|
|
5
|
+
directory: TaskDirectory;
|
|
6
|
+
onCreate: (task: NewTask) => Promise<unknown>;
|
|
7
|
+
onCancel?: (() => void) | undefined;
|
|
8
|
+
/** Starting values, e.g. the project or assignee the view is filtered to. */
|
|
9
|
+
initial?: Partial<NewTask>;
|
|
10
|
+
}
|
|
11
|
+
/** A form for a new task: title (required), description, priority, assignee, project and due date. */
|
|
12
|
+
export declare function TaskCreateForm({ directory, onCreate, onCancel, initial }: TaskCreateFormProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=TaskCreateForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskCreateForm.d.ts","sourceRoot":"","sources":["../../src/react/TaskCreateForm.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAM/D,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACpC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,sGAAsG;AACtG,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,mBAAmB,+BA2I7F"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
3
|
+
import { Plus, X } from 'lucide-react';
|
|
4
|
+
import { TASK_PRIORITIES } from "../tasks.js";
|
|
5
|
+
import { fromLocalInput } from "../time.js";
|
|
6
|
+
import { priorityCopy, useCopy } from "./copy.js";
|
|
7
|
+
import { ChoiceSelect, Field, NONE } from "./fields.js";
|
|
8
|
+
import { PersonAvatar } from "./parts.js";
|
|
9
|
+
import { Alert, AlertDescription } from "./ui/alert.js";
|
|
10
|
+
import { Button } from "./ui/button.js";
|
|
11
|
+
import { Input } from "./ui/input.js";
|
|
12
|
+
import { Textarea } from "./ui/textarea.js";
|
|
13
|
+
/** A form for a new task: title (required), description, priority, assignee, project and due date. */
|
|
14
|
+
export function TaskCreateForm({ directory, onCreate, onCancel, initial }) {
|
|
15
|
+
const copy = useCopy();
|
|
16
|
+
const ids = useId();
|
|
17
|
+
const title = useRef(null);
|
|
18
|
+
const [values, setValues] = useState({
|
|
19
|
+
title: initial?.title ?? '',
|
|
20
|
+
description: initial?.description ?? '',
|
|
21
|
+
priority: initial?.priority ?? 'NONE',
|
|
22
|
+
assignee: initial?.assignee?.urn ?? NONE,
|
|
23
|
+
project: initial?.project?.urn ?? NONE,
|
|
24
|
+
due: '',
|
|
25
|
+
});
|
|
26
|
+
const [sending, setSending] = useState(false);
|
|
27
|
+
const [failed, setFailed] = useState(false);
|
|
28
|
+
useEffect(() => title.current?.focus(), []);
|
|
29
|
+
const set = (key, value) => setValues((current) => ({ ...current, [key]: value }));
|
|
30
|
+
return (_jsxs("form", { "aria-labelledby": `${ids}-heading`, className: "grid gap-4", onSubmit: async (event) => {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
if (!values.title.trim())
|
|
33
|
+
return;
|
|
34
|
+
setSending(true);
|
|
35
|
+
setFailed(false);
|
|
36
|
+
const due = fromLocalInput(values.due);
|
|
37
|
+
try {
|
|
38
|
+
await onCreate({
|
|
39
|
+
...initial,
|
|
40
|
+
title: values.title.trim(),
|
|
41
|
+
description: values.description,
|
|
42
|
+
priority: values.priority,
|
|
43
|
+
...(values.assignee === NONE ? {} : { assignee: { urn: values.assignee } }),
|
|
44
|
+
...(values.project === NONE ? {} : { project: { urn: values.project } }),
|
|
45
|
+
...(due === undefined ? {} : { dueTimestamp: due }),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
setFailed(true);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
setSending(false);
|
|
53
|
+
}
|
|
54
|
+
}, children: [_jsxs("header", { className: "flex items-center justify-between gap-2", children: [_jsx("h2", { id: `${ids}-heading`, className: "text-lg font-bold", children: copy('create_heading') }), onCancel && (_jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: onCancel, "aria-label": copy('create_cancel'), children: _jsx(X, { "aria-hidden": "true" }) }))] }), failed && (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: copy('create_failed') }) })), _jsx(Field, { id: `${ids}-title`, label: copy('field_title'), children: _jsx(Input, { ref: title, id: `${ids}-title`, required: true, maxLength: 1024, value: values.title, onChange: (e) => set('title', e.target.value) }) }), _jsx(Field, { id: `${ids}-description`, label: copy('field_description'), children: _jsx(Textarea, { id: `${ids}-description`, rows: 4, value: values.description, onChange: (e) => set('description', e.target.value) }) }), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsx(Field, { id: `${ids}-priority`, label: copy('field_priority'), children: _jsx(ChoiceSelect, { id: `${ids}-priority`, value: values.priority, choices: [...TASK_PRIORITIES]
|
|
55
|
+
.reverse()
|
|
56
|
+
.map((priority) => ({ value: priority, label: copy(priorityCopy(priority)) })), onChange: (priority) => set('priority', priority) }) }), _jsx(Field, { id: `${ids}-due`, label: copy('field_due'), children: _jsx(Input, { id: `${ids}-due`, type: "datetime-local", className: "h-7 text-sm", value: values.due, onChange: (e) => set('due', e.target.value) }) }), _jsx(Field, { id: `${ids}-assignee`, label: copy('field_assignee'), children: _jsx(ChoiceSelect, { id: `${ids}-assignee`, value: values.assignee, choices: [
|
|
57
|
+
{ value: NONE, label: copy('option_unassigned') },
|
|
58
|
+
...directory.people.map((person) => ({
|
|
59
|
+
value: person.urn,
|
|
60
|
+
label: person.name,
|
|
61
|
+
icon: _jsx(PersonAvatar, { person: person }),
|
|
62
|
+
})),
|
|
63
|
+
], onChange: (urn) => set('assignee', urn) }) }), _jsx(Field, { id: `${ids}-project`, label: copy('field_project'), children: _jsx(ChoiceSelect, { id: `${ids}-project`, value: values.project, choices: [
|
|
64
|
+
{ value: NONE, label: copy('option_no_project') },
|
|
65
|
+
...directory.projects.map((project) => ({ value: project.urn, label: project.name })),
|
|
66
|
+
], onChange: (urn) => set('project', urn) }) })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { type: "submit", disabled: !values.title.trim() || sending, children: [_jsx(Plus, { "aria-hidden": "true" }), copy('create_submit')] }), onCancel && (_jsx(Button, { type: "button", variant: "ghost", onClick: onCancel, children: copy('create_cancel') }))] })] }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=TaskCreateForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskCreateForm.js","sourceRoot":"","sources":["../../src/react/TaskCreateForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Task } from '@baack-software/baack-ts-client';
|
|
3
|
+
import { type TaskField } from '../conflicts.ts';
|
|
4
|
+
import type { TaskInput, TaskListField } from '../types.ts';
|
|
5
|
+
import { type TaskDirectory } from './parts.tsx';
|
|
6
|
+
export interface TaskEditorProps {
|
|
7
|
+
task: Task;
|
|
8
|
+
directory: TaskDirectory;
|
|
9
|
+
/**
|
|
10
|
+
* Sends a change. Rejections are shown in the editor. A `TaskConflictError` (from `TaskStore.update`, or
|
|
11
|
+
* `TaskClient.update` with `base: task`) opens a panel to choose, field by field, between this person's value and
|
|
12
|
+
* the other one; the choices are sent as another change. Without the store, update `task` to the error's `current`
|
|
13
|
+
* so that change is checked against what the person now sees.
|
|
14
|
+
*/
|
|
15
|
+
onChange: (changes: TaskInput) => Promise<unknown>;
|
|
16
|
+
/** Fields someone else changed while this person was editing, shown as a note. */
|
|
17
|
+
changedElsewhere?: readonly (TaskField | TaskListField)[] | undefined;
|
|
18
|
+
onDismissChangedElsewhere?: (() => void) | undefined;
|
|
19
|
+
onDelete?: (() => Promise<unknown>) | undefined;
|
|
20
|
+
onClose?: (() => void) | undefined;
|
|
21
|
+
/** Shown while a change is being saved. */
|
|
22
|
+
saving?: boolean;
|
|
23
|
+
/** The activity log, usually a `TaskActivity`. */
|
|
24
|
+
activity?: ReactNode;
|
|
25
|
+
/** Focus the heading when the editor opens, for keyboard and screen reader users. Default true. */
|
|
26
|
+
focusOnOpen?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Every field of a task, saved as it changes: selects at once, text when it loses focus. Blockers can be added
|
|
30
|
+
* and removed, related records are listed, and the activity log goes below.
|
|
31
|
+
*/
|
|
32
|
+
export declare function TaskEditor({ task, directory, onChange, onDelete, onClose, saving, activity, focusOnOpen, changedElsewhere, onDismissChangedElsewhere, }: TaskEditorProps): import("react").JSX.Element;
|
|
33
|
+
//# sourceMappingURL=TaskEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskEditor.d.ts","sourceRoot":"","sources":["../../src/react/TaskEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,KAAK,EAAE,IAAI,EAA4B,MAAM,iCAAiC,CAAC;AAGtF,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAMtF,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5D,OAAO,EAA4D,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ3G,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,aAAa,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,GAAG,aAAa,CAAC,EAAE,GAAG,SAAS,CAAC;IACtE,yBAAyB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACnC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mGAAmG;IACnG,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,WAAkB,EAClB,gBAAgB,EAChB,yBAAyB,GAC1B,EAAE,eAAe,+BA0QjB"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
3
|
+
import { Building2, FileText, Link2, Trash2, UserRound, X } from 'lucide-react';
|
|
4
|
+
import { wouldCreateCycle } from "../blockers.js";
|
|
5
|
+
import { resolveConflicts } from "../conflicts.js";
|
|
6
|
+
import { isEmptyChange } from "../draft.js";
|
|
7
|
+
import { TaskConflictError } from "../errors.js";
|
|
8
|
+
import { withoutRef, withRef } from "../refs.js";
|
|
9
|
+
import { isOpen, TASK_PRIORITIES, TASK_STATUSES, workflowStages } from "../tasks.js";
|
|
10
|
+
import { fromLocalInput, toLocalInput } from "../time.js";
|
|
11
|
+
import { priorityCopy, statusCopy, useCopy } from "./copy.js";
|
|
12
|
+
import { ChoiceSelect, Field, NONE } from "./fields.js";
|
|
13
|
+
import { nameOf, PersonAvatar, StatusBadge, Timestamp } from "./parts.js";
|
|
14
|
+
import { Alert, AlertDescription } from "./ui/alert.js";
|
|
15
|
+
import { Button } from "./ui/button.js";
|
|
16
|
+
import { Input } from "./ui/input.js";
|
|
17
|
+
import { Separator } from "./ui/separator.js";
|
|
18
|
+
import { Textarea } from "./ui/textarea.js";
|
|
19
|
+
import { ChangedElsewhere, TaskConflicts } from "./TaskConflicts.js";
|
|
20
|
+
/**
|
|
21
|
+
* Every field of a task, saved as it changes: selects at once, text when it loses focus. Blockers can be added
|
|
22
|
+
* and removed, related records are listed, and the activity log goes below.
|
|
23
|
+
*/
|
|
24
|
+
export function TaskEditor({ task, directory, onChange, onDelete, onClose, saving, activity, focusOnOpen = true, changedElsewhere, onDismissChangedElsewhere, }) {
|
|
25
|
+
const copy = useCopy();
|
|
26
|
+
const ids = useId();
|
|
27
|
+
const heading = useRef(null);
|
|
28
|
+
const [error, setError] = useState();
|
|
29
|
+
const [confirmDelete, setConfirmDelete] = useState(false);
|
|
30
|
+
const stages = (directory.workflows ?? []).flatMap((workflow) => workflow.stages ?? []);
|
|
31
|
+
const [conflict, setConflict] = useState();
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (focusOnOpen)
|
|
34
|
+
heading.current?.focus();
|
|
35
|
+
setError(undefined);
|
|
36
|
+
setConfirmDelete(false);
|
|
37
|
+
setConflict(undefined);
|
|
38
|
+
}, [task.urn, focusOnOpen]);
|
|
39
|
+
const save = async (changes) => {
|
|
40
|
+
setError(undefined);
|
|
41
|
+
try {
|
|
42
|
+
await onChange(changes);
|
|
43
|
+
}
|
|
44
|
+
catch (failure) {
|
|
45
|
+
if (failure instanceof TaskConflictError) {
|
|
46
|
+
// Builds on a conflict already open, so choices cover every field this person changed.
|
|
47
|
+
setConflict((open) => ({
|
|
48
|
+
conflicts: [
|
|
49
|
+
...(open?.conflicts.filter((c) => !failure.conflicts.some((f) => f.field === c.field)) ?? []),
|
|
50
|
+
...failure.conflicts,
|
|
51
|
+
],
|
|
52
|
+
changes: { ...open?.changes, ...changes },
|
|
53
|
+
}));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const detail = failure instanceof Error && failure.name === 'TaskValidationError' ? failure.message : undefined;
|
|
57
|
+
setError(detail ? `${copy('editor_save_failed')} ${detail}` : copy('editor_save_failed'));
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const others = directory.tasks.filter((t) => t.urn !== task.urn);
|
|
61
|
+
const blockerChoices = others.filter((t) => isOpen(t) &&
|
|
62
|
+
!task.blockedBy?.some((b) => b.urn === t.urn) &&
|
|
63
|
+
!wouldCreateCycle(directory.tasks, task.urn, t.urn));
|
|
64
|
+
return (_jsxs("article", { "aria-labelledby": `${ids}-heading`, className: "grid gap-4", children: [_jsxs("header", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-muted-foreground text-xs", children: copy('editor_label') }), _jsx("h2", { id: `${ids}-heading`, ref: heading, tabIndex: -1, className: "text-lg leading-snug font-bold break-words outline-none", children: task.title })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx("span", { "aria-live": "polite", className: "text-muted-foreground text-xs", children: saving ? copy('editor_saving') : '' }), onClose && (_jsx(Button, { variant: "ghost", size: "icon-sm", onClick: onClose, "aria-label": copy('editor_close'), children: _jsx(X, { "aria-hidden": "true" }) }))] })] }), error && (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })), conflict && (_jsx(TaskConflicts, { conflicts: conflict.conflicts, directory: directory, onResolve: (choices) => {
|
|
65
|
+
const resolved = resolveConflicts(conflict.changes, choices);
|
|
66
|
+
setConflict(undefined);
|
|
67
|
+
if (!isEmptyChange(resolved))
|
|
68
|
+
void save(resolved);
|
|
69
|
+
}, onDiscard: () => setConflict(undefined) })), changedElsewhere && changedElsewhere.length > 0 && (_jsx(ChangedElsewhere, { fields: changedElsewhere, onDismiss: onDismissChangedElsewhere })), _jsx(TextField, { id: `${ids}-title`, label: copy('field_title'), value: task.title, onCommit: (title) => save({ title }), required: true }, `title-${task.urn}`), _jsxs("div", { className: "grid grid-cols-2 gap-x-3 gap-y-3", children: [_jsx(Field, { id: `${ids}-status`, label: copy('field_status'), children: _jsx(ChoiceSelect, { id: `${ids}-status`, value: task.status, choices: TASK_STATUSES.map((status) => ({ value: status, label: copy(statusCopy(status)) })), onChange: (status) => save({ status: status }) }) }), _jsx(Field, { id: `${ids}-priority`, label: copy('field_priority'), children: _jsx(ChoiceSelect, { id: `${ids}-priority`, value: task.priority, choices: [...TASK_PRIORITIES]
|
|
70
|
+
.reverse()
|
|
71
|
+
.map((priority) => ({ value: priority, label: copy(priorityCopy(priority)) })), onChange: (priority) => save({ priority: priority }) }) }), _jsx(Field, { id: `${ids}-assignee`, label: copy('field_assignee'), children: _jsx(ChoiceSelect, { id: `${ids}-assignee`, value: task.assignee?.urn ?? NONE, choices: [
|
|
72
|
+
{ value: NONE, label: copy('option_unassigned') },
|
|
73
|
+
...withCurrent(directory.people, task.assignee, directory).map((person) => ({
|
|
74
|
+
value: person.urn,
|
|
75
|
+
label: person.name,
|
|
76
|
+
icon: _jsx(PersonAvatar, { person: person }),
|
|
77
|
+
})),
|
|
78
|
+
], onChange: (urn) => save({ assignee: urn === NONE ? null : { urn } }) }) }), _jsx(Field, { id: `${ids}-project`, label: copy('field_project'), children: _jsx(ChoiceSelect, { id: `${ids}-project`, value: task.project?.urn ?? NONE, choices: [
|
|
79
|
+
{ value: NONE, label: copy('option_no_project') },
|
|
80
|
+
...withCurrent(directory.projects, task.project, directory).map((project) => ({
|
|
81
|
+
value: project.urn,
|
|
82
|
+
label: project.name,
|
|
83
|
+
})),
|
|
84
|
+
], onChange: (urn) => save({ project: urn === NONE ? null : { urn } }) }) }), (directory.workflows?.length || task.workflowStage) && (_jsx(Field, { id: `${ids}-stage`, label: copy('field_stage'), children: _jsx(ChoiceSelect, { id: `${ids}-stage`, value: task.workflowStage?.urn ?? NONE, choices: [
|
|
85
|
+
{ value: NONE, label: copy('option_no_stage') },
|
|
86
|
+
// A stage of a workflow the directory doesn't have still shows.
|
|
87
|
+
...(task.workflowStage && !stages.some((stage) => stage.urn === task.workflowStage?.urn)
|
|
88
|
+
? [{ value: task.workflowStage.urn, label: nameOf(directory, task.workflowStage) }]
|
|
89
|
+
: []),
|
|
90
|
+
], groups: (directory.workflows ?? []).map((workflow) => ({
|
|
91
|
+
label: workflow.name,
|
|
92
|
+
choices: workflowStages(workflow).map((stage) => ({ value: stage.urn, label: stage.name })),
|
|
93
|
+
})), onChange: (urn) => save({ workflowStage: urn === NONE ? null : { urn } }) }) })), _jsx(DueField, { id: `${ids}-due`, task: task, onCommit: (dueTimestamp) => save({ dueTimestamp }) }, `due-${task.urn}`), _jsxs("div", { className: "text-muted-foreground grid content-end gap-1 pb-1 text-xs", children: [_jsx("span", { children: copy('field_updated') }), _jsx(Timestamp, { value: task.updatedTimestamp, className: "text-foreground" })] })] }), _jsx(TextField, { id: `${ids}-description`, label: copy('field_description'), value: task.description, onCommit: (description) => save({ description }), multiline: true }, `description-${task.urn}`), _jsxs("section", { "aria-labelledby": `${ids}-blockers`, className: "grid gap-2", children: [_jsx("h3", { id: `${ids}-blockers`, className: "text-xs font-semibold tracking-wide uppercase", children: copy('blockers_heading') }), (task.blockedBy?.length ?? 0) === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: copy('blockers_none') })) : (_jsx("ul", { className: "grid gap-1.5", children: task.blockedBy.map((blocker) => {
|
|
94
|
+
const known = directory.tasks.find((t) => t.urn === blocker.urn);
|
|
95
|
+
const name = nameOf(directory, blocker);
|
|
96
|
+
return (_jsxs("li", { className: "flex items-center gap-2 text-sm", children: [known && _jsx(StatusBadge, { status: known.status }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: name }), _jsx(Button, { variant: "ghost", size: "icon-xs", "aria-label": copy('blockers_remove', { name }), onClick: () => save({ blockedBy: withoutRef(task.blockedBy, blocker) }), children: _jsx(X, { "aria-hidden": "true" }) })] }, blocker.urn));
|
|
97
|
+
}) })), blockerChoices.length > 0 && (_jsx(ChoiceSelect, { value: NONE, label: copy('blockers_add'), choices: [
|
|
98
|
+
{ value: NONE, label: copy('blockers_add') },
|
|
99
|
+
...blockerChoices.map((t) => ({ value: t.urn, label: t.title })),
|
|
100
|
+
], onChange: (urn) => urn !== NONE && save({ blockedBy: withRef(task.blockedBy, urn) }) }, `add-blocker-${task.blockedBy?.length ?? 0}`))] }), _jsx(Related, { task: task, directory: directory, onChange: save }), activity && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), activity] })), onDelete && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), confirmDelete ? (_jsxs("div", { role: "alertdialog", "aria-labelledby": `${ids}-delete`, className: "grid gap-2", children: [_jsx("p", { id: `${ids}-delete`, className: "text-sm", children: copy('task_delete_confirm') }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "destructive", size: "sm", onClick: () => onDelete().catch(() => setError(copy('editor_save_failed'))), children: [_jsx(Trash2, { "aria-hidden": "true" }), copy('task_delete')] }), _jsx(Button, { variant: "ghost", size: "sm", autoFocus: true, onClick: () => setConfirmDelete(false), children: copy('task_delete_cancel') })] })] })) : (_jsxs(Button, { variant: "ghost", size: "sm", className: "text-destructive justify-self-start", onClick: () => setConfirmDelete(true), children: [_jsx(Trash2, { "aria-hidden": "true" }), copy('task_delete')] }))] }))] }));
|
|
101
|
+
}
|
|
102
|
+
/** The directory's choices, plus the current value when the directory doesn't list it, so it still shows. */
|
|
103
|
+
function withCurrent(choices, current, directory) {
|
|
104
|
+
if (!current || choices.some((choice) => choice.urn === current.urn))
|
|
105
|
+
return choices;
|
|
106
|
+
return [...choices, { urn: current.urn, name: nameOf(directory, current) }];
|
|
107
|
+
}
|
|
108
|
+
/** A text input or textarea that saves when it loses focus (or on Enter for a single line), if the value changed. */
|
|
109
|
+
function TextField({ id, label, value, onCommit, multiline, required, }) {
|
|
110
|
+
const [draft, setDraft] = useState(value);
|
|
111
|
+
useEffect(() => setDraft(value), [value]);
|
|
112
|
+
const commit = () => {
|
|
113
|
+
if (draft === value)
|
|
114
|
+
return;
|
|
115
|
+
if (required && !draft.trim())
|
|
116
|
+
return setDraft(value);
|
|
117
|
+
onCommit(draft);
|
|
118
|
+
};
|
|
119
|
+
return (_jsx(Field, { id: id, label: label, children: multiline ? (_jsx(Textarea, { id: id, rows: 5, value: draft, onChange: (e) => setDraft(e.target.value), onBlur: commit })) : (_jsx(Input, { id: id, value: draft, required: required, onChange: (e) => setDraft(e.target.value), onBlur: commit, onKeyDown: (e) => {
|
|
120
|
+
if (e.key === 'Enter')
|
|
121
|
+
commit();
|
|
122
|
+
if (e.key === 'Escape')
|
|
123
|
+
setDraft(value);
|
|
124
|
+
} })) }));
|
|
125
|
+
}
|
|
126
|
+
function DueField({ id, task, onCommit }) {
|
|
127
|
+
const copy = useCopy();
|
|
128
|
+
const value = toLocalInput(task.dueTimestamp);
|
|
129
|
+
const [draft, setDraft] = useState(value);
|
|
130
|
+
useEffect(() => setDraft(value), [value]);
|
|
131
|
+
const commit = (next) => {
|
|
132
|
+
if (next === value)
|
|
133
|
+
return;
|
|
134
|
+
onCommit(fromLocalInput(next) ?? null);
|
|
135
|
+
};
|
|
136
|
+
return (_jsx(Field, { id: id, label: copy('field_due'), children: _jsx(Input, { id: id, type: "datetime-local", className: "h-7 text-sm", value: draft, onChange: (e) => setDraft(e.target.value), onBlur: (e) => commit(e.target.value) }) }));
|
|
137
|
+
}
|
|
138
|
+
/** The kinds of related item, in the order they're shown, with their icon and the heading for adding one. */
|
|
139
|
+
const ASSOCIATIONS = [
|
|
140
|
+
{ field: 'associatedIdentities', Icon: UserRound, heading: 'related_people' },
|
|
141
|
+
{ field: 'associatedCompanies', Icon: Building2, heading: 'related_companies' },
|
|
142
|
+
{ field: 'associatedEntities', Icon: FileText, heading: 'related_entities' },
|
|
143
|
+
{ field: 'associatedTasks', Icon: Link2, heading: 'related_tasks' },
|
|
144
|
+
];
|
|
145
|
+
/** The people, companies, content and tasks the task is associated with, each removable, and a picker to add more. */
|
|
146
|
+
function Related({ task, directory, onChange, }) {
|
|
147
|
+
const copy = useCopy();
|
|
148
|
+
const ids = useId();
|
|
149
|
+
const items = ASSOCIATIONS.flatMap(({ field, Icon }) => (task[field] ?? []).map((item) => ({ field, item, Icon })));
|
|
150
|
+
const offered = {
|
|
151
|
+
associatedIdentities: directory.people,
|
|
152
|
+
associatedCompanies: directory.companies ?? [],
|
|
153
|
+
associatedEntities: directory.entities ?? [],
|
|
154
|
+
associatedTasks: directory.tasks.filter((t) => t.urn !== task.urn).map((t) => ({ urn: t.urn, name: t.title })),
|
|
155
|
+
};
|
|
156
|
+
const groups = ASSOCIATIONS.map(({ field, heading }) => ({
|
|
157
|
+
label: copy(heading),
|
|
158
|
+
choices: offered[field]
|
|
159
|
+
.filter((choice) => !(task[field] ?? []).some((item) => item.urn === choice.urn))
|
|
160
|
+
.map((choice) => ({ value: `${field} ${choice.urn}`, label: choice.name })),
|
|
161
|
+
}));
|
|
162
|
+
return (_jsxs("section", { "aria-labelledby": `${ids}-related`, className: "grid gap-2", children: [_jsx("h3", { id: `${ids}-related`, className: "text-xs font-semibold tracking-wide uppercase", children: copy('related_heading') }), items.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: copy('related_none') })) : (_jsx("ul", { className: "flex flex-wrap gap-1.5 text-xs", children: items.map(({ field, item, Icon }) => {
|
|
163
|
+
const name = nameOf(directory, item);
|
|
164
|
+
return (_jsxs("li", { className: "bg-muted inline-flex items-center gap-1 rounded py-0.5 ps-1.5 pe-0.5", children: [_jsx(Icon, { "aria-hidden": "true", className: "size-3" }), name, _jsx(Button, { variant: "ghost", size: "icon-xs", className: "size-5", "aria-label": copy('related_remove', { name }), onClick: () => onChange({ [field]: withoutRef(task[field], item) }), children: _jsx(X, { "aria-hidden": "true" }) })] }, `${field} ${item.urn}`));
|
|
165
|
+
}) })), groups.some((group) => group.choices.length > 0) && (_jsx(ChoiceSelect, { value: NONE, label: copy('related_add'), choices: [{ value: NONE, label: copy('related_add') }], groups: groups, onChange: (value) => {
|
|
166
|
+
if (value === NONE)
|
|
167
|
+
return;
|
|
168
|
+
const [field, urn] = value.split(' ');
|
|
169
|
+
onChange({ [field]: withRef(task[field], urn) });
|
|
170
|
+
} }, `add-related-${items.length}`))] }));
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=TaskEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskEditor.js","sourceRoot":"","sources":["../../src/react/TaskEditor.tsx"],"names":[],"mappings":"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"}
|