@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
@@ -1,73 +1,77 @@
1
1
  import { api as e, unwrap as t } from "../api/client.js";
2
2
  import { useNavigate as n } from "../lib/router.js";
3
3
  import { cyclesQuery as r, issueTemplatesQuery as i, labelsQuery as a, statusesQuery as ee, teamsQuery as te } from "../api/queries.js";
4
- import { CalendarIcon as ne, CycleIcon as re, EstimateIcon as ie, FileTextIcon as o, FolderIcon as ae, PriorityIcon as s, StatusIcon as oe, TagIcon as se, UserIcon as ce, usePriorityNames as le } from "./icons.js";
5
- import { invalidateIssueViews as ue } from "../api/mutations.js";
6
- import { useTime as de } from "../lib/time.js";
7
- import { scalePoints as fe, useEstimateLabel as pe } from "./Planning.js";
8
- import { PickManyBox as me, usePickMany as he } from "../lib/pickMany.js";
9
- import { parseAssigneeKey as ge, useAssigneeOptions as _e } from "../lib/assignees.js";
10
- import { useCan as ve } from "../lib/roles.js";
11
- import { useConfirm as ye } from "../lib/confirm.js";
12
- import { attachmentPrefix as be, insertPreviews as xe, readDataURL as Se, uploadAttachment as Ce } from "../lib/attachments.js";
13
- import { withoutLink as we } from "../lib/markdownLinks.js";
14
- import { AttachButton as Te, useAttachmentsOn as Ee } from "./Attachments.js";
15
- import { Editor as De } from "./Editor.js";
16
- import { TeamForm as Oe } from "./TeamForm.js";
17
- import { Button as ke, Combobox as c, CreateModal as Ae, DatePicker as je, Modal as Me, buttonClasses as Ne, toast as l } from "@parallelworks/ui";
18
- import { useEffect as Pe, useRef as u, useState as d } from "react";
19
- import { useErrorMessage as Fe } from "@parallelworks/problem/react";
20
- import { useTranslations as f } from "use-intl";
21
- import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
22
- import { useQuery as g, useQueryClient as Ie, useSuspenseQuery as Le } from "@tanstack/react-query";
4
+ import { useConfirm as ne } from "../lib/confirm.js";
5
+ import { hasValue as o } from "../lib/customFields.js";
6
+ import { issueTypesQuery as re, typesFor as ie } from "../lib/issueTypes.js";
7
+ import { CalendarIcon as ae, CycleIcon as oe, EstimateIcon as se, FileTextIcon as ce, FolderIcon as le, PriorityIcon as ue, StatusIcon as de, TagIcon as fe, UserIcon as pe, usePriorityNames as me } from "./icons.js";
8
+ import { TypeIcon as he } from "./IssueTypes.js";
9
+ import { invalidateIssueViews as ge } from "../api/mutations.js";
10
+ import { useTime as _e } from "../lib/time.js";
11
+ import { scalePoints as ve, useEstimateLabel as ye } from "./Planning.js";
12
+ import { PickManyBox as be, usePickMany as xe } from "../lib/pickMany.js";
13
+ import { parseAssigneeKey as Se, useAssigneeOptions as Ce } from "../lib/assignees.js";
14
+ import { useCan as we } from "../lib/roles.js";
15
+ import { attachmentPrefix as Te, insertPreviews as Ee, readDataURL as De, uploadAttachment as Oe } from "../lib/attachments.js";
16
+ import { withoutLink as ke } from "../lib/markdownLinks.js";
17
+ import { AttachButton as Ae, useAttachmentsOn as je } from "./Attachments.js";
18
+ import { NewIssueFields as Me } from "./CustomFields.js";
19
+ import { Editor as Ne } from "./Editor.js";
20
+ import { TeamForm as Pe } from "./TeamForm.js";
21
+ import { Button as Fe, Combobox as s, CreateModal as Ie, DatePicker as Le, Modal as Re, buttonClasses as ze, toast as Be } from "@parallelworks/ui";
22
+ import { useEffect as Ve, useRef as c, useState as l } from "react";
23
+ import { useErrorMessage as He } from "@parallelworks/problem/react";
24
+ import { useTranslations as u } from "use-intl";
25
+ import { Fragment as Ue, jsx as d, jsxs as f } from "react/jsx-runtime";
26
+ import { useQuery as p, useQueryClient as We, useSuspenseQuery as Ge } from "@tanstack/react-query";
23
27
  // src/components/NewIssueDialog.tsx
24
- function _({ workspace: _, defaultTeam: v, defaultTitle: Be = "", defaultBody: y = "", defaultArea: b, origin: x, defaults: S = {}, onCreated: Ve, onClose: C }) {
25
- let { data: He } = Le(te(_)), w = He.filter((e) => !e.archivedAt), T = !Be && !y && !b && !x && Object.keys(S).length === 0, [E] = d(() => T ? Re(_) : void 0), [D, O] = d(v ?? w.find((e) => e.key === E?.team)?.key ?? w[0]?.key ?? ""), { data: k = [] } = g({
26
- ...ee(_, D),
27
- enabled: !!D
28
- }), { data: Ue = [] } = g(a(_)), { data: A = [] } = g({
29
- ...i(_, D),
30
- enabled: !!D
31
- }), [j, M] = d(null), We = A.find((e) => e.id === j), [N, Ge] = d(Be || E?.title || ""), P = u(N), Ke = f("issueTemplates"), qe = _e(_, !0), Je = le(), F = f("newIssue"), Ye = Fe(), I = f("common"), L = ve(_, "manage_teams"), [R, Xe] = d(y || E?.body || ""), Ze = u(R), [Qe, $e] = d(S.statusId ?? null), [z, et] = d(S.priority ?? 0), [B, tt] = d(0), [V, nt] = d(""), [H, rt] = d(S.cycleId ?? ""), U = f("planning"), it = pe(), at = de(), { data: ot = [] } = g({
32
- ...r(_, D),
33
- enabled: !!w.find((e) => e.key === D)?.cyclesEnabled
34
- }), st = ot.find((e) => e.id === H), ct = (e) => e.name ? U("cycleNamed", {
28
+ function m({ workspace: m, defaultTeam: h, defaultTitle: Je = "", defaultBody: g = "", defaultArea: _, origin: v, defaults: y = {}, onCreated: Ye, onClose: b }) {
29
+ let { data: Xe } = Ge(te(m)), x = Xe.filter((e) => !e.archivedAt), S = !Je && !g && !_ && !v && Object.keys(y).length === 0, [Ze] = l(() => S ? Ke(m) : void 0), [C, Qe] = l(h ?? x.find((e) => e.key === Ze?.team)?.key ?? x[0]?.key ?? ""), { data: w = [] } = p({
30
+ ...ee(m, C),
31
+ enabled: !!C
32
+ }), { data: $e = [] } = p(a(m)), { data: T = [] } = p({
33
+ ...i(m, C),
34
+ enabled: !!C
35
+ }), [E, et] = l(null), tt = T.find((e) => e.id === E), [D, nt] = l(Je || Ze?.title || ""), O = c(D), rt = u("issueTemplates"), it = Ce(m, !0), at = me(), k = u("newIssue"), ot = He(), A = u("common"), j = we(m, "manage_teams"), [M, N] = l(g || Ze?.body || ""), st = c(M), [ct, lt] = l(y.statusId ?? null), [P, ut] = l(y.priority ?? 0), [F, dt] = l(0), [I, ft] = l(""), [L, pt] = l(y.cycleId ?? ""), R = u("planning"), mt = ye(), ht = _e(), { data: gt = [] } = p({
36
+ ...r(m, C),
37
+ enabled: !!x.find((e) => e.key === C)?.cyclesEnabled
38
+ }), _t = gt.find((e) => e.id === L), vt = (e) => e.name ? R("cycleNamed", {
35
39
  number: e.number,
36
40
  name: e.name
37
- }) : U("cycle", { number: e.number }), W = w.find((e) => e.key === D)?.estimateScale ?? "none", [G, lt] = d(S.assignees ?? []), [K, ut] = d(S.labelIds ?? []), [q, J] = d(null), dt = he(q === "assignees", () => J(null)), ft = he(q === "labels", () => J(null)), [pt, mt] = d(null), ht = Ie(), gt = n(), { confirm: _t, dialog: vt } = ye(), Y = u(!1);
38
- Pe(() => {
41
+ }) : R("cycle", { number: e.number }), z = x.find((e) => e.key === C)?.estimateScale ?? "none", [B, yt] = l(y.assignees ?? []), [V, bt] = l(y.labelIds ?? []), [H, U] = l({}), [W, G] = l(null), { data: xt } = p(re(m)), K = ie(xt, x.find((e) => e.key === C)?.id), q = K.find((e) => e.id === W), St = u("issueTypes"), [J, Y] = l(null), Ct = xe(J === "assignees", () => Y(null)), wt = xe(J === "labels", () => Y(null)), [Tt, Et] = l(null), Dt = We(), Ot = n(), { confirm: kt, dialog: At } = ne(), jt = c(!1);
42
+ Ve(() => {
39
43
  let e = () => {
40
- T && ze(_, {
41
- team: D,
42
- title: P.current,
43
- body: R
44
- }), C();
44
+ S && qe(m, {
45
+ team: C,
46
+ title: O.current,
47
+ body: M
48
+ }), b();
45
49
  }, t = (t) => {
46
- if (!(t.key !== "Escape" || q !== null || Y.current) && !document.querySelector("[role=\"menu\"], [role=\"listbox\"]")) {
47
- if (P.current === N && R === Ze.current) return e();
48
- Y.current = !0, _t({
49
- title: F("closeTitle"),
50
- description: F(T ? "closeKeepsDraft" : "closeLoses"),
51
- confirmLabel: I("close"),
50
+ if (!(t.key !== "Escape" || J !== null || jt.current) && !document.querySelector("[role=\"menu\"], [role=\"listbox\"]")) {
51
+ if (O.current === D && M === st.current) return e();
52
+ jt.current = !0, kt({
53
+ title: k("closeTitle"),
54
+ description: k(S ? "closeKeepsDraft" : "closeLoses"),
55
+ confirmLabel: A("close"),
52
56
  onConfirm: async () => e()
53
57
  }).finally(() => {
54
- Y.current = !1;
58
+ jt.current = !1;
55
59
  });
56
60
  }
57
61
  };
58
62
  return window.addEventListener("keydown", t, !0), () => window.removeEventListener("keydown", t, !0);
59
63
  }, [
60
- q,
61
- T,
62
- _,
63
- D,
64
- R,
65
- N,
64
+ J,
65
+ S,
66
+ m,
66
67
  C,
67
- _t,
68
- F,
69
- I
70
- ]), Pe(() => {
68
+ M,
69
+ D,
70
+ b,
71
+ kt,
72
+ k,
73
+ A
74
+ ]), Ve(() => {
71
75
  let e = (e) => {
72
76
  if (e.metaKey || e.ctrlKey || e.altKey || e.key.length !== 1 || document.activeElement && document.activeElement !== document.body) return;
73
77
  let t = document.querySelector("[role=\"dialog\"]");
@@ -77,179 +81,213 @@ function _({ workspace: _, defaultTeam: v, defaultTitle: Be = "", defaultBody: y
77
81
  };
78
82
  return window.addEventListener("keydown", e, !0), () => window.removeEventListener("keydown", e, !0);
79
83
  }, []);
80
- let yt = () => {
81
- T && ze(_, {
82
- team: D,
84
+ let Mt = () => {
85
+ S && qe(m, {
86
+ team: C,
83
87
  title: "",
84
88
  body: ""
85
- }), C();
86
- }, X = k.find((e) => e.id === Qe) ?? k.find((e) => e.category === "unstarted"), Z = u(null), Q = u(/* @__PURE__ */ new Map()), bt = Ee(), xt = f("issue.attachments"), St = async (e, t) => {
87
- if (!bt) {
88
- l.error(xt("off", { name: e[0]?.name ?? "" }));
89
+ }), b();
90
+ }, X = w.find((e) => e.id === ct) ?? w.find((e) => e.category === "unstarted"), Z = c(null), Q = c(/* @__PURE__ */ new Map()), Nt = je(), Pt = u("issue.attachments"), Ft = async (e, t) => {
91
+ if (!Nt) {
92
+ Be.error(Pt("off", { name: e[0]?.name ?? "" }));
89
93
  return;
90
94
  }
91
95
  let n = await Promise.all(e.map(async (e) => ({
92
96
  file: e,
93
- src: await Se(e)
97
+ src: await De(e)
94
98
  })));
95
99
  for (let { file: e, src: t } of n) Q.current.set(t, e);
96
- Z.current && !Z.current.isDestroyed && xe(Z.current, n, t);
97
- }, Ct = async (t) => {
98
- let n = R;
99
- for (let [e, r] of Q.current) if (R.includes(e)) try {
100
- let i = await Ce(_, t, r);
101
- n = n.replaceAll(`(${e})`, `(${be}${i.id})`);
100
+ Z.current && !Z.current.isDestroyed && Ee(Z.current, n, t);
101
+ }, It = async (t) => {
102
+ let n = M;
103
+ for (let [e, r] of Q.current) if (M.includes(e)) try {
104
+ let i = await Oe(m, t, r);
105
+ n = n.replaceAll(`(${e})`, `(${Te}${i.id})`);
102
106
  } catch (t) {
103
- n = we(n, e), l.error(F("attachFailed", {
107
+ n = ke(n, e), Be.error(k("attachFailed", {
104
108
  name: r.name,
105
- reason: Ye(t)
109
+ reason: ot(t)
106
110
  }));
107
111
  }
108
112
  await e.PATCH("/api/v1/workspaces/{workspace}/issues/{identifier}", {
109
113
  params: { path: {
110
- workspace: _,
114
+ workspace: m,
111
115
  identifier: t
112
116
  } },
113
117
  body: { body: n }
114
118
  });
115
- }, wt = async (n, r) => {
116
- if (!D) return !1;
117
- mt(null);
118
- let i = [...Q.current.keys()].filter((e) => R.includes(e));
119
+ }, Lt = async (n, r) => {
120
+ if (!C) return !1;
121
+ Et(null);
122
+ let i = [...Q.current.keys()].filter((e) => M.includes(e));
119
123
  try {
120
124
  let a = t(await e.POST("/api/v1/workspaces/{workspace}/teams/{key}/issues", {
121
125
  params: { path: {
122
- workspace: _,
123
- key: D
126
+ workspace: m,
127
+ key: C
124
128
  } },
125
129
  body: {
126
130
  title: n,
127
- body: i.reduce(we, R),
128
- priority: z,
131
+ body: i.reduce(ke, M),
132
+ priority: P,
129
133
  ...X && { statusId: X.id },
130
- assignees: G.map(ge),
131
- labelIds: K,
132
- ...B && fe(W).includes(B) && { estimate: B },
133
- ...V && { dueDate: V },
134
- ...H && { cycleId: H },
135
- ...(!v || D === v) && b && { area: b },
136
- ...(!v || D === v) && x && { origin: x },
137
- ...(!v || D === v) && S.projectId && { projectId: S.projectId }
134
+ assignees: B.map(Se),
135
+ labelIds: V,
136
+ ...q && { typeId: q.id },
137
+ ...Object.values(H).some(o) && { fields: Object.fromEntries(Object.entries(H).filter(([, e]) => o(e))) },
138
+ ...F && ve(z).includes(F) && { estimate: F },
139
+ ...I && { dueDate: I },
140
+ ...L && { cycleId: L },
141
+ ...(!h || C === h) && _ && { area: _ },
142
+ ...(!h || C === h) && v && { origin: v },
143
+ ...(!h || C === h) && y.projectId && { projectId: y.projectId }
138
144
  }
139
145
  }));
140
- return i.length > 0 && await Ct(a.identifier), ue(ht, _, a.identifier), Ve?.(a), r && gt({
146
+ return i.length > 0 && await It(a.identifier), ge(Dt, m, a.identifier), Ye?.(a), r && Ot({
141
147
  to: "/$workspace/issues/$identifier",
142
148
  params: {
143
- workspace: _,
149
+ workspace: m,
144
150
  identifier: a.identifier
145
151
  }
146
152
  }), !0;
147
153
  } catch (e) {
148
- return mt(Ye(e)), !1;
154
+ return Et(ot(e)), !1;
149
155
  }
150
- }, $ = Ne({ size: "sm" });
151
- if (w.length === 0) return /* @__PURE__ */ m(Me, {
156
+ }, $ = ze({ size: "sm" });
157
+ if (x.length === 0) return /* @__PURE__ */ d(Re, {
152
158
  open: !0,
153
- onClose: C,
159
+ onClose: b,
154
160
  size: "lg",
155
- title: F("noTeamTitle"),
156
- description: F(L ? "noTeamDescription" : "noTeamAskAdmin"),
157
- ...!L && { footer: /* @__PURE__ */ m(ke, {
161
+ title: k("noTeamTitle"),
162
+ description: k(j ? "noTeamDescription" : "noTeamAskAdmin"),
163
+ ...!j && { footer: /* @__PURE__ */ d(Fe, {
158
164
  type: "button",
159
- onClick: C,
160
- children: I("close")
165
+ onClick: b,
166
+ children: A("close")
161
167
  }) },
162
- children: L && /* @__PURE__ */ m(Oe, {
163
- workspace: _,
168
+ children: j && /* @__PURE__ */ d(Pe, {
169
+ workspace: m,
164
170
  autoFocus: !0,
165
- onCreated: (e) => O(e.key)
171
+ onCreated: (e) => Qe(e.key)
166
172
  })
167
173
  });
168
- let Tt = w.find((e) => e.key === D);
169
- return /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(Ae, {
174
+ let Rt = x.find((e) => e.key === C);
175
+ return /* @__PURE__ */ f(Ue, { children: [/* @__PURE__ */ d(Ie, {
170
176
  open: !0,
171
- onClose: yt,
177
+ onClose: Mt,
172
178
  size: "xl",
173
- typeIcon: /* @__PURE__ */ m(ae, { className: "size-3.5" }),
174
- typeLabel: Tt?.name ?? "",
175
- typeMenu: w.map((e) => ({
179
+ typeIcon: /* @__PURE__ */ d(le, { className: "size-3.5" }),
180
+ typeLabel: Rt?.name ?? "",
181
+ typeMenu: x.map((e) => ({
176
182
  label: e.name,
177
183
  hint: e.key,
178
- checked: e.key === D,
184
+ checked: e.key === C,
179
185
  onClick: () => {
180
- O(e.key), $e(null), M(null), rt("");
186
+ Qe(e.key), lt(null), et(null), U({}), G(null), pt("");
181
187
  }
182
188
  })),
183
189
  typeMenuSearch: {
184
- placeholder: F("moveToTeam"),
185
- empty: F("noTeamMatches")
190
+ placeholder: k("moveToTeam"),
191
+ empty: k("noTeamMatches")
186
192
  },
187
- namePlaceholder: F("issueTitle"),
188
- initialName: N,
193
+ namePlaceholder: k("issueTitle"),
194
+ initialName: D,
189
195
  onNameChange: (e) => {
190
- P.current = e;
196
+ O.current = e;
191
197
  },
192
- submitLabel: F("create"),
193
- descriptionField: /* @__PURE__ */ m("div", {
198
+ submitLabel: k("create"),
199
+ descriptionField: /* @__PURE__ */ f("div", {
194
200
  className: "min-h-24 pb-2",
195
- children: /* @__PURE__ */ m(De, {
196
- value: R,
197
- onChange: Xe,
198
- onFiles: (e, t) => void St(e, t),
201
+ children: [/* @__PURE__ */ d(Ne, {
202
+ value: M,
203
+ onChange: N,
204
+ onFiles: (e, t) => void Ft(e, t),
199
205
  onEditor: (e) => {
200
206
  Z.current = e;
201
207
  },
202
208
  onSubmit: () => {},
203
- placeholder: F("descriptionPlaceholder"),
204
- label: I("description"),
209
+ placeholder: k("descriptionPlaceholder"),
210
+ label: A("description"),
205
211
  className: "min-h-24"
206
- })
212
+ }), /* @__PURE__ */ d(Me, {
213
+ workspace: m,
214
+ teamId: x.find((e) => e.key === C)?.id,
215
+ typeId: W,
216
+ values: H,
217
+ onChange: U
218
+ })]
207
219
  }),
208
- dirty: R !== y || j !== null || Qe !== null || z !== 0 || B !== 0 || V !== "" || H !== "" || G.length > 0 || K.length > 0,
209
- footerHint: F("hint"),
210
- error: pt,
211
- onSubmit: (e, t, n, { modifier: r }) => wt(e, r),
212
- properties: /* @__PURE__ */ h(p, { children: [
213
- A.length > 0 && /* @__PURE__ */ m(c, {
214
- open: q === "template",
215
- onOpenChange: (e) => J(e ? "template" : null),
216
- items: A.map((e) => ({
220
+ dirty: M !== g || E !== null || ct !== null || P !== 0 || F !== 0 || I !== "" || L !== "" || B.length > 0 || V.length > 0 || W !== null || Object.values(H).some(o),
221
+ footerHint: k("hint"),
222
+ error: Tt,
223
+ onSubmit: (e, t, n, { modifier: r }) => Lt(e, r),
224
+ properties: /* @__PURE__ */ f(Ue, { children: [
225
+ T.length > 0 && /* @__PURE__ */ d(s, {
226
+ open: J === "template",
227
+ onOpenChange: (e) => Y(e ? "template" : null),
228
+ items: T.map((e) => ({
229
+ value: e.id,
230
+ label: e.name,
231
+ icon: /* @__PURE__ */ d(ce, { className: "size-3.5 text-muted-foreground" })
232
+ })),
233
+ value: E,
234
+ onValueChange: (e) => {
235
+ let t = T.find((t) => t.id === e);
236
+ t && (et(t.id), t.title && (nt(t.title), O.current = t.title), N(t.body), ut(t.priority), bt(t.labelIds), U(t.fields), G(t.typeId ?? null));
237
+ },
238
+ placeholder: rt("choose"),
239
+ trigger: /* @__PURE__ */ f("button", {
240
+ type: "button",
241
+ className: $,
242
+ children: [/* @__PURE__ */ d(ce, { className: "size-3.5" }), tt?.name ?? rt("choose")]
243
+ })
244
+ }),
245
+ K.length > 0 && /* @__PURE__ */ d(s, {
246
+ open: J === "type",
247
+ onOpenChange: (e) => Y(e ? "type" : null),
248
+ items: K.map((e) => ({
217
249
  value: e.id,
218
250
  label: e.name,
219
- icon: /* @__PURE__ */ m(o, { className: "size-3.5 text-muted-foreground" })
251
+ icon: /* @__PURE__ */ d(he, {
252
+ type: e,
253
+ className: "size-3.5"
254
+ })
220
255
  })),
221
- value: j,
256
+ value: W,
222
257
  onValueChange: (e) => {
223
- let t = A.find((t) => t.id === e);
224
- t && (M(t.id), t.title && (Ge(t.title), P.current = t.title), Xe(t.body), et(t.priority), ut(t.labelIds));
258
+ let t = K.find((t) => t.id === e);
259
+ G(t?.id ?? null), t?.template && !M.trim() && N(t.template);
225
260
  },
226
- placeholder: Ke("choose"),
227
- trigger: /* @__PURE__ */ h("button", {
261
+ placeholder: St("type"),
262
+ trigger: /* @__PURE__ */ f("button", {
228
263
  type: "button",
229
264
  className: $,
230
- children: [/* @__PURE__ */ m(o, { className: "size-3.5" }), We?.name ?? Ke("choose")]
265
+ children: [q && /* @__PURE__ */ d(he, {
266
+ type: q,
267
+ className: "size-3.5"
268
+ }), q?.name ?? St("type")]
231
269
  })
232
270
  }),
233
- /* @__PURE__ */ m(c, {
234
- open: q === "status",
235
- onOpenChange: (e) => J(e ? "status" : null),
236
- items: k.map((e) => ({
271
+ /* @__PURE__ */ d(s, {
272
+ open: J === "status",
273
+ onOpenChange: (e) => Y(e ? "status" : null),
274
+ items: w.map((e) => ({
237
275
  value: e.id,
238
276
  label: e.name,
239
- icon: /* @__PURE__ */ m(oe, { category: e.category })
277
+ icon: /* @__PURE__ */ d(de, { category: e.category })
240
278
  })),
241
279
  value: X?.id ?? null,
242
- onValueChange: (e) => e !== null && $e(e),
243
- placeholder: F("changeStatus"),
244
- trigger: /* @__PURE__ */ h("button", {
280
+ onValueChange: (e) => e !== null && lt(e),
281
+ placeholder: k("changeStatus"),
282
+ trigger: /* @__PURE__ */ f("button", {
245
283
  type: "button",
246
284
  className: $,
247
- children: [X && /* @__PURE__ */ m(oe, { category: X.category }), X?.name ?? I("status")]
285
+ children: [X && /* @__PURE__ */ d(de, { category: X.category }), X?.name ?? A("status")]
248
286
  })
249
287
  }),
250
- /* @__PURE__ */ m(c, {
251
- open: q === "priority",
252
- onOpenChange: (e) => J(e ? "priority" : null),
288
+ /* @__PURE__ */ d(s, {
289
+ open: J === "priority",
290
+ onOpenChange: (e) => Y(e ? "priority" : null),
253
291
  items: [
254
292
  1,
255
293
  2,
@@ -258,125 +296,125 @@ function _({ workspace: _, defaultTeam: v, defaultTitle: Be = "", defaultBody: y
258
296
  0
259
297
  ].map((e) => ({
260
298
  value: String(e),
261
- label: Je[e] ?? "",
262
- icon: /* @__PURE__ */ m(s, { priority: e })
299
+ label: at[e] ?? "",
300
+ icon: /* @__PURE__ */ d(ue, { priority: e })
263
301
  })),
264
- value: String(z),
265
- onValueChange: (e) => e !== null && et(Number(e)),
266
- placeholder: F("setPriority"),
267
- trigger: /* @__PURE__ */ h("button", {
302
+ value: String(P),
303
+ onValueChange: (e) => e !== null && ut(Number(e)),
304
+ placeholder: k("setPriority"),
305
+ trigger: /* @__PURE__ */ f("button", {
268
306
  type: "button",
269
307
  className: $,
270
- children: [/* @__PURE__ */ m(s, { priority: z }), z ? Je[z] : I("priority")]
308
+ children: [/* @__PURE__ */ d(ue, { priority: P }), P ? at[P] : A("priority")]
271
309
  })
272
310
  }),
273
- /* @__PURE__ */ m(c, {
311
+ /* @__PURE__ */ d(s, {
274
312
  multiple: !0,
275
- open: q === "assignees",
276
- onOpenChange: (e) => J(e ? "assignees" : null),
277
- items: qe,
278
- value: G,
313
+ open: J === "assignees",
314
+ onOpenChange: (e) => Y(e ? "assignees" : null),
315
+ items: it,
316
+ value: B,
279
317
  onValueChange: (e) => {
280
- lt(e), dt();
318
+ yt(e), Ct();
281
319
  },
282
- placeholder: F("assignTo"),
283
- trigger: /* @__PURE__ */ h("button", {
320
+ placeholder: k("assignTo"),
321
+ trigger: /* @__PURE__ */ f("button", {
284
322
  type: "button",
285
323
  className: $,
286
- children: [/* @__PURE__ */ m(ce, { className: "size-3.5" }), G.length ? F("assignedCount", { count: G.length }) : I("assignee")]
324
+ children: [/* @__PURE__ */ d(pe, { className: "size-3.5" }), B.length ? k("assignedCount", { count: B.length }) : A("assignee")]
287
325
  })
288
326
  }),
289
- /* @__PURE__ */ m(c, {
327
+ /* @__PURE__ */ d(s, {
290
328
  multiple: !0,
291
- open: q === "labels",
292
- onOpenChange: (e) => J(e ? "labels" : null),
293
- items: Ue.map((e) => ({
329
+ open: J === "labels",
330
+ onOpenChange: (e) => Y(e ? "labels" : null),
331
+ items: $e.map((e) => ({
294
332
  value: e.id,
295
333
  label: e.name,
296
- icon: /* @__PURE__ */ h("span", {
334
+ icon: /* @__PURE__ */ f("span", {
297
335
  className: "flex items-center gap-2",
298
- children: [/* @__PURE__ */ m(me, {}), /* @__PURE__ */ m("span", {
336
+ children: [/* @__PURE__ */ d(be, {}), /* @__PURE__ */ d("span", {
299
337
  className: "size-2.5 rounded-full",
300
338
  style: { background: e.color }
301
339
  })]
302
340
  })
303
341
  })),
304
- value: K,
342
+ value: V,
305
343
  onValueChange: (e) => {
306
- ut(e), ft();
344
+ bt(e), wt();
307
345
  },
308
- placeholder: F("addLabels"),
309
- trigger: /* @__PURE__ */ h("button", {
346
+ placeholder: k("addLabels"),
347
+ trigger: /* @__PURE__ */ f("button", {
310
348
  type: "button",
311
349
  className: $,
312
- children: [/* @__PURE__ */ m(se, { className: "size-3.5" }), K.length ? F("labelCount", { count: K.length }) : I("labels")]
350
+ children: [/* @__PURE__ */ d(fe, { className: "size-3.5" }), V.length ? k("labelCount", { count: V.length }) : A("labels")]
313
351
  })
314
352
  }),
315
- W !== "none" && /* @__PURE__ */ m(c, {
316
- open: q === "estimate",
317
- onOpenChange: (e) => J(e ? "estimate" : null),
318
- items: [0, ...fe(W)].map((e) => ({
353
+ z !== "none" && /* @__PURE__ */ d(s, {
354
+ open: J === "estimate",
355
+ onOpenChange: (e) => Y(e ? "estimate" : null),
356
+ items: [0, ...ve(z)].map((e) => ({
319
357
  value: String(e),
320
- label: e ? it(e, W) : U("noEstimate")
358
+ label: e ? mt(e, z) : R("noEstimate")
321
359
  })),
322
- value: String(B),
323
- onValueChange: (e) => e !== null && tt(Number(e)),
324
- placeholder: U("setEstimate"),
325
- trigger: /* @__PURE__ */ h("button", {
360
+ value: String(F),
361
+ onValueChange: (e) => e !== null && dt(Number(e)),
362
+ placeholder: R("setEstimate"),
363
+ trigger: /* @__PURE__ */ f("button", {
326
364
  type: "button",
327
365
  className: $,
328
- children: [/* @__PURE__ */ m(ie, { className: "size-3.5" }), B ? it(B, W) : U("estimate")]
366
+ children: [/* @__PURE__ */ d(se, { className: "size-3.5" }), F ? mt(F, z) : R("estimate")]
329
367
  })
330
368
  }),
331
- Tt?.cyclesEnabled && /* @__PURE__ */ m(c, {
332
- open: q === "cycle",
333
- onOpenChange: (e) => J(e ? "cycle" : null),
369
+ Rt?.cyclesEnabled && /* @__PURE__ */ d(s, {
370
+ open: J === "cycle",
371
+ onOpenChange: (e) => Y(e ? "cycle" : null),
334
372
  items: [{
335
373
  value: "",
336
- label: U("noCycle")
337
- }, ...ot.filter((e) => e.state !== "past").map((e) => ({
374
+ label: R("noCycle")
375
+ }, ...gt.filter((e) => e.state !== "past").map((e) => ({
338
376
  value: e.id,
339
- label: ct(e),
340
- description: U("stateAndDates", {
341
- state: U(`states.${e.state}`),
342
- dates: at.dayRange(e.startsOn, e.endsOn)
377
+ label: vt(e),
378
+ description: R("stateAndDates", {
379
+ state: R(`states.${e.state}`),
380
+ dates: ht.dayRange(e.startsOn, e.endsOn)
343
381
  })
344
382
  }))],
345
- value: H,
346
- onValueChange: (e) => e !== null && rt(e),
347
- placeholder: U("cycleLabel"),
348
- trigger: /* @__PURE__ */ h("button", {
383
+ value: L,
384
+ onValueChange: (e) => e !== null && pt(e),
385
+ placeholder: R("cycleLabel"),
386
+ trigger: /* @__PURE__ */ f("button", {
349
387
  type: "button",
350
388
  className: $,
351
- children: [/* @__PURE__ */ m(re, { className: "size-3.5" }), st ? ct(st) : U("cycleLabel")]
389
+ children: [/* @__PURE__ */ d(oe, { className: "size-3.5" }), _t ? vt(_t) : R("cycleLabel")]
352
390
  })
353
391
  }),
354
- /* @__PURE__ */ m(je, {
355
- value: V,
356
- onValueChange: nt,
357
- "aria-label": U("dueDate"),
358
- trigger: /* @__PURE__ */ h("button", {
392
+ /* @__PURE__ */ d(Le, {
393
+ value: I,
394
+ onValueChange: ft,
395
+ "aria-label": R("dueDate"),
396
+ trigger: /* @__PURE__ */ f("button", {
359
397
  type: "button",
360
398
  className: $,
361
- children: [/* @__PURE__ */ m(ne, { className: "size-3.5" }), V ? U("dueOn", { date: at.day(V) }) : U("dueDate")]
399
+ children: [/* @__PURE__ */ d(ae, { className: "size-3.5" }), I ? R("dueOn", { date: ht.day(I) }) : R("dueDate")]
362
400
  })
363
401
  }),
364
- /* @__PURE__ */ m(Te, { onFiles: (e) => void St(e) })
402
+ /* @__PURE__ */ d(Ae, { onFiles: (e) => void Ft(e) })
365
403
  ] })
366
- }), vt] });
404
+ }), At] });
367
405
  }
368
- var v = (e) => `tandem:new-issue-draft:${e}`;
369
- function Re(e) {
406
+ var h = (e) => `tandem:new-issue-draft:${e}`;
407
+ function Ke(e) {
370
408
  try {
371
- let t = JSON.parse(localStorage.getItem(v(e)) ?? "null");
409
+ let t = JSON.parse(localStorage.getItem(h(e)) ?? "null");
372
410
  return t && typeof t.title == "string" && typeof t.body == "string" ? t : void 0;
373
411
  } catch {
374
412
  return;
375
413
  }
376
414
  }
377
- function ze(e, t) {
415
+ function qe(e, t) {
378
416
  try {
379
- t.title.trim() || t.body.trim() ? localStorage.setItem(v(e), JSON.stringify(t)) : localStorage.removeItem(v(e));
417
+ t.title.trim() || t.body.trim() ? localStorage.setItem(h(e), JSON.stringify(t)) : localStorage.removeItem(h(e));
380
418
  } catch {}
381
419
  }
382
- export { _ as NewIssueDialog };
420
+ export { m as NewIssueDialog };