@parallelworks/tandem-web 0.138.0 → 0.139.0
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/components/AgentWork.js +35 -35
- package/components/AppRoot.js +4 -4
- package/components/AreaWork.js +1 -1
- package/components/BlockHandle.js +3 -3
- package/components/CommandPalette.js +27 -27
- package/components/DateChip.js +27 -27
- package/components/DocLinkPicker.js +17 -17
- package/components/Graph.js +6 -6
- package/components/HoverCards.js +30 -29
- package/components/IssueListBlock.js +83 -83
- package/components/LinkCard.js +20 -20
- package/components/MentionPicker.js +12 -12
- package/components/NewIssueDialog.js +116 -116
- package/components/NewProjectDialog.js +5 -4
- package/components/Planning.js +31 -43
- package/components/RouterLink.js +4 -4
- package/components/ShareDialog.js +12 -12
- package/components/SharedUI.js +19 -19
- package/components/SlashMenu.js +11 -11
- package/components/SubPages.js +10 -10
- package/components/UnlinkedMentions.js +10 -10
- package/components/WorkCounts.js +8 -8
- package/components/settings.js +26 -26
- package/hostedApp.js +36 -36
- package/hosting.d.ts +24 -11
- package/index.js +58 -27
- package/lib/base.js +1 -14
- package/lib/docs.js +6 -6
- package/lib/issueMenu.js +33 -33
- package/lib/knowledge.js +90 -101
- package/lib/knowledgeKinds.js +14 -0
- package/lib/projectList.js +1 -1
- package/lib/projectStates.js +15 -0
- package/lib/router.js +20 -34
- package/package.json +6 -6
- package/pages/areas.js +147 -147
- package/pages/decisions.js +40 -40
- package/pages/issues.js +4 -4
- package/pages/projects.js +232 -231
- package/pages/triage.js +86 -86
- package/pages.js +21 -0
- package/routes/__root.js +6 -6
- package/routes/_workspace/docs/_doc2.js +12 -12
- package/routes/_workspace/docs2.js +8 -8
- package/routes/_workspace/graph2.js +9 -9
- package/routes/_workspace/issues/_identifier2.js +327 -327
- package/routes/_workspace/issues/index.js +6 -6
- package/routes/_workspace/knowledge/_term2.js +125 -124
- package/routes/_workspace/knowledge/index.js +8 -8
- package/routes/_workspace/knowledge/index2.js +22 -21
- package/routes/_workspace/measures2.js +4 -4
- package/routes/_workspace/people/_username.js +4 -4
- package/routes/_workspace/projects/_projectId3.js +264 -263
- package/routes/_workspace/projects/index.js +7 -7
- package/routes/_workspace/settings/account2.js +3 -3
- package/routes/_workspace/settings/audit-log2.js +4 -4
- package/routes/_workspace/settings/audit-log3.js +51 -51
- package/routes/_workspace/settings/labels2.js +14 -14
- package/routes/_workspace/settings/members2.js +9 -9
- package/routes/_workspace/settings/runners2.js +11 -11
- package/routes/_workspace/settings/teams2.js +15 -15
- package/routes/_workspace/settings/tokens2.js +5 -5
- package/routes/_workspace/settings/webhooks2.js +7 -7
- package/routes/_workspace/settings2.js +3 -3
- package/routes/_workspace/teams/_key/cycles/_number2.js +8 -8
- package/routes/_workspace/teams/_key/cycles/index2.js +20 -20
- package/routes/_workspace/teams/_key/issues.js +4 -4
- package/routes/_workspace/teams/_key/projects.js +4 -4
- package/routes/_workspace/teams/_key/settings2.js +8 -8
- package/routes/_workspace2.js +319 -319
- package/routes/docs/route2.js +15 -15
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { appURL as e } from "../lib/base.js";
|
|
2
2
|
import { docQuery as t, docsQuery as n, issueSearchQuery as r, projectsQuery as i } from "../api/queries.js";
|
|
3
3
|
import { ProjectIcon as a, StatusIcon as o } from "./icons.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { docURL as s } from "../lib/docs.js";
|
|
5
|
+
import { headingAnchor as c, headings as l } from "../lib/glossary.js";
|
|
6
6
|
import { issueURL as u } from "../lib/issueMenu.js";
|
|
7
7
|
import { DocIcon as d } from "./DocIcon.js";
|
|
8
8
|
import { projectRef as f } from "../lib/projects.js";
|
|
9
9
|
import { useEditorListbox as p } from "./editorListbox.js";
|
|
10
10
|
import { ListboxOption as m, ListboxPanel as h, useListboxNavigation as g } from "@parallelworks/ui";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { useParams as _ } from "@tanstack/react-router";
|
|
12
|
+
import { useEffect as v, useMemo as y, useRef as b, useState as x } from "react";
|
|
13
|
+
import { useTranslations as S } from "use-intl";
|
|
14
|
+
import { jsx as C } from "react/jsx-runtime";
|
|
15
15
|
import { keepPreviousData as w, useQuery as T } from "@tanstack/react-query";
|
|
16
16
|
// src/components/DocLinkPicker.tsx
|
|
17
17
|
function E(e) {
|
|
@@ -32,7 +32,7 @@ function E(e) {
|
|
|
32
32
|
}
|
|
33
33
|
var D = 4;
|
|
34
34
|
function O({ editor: O }) {
|
|
35
|
-
let { workspace: k } =
|
|
35
|
+
let { workspace: k } = _({ strict: !1 }), A = S("docLinks"), [j, M] = x(null), [N, P] = (j?.query ?? "").split("#", 2), F = N.trim(), { data: I = [] } = T({
|
|
36
36
|
...n(k ?? "", F ? {
|
|
37
37
|
title: F,
|
|
38
38
|
limit: 8
|
|
@@ -52,7 +52,7 @@ function O({ editor: O }) {
|
|
|
52
52
|
}), { data: V = [] } = T({
|
|
53
53
|
...i(k ?? ""),
|
|
54
54
|
enabled: z
|
|
55
|
-
}), H =
|
|
55
|
+
}), H = y(() => {
|
|
56
56
|
if (P === void 0 || !L) {
|
|
57
57
|
let e = I.map((e) => ({
|
|
58
58
|
kind: "doc",
|
|
@@ -73,7 +73,7 @@ function O({ editor: O }) {
|
|
|
73
73
|
];
|
|
74
74
|
}
|
|
75
75
|
let e = P.trim().toLowerCase();
|
|
76
|
-
return
|
|
76
|
+
return l(R?.body ?? "").filter((t) => t.text.toLowerCase().includes(e)).slice(0, 8).map((e) => ({
|
|
77
77
|
kind: "doc",
|
|
78
78
|
doc: L,
|
|
79
79
|
heading: e.text
|
|
@@ -87,7 +87,7 @@ function O({ editor: O }) {
|
|
|
87
87
|
B,
|
|
88
88
|
V
|
|
89
89
|
]);
|
|
90
|
-
|
|
90
|
+
v(() => {
|
|
91
91
|
if (!O) return;
|
|
92
92
|
let e = () => {
|
|
93
93
|
M(O.isEditable && O.isFocused ? E(O) : null), G.current(0);
|
|
@@ -98,7 +98,7 @@ function O({ editor: O }) {
|
|
|
98
98
|
}, [O]);
|
|
99
99
|
let U = (t) => {
|
|
100
100
|
if (!O || !j || !t || !k) return;
|
|
101
|
-
let [n, r] = t.kind === "doc" ? [t.heading ? `${t.doc.title} › ${t.heading}` : t.doc.title,
|
|
101
|
+
let [n, r] = t.kind === "doc" ? [t.heading ? `${t.doc.title} › ${t.heading}` : t.doc.title, s(k, t.doc) + (t.heading ? `#${c(t.heading)}` : "")] : t.kind === "issue" ? [t.issue.identifier, u(k, t.issue.identifier)] : [t.project.name, e(`/${k}/projects/${f(t.project)}`)];
|
|
102
102
|
O.chain().focus().insertContentAt({
|
|
103
103
|
from: j.from,
|
|
104
104
|
to: j.to
|
|
@@ -118,8 +118,8 @@ function O({ editor: O }) {
|
|
|
118
118
|
onChoose: (e) => U(e),
|
|
119
119
|
onDismiss: () => M(null),
|
|
120
120
|
open: !!j && !!k
|
|
121
|
-
}), G =
|
|
122
|
-
return G.current = W.setActive, p(O, W, !!j && !!k, (e) => !j || e.key !== "Escape" || H.length > 0 ? !1 : (e.preventDefault(), M(null), !0)), !j || !k ? null : /* @__PURE__ */
|
|
121
|
+
}), G = b(W.setActive);
|
|
122
|
+
return G.current = W.setActive, p(O, W, !!j && !!k, (e) => !j || e.key !== "Escape" || H.length > 0 ? !1 : (e.preventDefault(), M(null), !0)), !j || !k ? null : /* @__PURE__ */ C(h, {
|
|
123
123
|
at: {
|
|
124
124
|
clientX: j.x,
|
|
125
125
|
clientY: j.y
|
|
@@ -133,7 +133,7 @@ function O({ editor: O }) {
|
|
|
133
133
|
children: H.map((e, t) => {
|
|
134
134
|
let n = e.kind === "doc" ? {
|
|
135
135
|
key: `doc:${e.doc.id}:${e.heading ?? ""}`,
|
|
136
|
-
icon: /* @__PURE__ */
|
|
136
|
+
icon: /* @__PURE__ */ C(d, {
|
|
137
137
|
icon: e.doc.icon,
|
|
138
138
|
className: "size-3.5"
|
|
139
139
|
}),
|
|
@@ -141,16 +141,16 @@ function O({ editor: O }) {
|
|
|
141
141
|
hint: e.heading ? e.doc.title : void 0
|
|
142
142
|
} : e.kind === "issue" ? {
|
|
143
143
|
key: `issue:${e.issue.id}`,
|
|
144
|
-
icon: /* @__PURE__ */
|
|
144
|
+
icon: /* @__PURE__ */ C(o, { category: e.issue.status.category }),
|
|
145
145
|
label: e.issue.title,
|
|
146
146
|
hint: e.issue.identifier
|
|
147
147
|
} : {
|
|
148
148
|
key: `project:${e.project.id}`,
|
|
149
|
-
icon: /* @__PURE__ */
|
|
149
|
+
icon: /* @__PURE__ */ C(a, {}),
|
|
150
150
|
label: e.project.name,
|
|
151
151
|
hint: A("project")
|
|
152
152
|
};
|
|
153
|
-
return /* @__PURE__ */
|
|
153
|
+
return /* @__PURE__ */ C(m, {
|
|
154
154
|
option: W.optionProps(t),
|
|
155
155
|
icon: n.icon,
|
|
156
156
|
label: n.label,
|
package/components/Graph.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Link as e, useNavigate as t } from "../lib/router.js";
|
|
2
2
|
import { docGraphQuery as n, knowledgeGraphQuery as r, teamsQuery as i, workspaceQuery as a } from "../api/queries.js";
|
|
3
3
|
import { FileTextIcon as o, LibraryIcon as s, ListViewIcon as c } from "./icons.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { docRef as l } from "../lib/docs.js";
|
|
5
|
+
import { useTermRefs as u } from "../lib/knowledge.js";
|
|
6
6
|
import { IconButton as d, SegmentedControl as f, Tooltip as p } from "@parallelworks/ui";
|
|
7
7
|
import { useMemo as m, useState as h } from "react";
|
|
8
8
|
import { useTranslations as g } from "use-intl";
|
|
@@ -173,13 +173,13 @@ function B(e, t, n) {
|
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
function V(e) {
|
|
176
|
-
let n = t(), r =
|
|
176
|
+
let n = t(), r = u(e);
|
|
177
177
|
return (t) => {
|
|
178
178
|
t.kind === "doc" ? n({
|
|
179
179
|
to: "/$workspace/docs/$doc",
|
|
180
180
|
params: {
|
|
181
181
|
workspace: e,
|
|
182
|
-
doc:
|
|
182
|
+
doc: l({
|
|
183
183
|
slug: t.slug ?? "",
|
|
184
184
|
key: t.ref ?? ""
|
|
185
185
|
})
|
|
@@ -322,7 +322,7 @@ function G({ workspace: e, nodes: t, edges: n, width: r, rooted: o, height: s })
|
|
|
322
322
|
});
|
|
323
323
|
}
|
|
324
324
|
function K({ workspace: t, nodes: n, label: r }) {
|
|
325
|
-
let i =
|
|
325
|
+
let i = u(t), a = g("graph"), o = H(), s = "flex items-baseline gap-2 rounded-md px-2 py-1 text-sm hover:bg-muted";
|
|
326
326
|
return /* @__PURE__ */ v("ul", {
|
|
327
327
|
className: "mt-3 space-y-px",
|
|
328
328
|
"aria-label": r,
|
|
@@ -338,7 +338,7 @@ function K({ workspace: t, nodes: n, label: r }) {
|
|
|
338
338
|
to: "/$workspace/docs/$doc",
|
|
339
339
|
params: {
|
|
340
340
|
workspace: t,
|
|
341
|
-
doc:
|
|
341
|
+
doc: l({
|
|
342
342
|
slug: n.slug ?? "",
|
|
343
343
|
key: n.ref ?? ""
|
|
344
344
|
})
|
package/components/HoverCards.js
CHANGED
|
@@ -2,12 +2,13 @@ import { api as e, unwrap as t } from "../api/client.js";
|
|
|
2
2
|
import { Link as n, useNavigate as r } from "../lib/router.js";
|
|
3
3
|
import { docQuery as i, docsQuery as a, knowledgeQuery as o, membersQuery as s, teamsQuery as c } from "../api/queries.js";
|
|
4
4
|
import { FileTextIcon as l } from "./icons.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { DocIcon as
|
|
9
|
-
import { docLooks as
|
|
10
|
-
import { issueRefs as
|
|
5
|
+
import { termRef as u } from "../lib/knowledgeKinds.js";
|
|
6
|
+
import { docKey as d, docRef as f } from "../lib/docs.js";
|
|
7
|
+
import { glossary as p, headingAnchor as m } from "../lib/glossary.js";
|
|
8
|
+
import { DocIcon as h } from "./DocIcon.js";
|
|
9
|
+
import { docLooks as g } from "../lib/docLooks.js";
|
|
10
|
+
import { issueRefs as _ } from "../lib/issueRefs.js";
|
|
11
|
+
import { useTermRefs as v } from "../lib/knowledge.js";
|
|
11
12
|
import { mentionable as y } from "../lib/mentions.js";
|
|
12
13
|
import { teamNames as b } from "../lib/teamNames.js";
|
|
13
14
|
import { termCaretEvent as x } from "./editorPlugins.js";
|
|
@@ -42,27 +43,27 @@ function R(e) {
|
|
|
42
43
|
return r?.[1] ? {
|
|
43
44
|
kind: "doc",
|
|
44
45
|
el: t,
|
|
45
|
-
key:
|
|
46
|
+
key: d(r[1])
|
|
46
47
|
} : null;
|
|
47
48
|
}
|
|
48
49
|
function z({ workspace: n }) {
|
|
49
|
-
let [i, l] = O(null), d = D(null),
|
|
50
|
-
|
|
50
|
+
let [i, l] = O(null), d = D(null), f = D(void 0), { data: m } = N(o(n)), h = r(), v = D((e) => {});
|
|
51
|
+
v.current = (e) => {
|
|
51
52
|
let t = m?.find((t) => t.id === e);
|
|
52
53
|
h({
|
|
53
54
|
to: "/$workspace/knowledge/$term",
|
|
54
55
|
params: {
|
|
55
56
|
workspace: n,
|
|
56
|
-
term: t ?
|
|
57
|
+
term: t ? u(t) : e
|
|
57
58
|
}
|
|
58
59
|
});
|
|
59
60
|
}, E(() => {
|
|
60
|
-
|
|
61
|
-
}, [m]), E(() => () =>
|
|
61
|
+
p.set(m ?? []);
|
|
62
|
+
}, [m]), E(() => () => p.set([]), []);
|
|
62
63
|
let { data: w } = N(a(n));
|
|
63
64
|
E(() => {
|
|
64
|
-
|
|
65
|
-
}, [w]), E(() => () =>
|
|
65
|
+
g.set(w ?? []);
|
|
66
|
+
}, [w]), E(() => () => g.set([]), []);
|
|
66
67
|
let { data: T } = N(s(n));
|
|
67
68
|
E(() => {
|
|
68
69
|
y.set((T ?? []).map((e) => e.user.username));
|
|
@@ -73,7 +74,7 @@ function z({ workspace: n }) {
|
|
|
73
74
|
}, [k]), E(() => () => b.set([]), []);
|
|
74
75
|
let A = P();
|
|
75
76
|
E(() => {
|
|
76
|
-
|
|
77
|
+
_.set(n, async (r) => {
|
|
77
78
|
let { issues: i } = t(await e.POST("/api/v1/workspaces/{workspace}/issue-refs", {
|
|
78
79
|
params: { path: { workspace: n } },
|
|
79
80
|
body: { identifiers: r }
|
|
@@ -81,10 +82,10 @@ function z({ workspace: n }) {
|
|
|
81
82
|
return new Map(i.map((e) => [e.identifier, e.issue]));
|
|
82
83
|
});
|
|
83
84
|
let r, i = A.getQueryCache().subscribe((e) => {
|
|
84
|
-
e.type === "updated" && e.query.queryKey[2] === "issues" && (clearTimeout(r), r = setTimeout(() =>
|
|
85
|
+
e.type === "updated" && e.query.queryKey[2] === "issues" && (clearTimeout(r), r = setTimeout(() => _.refresh(), 1e3));
|
|
85
86
|
});
|
|
86
87
|
return () => {
|
|
87
|
-
clearTimeout(r), i(),
|
|
88
|
+
clearTimeout(r), i(), _.set("", void 0);
|
|
88
89
|
};
|
|
89
90
|
}, [n, A]);
|
|
90
91
|
let M = D((e) => {});
|
|
@@ -104,7 +105,7 @@ function z({ workspace: n }) {
|
|
|
104
105
|
}
|
|
105
106
|
}), E(() => {
|
|
106
107
|
let e = (e, t) => {
|
|
107
|
-
clearTimeout(
|
|
108
|
+
clearTimeout(f.current), f.current = setTimeout(e, t);
|
|
108
109
|
}, t = (t) => {
|
|
109
110
|
if (t.pointerType === "touch") return;
|
|
110
111
|
let n = R(t.target);
|
|
@@ -114,7 +115,7 @@ function z({ workspace: n }) {
|
|
|
114
115
|
n && d.current?.contains(n) || R(t.target) && e(() => l(null), L);
|
|
115
116
|
}, r = (e) => {
|
|
116
117
|
let t = R(e.target);
|
|
117
|
-
t && (clearTimeout(
|
|
118
|
+
t && (clearTimeout(f.current), l(t));
|
|
118
119
|
}, i = (e) => {
|
|
119
120
|
e.target.matches?.(".kb-term[tabindex], .prose-issue a[href*=\"/docs/\"]") && r(e);
|
|
120
121
|
}, a = (e) => {
|
|
@@ -131,12 +132,12 @@ function z({ workspace: n }) {
|
|
|
131
132
|
let o = e.target.closest?.(".kb-term");
|
|
132
133
|
if (!o) return;
|
|
133
134
|
let s = o.dataset.term;
|
|
134
|
-
s && (!o.closest("[contenteditable=\"true\"]") || e.metaKey || e.ctrlKey) ? (e.preventDefault(), l(null),
|
|
135
|
+
s && (!o.closest("[contenteditable=\"true\"]") || e.metaKey || e.ctrlKey) ? (e.preventDefault(), l(null), v.current(s)) : r(e);
|
|
135
136
|
}, o = (e) => {
|
|
136
137
|
e.key === "Escape" && d.current?.isConnected && (e.stopPropagation(), e.preventDefault(), l((e) => (e?.el.tabIndex === 0 && e.el.focus(), null)));
|
|
137
138
|
};
|
|
138
139
|
return document.addEventListener("pointerover", t), document.addEventListener("pointerout", n), document.addEventListener("focusin", i), document.addEventListener("click", a), document.addEventListener(x, r), document.addEventListener("keydown", o, !0), () => {
|
|
139
|
-
clearTimeout(
|
|
140
|
+
clearTimeout(f.current), document.removeEventListener("pointerover", t), document.removeEventListener("pointerout", n), document.removeEventListener("focusin", i), document.removeEventListener("click", a), document.removeEventListener(x, r), document.removeEventListener("keydown", o, !0);
|
|
140
141
|
};
|
|
141
142
|
}, []), E(() => {
|
|
142
143
|
if (!i) return;
|
|
@@ -153,9 +154,9 @@ function z({ workspace: n }) {
|
|
|
153
154
|
onOpenChange: (e) => {
|
|
154
155
|
e || l(null);
|
|
155
156
|
},
|
|
156
|
-
onPointerEnter: () => clearTimeout(
|
|
157
|
+
onPointerEnter: () => clearTimeout(f.current),
|
|
157
158
|
onPointerLeave: () => {
|
|
158
|
-
clearTimeout(
|
|
159
|
+
clearTimeout(f.current), f.current = setTimeout(() => l(null), L);
|
|
159
160
|
},
|
|
160
161
|
card: z && /* @__PURE__ */ j("div", {
|
|
161
162
|
ref: d,
|
|
@@ -192,7 +193,7 @@ function V({ status: e }) {
|
|
|
192
193
|
});
|
|
193
194
|
}
|
|
194
195
|
function H({ workspace: e, entry: t }) {
|
|
195
|
-
let r = k("knowledge"), i =
|
|
196
|
+
let r = k("knowledge"), i = v(e);
|
|
196
197
|
if (!t) return /* @__PURE__ */ j("p", {
|
|
197
198
|
className: "text-muted-foreground",
|
|
198
199
|
children: r("gone")
|
|
@@ -206,7 +207,7 @@ function H({ workspace: e, entry: t }) {
|
|
|
206
207
|
to: "/$workspace/knowledge/$term",
|
|
207
208
|
params: {
|
|
208
209
|
workspace: e,
|
|
209
|
-
term:
|
|
210
|
+
term: u(t)
|
|
210
211
|
},
|
|
211
212
|
className: "font-semibold hover:underline",
|
|
212
213
|
children: t.name
|
|
@@ -243,9 +244,9 @@ function H({ workspace: e, entry: t }) {
|
|
|
243
244
|
to: "/$workspace/docs/$doc",
|
|
244
245
|
params: {
|
|
245
246
|
workspace: e,
|
|
246
|
-
doc:
|
|
247
|
+
doc: f(a)
|
|
247
248
|
},
|
|
248
|
-
...t.source.section && { hash:
|
|
249
|
+
...t.source.section && { hash: m(t.source.section) },
|
|
249
250
|
className: "inline-flex items-center gap-1 hover:text-foreground",
|
|
250
251
|
children: [/* @__PURE__ */ j(l, { className: "size-3" }), t.source.section ? r("sourceSection", {
|
|
251
252
|
doc: a.title,
|
|
@@ -265,7 +266,7 @@ function H({ workspace: e, entry: t }) {
|
|
|
265
266
|
to: "/$workspace/knowledge/$term",
|
|
266
267
|
params: {
|
|
267
268
|
workspace: e,
|
|
268
|
-
term:
|
|
269
|
+
term: u(t)
|
|
269
270
|
},
|
|
270
271
|
className: "mt-2 block text-xs text-primary hover:underline",
|
|
271
272
|
children: r("openEntry")
|
|
@@ -285,7 +286,7 @@ function W({ workspace: e, docKey: t }) {
|
|
|
285
286
|
children: n("unavailable")
|
|
286
287
|
}) : r ? /* @__PURE__ */ M(A, { children: [/* @__PURE__ */ M("p", {
|
|
287
288
|
className: "flex items-center gap-2 font-semibold",
|
|
288
|
-
children: [/* @__PURE__ */ j(
|
|
289
|
+
children: [/* @__PURE__ */ j(h, {
|
|
289
290
|
icon: r.icon,
|
|
290
291
|
className: "size-3.5",
|
|
291
292
|
emojiClassName: "text-xs"
|
|
@@ -5,25 +5,25 @@ import { AddIcon as l, BoardIcon as u, EditIcon as d, ListViewIcon as f, usePrio
|
|
|
5
5
|
import { isViewAt as m, statusRef as h } from "../lib/refs.js";
|
|
6
6
|
import { groupIssues as g, issueFilterOf as _, issueSearch as v, sortIssues as y } from "../lib/issueList.js";
|
|
7
7
|
import { issuesHref as b } from "../lib/teamPaths.js";
|
|
8
|
-
import { usePeople as
|
|
9
|
-
import { useIssueMenu as
|
|
10
|
-
import { useNewIssue as
|
|
11
|
-
import { viewSearch as
|
|
12
|
-
import { projectRef as
|
|
13
|
-
import { useBoardMove as
|
|
14
|
-
import { IssueBoard as
|
|
15
|
-
import { useIssueFilters as
|
|
16
|
-
import { IssueRow as
|
|
17
|
-
import { Button as
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { keepPreviousData as
|
|
23
|
-
import { ListFilterBar as
|
|
24
|
-
import { Node as
|
|
8
|
+
import { usePeople as x } from "../lib/people.js";
|
|
9
|
+
import { useIssueMenu as ee } from "../lib/issueMenu.js";
|
|
10
|
+
import { useNewIssue as S } from "../lib/newIssue.js";
|
|
11
|
+
import { viewSearch as C } from "../lib/views.js";
|
|
12
|
+
import { projectRef as w } from "../lib/projects.js";
|
|
13
|
+
import { useBoardMove as T } from "../lib/boardMove.js";
|
|
14
|
+
import { IssueBoard as E } from "./IssueBoard.js";
|
|
15
|
+
import { useIssueFilters as D, withIssueFilters as O } from "./IssueFilters.js";
|
|
16
|
+
import { IssueRow as k } from "./IssueRow.js";
|
|
17
|
+
import { Button as A, IconButton as j, SegmentedControl as M, Select as N, buttonClasses as P, useOpenMenu as F } from "@parallelworks/ui";
|
|
18
|
+
import { useParams as I } from "@tanstack/react-router";
|
|
19
|
+
import { useMemo as L, useState as R } from "react";
|
|
20
|
+
import { useTranslations as z } from "use-intl";
|
|
21
|
+
import { jsx as B, jsxs as V } from "react/jsx-runtime";
|
|
22
|
+
import { keepPreviousData as H, useQuery as U } from "@tanstack/react-query";
|
|
23
|
+
import { ListFilterBar as W, ListFilterMenu as G } from "@parallelworks/ui/list";
|
|
24
|
+
import { Node as K, NodeViewWrapper as q, ReactNodeViewRenderer as J, mergeAttributes as Y } from "@tiptap/react";
|
|
25
25
|
// src/components/IssueListBlock.tsx
|
|
26
|
-
var
|
|
26
|
+
var X = /^:::issues[ \t]*\n([\s\S]*?)(?:^|\n):::[ \t]*(?:\n|$)/, Z = 50, Q = /* @__PURE__ */ new Map(), $ = (e) => v(Object.fromEntries(new URLSearchParams(e))), te = (e) => new URLSearchParams(Object.entries(e).filter((e) => !!e[1])).toString(), ne = () => window.location.pathname.slice(e.length).split("/").filter(Boolean)[0] ?? "", re = K.create({
|
|
27
27
|
name: "issueList",
|
|
28
28
|
group: "block",
|
|
29
29
|
atom: !0,
|
|
@@ -34,15 +34,15 @@ var Y = /^:::issues[ \t]*\n([\s\S]*?)(?:^|\n):::[ \t]*(?:\n|$)/, X = 50, Z = /*
|
|
|
34
34
|
title: { default: "" }
|
|
35
35
|
}),
|
|
36
36
|
parseHTML: () => [{ tag: "div[data-issue-list]" }],
|
|
37
|
-
renderHTML: ({ HTMLAttributes: e }) => ["div",
|
|
38
|
-
addNodeView: () =>
|
|
37
|
+
renderHTML: ({ HTMLAttributes: e }) => ["div", Y(e, { "data-issue-list": "" })],
|
|
38
|
+
addNodeView: () => J(ie, { stopEvent: ({ event: e }) => !e.type.startsWith("drag") && e.target instanceof Element && !!e.target.closest("[data-block-ui]") }),
|
|
39
39
|
markdownTokenName: "issueList",
|
|
40
40
|
markdownTokenizer: {
|
|
41
41
|
name: "issueList",
|
|
42
42
|
level: "block",
|
|
43
43
|
start: (e) => e.search(/^:::issues/m),
|
|
44
44
|
tokenize: (e) => {
|
|
45
|
-
let t =
|
|
45
|
+
let t = X.exec(e);
|
|
46
46
|
return t ? {
|
|
47
47
|
type: "issueList",
|
|
48
48
|
raw: t[0],
|
|
@@ -64,7 +64,7 @@ var Y = /^:::issues[ \t]*\n([\s\S]*?)(?:^|\n):::[ \t]*(?:\n|$)/, X = 50, Z = /*
|
|
|
64
64
|
renderMarkdown: (t) => {
|
|
65
65
|
let n = t.attrs?.search ?? "", r = t.attrs?.title || "Issues";
|
|
66
66
|
if (!n) return ":::issues\n:::";
|
|
67
|
-
let i = `${window.location.origin}${e}${b(
|
|
67
|
+
let i = `${window.location.origin}${e}${b(ne(), $(n))}`, a = (Q.get(n) ?? []).map((e) => `- ${e.identifier} ${e.title} (${e.status.name})`);
|
|
68
68
|
return [
|
|
69
69
|
":::issues",
|
|
70
70
|
`[${r}](${i})`,
|
|
@@ -74,12 +74,12 @@ var Y = /^:::issues[ \t]*\n([\s\S]*?)(?:^|\n):::[ \t]*(?:\n|$)/, X = 50, Z = /*
|
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
function ie({ node: e, updateAttributes: t, editor: n }) {
|
|
77
|
-
let { workspace: r = "" } =
|
|
78
|
-
return /* @__PURE__ */
|
|
77
|
+
let { workspace: r = "" } = I({ strict: !1 }), i = e.attrs.search ?? "", [a, o] = R(!i), s = e.attrs.title;
|
|
78
|
+
return /* @__PURE__ */ B(q, {
|
|
79
79
|
className: "issue-list-block not-prose",
|
|
80
80
|
contentEditable: !1,
|
|
81
81
|
"data-drag-handle": !0,
|
|
82
|
-
children: a && n.isEditable ? /* @__PURE__ */
|
|
82
|
+
children: a && n.isEditable ? /* @__PURE__ */ B(ae, {
|
|
83
83
|
workspace: r,
|
|
84
84
|
query: i,
|
|
85
85
|
onDone: (e, n) => {
|
|
@@ -89,7 +89,7 @@ function ie({ node: e, updateAttributes: t, editor: n }) {
|
|
|
89
89
|
}), o(!1);
|
|
90
90
|
},
|
|
91
91
|
onCancel: i ? () => o(!1) : void 0
|
|
92
|
-
}) : /* @__PURE__ */
|
|
92
|
+
}) : /* @__PURE__ */ B(oe, {
|
|
93
93
|
workspace: r,
|
|
94
94
|
query: i,
|
|
95
95
|
title: s,
|
|
@@ -98,35 +98,35 @@ function ie({ node: e, updateAttributes: t, editor: n }) {
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
function ae({ workspace: e, query: t, onDone: n, onCancel: r }) {
|
|
101
|
-
let i =
|
|
102
|
-
let { saved: t, ...n } =
|
|
101
|
+
let i = z("issueListBlock"), a = z("issues"), { data: o = [] } = U(c(e)), [s, l] = R(() => $(t)), d = o.find((e) => m(e, s.saved)), p = D(e, s, (e) => {
|
|
102
|
+
let { saved: t, ...n } = O(s, e);
|
|
103
103
|
l(n);
|
|
104
104
|
});
|
|
105
|
-
return /* @__PURE__ */
|
|
105
|
+
return /* @__PURE__ */ V("div", {
|
|
106
106
|
"data-block-ui": !0,
|
|
107
107
|
className: "space-y-3 p-3",
|
|
108
108
|
children: [
|
|
109
|
-
/* @__PURE__ */
|
|
109
|
+
/* @__PURE__ */ V("div", {
|
|
110
110
|
className: "flex flex-wrap items-center gap-2",
|
|
111
111
|
children: [
|
|
112
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ B(N, {
|
|
113
113
|
value: d ? s.saved ?? "" : "",
|
|
114
114
|
items: [{
|
|
115
115
|
value: "",
|
|
116
116
|
label: i("noView")
|
|
117
117
|
}, ...o.map((e) => ({
|
|
118
|
-
value:
|
|
118
|
+
value: C(e).saved,
|
|
119
119
|
label: e.name
|
|
120
120
|
}))],
|
|
121
121
|
onValueChange: (e) => {
|
|
122
|
-
let t = o.find((t) =>
|
|
123
|
-
l(t ?
|
|
122
|
+
let t = o.find((t) => C(t).saved === e);
|
|
123
|
+
l(t ? $(new URLSearchParams(C(t)).toString()) : {});
|
|
124
124
|
},
|
|
125
125
|
"aria-label": i("savedView"),
|
|
126
126
|
width: "content"
|
|
127
127
|
}),
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ B(G, { filters: p }),
|
|
129
|
+
/* @__PURE__ */ B(M, {
|
|
130
130
|
label: i("statuses"),
|
|
131
131
|
size: "sm",
|
|
132
132
|
value: s.view ?? "active",
|
|
@@ -144,7 +144,7 @@ function ae({ workspace: e, query: t, onDone: n, onCancel: r }) {
|
|
|
144
144
|
label: a(`views.${e}`)
|
|
145
145
|
}))
|
|
146
146
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ B(M, {
|
|
148
148
|
label: i("layout"),
|
|
149
149
|
size: "sm",
|
|
150
150
|
value: s.layout ?? "list",
|
|
@@ -155,26 +155,26 @@ function ae({ workspace: e, query: t, onDone: n, onCancel: r }) {
|
|
|
155
155
|
options: [{
|
|
156
156
|
value: "list",
|
|
157
157
|
label: a("layouts.list"),
|
|
158
|
-
icon: /* @__PURE__ */
|
|
158
|
+
icon: /* @__PURE__ */ B(f, {})
|
|
159
159
|
}, {
|
|
160
160
|
value: "board",
|
|
161
161
|
label: a("layouts.board"),
|
|
162
|
-
icon: /* @__PURE__ */
|
|
162
|
+
icon: /* @__PURE__ */ B(u, {})
|
|
163
163
|
}]
|
|
164
164
|
})
|
|
165
165
|
]
|
|
166
166
|
}),
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
167
|
+
/* @__PURE__ */ B(W, { filters: p }),
|
|
168
|
+
/* @__PURE__ */ V("div", {
|
|
169
169
|
className: "flex justify-end gap-2",
|
|
170
|
-
children: [r && /* @__PURE__ */
|
|
170
|
+
children: [r && /* @__PURE__ */ B(A, {
|
|
171
171
|
size: "sm",
|
|
172
172
|
onClick: r,
|
|
173
173
|
children: i("cancel")
|
|
174
|
-
}), /* @__PURE__ */
|
|
174
|
+
}), /* @__PURE__ */ B(A, {
|
|
175
175
|
size: "sm",
|
|
176
176
|
variant: "primary",
|
|
177
|
-
onClick: () => n(
|
|
177
|
+
onClick: () => n(te({
|
|
178
178
|
view: "active",
|
|
179
179
|
...s
|
|
180
180
|
}), d?.name ?? ""),
|
|
@@ -185,20 +185,20 @@ function ae({ workspace: e, query: t, onDone: n, onCancel: r }) {
|
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
187
|
function oe({ workspace: e, query: n, title: i, onEdit: a }) {
|
|
188
|
-
let c =
|
|
188
|
+
let c = z("issueListBlock"), u = z("issues"), f = L(() => $(n), [n]), { data: m = [] } = U(s(e)), { data: h } = U({
|
|
189
189
|
...o(e, f.team ?? ""),
|
|
190
190
|
enabled: !!f.team
|
|
191
|
-
}), { data: v, isPending:
|
|
191
|
+
}), { data: v, isPending: S } = U({
|
|
192
192
|
...r(e, _(f, h)),
|
|
193
|
-
placeholderData:
|
|
193
|
+
placeholderData: H,
|
|
194
194
|
enabled: !f.status || !f.team || !!h
|
|
195
|
-
}),
|
|
196
|
-
|
|
197
|
-
let
|
|
195
|
+
}), C = L(() => y(v?.issues ?? [], f.order ?? "updated"), [v, f.order]);
|
|
196
|
+
Q.set(n, C);
|
|
197
|
+
let w = ee(e), D = F(), O = T(e, m), A = p(), { nameOf: M, avatarOf: N } = x(e), I = se(e, f, h), R = f.layout === "board", W = b(e, f), G = R ? g(C, "status", {
|
|
198
198
|
status: (e) => u(`groups.${e}`),
|
|
199
|
-
priority: (e) =>
|
|
200
|
-
person:
|
|
201
|
-
avatar:
|
|
199
|
+
priority: (e) => A[e] ?? "",
|
|
200
|
+
person: M,
|
|
201
|
+
avatar: N,
|
|
202
202
|
none: {
|
|
203
203
|
assignee: u("noAssignee"),
|
|
204
204
|
project: u("noProject"),
|
|
@@ -206,82 +206,82 @@ function oe({ workspace: e, query: n, title: i, onEdit: a }) {
|
|
|
206
206
|
all: u("all")
|
|
207
207
|
}
|
|
208
208
|
}, !0) : [];
|
|
209
|
-
return /* @__PURE__ */
|
|
209
|
+
return /* @__PURE__ */ V("div", {
|
|
210
210
|
"data-block-ui": !0,
|
|
211
|
-
children: [/* @__PURE__ */
|
|
211
|
+
children: [/* @__PURE__ */ V("div", {
|
|
212
212
|
className: "flex items-center gap-2 border-b border-border px-3 py-1.5",
|
|
213
213
|
children: [
|
|
214
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ B("span", {
|
|
215
215
|
className: "min-w-0 truncate text-xs font-medium",
|
|
216
216
|
children: i || c("title")
|
|
217
217
|
}),
|
|
218
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ B("span", {
|
|
219
219
|
className: "text-xs text-muted-foreground tabular-nums",
|
|
220
|
-
children: v ?
|
|
220
|
+
children: v ? C.length : ""
|
|
221
221
|
}),
|
|
222
|
-
/* @__PURE__ */
|
|
223
|
-
/* @__PURE__ */
|
|
224
|
-
to:
|
|
225
|
-
className:
|
|
222
|
+
/* @__PURE__ */ B("span", { className: "flex-1" }),
|
|
223
|
+
/* @__PURE__ */ B(t, {
|
|
224
|
+
to: W,
|
|
225
|
+
className: P({
|
|
226
226
|
variant: "ghost",
|
|
227
227
|
size: "xs"
|
|
228
228
|
}),
|
|
229
229
|
children: c("openList")
|
|
230
230
|
}),
|
|
231
|
-
/* @__PURE__ */
|
|
231
|
+
/* @__PURE__ */ B(j, {
|
|
232
232
|
variant: "ghost",
|
|
233
233
|
size: "xs",
|
|
234
|
-
icon: /* @__PURE__ */
|
|
234
|
+
icon: /* @__PURE__ */ B(l, {}),
|
|
235
235
|
label: c("newIssue"),
|
|
236
236
|
onClick: I
|
|
237
237
|
}),
|
|
238
|
-
a && /* @__PURE__ */
|
|
238
|
+
a && /* @__PURE__ */ B(j, {
|
|
239
239
|
variant: "ghost",
|
|
240
240
|
size: "xs",
|
|
241
|
-
icon: /* @__PURE__ */
|
|
241
|
+
icon: /* @__PURE__ */ B(d, {}),
|
|
242
242
|
label: c("edit"),
|
|
243
243
|
onClick: a
|
|
244
244
|
})
|
|
245
245
|
]
|
|
246
|
-
}),
|
|
246
|
+
}), S ? /* @__PURE__ */ B("p", {
|
|
247
247
|
className: "px-3 py-2 text-xs text-muted-foreground",
|
|
248
248
|
children: c("loading")
|
|
249
|
-
}) :
|
|
249
|
+
}) : C.length === 0 ? /* @__PURE__ */ B("p", {
|
|
250
250
|
className: "px-3 py-2 text-xs text-muted-foreground",
|
|
251
251
|
children: c("none")
|
|
252
|
-
}) :
|
|
252
|
+
}) : R ? /* @__PURE__ */ B("div", {
|
|
253
253
|
className: "max-h-[28rem] overflow-hidden",
|
|
254
|
-
children: /* @__PURE__ */
|
|
254
|
+
children: /* @__PURE__ */ B(E, {
|
|
255
255
|
workspace: e,
|
|
256
|
-
columns:
|
|
257
|
-
onMove: (e, t, n) =>
|
|
258
|
-
onContextMenu: (e, t) =>
|
|
256
|
+
columns: G,
|
|
257
|
+
onMove: (e, t, n) => O(e, "status", t, n),
|
|
258
|
+
onContextMenu: (e, t) => D(e, w([t]))
|
|
259
259
|
})
|
|
260
|
-
}) : /* @__PURE__ */
|
|
260
|
+
}) : /* @__PURE__ */ V("ul", { children: [C.slice(0, Z).map((t) => /* @__PURE__ */ B(k, {
|
|
261
261
|
issue: t,
|
|
262
262
|
team: m.find((e) => e.id === t.teamId),
|
|
263
263
|
workspace: e,
|
|
264
|
-
onContextMenu: (e) =>
|
|
265
|
-
}, t.id)),
|
|
264
|
+
onContextMenu: (e) => D(e, w([t]))
|
|
265
|
+
}, t.id)), C.length > Z && /* @__PURE__ */ B("li", {
|
|
266
266
|
className: "px-3 py-2 text-xs",
|
|
267
|
-
children: /* @__PURE__ */
|
|
268
|
-
to:
|
|
267
|
+
children: /* @__PURE__ */ B(t, {
|
|
268
|
+
to: W,
|
|
269
269
|
className: "text-primary hover:underline",
|
|
270
|
-
children: c("more", { count:
|
|
270
|
+
children: c("more", { count: C.length - Z })
|
|
271
271
|
})
|
|
272
272
|
})] })]
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
function se(e, t, r) {
|
|
276
|
-
let o =
|
|
276
|
+
let o = S(), { data: s = [] } = U(i(e)), { data: c = [] } = U({
|
|
277
277
|
...a(e),
|
|
278
278
|
enabled: !!t.project
|
|
279
|
-
}), { data: l = [] } =
|
|
279
|
+
}), { data: l = [] } = U({
|
|
280
280
|
...n(e, t.team ?? ""),
|
|
281
281
|
enabled: !!t.team && !!t.cycle
|
|
282
282
|
});
|
|
283
283
|
return () => {
|
|
284
|
-
let e = (e) => e?.split(",")[0], n = r?.find((n) => h(n) === e(t.status)), i = s.find((e) => e.name.toLowerCase() === t.label?.toLowerCase()), a = c.find((e) =>
|
|
284
|
+
let e = (e) => e?.split(",")[0], n = r?.find((n) => h(n) === e(t.status)), i = s.find((e) => e.name.toLowerCase() === t.label?.toLowerCase()), a = c.find((e) => w(e) === t.project), u = l.find((e) => String(e.number) === t.cycle || e.id === t.cycle), d = e(t.priority);
|
|
285
285
|
o({
|
|
286
286
|
...t.team && { team: t.team },
|
|
287
287
|
fields: {
|
|
@@ -295,4 +295,4 @@ function se(e, t, r) {
|
|
|
295
295
|
});
|
|
296
296
|
};
|
|
297
297
|
}
|
|
298
|
-
export {
|
|
298
|
+
export { re as IssueListBlock };
|