@parallelworks/tandem-web 0.138.2 → 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.
Files changed (71) hide show
  1. package/components/AgentWork.js +35 -35
  2. package/components/AppRoot.js +4 -4
  3. package/components/AreaWork.js +1 -1
  4. package/components/BlockHandle.js +3 -3
  5. package/components/CommandPalette.js +27 -27
  6. package/components/DateChip.js +27 -27
  7. package/components/DocLinkPicker.js +17 -17
  8. package/components/Graph.js +6 -6
  9. package/components/HoverCards.js +30 -29
  10. package/components/IssueListBlock.js +83 -83
  11. package/components/LinkCard.js +20 -20
  12. package/components/MentionPicker.js +12 -12
  13. package/components/NewIssueDialog.js +116 -116
  14. package/components/NewProjectDialog.js +5 -4
  15. package/components/Planning.js +31 -43
  16. package/components/RouterLink.js +4 -4
  17. package/components/ShareDialog.js +12 -12
  18. package/components/SharedUI.js +19 -19
  19. package/components/SlashMenu.js +11 -11
  20. package/components/SubPages.js +10 -10
  21. package/components/UnlinkedMentions.js +10 -10
  22. package/components/WorkCounts.js +8 -8
  23. package/components/settings.js +26 -26
  24. package/hostedApp.js +36 -36
  25. package/hosting.d.ts +24 -11
  26. package/index.js +58 -27
  27. package/lib/base.js +1 -14
  28. package/lib/docs.js +6 -6
  29. package/lib/issueMenu.js +33 -33
  30. package/lib/knowledge.js +90 -101
  31. package/lib/knowledgeKinds.js +14 -0
  32. package/lib/projectList.js +1 -1
  33. package/lib/projectStates.js +15 -0
  34. package/lib/router.js +20 -34
  35. package/package.json +2 -2
  36. package/pages/areas.js +147 -147
  37. package/pages/decisions.js +40 -40
  38. package/pages/issues.js +4 -4
  39. package/pages/projects.js +232 -231
  40. package/pages/triage.js +86 -86
  41. package/pages.js +21 -0
  42. package/routes/__root.js +6 -6
  43. package/routes/_workspace/docs/_doc2.js +12 -12
  44. package/routes/_workspace/docs2.js +8 -8
  45. package/routes/_workspace/graph2.js +9 -9
  46. package/routes/_workspace/issues/_identifier2.js +327 -327
  47. package/routes/_workspace/issues/index.js +6 -6
  48. package/routes/_workspace/knowledge/_term2.js +125 -124
  49. package/routes/_workspace/knowledge/index.js +8 -8
  50. package/routes/_workspace/knowledge/index2.js +22 -21
  51. package/routes/_workspace/measures2.js +4 -4
  52. package/routes/_workspace/people/_username.js +4 -4
  53. package/routes/_workspace/projects/_projectId3.js +264 -263
  54. package/routes/_workspace/projects/index.js +7 -7
  55. package/routes/_workspace/settings/account2.js +3 -3
  56. package/routes/_workspace/settings/audit-log2.js +4 -4
  57. package/routes/_workspace/settings/audit-log3.js +51 -51
  58. package/routes/_workspace/settings/labels2.js +14 -14
  59. package/routes/_workspace/settings/members2.js +9 -9
  60. package/routes/_workspace/settings/runners2.js +11 -11
  61. package/routes/_workspace/settings/teams2.js +15 -15
  62. package/routes/_workspace/settings/tokens2.js +5 -5
  63. package/routes/_workspace/settings/webhooks2.js +7 -7
  64. package/routes/_workspace/settings2.js +3 -3
  65. package/routes/_workspace/teams/_key/cycles/_number2.js +8 -8
  66. package/routes/_workspace/teams/_key/cycles/index2.js +20 -20
  67. package/routes/_workspace/teams/_key/issues.js +4 -4
  68. package/routes/_workspace/teams/_key/projects.js +4 -4
  69. package/routes/_workspace/teams/_key/settings2.js +8 -8
  70. package/routes/_workspace2.js +319 -319
  71. 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 { headingAnchor as s, headings as c } from "../lib/glossary.js";
5
- import { docURL as l } from "../lib/docs.js";
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 { useEffect as _, useMemo as v, useRef as y, useState as b } from "react";
12
- import { useTranslations as x } from "use-intl";
13
- import { jsx as S } from "react/jsx-runtime";
14
- import { useParams as C } from "@tanstack/react-router";
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 } = C({ strict: !1 }), A = x("docLinks"), [j, M] = b(null), [N, P] = (j?.query ?? "").split("#", 2), F = N.trim(), { data: I = [] } = T({
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 = v(() => {
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 c(R?.body ?? "").filter((t) => t.text.toLowerCase().includes(e)).slice(0, 8).map((e) => ({
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, l(k, t.doc) + (t.heading ? `#${s(t.heading)}` : "")] : t.kind === "issue" ? [t.issue.identifier, u(k, t.issue.identifier)] : [t.project.name, e(`/${k}/projects/${f(t.project)}`)];
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 = y(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__ */ S(h, {
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__ */ S(d, {
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__ */ S(o, { category: e.issue.status.category }),
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__ */ S(a, {}),
149
+ icon: /* @__PURE__ */ C(a, {}),
150
150
  label: e.project.name,
151
151
  hint: A("project")
152
152
  };
153
- return /* @__PURE__ */ S(m, {
153
+ return /* @__PURE__ */ C(m, {
154
154
  option: W.optionProps(t),
155
155
  icon: n.icon,
156
156
  label: n.label,
@@ -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 { useTermRefs as l } from "../lib/knowledge.js";
5
- import { docRef as u } from "../lib/docs.js";
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 = l(e);
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: u({
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 = l(t), a = g("graph"), o = H(), s = "flex items-baseline gap-2 rounded-md px-2 py-1 text-sm hover:bg-muted";
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: u({
341
+ doc: l({
342
342
  slug: n.slug ?? "",
343
343
  key: n.ref ?? ""
344
344
  })
@@ -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 { glossary as u, headingAnchor as d } from "../lib/glossary.js";
6
- import { termRef as f, useTermRefs as p } from "../lib/knowledge.js";
7
- import { docKey as m, docRef as h } from "../lib/docs.js";
8
- import { DocIcon as g } from "./DocIcon.js";
9
- import { docLooks as _ } from "../lib/docLooks.js";
10
- import { issueRefs as v } from "../lib/issueRefs.js";
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: m(r[1])
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), p = D(void 0), { data: m } = N(o(n)), h = r(), g = D((e) => {});
50
- g.current = (e) => {
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 ? f(t) : e
57
+ term: t ? u(t) : e
57
58
  }
58
59
  });
59
60
  }, E(() => {
60
- u.set(m ?? []);
61
- }, [m]), E(() => () => u.set([]), []);
61
+ p.set(m ?? []);
62
+ }, [m]), E(() => () => p.set([]), []);
62
63
  let { data: w } = N(a(n));
63
64
  E(() => {
64
- _.set(w ?? []);
65
- }, [w]), E(() => () => _.set([]), []);
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
- v.set(n, async (r) => {
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(() => v.refresh(), 1e3));
85
+ e.type === "updated" && e.query.queryKey[2] === "issues" && (clearTimeout(r), r = setTimeout(() => _.refresh(), 1e3));
85
86
  });
86
87
  return () => {
87
- clearTimeout(r), i(), v.set("", void 0);
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(p.current), p.current = setTimeout(e, t);
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(p.current), l(t));
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), g.current(s)) : r(e);
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(p.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
+ 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(p.current),
157
+ onPointerEnter: () => clearTimeout(f.current),
157
158
  onPointerLeave: () => {
158
- clearTimeout(p.current), p.current = setTimeout(() => l(null), L);
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 = p(e);
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: f(t)
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: h(a)
247
+ doc: f(a)
247
248
  },
248
- ...t.source.section && { hash: d(t.source.section) },
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: f(t)
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(g, {
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 ee } from "../lib/people.js";
9
- import { useIssueMenu as te } from "../lib/issueMenu.js";
10
- import { useNewIssue as x } from "../lib/newIssue.js";
11
- import { viewSearch as S } from "../lib/views.js";
12
- import { projectRef as C } from "../lib/projects.js";
13
- import { useBoardMove as w } from "../lib/boardMove.js";
14
- import { IssueBoard as T } from "./IssueBoard.js";
15
- import { useIssueFilters as E, withIssueFilters as D } from "./IssueFilters.js";
16
- import { IssueRow as O } from "./IssueRow.js";
17
- import { Button as k, IconButton as A, SegmentedControl as j, Select as M, buttonClasses as N, useOpenMenu as P } from "@parallelworks/ui";
18
- import { useMemo as F, useState as I } from "react";
19
- import { useTranslations as L } from "use-intl";
20
- import { jsx as R, jsxs as z } from "react/jsx-runtime";
21
- import { useParams as B } from "@tanstack/react-router";
22
- import { keepPreviousData as V, useQuery as H } from "@tanstack/react-query";
23
- import { ListFilterBar as U, ListFilterMenu as W } from "@parallelworks/ui/list";
24
- import { Node as G, NodeViewWrapper as K, ReactNodeViewRenderer as q, mergeAttributes as J } from "@tiptap/react";
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 Y = /^:::issues[ \t]*\n([\s\S]*?)(?:^|\n):::[ \t]*(?:\n|$)/, X = 50, Z = /* @__PURE__ */ new Map(), Q = (e) => v(Object.fromEntries(new URLSearchParams(e))), ne = (e) => new URLSearchParams(Object.entries(e).filter((e) => !!e[1])).toString(), re = () => window.location.pathname.slice(e.length).split("/").filter(Boolean)[0] ?? "", $ = G.create({
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", J(e, { "data-issue-list": "" })],
38
- addNodeView: () => q(ie, { stopEvent: ({ event: e }) => !e.type.startsWith("drag") && e.target instanceof Element && !!e.target.closest("[data-block-ui]") }),
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 = Y.exec(e);
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(re(), Q(n))}`, a = (Z.get(n) ?? []).map((e) => `- ${e.identifier} ${e.title} (${e.status.name})`);
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 = "" } = B({ strict: !1 }), i = e.attrs.search ?? "", [a, o] = I(!i), s = e.attrs.title;
78
- return /* @__PURE__ */ R(K, {
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__ */ R(ae, {
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__ */ R(oe, {
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 = L("issueListBlock"), a = L("issues"), { data: o = [] } = H(c(e)), [s, l] = I(() => Q(t)), d = o.find((e) => m(e, s.saved)), p = E(e, s, (e) => {
102
- let { saved: t, ...n } = D(s, e);
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__ */ z("div", {
105
+ return /* @__PURE__ */ V("div", {
106
106
  "data-block-ui": !0,
107
107
  className: "space-y-3 p-3",
108
108
  children: [
109
- /* @__PURE__ */ z("div", {
109
+ /* @__PURE__ */ V("div", {
110
110
  className: "flex flex-wrap items-center gap-2",
111
111
  children: [
112
- /* @__PURE__ */ R(M, {
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: S(e).saved,
118
+ value: C(e).saved,
119
119
  label: e.name
120
120
  }))],
121
121
  onValueChange: (e) => {
122
- let t = o.find((t) => S(t).saved === e);
123
- l(t ? Q(new URLSearchParams(S(t)).toString()) : {});
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__ */ R(W, { filters: p }),
129
- /* @__PURE__ */ R(j, {
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__ */ R(j, {
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__ */ R(f, {})
158
+ icon: /* @__PURE__ */ B(f, {})
159
159
  }, {
160
160
  value: "board",
161
161
  label: a("layouts.board"),
162
- icon: /* @__PURE__ */ R(u, {})
162
+ icon: /* @__PURE__ */ B(u, {})
163
163
  }]
164
164
  })
165
165
  ]
166
166
  }),
167
- /* @__PURE__ */ R(U, { filters: p }),
168
- /* @__PURE__ */ z("div", {
167
+ /* @__PURE__ */ B(W, { filters: p }),
168
+ /* @__PURE__ */ V("div", {
169
169
  className: "flex justify-end gap-2",
170
- children: [r && /* @__PURE__ */ R(k, {
170
+ children: [r && /* @__PURE__ */ B(A, {
171
171
  size: "sm",
172
172
  onClick: r,
173
173
  children: i("cancel")
174
- }), /* @__PURE__ */ R(k, {
174
+ }), /* @__PURE__ */ B(A, {
175
175
  size: "sm",
176
176
  variant: "primary",
177
- onClick: () => n(ne({
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 = L("issueListBlock"), u = L("issues"), f = F(() => Q(n), [n]), { data: m = [] } = H(s(e)), { data: h } = H({
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: x } = H({
191
+ }), { data: v, isPending: S } = U({
192
192
  ...r(e, _(f, h)),
193
- placeholderData: V,
193
+ placeholderData: H,
194
194
  enabled: !f.status || !f.team || !!h
195
- }), S = F(() => y(v?.issues ?? [], f.order ?? "updated"), [v, f.order]);
196
- Z.set(n, S);
197
- let C = te(e), E = P(), D = w(e, m), k = p(), { nameOf: j, avatarOf: M } = ee(e), I = se(e, f, h), B = f.layout === "board", U = b(e, f), W = B ? g(S, "status", {
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) => k[e] ?? "",
200
- person: j,
201
- avatar: M,
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__ */ z("div", {
209
+ return /* @__PURE__ */ V("div", {
210
210
  "data-block-ui": !0,
211
- children: [/* @__PURE__ */ z("div", {
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__ */ R("span", {
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__ */ R("span", {
218
+ /* @__PURE__ */ B("span", {
219
219
  className: "text-xs text-muted-foreground tabular-nums",
220
- children: v ? S.length : ""
220
+ children: v ? C.length : ""
221
221
  }),
222
- /* @__PURE__ */ R("span", { className: "flex-1" }),
223
- /* @__PURE__ */ R(t, {
224
- to: U,
225
- className: N({
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__ */ R(A, {
231
+ /* @__PURE__ */ B(j, {
232
232
  variant: "ghost",
233
233
  size: "xs",
234
- icon: /* @__PURE__ */ R(l, {}),
234
+ icon: /* @__PURE__ */ B(l, {}),
235
235
  label: c("newIssue"),
236
236
  onClick: I
237
237
  }),
238
- a && /* @__PURE__ */ R(A, {
238
+ a && /* @__PURE__ */ B(j, {
239
239
  variant: "ghost",
240
240
  size: "xs",
241
- icon: /* @__PURE__ */ R(d, {}),
241
+ icon: /* @__PURE__ */ B(d, {}),
242
242
  label: c("edit"),
243
243
  onClick: a
244
244
  })
245
245
  ]
246
- }), x ? /* @__PURE__ */ R("p", {
246
+ }), S ? /* @__PURE__ */ B("p", {
247
247
  className: "px-3 py-2 text-xs text-muted-foreground",
248
248
  children: c("loading")
249
- }) : S.length === 0 ? /* @__PURE__ */ R("p", {
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
- }) : B ? /* @__PURE__ */ R("div", {
252
+ }) : R ? /* @__PURE__ */ B("div", {
253
253
  className: "max-h-[28rem] overflow-hidden",
254
- children: /* @__PURE__ */ R(T, {
254
+ children: /* @__PURE__ */ B(E, {
255
255
  workspace: e,
256
- columns: W,
257
- onMove: (e, t, n) => D(e, "status", t, n),
258
- onContextMenu: (e, t) => E(e, C([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__ */ z("ul", { children: [S.slice(0, X).map((t) => /* @__PURE__ */ R(O, {
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) => E(e, C([t]))
265
- }, t.id)), S.length > X && /* @__PURE__ */ R("li", {
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__ */ R(t, {
268
- to: U,
267
+ children: /* @__PURE__ */ B(t, {
268
+ to: W,
269
269
  className: "text-primary hover:underline",
270
- children: c("more", { count: S.length - X })
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 = x(), { data: s = [] } = H(i(e)), { data: c = [] } = H({
276
+ let o = S(), { data: s = [] } = U(i(e)), { data: c = [] } = U({
277
277
  ...a(e),
278
278
  enabled: !!t.project
279
- }), { data: l = [] } = H({
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) => C(e) === t.project), u = l.find((e) => String(e.number) === t.cycle || e.id === t.cycle), d = e(t.priority);
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 { $ as IssueListBlock };
298
+ export { re as IssueListBlock };