@parallelworks/tandem-web 0.142.0 → 0.144.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 (58) hide show
  1. package/_virtual/_virtual_i18n/en/common.js +156 -6
  2. package/_virtual/_virtual_i18n/es/common.js +156 -6
  3. package/_virtual/_virtual_i18n/ja/common.js +156 -6
  4. package/_virtual/_virtual_i18n/ko/common.js +156 -6
  5. package/_virtual/_virtual_i18n/zh/common.js +156 -6
  6. package/api/queries.js +85 -74
  7. package/components/AccessGrants.js +6 -6
  8. package/components/ActivityTimeline.js +2 -0
  9. package/components/CodeHostSettings.js +25 -25
  10. package/components/CustomFields.js +349 -0
  11. package/components/DocProperties.js +8 -2
  12. package/components/GitHub.js +22 -22
  13. package/components/IssueBoard.js +48 -43
  14. package/components/IssueEvent.js +2 -0
  15. package/components/IssueFilters.js +210 -122
  16. package/components/IssueImport.js +1 -1
  17. package/components/IssueRow.js +96 -79
  18. package/components/IssueTemplates.js +216 -156
  19. package/components/IssueTypes.js +318 -0
  20. package/components/NewIssueDialog.js +254 -216
  21. package/components/SettingsNav.js +45 -35
  22. package/components/TeamForm.js +49 -35
  23. package/components/TeamRepositories.js +51 -51
  24. package/components/TeamWorkflow.js +8 -8
  25. package/components/Updates.js +8 -8
  26. package/components/icons.js +8 -8
  27. package/lib/boardMove.js +69 -47
  28. package/lib/customFields.js +113 -0
  29. package/lib/issueDisplay.js +27 -12
  30. package/lib/issueList.js +166 -62
  31. package/lib/issueTypes.js +50 -0
  32. package/lib/teamTree.js +24 -0
  33. package/lib/views.js +13 -11
  34. package/package.json +1 -1
  35. package/pages/issues.js +331 -291
  36. package/routeTree.gen.js +186 -174
  37. package/routes/_workspace/agents/index2.js +9 -9
  38. package/routes/_workspace/issues/_identifier2.js +433 -370
  39. package/routes/_workspace/projects/_projectId3.js +213 -201
  40. package/routes/_workspace/settings/audit-log3.js +2 -0
  41. package/routes/_workspace/settings/fields.js +6 -0
  42. package/routes/_workspace/settings/fields2.js +30 -0
  43. package/routes/_workspace/settings/fields3.js +5 -0
  44. package/routes/_workspace/settings/groups2.js +74 -74
  45. package/routes/_workspace/settings/import.js +6 -0
  46. package/routes/_workspace/settings/import2.js +330 -0
  47. package/routes/_workspace/settings/import3.js +4 -0
  48. package/routes/_workspace/settings/labels2.js +33 -33
  49. package/routes/_workspace/settings/members2.js +35 -35
  50. package/routes/_workspace/settings/roles2.js +24 -24
  51. package/routes/_workspace/settings/runners2.js +18 -18
  52. package/routes/_workspace/settings/sessions2.js +9 -9
  53. package/routes/_workspace/settings/slack2.js +8 -8
  54. package/routes/_workspace/settings/sso2.js +50 -50
  55. package/routes/_workspace/settings/tokens2.js +15 -15
  56. package/routes/_workspace/settings/webhooks2.js +42 -42
  57. package/routes/_workspace/teams/_key/settings2.js +138 -76
  58. package/routes/_workspace2.js +320 -318
@@ -0,0 +1,318 @@
1
+ import { teamsQuery as e } from "../api/queries.js";
2
+ import { useConfirm as t } from "../lib/confirm.js";
3
+ import { customFieldsQuery as n } from "../lib/customFields.js";
4
+ import { issueTypesQuery as r, useIssueTypeActions as i } from "../lib/issueTypes.js";
5
+ import { AddIcon as a } from "./icons.js";
6
+ import { Button as o, ColorInput as s, ErrorText as c, IconButton as l, Input as u, Select as d, SettingsCard as f, Textarea as p, menuDivider as m, useOpenMenu as h } from "@parallelworks/ui";
7
+ import { useState as g } from "react";
8
+ import { useErrorMessage as _ } from "@parallelworks/problem/react";
9
+ import { useTranslations as v } from "use-intl";
10
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
11
+ import { useQuery as x } from "@tanstack/react-query";
12
+ // src/components/IssueTypes.tsx
13
+ function S({ type: e, className: t = "size-4" }) {
14
+ return e.icon ? /* @__PURE__ */ y("span", {
15
+ "aria-hidden": !0,
16
+ className: `inline-flex shrink-0 items-center justify-center ${t}`,
17
+ children: e.icon
18
+ }) : /* @__PURE__ */ y("span", {
19
+ "aria-hidden": !0,
20
+ className: `inline-flex shrink-0 items-center justify-center rounded-[4px] text-[9px] font-semibold text-white ${t}`,
21
+ style: { background: e.color || "var(--color-muted-foreground)" },
22
+ children: e.name.trim().charAt(0).toUpperCase()
23
+ });
24
+ }
25
+ function C({ workspace: e }) {
26
+ let t = v("issueTypes"), { data: n = [] } = x(r(e)), [i, s] = g(!1);
27
+ return /* @__PURE__ */ b(f, {
28
+ title: t("title"),
29
+ description: t("description"),
30
+ action: /* @__PURE__ */ y(o, {
31
+ size: "sm",
32
+ icon: /* @__PURE__ */ y(a, {}),
33
+ onClick: () => s(!0),
34
+ children: t("add")
35
+ }),
36
+ children: [i && /* @__PURE__ */ y("div", {
37
+ className: "p-2",
38
+ children: /* @__PURE__ */ y(T, {
39
+ workspace: e,
40
+ onDone: () => s(!1)
41
+ })
42
+ }), n.length === 0 && !i ? /* @__PURE__ */ y("p", {
43
+ className: "px-3 py-3 text-sm text-muted-foreground",
44
+ children: t("none")
45
+ }) : /* @__PURE__ */ y("ul", {
46
+ className: "divide-y divide-border",
47
+ children: n.map((t, r) => /* @__PURE__ */ y(w, {
48
+ workspace: e,
49
+ type: t,
50
+ before: n[r - 1],
51
+ after: n[r + 1]
52
+ }, t.id))
53
+ })]
54
+ });
55
+ }
56
+ function w({ workspace: n, type: r, before: a, after: o }) {
57
+ let s = v("issueTypes"), c = i(n), u = h(), { confirm: d, dialog: f } = t(), [p, _] = g(!1), { data: C = [] } = x(e(n)), w = (e) => {
58
+ let t = {
59
+ ...r,
60
+ ...e
61
+ };
62
+ return {
63
+ id: r.id,
64
+ name: t.name,
65
+ description: t.description ?? "",
66
+ icon: t.icon ?? "",
67
+ color: t.color ?? "",
68
+ teamIds: t.teamIds,
69
+ fieldIds: t.fieldIds,
70
+ requiredFieldIds: t.requiredFieldIds,
71
+ template: t.template ?? ""
72
+ };
73
+ }, E = () => [
74
+ {
75
+ label: s("edit"),
76
+ onClick: () => _(!0)
77
+ },
78
+ ...a ? [{
79
+ label: s("moveUp"),
80
+ onClick: () => c.update.mutate({
81
+ ...w({}),
82
+ position: a.position - .5
83
+ })
84
+ }] : [],
85
+ ...o ? [{
86
+ label: s("moveDown"),
87
+ onClick: () => c.update.mutate({
88
+ ...w({}),
89
+ position: o.position + .5
90
+ })
91
+ }] : [],
92
+ {
93
+ label: r.archivedAt ? s("restore") : s("archive"),
94
+ onClick: () => c.update.mutate({
95
+ ...w({}),
96
+ archived: !r.archivedAt
97
+ })
98
+ },
99
+ m,
100
+ {
101
+ label: s("delete"),
102
+ destructive: !0,
103
+ onClick: () => d({
104
+ title: s("deleteTitle", { name: r.name }),
105
+ description: s("deleteDescription", { count: r.issues }),
106
+ confirmLabel: s("delete"),
107
+ onConfirm: () => c.remove.mutateAsync(r.id)
108
+ })
109
+ }
110
+ ];
111
+ if (p) return /* @__PURE__ */ y("li", {
112
+ className: "p-2",
113
+ children: /* @__PURE__ */ y(T, {
114
+ workspace: n,
115
+ type: r,
116
+ onDone: () => _(!1)
117
+ })
118
+ });
119
+ let D = r.teamIds.map((e) => C.find((t) => t.id === e)?.name).filter(Boolean).join(", ");
120
+ return /* @__PURE__ */ b("li", {
121
+ className: "flex min-h-10 items-center gap-3 px-3 py-1.5",
122
+ onContextMenu: (e) => u(e, E()),
123
+ children: [
124
+ /* @__PURE__ */ y(S, { type: r }),
125
+ /* @__PURE__ */ b("div", {
126
+ className: "min-w-0 flex-1",
127
+ children: [/* @__PURE__ */ y("p", {
128
+ className: `truncate text-sm ${r.archivedAt ? "text-muted-foreground" : ""}`,
129
+ children: r.name
130
+ }), r.description && /* @__PURE__ */ y("p", {
131
+ className: "truncate text-xs text-muted-foreground",
132
+ children: r.description
133
+ })]
134
+ }),
135
+ r.archivedAt && /* @__PURE__ */ y("span", {
136
+ className: "shrink-0 text-xs text-muted-foreground",
137
+ children: s("archived")
138
+ }),
139
+ /* @__PURE__ */ y("span", {
140
+ className: "max-w-48 shrink-0 truncate text-xs text-muted-foreground",
141
+ children: D || s("everyTeam")
142
+ }),
143
+ /* @__PURE__ */ y("span", {
144
+ className: "w-20 shrink-0 text-right text-xs tabular-nums text-muted-foreground",
145
+ children: s("issues", { count: r.issues })
146
+ }),
147
+ /* @__PURE__ */ y(l, {
148
+ variant: "ghost",
149
+ size: "sm",
150
+ label: s("actions", { name: r.name }),
151
+ icon: /* @__PURE__ */ y("span", {
152
+ "aria-hidden": !0,
153
+ children: "⋯"
154
+ }),
155
+ onClick: (e) => u(e, E())
156
+ }),
157
+ f
158
+ ]
159
+ });
160
+ }
161
+ function T({ workspace: t, type: r, onDone: a }) {
162
+ let l = v("issueTypes"), f = v("common"), m = _(), h = i(t), { data: S = [] } = x(e(t)), { data: C = [] } = x(n(t)), w = C.filter((e) => e.target === "issue" && !e.archivedAt), [T, E] = g(r?.name ?? ""), [D, O] = g(r?.description ?? ""), [k, A] = g(r?.icon ?? ""), [j, M] = g(r?.color || "#6e7781"), [N, P] = g(r?.teamIds ?? []), [F, I] = g(r?.fieldIds ?? []), [L, R] = g(r?.requiredFieldIds ?? []), [z, B] = g(r?.template ?? ""), V = r ? h.update : h.create, H = F.length > 0 ? w.filter((e) => F.includes(e.id)) : w, U = (e) => {
163
+ e.preventDefault();
164
+ let t = {
165
+ name: T,
166
+ description: D,
167
+ icon: k,
168
+ color: j,
169
+ teamIds: N,
170
+ fieldIds: F,
171
+ requiredFieldIds: L.filter((e) => H.some((t) => t.id === e)),
172
+ template: z
173
+ };
174
+ r ? h.update.mutate({
175
+ id: r.id,
176
+ ...t
177
+ }, { onSuccess: a }) : h.create.mutate(t, { onSuccess: a });
178
+ }, W = "block text-xs font-medium text-muted-foreground";
179
+ return /* @__PURE__ */ b("form", {
180
+ onSubmit: U,
181
+ className: "space-y-3 rounded-md border border-border p-3 text-sm",
182
+ children: [
183
+ /* @__PURE__ */ b("div", {
184
+ className: "grid gap-3 sm:grid-cols-[1fr_8rem_8rem]",
185
+ children: [
186
+ /* @__PURE__ */ b("label", {
187
+ className: W,
188
+ children: [l("name"), /* @__PURE__ */ y(u, {
189
+ value: T,
190
+ onChange: (e) => E(e.target.value),
191
+ required: !0,
192
+ maxLength: 40,
193
+ className: "mt-1",
194
+ autoFocus: !0
195
+ })]
196
+ }),
197
+ /* @__PURE__ */ b("label", {
198
+ className: W,
199
+ children: [l("icon"), /* @__PURE__ */ y(u, {
200
+ value: k,
201
+ onChange: (e) => A(e.target.value),
202
+ maxLength: 8,
203
+ placeholder: l("iconHint"),
204
+ className: "mt-1"
205
+ })]
206
+ }),
207
+ /* @__PURE__ */ b("div", {
208
+ className: W,
209
+ children: [l("color"), /* @__PURE__ */ y("div", {
210
+ className: "mt-1",
211
+ children: /* @__PURE__ */ y(s, {
212
+ value: j,
213
+ onValueChange: M,
214
+ "aria-label": l("color")
215
+ })
216
+ })]
217
+ })
218
+ ]
219
+ }),
220
+ /* @__PURE__ */ b("label", {
221
+ className: W,
222
+ children: [l("descriptionLabel"), /* @__PURE__ */ y(u, {
223
+ value: D,
224
+ onChange: (e) => O(e.target.value),
225
+ maxLength: 500,
226
+ className: "mt-1"
227
+ })]
228
+ }),
229
+ /* @__PURE__ */ b("div", {
230
+ className: "grid gap-3 sm:grid-cols-3",
231
+ children: [
232
+ /* @__PURE__ */ b("div", {
233
+ className: W,
234
+ children: [l("teams"), /* @__PURE__ */ y("div", {
235
+ className: "mt-1",
236
+ children: /* @__PURE__ */ y(d, {
237
+ multiple: !0,
238
+ value: N,
239
+ items: S.filter((e) => !e.archivedAt).map((e) => ({
240
+ value: e.id,
241
+ label: e.name
242
+ })),
243
+ onValueChange: P,
244
+ placeholder: l("everyTeam"),
245
+ "aria-label": l("teams"),
246
+ width: "fill"
247
+ })
248
+ })]
249
+ }),
250
+ /* @__PURE__ */ b("div", {
251
+ className: W,
252
+ children: [l("fields"), /* @__PURE__ */ y("div", {
253
+ className: "mt-1",
254
+ children: /* @__PURE__ */ y(d, {
255
+ multiple: !0,
256
+ value: F,
257
+ items: w.map((e) => ({
258
+ value: e.id,
259
+ label: e.name
260
+ })),
261
+ onValueChange: I,
262
+ placeholder: l("allFields"),
263
+ "aria-label": l("fields"),
264
+ width: "fill"
265
+ })
266
+ })]
267
+ }),
268
+ /* @__PURE__ */ b("div", {
269
+ className: W,
270
+ children: [l("required"), /* @__PURE__ */ y("div", {
271
+ className: "mt-1",
272
+ children: /* @__PURE__ */ y(d, {
273
+ multiple: !0,
274
+ value: L.filter((e) => H.some((t) => t.id === e)),
275
+ items: H.map((e) => ({
276
+ value: e.id,
277
+ label: e.name
278
+ })),
279
+ onValueChange: R,
280
+ placeholder: l("noneRequired"),
281
+ "aria-label": l("required"),
282
+ width: "fill"
283
+ })
284
+ })]
285
+ })
286
+ ]
287
+ }),
288
+ /* @__PURE__ */ b("label", {
289
+ className: W,
290
+ children: [l("template"), /* @__PURE__ */ y(p, {
291
+ value: z,
292
+ onChange: (e) => B(e.target.value),
293
+ rows: 3,
294
+ placeholder: l("templateHint"),
295
+ className: "mt-1 font-mono"
296
+ })]
297
+ }),
298
+ V.error && /* @__PURE__ */ y(c, { children: m(V.error) }),
299
+ /* @__PURE__ */ b("div", {
300
+ className: "flex justify-end gap-2",
301
+ children: [/* @__PURE__ */ y(o, {
302
+ size: "sm",
303
+ variant: "ghost",
304
+ onClick: a,
305
+ children: f("cancel")
306
+ }), /* @__PURE__ */ y(o, {
307
+ type: "submit",
308
+ size: "sm",
309
+ variant: "primary",
310
+ loading: V.isPending,
311
+ disabled: !T.trim(),
312
+ children: r ? f("save") : l("add")
313
+ })]
314
+ })
315
+ ]
316
+ });
317
+ }
318
+ export { C as IssueTypeSettings, S as TypeIcon };