@dxos/react-ui-task 0.13.0 → 0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a
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/dist/lib/index.mjs +56 -34
- package/dist/lib/index.mjs.map +1 -1
- package/dist/types/src/components/TaskList/TaskList.d.ts.map +1 -1
- package/dist/types/src/components/TaskList/TaskRowCells.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/src/components/TaskList/TaskList.tsx +60 -28
- package/src/components/TaskList/TaskRowCells.tsx +15 -8
- package/src/components/TaskProperties/TaskProperties.tsx +9 -5
package/dist/lib/index.mjs
CHANGED
|
@@ -7,8 +7,10 @@ import { Person, PullRequest, RemoteSession, Task } from "@dxos/types";
|
|
|
7
7
|
import { getHashHue, getStyles, mx, toHue } from "@dxos/ui-theme";
|
|
8
8
|
import { translationKey } from "#translations";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { useAtomValue } from "@effect/atom-react/Hooks";
|
|
11
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
10
12
|
import { Filter, Obj, Ref, Tag } from "@dxos/echo";
|
|
11
|
-
import { useObject, useQuery } from "@dxos/echo-react";
|
|
13
|
+
import { useLabel, useObject, useQuery } from "@dxos/echo-react";
|
|
12
14
|
import { Tree, createStaticTreeModel } from "@dxos/react-ui-list";
|
|
13
15
|
import { ActionMenu, createMenuAction, executeMenuAction, fallbackIcon } from "@dxos/react-ui-menu";
|
|
14
16
|
import * as Button from "@dxos/react-ui/Button";
|
|
@@ -391,10 +393,13 @@ var [TaskListProvider, useTaskListContext] = Hooks.createContext("TaskList.Root"
|
|
|
391
393
|
//#endregion
|
|
392
394
|
//#region src/components/TaskList/TaskRowCells.tsx
|
|
393
395
|
/** The status glyph, which is also the control that completes the task. */
|
|
396
|
+
var useAgentWorking = (task) => useAtomValue(useMemo(() => Atom.make((get) => Task.isAgentWorking(get(Obj.atom(task)))), [task]));
|
|
394
397
|
var TaskStatusControl = ({ task, onTaskUpdate, active, classNames }) => {
|
|
395
398
|
const { t } = Hooks.useTranslation(translationKey);
|
|
396
|
-
const
|
|
397
|
-
const
|
|
399
|
+
const [storedStatus] = useObject(task, "status");
|
|
400
|
+
const status = storedStatus ?? "todo";
|
|
401
|
+
const agentWorking = useAgentWorking(task);
|
|
402
|
+
const { icon, classNames: iconClassNames } = active ?? agentWorking ? {
|
|
398
403
|
icon: "ph--spinner--regular",
|
|
399
404
|
classNames: "text-info-text animate-spin"
|
|
400
405
|
} : {
|
|
@@ -517,8 +522,9 @@ TaskCheckbox.displayName = "TaskList.Checkbox";
|
|
|
517
522
|
*/
|
|
518
523
|
var TaskEstimateControl = ({ task, classNames }) => {
|
|
519
524
|
const { onTaskUpdate } = useTaskListContext("TaskList.EstimateControl");
|
|
525
|
+
const [estimate] = useObject(task, "estimate");
|
|
520
526
|
return /* @__PURE__ */ jsx(TaskEstimatePicker, {
|
|
521
|
-
estimate
|
|
527
|
+
estimate,
|
|
522
528
|
onChange: onTaskUpdate && ((estimate) => onTaskUpdate(task, { estimate: estimate ?? null })),
|
|
523
529
|
testId: "taskList.item.estimate",
|
|
524
530
|
classNames
|
|
@@ -564,8 +570,9 @@ TaskEstimateControl.displayName = "TaskList.EstimateControl";
|
|
|
564
570
|
*/
|
|
565
571
|
var TaskPriorityIcon = ({ task, classNames }) => {
|
|
566
572
|
const { onTaskUpdate } = useTaskListContext("TaskList.PriorityIcon");
|
|
573
|
+
const [priority] = useObject(task, "priority");
|
|
567
574
|
return /* @__PURE__ */ jsx(TaskPriorityPicker, {
|
|
568
|
-
priority:
|
|
575
|
+
priority: priority ?? void 0,
|
|
569
576
|
onChange: onTaskUpdate && ((priority) => onTaskUpdate(task, { priority: priority ?? null })),
|
|
570
577
|
testId: "taskList.item.priority",
|
|
571
578
|
classNames
|
|
@@ -1668,12 +1675,10 @@ var TaskListItem = ({ node, indicator, ordinal, checked, translationKey: itemTra
|
|
|
1668
1675
|
}),
|
|
1669
1676
|
/* @__PURE__ */ jsx(Layout.Flex, {
|
|
1670
1677
|
align: "center",
|
|
1671
|
-
|
|
1678
|
+
gap: "xs",
|
|
1679
|
+
classNames: "col-[title] row-start-2 px-(--dx-gap-size) empty:hidden",
|
|
1672
1680
|
"data-testid": "taskList.item.chips",
|
|
1673
|
-
children: /* @__PURE__ */ jsx(TaskListItemTags, {
|
|
1674
|
-
task,
|
|
1675
|
-
tags: Obj.getMeta(task).tags
|
|
1676
|
-
})
|
|
1681
|
+
children: /* @__PURE__ */ jsx(TaskListItemTags, { task })
|
|
1677
1682
|
}),
|
|
1678
1683
|
description && /* @__PURE__ */ jsx(TaskDescription, {
|
|
1679
1684
|
content: description,
|
|
@@ -1730,12 +1735,13 @@ TaskListItemActions.displayName = "TaskList.ItemActions";
|
|
|
1730
1735
|
*/
|
|
1731
1736
|
var TaskListItemArtifacts = ({ task, filter }) => {
|
|
1732
1737
|
const db = Obj.getDatabase(task);
|
|
1733
|
-
const
|
|
1738
|
+
const [refs] = useObject(task, "artifacts");
|
|
1739
|
+
const ids = useMemo(() => (refs ?? []).flatMap((ref) => {
|
|
1734
1740
|
const id = Task.refEntityId(ref);
|
|
1735
1741
|
return id ? [id] : [];
|
|
1736
|
-
}), [
|
|
1742
|
+
}), [refs]);
|
|
1737
1743
|
const queried = useQuery(ids.length > 0 ? db : void 0, Filter.id(...ids));
|
|
1738
|
-
const resolved = db ? queried : (
|
|
1744
|
+
const resolved = db ? queried : (refs ?? []).flatMap((ref) => ref.target ? [ref.target] : []);
|
|
1739
1745
|
const artifacts = filter ? resolved.filter(filter) : resolved;
|
|
1740
1746
|
return /* @__PURE__ */ jsx(Fragment, { children: artifacts.map((artifact) => /* @__PURE__ */ jsx(ArtifactTag, { artifact }, artifact.id)) });
|
|
1741
1747
|
};
|
|
@@ -1744,10 +1750,7 @@ TaskListItemArtifacts.displayName = "TaskList.ItemArtifacts";
|
|
|
1744
1750
|
* Everything a task carries as a chip: its tags, what it produced, and who has it.
|
|
1745
1751
|
*/
|
|
1746
1752
|
var TaskTags = ({ task }) => {
|
|
1747
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(TaskListItemTags, {
|
|
1748
|
-
task,
|
|
1749
|
-
tags: Obj.getMeta(task).tags
|
|
1750
|
-
}), /* @__PURE__ */ jsx(TaskListItemArtifacts, {
|
|
1753
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(TaskListItemTags, { task }), /* @__PURE__ */ jsx(TaskListItemArtifacts, {
|
|
1751
1754
|
task,
|
|
1752
1755
|
filter: (artifact) => PullRequest.instanceOf(artifact)
|
|
1753
1756
|
})] });
|
|
@@ -1757,15 +1760,21 @@ TaskTags.displayName = "TaskList.Tags";
|
|
|
1757
1760
|
* The task's tags, as chips in the same cell as its artifacts and assignee. Queried by id for the
|
|
1758
1761
|
* reason artifacts are: a tag's target is not in memory on a cold load.
|
|
1759
1762
|
*/
|
|
1760
|
-
var TaskListItemTags = ({ task
|
|
1763
|
+
var TaskListItemTags = ({ task }) => {
|
|
1761
1764
|
const db = Obj.getDatabase(task);
|
|
1765
|
+
const tags = useAtomValue(Obj.tagsAtom(task));
|
|
1762
1766
|
const ids = useMemo(() => tags.flatMap((ref) => {
|
|
1763
1767
|
const id = Task.refEntityId(ref);
|
|
1764
1768
|
return id ? [id] : [];
|
|
1765
1769
|
}), [tags]);
|
|
1766
1770
|
const queried = useQuery(ids.length > 0 ? db : void 0, Filter.id(...ids));
|
|
1767
|
-
const resolved = db ? queried : tags.flatMap((ref) => ref.target ? [ref.target] : [])
|
|
1768
|
-
|
|
1771
|
+
const resolved = useMemo(() => db ? queried : tags.flatMap((ref) => ref.target ? [ref.target] : []), [
|
|
1772
|
+
db,
|
|
1773
|
+
queried,
|
|
1774
|
+
tags
|
|
1775
|
+
]);
|
|
1776
|
+
const labelledAtom = useMemo(() => Atom.make((get) => resolved.filter((object) => Obj.instanceOf(Tag.Tag, object)).map((tag) => get(Obj.atom(tag))).sort(Tag.sortTags)), [resolved]);
|
|
1777
|
+
const labelled = useAtomValue(labelledAtom);
|
|
1769
1778
|
return /* @__PURE__ */ jsx(Fragment, { children: labelled.map((tag) => /* @__PURE__ */ jsx(Tag$1.Tag, {
|
|
1770
1779
|
hue: toHue(tag.hue),
|
|
1771
1780
|
"data-testid": "taskList.item.tag",
|
|
@@ -1782,20 +1791,14 @@ TaskListItemTags.displayName = "TaskList.ItemTags";
|
|
|
1782
1791
|
* markdown — so a row reads the same as the text that references it.
|
|
1783
1792
|
*/
|
|
1784
1793
|
var ArtifactTag = ({ artifact }) => {
|
|
1785
|
-
const label =
|
|
1794
|
+
const label = useLabel(artifact, { fallback: "typename" }) ?? "";
|
|
1786
1795
|
const anchor = usePreviewAnchor({
|
|
1787
1796
|
eid: Obj.getURI(artifact).toString(),
|
|
1788
1797
|
label
|
|
1789
1798
|
});
|
|
1790
|
-
if (
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
size: "sm",
|
|
1794
|
-
classNames: "bg-input-surface text-fg font-normal ring-inset ring ring-neutral-border hover:bg-hover-surface hover:ring-info-border",
|
|
1795
|
-
icon: "ph--git-pull-request--regular",
|
|
1796
|
-
iconClassNames: pullRequestStateStyle[artifact.state],
|
|
1797
|
-
label: `#${artifact.number}`,
|
|
1798
|
-
tabIndex: -1
|
|
1799
|
+
if (Obj.instanceOf(PullRequest.PullRequest, artifact)) return /* @__PURE__ */ jsx(PullRequestTag, {
|
|
1800
|
+
pullRequest: artifact,
|
|
1801
|
+
anchor
|
|
1799
1802
|
});
|
|
1800
1803
|
return /* @__PURE__ */ jsx(Tag$1.Tag, {
|
|
1801
1804
|
...anchor,
|
|
@@ -1805,6 +1808,21 @@ var ArtifactTag = ({ artifact }) => {
|
|
|
1805
1808
|
});
|
|
1806
1809
|
};
|
|
1807
1810
|
ArtifactTag.displayName = "TaskList.ArtifactTag";
|
|
1811
|
+
var PullRequestTag = ({ pullRequest, anchor }) => {
|
|
1812
|
+
const [state] = useObject(pullRequest, "state");
|
|
1813
|
+
const [number] = useObject(pullRequest, "number");
|
|
1814
|
+
return /* @__PURE__ */ jsx(Button.Root, {
|
|
1815
|
+
...anchor,
|
|
1816
|
+
hue: "neutral",
|
|
1817
|
+
size: "sm",
|
|
1818
|
+
classNames: "bg-input-surface text-fg font-normal ring-inset ring ring-neutral-border hover:bg-hover-surface hover:ring-info-border",
|
|
1819
|
+
icon: "ph--git-pull-request--regular",
|
|
1820
|
+
iconClassNames: pullRequestStateStyle[state],
|
|
1821
|
+
label: `#${number}`,
|
|
1822
|
+
tabIndex: -1
|
|
1823
|
+
});
|
|
1824
|
+
};
|
|
1825
|
+
PullRequestTag.displayName = "TaskList.PullRequestTag";
|
|
1808
1826
|
/** GitHub's own state colours, so the icon reads as open, merged or closed at a glance. */
|
|
1809
1827
|
var pullRequestStateStyle = {
|
|
1810
1828
|
open: "text-green-500",
|
|
@@ -1870,10 +1888,14 @@ var ESTIMATE_ICON = "ph--ruler--regular";
|
|
|
1870
1888
|
*/
|
|
1871
1889
|
var TaskProperties = ({ task, members = [], onTaskUpdate, classNames }) => {
|
|
1872
1890
|
const { t } = Hooks.useTranslation(translationKey);
|
|
1873
|
-
const
|
|
1874
|
-
const
|
|
1875
|
-
const
|
|
1876
|
-
const
|
|
1891
|
+
const [storedStatus] = useObject(task, "status");
|
|
1892
|
+
const [storedPriority] = useObject(task, "priority");
|
|
1893
|
+
const [storedEstimate] = useObject(task, "estimate");
|
|
1894
|
+
const [storedAssignee] = useObject(task, "assignee");
|
|
1895
|
+
const status = storedStatus ?? "todo";
|
|
1896
|
+
const priority = storedPriority ?? void 0;
|
|
1897
|
+
const estimate = storedEstimate ?? void 0;
|
|
1898
|
+
const assignee = storedAssignee ?? void 0;
|
|
1877
1899
|
const db = Obj.getDatabase(task);
|
|
1878
1900
|
const people = useQuery(onTaskUpdate ? db : void 0, Filter.type(Person.Person));
|
|
1879
1901
|
const { label: assigneeLabel, icon: assigneeIcon } = useAssigneeDisplay(assignee);
|