@burdenoff/microfe-planmagnet 2026.928.5 → 2026.928.7

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 (66) hide show
  1. package/dist/generated/wspace-operations.d.ts +5 -0
  2. package/dist/generated/wspace-operations.d.ts.map +1 -1
  3. package/dist/generated/wspace-types.d.ts +15 -0
  4. package/dist/generated/wspace-types.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  6. package/dist/planmagnet/PlanMagnetRoot.js +20 -11
  7. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  8. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  9. package/dist/planmagnet/PlanMagnetRoutes.js +216 -196
  10. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  11. package/dist/planmagnet/controls/Pickers.d.ts +14 -0
  12. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  13. package/dist/planmagnet/controls/Pickers.js +97 -22
  14. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  15. package/dist/planmagnet/controls/WorkItemControls.d.ts +6 -2
  16. package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -1
  17. package/dist/planmagnet/controls/WorkItemControls.js +8 -8
  18. package/dist/planmagnet/controls/WorkItemControls.js.map +1 -1
  19. package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +1 -1
  20. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +11 -3
  21. package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +1 -1
  22. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -1
  23. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +74 -59
  24. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -1
  25. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  26. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +138 -112
  27. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  28. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
  29. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +16 -6
  30. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
  31. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
  32. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +7 -2
  33. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
  34. package/dist/planmagnet/pages/ProjectsPlanningPagePage.d.ts.map +1 -1
  35. package/dist/planmagnet/pages/ProjectsPlanningPagePage.js +76 -56
  36. package/dist/planmagnet/pages/ProjectsPlanningPagePage.js.map +1 -1
  37. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  38. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +241 -188
  39. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  40. package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
  41. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +168 -122
  42. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
  43. package/dist/planmagnet/pages/TeamCreateTeamPagePage.d.ts.map +1 -1
  44. package/dist/planmagnet/pages/TeamCreateTeamPagePage.js +288 -91
  45. package/dist/planmagnet/pages/TeamCreateTeamPagePage.js.map +1 -1
  46. package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts +2 -0
  47. package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts.map +1 -0
  48. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js +217 -0
  49. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js.map +1 -0
  50. package/dist/planmagnet/pages/TeamTeamEditPagePage.d.ts +2 -0
  51. package/dist/planmagnet/pages/TeamTeamEditPagePage.d.ts.map +1 -0
  52. package/dist/planmagnet/pages/TeamTeamEditPagePage.js +211 -0
  53. package/dist/planmagnet/pages/TeamTeamEditPagePage.js.map +1 -0
  54. package/dist/planmagnet/pages/TeamTeamsListPagePage.d.ts +2 -0
  55. package/dist/planmagnet/pages/TeamTeamsListPagePage.d.ts.map +1 -0
  56. package/dist/planmagnet/pages/TeamTeamsListPagePage.js +118 -0
  57. package/dist/planmagnet/pages/TeamTeamsListPagePage.js.map +1 -0
  58. package/dist/planmagnet/sprints/SprintControls.d.ts +15 -3
  59. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  60. package/dist/planmagnet/sprints/SprintControls.js +293 -190
  61. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  62. package/dist/planmagnet/team/TeamControls.d.ts +31 -0
  63. package/dist/planmagnet/team/TeamControls.d.ts.map +1 -0
  64. package/dist/planmagnet/team/TeamControls.js +407 -0
  65. package/dist/planmagnet/team/TeamControls.js.map +1 -0
  66. package/package.json +1 -1
@@ -1,14 +1,15 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { throwOnError as t } from "../utils/mutationResult.js";
3
3
  import { ConfirmButton as n, ErrorLine as r } from "../controls/ConfirmButton.js";
4
- import { useDeferredValue as i, useState as a } from "react";
5
- import { CheckCircle2 as o, Play as s, Plus as c, X as l, XCircle as u } from "lucide-react";
6
- import { gql as d } from "@apollo/client";
7
- import { useMutation as f, useQuery as p } from "@apollo/client/react";
8
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
9
- import { Badge as g, Button as _, Checkbox as v, Input as y, ResponsiveDialog as b, ResponsiveDialogContent as x, ResponsiveDialogDescription as S, ResponsiveDialogFooter as C, ResponsiveDialogHeader as w, ResponsiveDialogTitle as T, ResponsiveDialogTrigger as E } from "@burdenoff/fe-libs/ui";
4
+ import { TeamSelect as i } from "../controls/Pickers.js";
5
+ import { useDeferredValue as a, useEffect as o, useState as s } from "react";
6
+ import { CheckCircle2 as c, Play as l, Plus as u, X as d, XCircle as f } from "lucide-react";
7
+ import { gql as p } from "@apollo/client";
8
+ import { useApolloClient as m, useMutation as h, useQuery as g } from "@apollo/client/react";
9
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
10
+ import { Badge as y, Button as b, Checkbox as x, Input as S, ResponsiveDialog as C, ResponsiveDialogContent as w, ResponsiveDialogDescription as T, ResponsiveDialogFooter as E, ResponsiveDialogHeader as D, ResponsiveDialogTitle as O, ResponsiveDialogTrigger as k } from "@burdenoff/fe-libs/ui";
10
11
  //#region src/planmagnet/sprints/SprintControls.tsx
11
- var D = {
12
+ var A = {
12
13
  start: ["PLANNING"],
13
14
  complete: ["ACTIVE", "REVIEW"],
14
15
  cancel: [
@@ -17,32 +18,32 @@ var D = {
17
18
  "REVIEW"
18
19
  ]
19
20
  };
20
- function O(e) {
21
- return Object.keys(D).filter((t) => D[t].includes(e));
21
+ function j(e) {
22
+ return Object.keys(A).filter((t) => A[t].includes(e));
22
23
  }
23
- function k(e) {
24
+ function M(e) {
24
25
  return e === "COMPLETED" || e === "CANCELLED";
25
26
  }
26
- var A = [
27
+ var N = [
27
28
  "GetSprints",
28
29
  "GetSprintDetail",
29
30
  "GetSprintForEdit",
30
31
  "GetDashboardData"
31
- ], j = d`
32
+ ], P = p`
32
33
  mutation SprintControlsStart($id: ID!) {
33
34
  planmagnetStartSprint(id: $id) {
34
35
  id
35
36
  status
36
37
  }
37
38
  }
38
- `, M = d`
39
+ `, F = p`
39
40
  mutation SprintControlsComplete($id: ID!) {
40
41
  planmagnetCompleteSprint(id: $id) {
41
42
  id
42
43
  status
43
44
  }
44
45
  }
45
- `, N = d`
46
+ `, I = p`
46
47
  mutation SprintControlsCancel($id: ID!) {
47
48
  planmagnetCancelSprint(id: $id) {
48
49
  id
@@ -50,12 +51,12 @@ var A = [
50
51
  }
51
52
  }
52
53
  `;
53
- function P({ sprintId: e, sprintName: i, status: c }) {
54
- let l = {
55
- refetchQueries: A,
54
+ function L({ sprintId: e, sprintName: i, status: a }) {
55
+ let o = {
56
+ refetchQueries: N,
56
57
  awaitRefetchQueries: !0
57
- }, [d, p] = f(j, l), [g, v] = f(M, l), [y, b] = f(N, l), [x, S] = a(null), C = p.loading || v.loading || b.loading, w = O(c);
58
- if (w.length === 0) return x ? /* @__PURE__ */ m(r, { message: x }) : null;
58
+ }, [u, d] = h(P, o), [p, m] = h(F, o), [g, y] = h(I, o), [x, S] = s(null), C = d.loading || m.loading || y.loading, w = j(a);
59
+ if (w.length === 0) return x ? /* @__PURE__ */ _(r, { message: x }) : null;
59
60
  let T = async (n) => {
60
61
  S(null);
61
62
  try {
@@ -64,55 +65,55 @@ function P({ sprintId: e, sprintName: i, status: c }) {
64
65
  S(e instanceof Error ? e.message : "The sprint could not be updated.");
65
66
  }
66
67
  };
67
- return /* @__PURE__ */ h("div", {
68
+ return /* @__PURE__ */ v("div", {
68
69
  className: "flex flex-col items-end gap-2",
69
70
  "data-testid": "sprint-lifecycle-actions",
70
- children: [/* @__PURE__ */ h("div", {
71
+ children: [/* @__PURE__ */ v("div", {
71
72
  className: "flex gap-2",
72
73
  children: [
73
- w.includes("start") && /* @__PURE__ */ h(_, {
74
+ w.includes("start") && /* @__PURE__ */ v(b, {
74
75
  size: "sm",
75
- onClick: () => T(d),
76
+ onClick: () => T(u),
76
77
  disabled: C,
77
- children: [/* @__PURE__ */ m(s, { className: "mr-1 h-4 w-4" }), "Start sprint"]
78
+ children: [/* @__PURE__ */ _(l, { className: "mr-1 h-4 w-4" }), "Start sprint"]
78
79
  }),
79
- w.includes("complete") && /* @__PURE__ */ m(n, {
80
+ w.includes("complete") && /* @__PURE__ */ _(n, {
80
81
  label: "Complete sprint",
81
- icon: /* @__PURE__ */ m(o, { className: "mr-1 h-4 w-4" }),
82
+ icon: /* @__PURE__ */ _(c, { className: "mr-1 h-4 w-4" }),
82
83
  title: `Complete ${i}?`,
83
84
  description: "The sprint is closed and its work items can no longer be changed from it. This cannot be undone.",
84
85
  confirmLabel: "Complete sprint",
85
86
  disabled: C,
86
- onConfirm: () => T(g)
87
+ onConfirm: () => T(p)
87
88
  }),
88
- w.includes("cancel") && /* @__PURE__ */ m(n, {
89
+ w.includes("cancel") && /* @__PURE__ */ _(n, {
89
90
  label: "Cancel sprint",
90
91
  variant: "outline",
91
- icon: /* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }),
92
+ icon: /* @__PURE__ */ _(f, { className: "mr-1 h-4 w-4" }),
92
93
  title: `Cancel ${i}?`,
93
94
  description: "The sprint is abandoned and cannot be restarted. Its work items stay in it for the record. This cannot be undone.",
94
95
  confirmLabel: "Cancel sprint",
95
96
  destructive: !0,
96
97
  disabled: C,
97
- onConfirm: () => T(y)
98
+ onConfirm: () => T(g)
98
99
  })
99
100
  ]
100
- }), x && /* @__PURE__ */ m(r, { message: x })]
101
+ }), x && /* @__PURE__ */ _(r, { message: x })]
101
102
  });
102
103
  }
103
- var F = d`
104
+ var R = p`
104
105
  mutation SprintControlsAddItems($id: ID!, $input: PlanmagnetSprintWorkItemsInput!) {
105
106
  planmagnetAddWorkItemsToSprint(id: $id, input: $input) {
106
107
  id
107
108
  }
108
109
  }
109
- `, I = d`
110
+ `, z = p`
110
111
  mutation SprintControlsRemoveItems($id: ID!, $input: PlanmagnetSprintWorkItemsInput!) {
111
112
  planmagnetRemoveWorkItemsFromSprint(id: $id, input: $input) {
112
113
  id
113
114
  }
114
115
  }
115
- `, L = d`
116
+ `, B = p`
116
117
  query SprintControlsCandidates($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {
117
118
  planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: { first: 100 }) {
118
119
  totalCount
@@ -123,87 +124,93 @@ var F = d`
123
124
  status
124
125
  storyPoints
125
126
  sprintId
127
+ projectId
126
128
  }
127
129
  }
128
130
  }
129
- `, R = (e) => e.toLowerCase().replace(/_/g, " ");
130
- function z({ sprintId: e, projectId: n, status: i, items: o }) {
131
- let s = k(i), [c, u] = f(I, {
132
- refetchQueries: A,
131
+ `, V = (e) => e.toLowerCase().replace(/_/g, " ");
132
+ function H({ sprintId: e, eligibleProjectIds: n, projectNames: i, status: a, items: o }) {
133
+ let c = M(a), [l, u] = h(z, {
134
+ refetchQueries: N,
133
135
  awaitRefetchQueries: !0
134
- }), [d, p] = a(null), [v, y] = a(null), b = async (n) => {
135
- p(null), y(n);
136
+ }), [f, p] = s(null), [m, g] = s(null), x = async (n) => {
137
+ p(null), g(n);
136
138
  try {
137
- await t(c({ variables: {
139
+ await t(l({ variables: {
138
140
  id: e,
139
141
  input: { workItemIds: [n] }
140
142
  } }));
141
143
  } catch (e) {
142
144
  p(e instanceof Error ? e.message : "The work item could not be removed.");
143
145
  } finally {
144
- y(null);
146
+ g(null);
145
147
  }
146
148
  };
147
- return /* @__PURE__ */ h("div", {
149
+ return /* @__PURE__ */ v("div", {
148
150
  className: "space-y-3",
149
151
  "data-testid": "sprint-work-items",
150
152
  children: [
151
- /* @__PURE__ */ h("div", {
153
+ /* @__PURE__ */ v("div", {
152
154
  className: "flex items-center justify-between",
153
- children: [/* @__PURE__ */ h("p", {
155
+ children: [/* @__PURE__ */ v("p", {
154
156
  className: "text-sm text-muted-foreground",
155
157
  children: [
156
158
  o.length,
157
159
  " work item",
158
160
  o.length === 1 ? "" : "s"
159
161
  ]
160
- }), !s && /* @__PURE__ */ m(B, {
162
+ }), !c && n.length > 0 && /* @__PURE__ */ _(U, {
161
163
  sprintId: e,
162
- projectId: n,
164
+ eligibleProjectIds: n,
165
+ projectNames: i,
163
166
  memberIds: o.map((e) => e.id)
164
167
  })]
165
168
  }),
166
- s && /* @__PURE__ */ h("p", {
169
+ c && /* @__PURE__ */ v("p", {
167
170
  className: "text-xs text-muted-foreground",
168
171
  children: [
169
172
  "This sprint is ",
170
- R(i),
173
+ V(a),
171
174
  "; its work items can no longer be changed."
172
175
  ]
173
176
  }),
174
- d && /* @__PURE__ */ m(r, { message: d }),
175
- o.length === 0 ? /* @__PURE__ */ m("p", {
177
+ !c && n.length === 0 && /* @__PURE__ */ _("p", {
178
+ className: "text-xs text-muted-foreground",
179
+ children: "This team has no projects yet — add a project to the team before adding work items."
180
+ }),
181
+ f && /* @__PURE__ */ _(r, { message: f }),
182
+ o.length === 0 ? /* @__PURE__ */ _("p", {
176
183
  className: "text-sm text-muted-foreground text-center py-4",
177
184
  children: "No work items in this sprint yet."
178
- }) : /* @__PURE__ */ m("ul", {
185
+ }) : /* @__PURE__ */ _("ul", {
179
186
  className: "space-y-1",
180
- children: o.map((e) => /* @__PURE__ */ h("li", {
187
+ children: o.map((e) => /* @__PURE__ */ v("li", {
181
188
  className: "flex items-center justify-between gap-2 border rounded-md p-2 text-sm",
182
- children: [/* @__PURE__ */ h("span", {
189
+ children: [/* @__PURE__ */ v("span", {
183
190
  className: "min-w-0 truncate",
184
- children: [/* @__PURE__ */ m("span", {
191
+ children: [/* @__PURE__ */ _("span", {
185
192
  className: "text-muted-foreground mr-2",
186
193
  children: e.key
187
194
  }), e.title]
188
- }), /* @__PURE__ */ h("span", {
195
+ }), /* @__PURE__ */ v("span", {
189
196
  className: "flex items-center gap-2 shrink-0",
190
197
  children: [
191
- /* @__PURE__ */ m(g, {
198
+ /* @__PURE__ */ _(y, {
192
199
  variant: "secondary",
193
200
  className: "text-xs capitalize",
194
- children: R(e.status)
201
+ children: V(e.status)
195
202
  }),
196
- /* @__PURE__ */ h("span", {
203
+ /* @__PURE__ */ v("span", {
197
204
  className: "text-xs text-muted-foreground",
198
205
  children: [e.storyPoints ?? 0, " pts"]
199
206
  }),
200
- !s && /* @__PURE__ */ m(_, {
207
+ !c && /* @__PURE__ */ _(b, {
201
208
  size: "sm",
202
209
  variant: "ghost",
203
210
  "aria-label": `Remove ${e.key} from sprint`,
204
211
  disabled: u.loading,
205
- onClick: () => b(e.id),
206
- children: v === e.id ? "…" : /* @__PURE__ */ m(l, { className: "h-4 w-4" })
212
+ onClick: () => x(e.id),
213
+ children: m === e.id ? "…" : /* @__PURE__ */ _(d, { className: "h-4 w-4" })
207
214
  })
208
215
  ]
209
216
  })]
@@ -212,129 +219,182 @@ function z({ sprintId: e, projectId: n, status: i, items: o }) {
212
219
  ]
213
220
  });
214
221
  }
215
- function B({ sprintId: n, projectId: o, memberIds: s }) {
216
- let { workspaceId: l } = e(), [u, d] = a(!1), [D, O] = a(""), k = i(D.trim()), [j, M] = a(/* @__PURE__ */ new Set()), [N, P] = a(null), { data: I, loading: z } = p(L, {
217
- variables: {
218
- workspaceId: l ?? "",
219
- filter: {
220
- projectId: o,
221
- excludeIds: s,
222
- ...k ? { search: k } : {}
222
+ function U({ sprintId: n, eligibleProjectIds: i, projectNames: c, memberIds: l }) {
223
+ let { workspaceId: d } = e(), f = m(), [p, g] = s(!1), [A, j] = s(""), M = a(A.trim()), [P, F] = s(/* @__PURE__ */ new Set()), [I, L] = s(null), z = `${i.join(",")}|${l.join(",")}|${M}`, [H, U] = s({
224
+ key: null,
225
+ items: [],
226
+ fetchedCount: 0,
227
+ totalCount: 0,
228
+ error: null
229
+ });
230
+ o(() => {
231
+ if (!p || !d || i.length === 0) return;
232
+ let e = !1;
233
+ return (async () => {
234
+ try {
235
+ let t = await Promise.all(i.map((e) => f.query({
236
+ query: B,
237
+ variables: {
238
+ workspaceId: d,
239
+ filter: {
240
+ projectId: e,
241
+ excludeIds: l,
242
+ ...M ? { search: M } : {}
243
+ }
244
+ },
245
+ fetchPolicy: "network-only"
246
+ })));
247
+ if (e) return;
248
+ U({
249
+ key: z,
250
+ items: t.flatMap((e) => e.data?.planmagnetWorkItems.items ?? []),
251
+ fetchedCount: t.reduce((e, t) => e + (t.data?.planmagnetWorkItems.items.length ?? 0), 0),
252
+ totalCount: t.reduce((e, t) => e + (t.data?.planmagnetWorkItems.totalCount ?? 0), 0),
253
+ error: null
254
+ });
255
+ } catch (t) {
256
+ if (e) return;
257
+ U({
258
+ key: z,
259
+ items: [],
260
+ fetchedCount: 0,
261
+ totalCount: 0,
262
+ error: t instanceof Error ? t.message : "The work items could not be loaded."
263
+ });
223
264
  }
224
- },
225
- skip: !u || !l,
226
- fetchPolicy: "network-only"
227
- }), [B, V] = f(F, {
228
- refetchQueries: A,
265
+ })(), () => {
266
+ e = !0;
267
+ };
268
+ }, [
269
+ p,
270
+ d,
271
+ i,
272
+ l,
273
+ M,
274
+ f,
275
+ z
276
+ ]);
277
+ let [W, G] = h(R, {
278
+ refetchQueries: N,
229
279
  awaitRefetchQueries: !0
230
- }), H = (I?.planmagnetWorkItems.items ?? []).filter((e) => e.sprintId !== n), U = I?.planmagnetWorkItems.totalCount ?? 0, W = (e, t) => M((n) => {
280
+ }), K = H.items.filter((e) => e.sprintId !== n), { totalCount: q, fetchedCount: J } = H, Y = p && H.key !== z, X = i.length > 1 && !!c, Z = (e, t) => F((n) => {
231
281
  let r = new Set(n);
232
282
  return t ? r.add(e) : r.delete(e), r;
233
- }), G = () => {
234
- M(/* @__PURE__ */ new Set()), O(""), P(null);
283
+ }), Q = () => {
284
+ F(/* @__PURE__ */ new Set()), j(""), L(null);
235
285
  };
236
- return /* @__PURE__ */ h(b, {
237
- open: u,
286
+ return /* @__PURE__ */ v(C, {
287
+ open: p,
238
288
  onOpenChange: (e) => {
239
- d(e), e || G();
289
+ g(e), e || Q();
240
290
  },
241
- children: [/* @__PURE__ */ m(E, {
291
+ children: [/* @__PURE__ */ _(k, {
242
292
  asChild: !0,
243
- children: /* @__PURE__ */ h(_, {
293
+ children: /* @__PURE__ */ v(b, {
244
294
  size: "sm",
245
295
  variant: "outline",
246
- children: [/* @__PURE__ */ m(c, { className: "mr-1 h-4 w-4" }), "Add work items"]
296
+ children: [/* @__PURE__ */ _(u, { className: "mr-1 h-4 w-4" }), "Add work items"]
247
297
  })
248
- }), /* @__PURE__ */ h(x, {
298
+ }), /* @__PURE__ */ v(w, {
249
299
  className: "max-w-lg",
250
300
  children: [
251
- /* @__PURE__ */ h(w, { children: [/* @__PURE__ */ m(T, { children: "Add work items" }), /* @__PURE__ */ m(S, { children: "Work items from this sprint's project. An item already in another sprint moves here." })] }),
252
- /* @__PURE__ */ m(y, {
253
- value: D,
254
- onChange: (e) => O(e.target.value),
301
+ /* @__PURE__ */ v(D, { children: [/* @__PURE__ */ _(O, { children: "Add work items" }), /* @__PURE__ */ _(T, { children: i.length > 1 ? "Work items from this team's projects. An item already in another sprint moves here." : "Work items from this sprint's project. An item already in another sprint moves here." })] }),
302
+ /* @__PURE__ */ _(S, {
303
+ value: A,
304
+ onChange: (e) => j(e.target.value),
255
305
  placeholder: "Search by title",
256
306
  "aria-label": "Search work items"
257
307
  }),
258
- /* @__PURE__ */ h("div", {
308
+ /* @__PURE__ */ v("div", {
259
309
  className: "max-h-80 overflow-y-auto space-y-1",
260
310
  "data-testid": "sprint-add-candidates",
261
311
  children: [
262
- z && /* @__PURE__ */ m("p", {
312
+ Y && /* @__PURE__ */ _("p", {
263
313
  className: "text-sm text-muted-foreground py-4 text-center",
264
314
  children: "Loading…"
265
315
  }),
266
- !z && H.length === 0 && /* @__PURE__ */ m("p", {
316
+ !Y && H.error && /* @__PURE__ */ _("p", {
317
+ className: "text-sm text-destructive py-4 text-center",
318
+ children: H.error
319
+ }),
320
+ !Y && !H.error && K.length === 0 && /* @__PURE__ */ _("p", {
267
321
  className: "text-sm text-muted-foreground py-4 text-center",
268
- children: k ? "No matching work items." : "Every work item in this project is already in this sprint."
322
+ children: M ? "No matching work items." : i.length > 1 ? "Every work item in this team's projects is already in this sprint." : "Every work item in this project is already in this sprint."
269
323
  }),
270
- H.map((e) => {
324
+ K.map((e) => {
271
325
  let t = `sprint-add-${e.id}`;
272
- return /* @__PURE__ */ h("label", {
326
+ return /* @__PURE__ */ v("label", {
273
327
  htmlFor: t,
274
328
  className: "flex items-center gap-3 border rounded-md p-2 text-sm cursor-pointer hover:bg-muted",
275
329
  children: [
276
- /* @__PURE__ */ m(v, {
330
+ /* @__PURE__ */ _(x, {
277
331
  id: t,
278
- checked: j.has(e.id),
279
- onCheckedChange: (t) => W(e.id, t === !0)
332
+ checked: P.has(e.id),
333
+ onCheckedChange: (t) => Z(e.id, t === !0)
280
334
  }),
281
- /* @__PURE__ */ h("span", {
335
+ /* @__PURE__ */ v("span", {
282
336
  className: "min-w-0 flex-1 truncate",
283
- children: [/* @__PURE__ */ m("span", {
337
+ children: [/* @__PURE__ */ _("span", {
284
338
  className: "text-muted-foreground mr-2",
285
339
  children: e.key
286
340
  }), e.title]
287
341
  }),
288
- e.sprintId && /* @__PURE__ */ m("span", {
342
+ X && /* @__PURE__ */ _("span", {
343
+ className: "text-xs text-muted-foreground shrink-0",
344
+ children: c?.[e.projectId] ?? e.projectId
345
+ }),
346
+ e.sprintId && /* @__PURE__ */ _("span", {
289
347
  className: "text-xs text-muted-foreground shrink-0",
290
348
  children: "in another sprint"
291
349
  }),
292
- /* @__PURE__ */ m(g, {
350
+ /* @__PURE__ */ _(y, {
293
351
  variant: "secondary",
294
352
  className: "text-xs capitalize shrink-0",
295
- children: R(e.status)
353
+ children: V(e.status)
296
354
  })
297
355
  ]
298
356
  }, e.id);
299
357
  }),
300
- U > 100 && /* @__PURE__ */ h("p", {
358
+ J < q && /* @__PURE__ */ v("p", {
301
359
  className: "text-xs text-muted-foreground pt-2",
302
360
  children: [
303
- "Showing the first 100 of ",
304
- U,
361
+ "Showing the first ",
362
+ J,
363
+ " of ",
364
+ q,
305
365
  ". Search to narrow the list."
306
366
  ]
307
367
  })
308
368
  ]
309
369
  }),
310
- N && /* @__PURE__ */ m(r, { message: N }),
311
- /* @__PURE__ */ m(C, { children: /* @__PURE__ */ m(_, {
370
+ I && /* @__PURE__ */ _(r, { message: I }),
371
+ /* @__PURE__ */ _(E, { children: /* @__PURE__ */ _(b, {
312
372
  onClick: async () => {
313
- P(null);
373
+ L(null);
314
374
  try {
315
- await t(B({ variables: {
375
+ await t(W({ variables: {
316
376
  id: n,
317
- input: { workItemIds: [...j] }
318
- } })), G(), d(!1);
377
+ input: { workItemIds: [...P] }
378
+ } })), Q(), g(!1);
319
379
  } catch (e) {
320
- P(e instanceof Error ? e.message : "The work items could not be added.");
380
+ L(e instanceof Error ? e.message : "The work items could not be added.");
321
381
  }
322
382
  },
323
- disabled: j.size === 0 || V.loading,
383
+ disabled: P.size === 0 || G.loading,
324
384
  "data-testid": "sprint-add-confirm",
325
- children: V.loading ? "Adding…" : `Add ${j.size} work item${j.size === 1 ? "" : "s"}`
385
+ children: G.loading ? "Adding…" : `Add ${P.size} work item${P.size === 1 ? "" : "s"}`
326
386
  }) })
327
387
  ]
328
388
  })]
329
389
  });
330
390
  }
331
- var V = d`
391
+ var W = p`
332
392
  mutation SprintControlsCreate($input: PlanmagnetCreateSprintInput!) {
333
393
  planmagnetCreateSprint(input: $input) {
334
394
  id
335
395
  }
336
396
  }
337
- `, H = d`
397
+ `, G = p`
338
398
  query SprintControlsProjects($workspaceId: ID!) {
339
399
  planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {
340
400
  items {
@@ -343,7 +403,7 @@ var V = d`
343
403
  }
344
404
  }
345
405
  }
346
- `, U = {
406
+ `, K = {
347
407
  name: "",
348
408
  projectId: "",
349
409
  startDate: "",
@@ -351,173 +411,216 @@ var V = d`
351
411
  goal: "",
352
412
  capacity: ""
353
413
  };
354
- function W({ onCreated: n }) {
355
- let { workspaceId: i } = e(), [o, s] = a(!1), [l, u] = a(U), [d, g] = a(null), { data: v, loading: D, error: O, refetch: k } = p(H, {
356
- variables: { workspaceId: i ?? "" },
357
- skip: !o || !i
358
- }), j = v?.planmagnetProjects.items ?? [], M = l.projectId || j[0]?.id || "", [N, { loading: P }] = f(V, {
359
- refetchQueries: A,
414
+ function q({ onCreated: n, initialScope: a, initialTeamId: o }) {
415
+ let { workspaceId: c } = e(), [l, d] = s(!1), [f, p] = s(K), [m, y] = s(a ?? "project"), [x, A] = s(o ?? ""), [j, M] = s(null), { data: P, loading: F, error: I, refetch: L } = g(G, {
416
+ variables: { workspaceId: c ?? "" },
417
+ skip: !l || !c || m !== "project"
418
+ }), R = P?.planmagnetProjects.items ?? [], z = f.projectId || R[0]?.id || "", [B, { loading: V }] = h(W, {
419
+ refetchQueries: N,
360
420
  awaitRefetchQueries: !0
361
- }), F = l.capacity.trim() === "" ? void 0 : Number(l.capacity), I = F !== void 0 && (!Number.isInteger(F) || F < 0), L = !!(l.startDate && l.endDate && l.endDate < l.startDate), R = l.name.trim() !== "" && M !== "" && !I && !L && !P;
362
- return /* @__PURE__ */ h(b, {
363
- open: o,
421
+ }), H = f.capacity.trim() === "" ? void 0 : Number(f.capacity), U = H !== void 0 && (!Number.isInteger(H) || H < 0), q = !!(f.startDate && f.endDate && f.endDate < f.startDate), J = m === "project" ? z !== "" : x !== "", Y = f.name.trim() !== "" && J && !U && !q && !V;
422
+ return /* @__PURE__ */ v(C, {
423
+ open: l,
364
424
  onOpenChange: (e) => {
365
- s(e), e || g(null);
425
+ d(e), e || M(null);
366
426
  },
367
- children: [/* @__PURE__ */ m(E, {
427
+ children: [/* @__PURE__ */ _(k, {
368
428
  asChild: !0,
369
- children: /* @__PURE__ */ h(_, {
429
+ children: /* @__PURE__ */ v(b, {
370
430
  size: "sm",
371
- children: [/* @__PURE__ */ m(c, { className: "mr-1 h-4 w-4" }), "New sprint"]
431
+ children: [/* @__PURE__ */ _(u, { className: "mr-1 h-4 w-4" }), "New sprint"]
372
432
  })
373
- }), /* @__PURE__ */ h(x, {
433
+ }), /* @__PURE__ */ v(w, {
374
434
  className: "max-w-lg",
375
435
  children: [
376
- /* @__PURE__ */ h(w, { children: [/* @__PURE__ */ m(T, { children: "New sprint" }), /* @__PURE__ */ m(S, { children: "The sprint starts in Planning. Start it when it is ready." })] }),
377
- /* @__PURE__ */ h("div", {
436
+ /* @__PURE__ */ v(D, { children: [/* @__PURE__ */ _(O, { children: "New sprint" }), /* @__PURE__ */ _(T, { children: "The sprint starts in Planning. Start it when it is ready." })] }),
437
+ /* @__PURE__ */ v("div", {
378
438
  className: "space-y-3",
379
439
  children: [
380
- /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
440
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
381
441
  htmlFor: "new-sprint-name",
382
442
  className: "text-sm font-medium",
383
443
  children: "Name"
384
- }), /* @__PURE__ */ m(y, {
444
+ }), /* @__PURE__ */ _(S, {
385
445
  id: "new-sprint-name",
386
446
  className: "mt-1",
387
- value: l.name,
388
- onChange: (e) => u({
389
- ...l,
447
+ value: f.name,
448
+ onChange: (e) => p({
449
+ ...f,
390
450
  name: e.target.value
391
451
  })
392
452
  })] }),
393
- /* @__PURE__ */ h("div", { children: [
394
- /* @__PURE__ */ m("label", {
453
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("span", {
454
+ className: "text-sm font-medium",
455
+ children: "Belongs to"
456
+ }), /* @__PURE__ */ v("div", {
457
+ className: "mt-1 flex gap-2",
458
+ role: "radiogroup",
459
+ "aria-label": "Sprint scope",
460
+ children: [/* @__PURE__ */ _(b, {
461
+ type: "button",
462
+ size: "sm",
463
+ variant: m === "project" ? "default" : "outline",
464
+ "aria-pressed": m === "project",
465
+ "data-testid": "new-sprint-scope-project",
466
+ onClick: () => y("project"),
467
+ children: "A project"
468
+ }), /* @__PURE__ */ _(b, {
469
+ type: "button",
470
+ size: "sm",
471
+ variant: m === "team" ? "default" : "outline",
472
+ "aria-pressed": m === "team",
473
+ "data-testid": "new-sprint-scope-team",
474
+ onClick: () => y("team"),
475
+ children: "A team"
476
+ })]
477
+ })] }),
478
+ m === "project" ? /* @__PURE__ */ v("div", { children: [
479
+ /* @__PURE__ */ _("label", {
395
480
  htmlFor: "new-sprint-project",
396
481
  className: "text-sm font-medium",
397
482
  children: "Project"
398
483
  }),
399
- /* @__PURE__ */ h("select", {
484
+ /* @__PURE__ */ v("select", {
400
485
  id: "new-sprint-project",
401
486
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
402
- value: M,
403
- onChange: (e) => u({
404
- ...l,
487
+ value: z,
488
+ onChange: (e) => p({
489
+ ...f,
405
490
  projectId: e.target.value
406
491
  }),
407
- children: [j.length === 0 && /* @__PURE__ */ m("option", {
492
+ children: [R.length === 0 && /* @__PURE__ */ _("option", {
408
493
  value: "",
409
- children: D && !v ? "Loading projects…" : O ? "Projects could not be loaded" : "No projects yet"
410
- }), j.map((e) => /* @__PURE__ */ m("option", {
494
+ children: F && !P ? "Loading projects…" : I ? "Projects could not be loaded" : "No projects yet"
495
+ }), R.map((e) => /* @__PURE__ */ _("option", {
411
496
  value: e.id,
412
497
  children: e.name
413
498
  }, e.id))]
414
499
  }),
415
- O && /* @__PURE__ */ h("p", {
500
+ I && /* @__PURE__ */ v("p", {
416
501
  role: "alert",
417
502
  className: "mt-1 flex items-center gap-2 text-xs text-destructive",
418
- children: [O.message, /* @__PURE__ */ m(_, {
503
+ children: [I.message, /* @__PURE__ */ _(b, {
419
504
  type: "button",
420
505
  size: "sm",
421
506
  variant: "ghost",
422
507
  className: "h-6 px-2 text-xs",
423
- onClick: () => void k(),
508
+ onClick: () => void L(),
424
509
  children: "Retry"
425
510
  })]
426
511
  }),
427
- !D && !O && v && j.length === 0 && /* @__PURE__ */ m("p", {
512
+ !F && !I && P && R.length === 0 && /* @__PURE__ */ _("p", {
428
513
  className: "mt-1 text-xs text-muted-foreground",
429
514
  children: "Create a project first (Projects → New project)."
430
515
  })
516
+ ] }) : /* @__PURE__ */ v("div", { children: [
517
+ /* @__PURE__ */ _("label", {
518
+ htmlFor: "new-sprint-team",
519
+ className: "text-sm font-medium",
520
+ children: "Team"
521
+ }),
522
+ /* @__PURE__ */ _("div", {
523
+ className: "mt-1",
524
+ children: /* @__PURE__ */ _(i, {
525
+ id: "new-sprint-team",
526
+ value: x,
527
+ onChange: A
528
+ })
529
+ }),
530
+ /* @__PURE__ */ _("p", {
531
+ className: "mt-1 text-xs text-muted-foreground",
532
+ children: "Only work items from the team's own projects can join this sprint."
533
+ })
431
534
  ] }),
432
- /* @__PURE__ */ h("div", {
535
+ /* @__PURE__ */ v("div", {
433
536
  className: "grid grid-cols-2 gap-3",
434
- children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
537
+ children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
435
538
  htmlFor: "new-sprint-start",
436
539
  className: "text-sm font-medium",
437
540
  children: "Start date"
438
- }), /* @__PURE__ */ m(y, {
541
+ }), /* @__PURE__ */ _(S, {
439
542
  id: "new-sprint-start",
440
543
  type: "date",
441
544
  className: "mt-1",
442
- value: l.startDate,
443
- onChange: (e) => u({
444
- ...l,
545
+ value: f.startDate,
546
+ onChange: (e) => p({
547
+ ...f,
445
548
  startDate: e.target.value
446
549
  })
447
- })] }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
550
+ })] }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
448
551
  htmlFor: "new-sprint-end",
449
552
  className: "text-sm font-medium",
450
553
  children: "End date"
451
- }), /* @__PURE__ */ m(y, {
554
+ }), /* @__PURE__ */ _(S, {
452
555
  id: "new-sprint-end",
453
556
  type: "date",
454
557
  className: "mt-1",
455
- value: l.endDate,
456
- onChange: (e) => u({
457
- ...l,
558
+ value: f.endDate,
559
+ onChange: (e) => p({
560
+ ...f,
458
561
  endDate: e.target.value
459
562
  })
460
563
  })] })]
461
564
  }),
462
- L && /* @__PURE__ */ m(r, { message: "The end date is before the start date." }),
463
- /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
565
+ q && /* @__PURE__ */ _(r, { message: "The end date is before the start date." }),
566
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
464
567
  htmlFor: "new-sprint-capacity",
465
568
  className: "text-sm font-medium",
466
569
  children: "Capacity (story points)"
467
- }), /* @__PURE__ */ m(y, {
570
+ }), /* @__PURE__ */ _(S, {
468
571
  id: "new-sprint-capacity",
469
572
  type: "number",
470
573
  min: 0,
471
574
  className: "mt-1",
472
- value: l.capacity,
473
- onChange: (e) => u({
474
- ...l,
575
+ value: f.capacity,
576
+ onChange: (e) => p({
577
+ ...f,
475
578
  capacity: e.target.value
476
579
  })
477
580
  })] }),
478
- I && /* @__PURE__ */ m(r, { message: "Capacity must be a whole number, 0 or more." }),
479
- /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
581
+ U && /* @__PURE__ */ _(r, { message: "Capacity must be a whole number, 0 or more." }),
582
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
480
583
  htmlFor: "new-sprint-goal",
481
584
  className: "text-sm font-medium",
482
585
  children: "Goal"
483
- }), /* @__PURE__ */ m(y, {
586
+ }), /* @__PURE__ */ _(S, {
484
587
  id: "new-sprint-goal",
485
588
  className: "mt-1",
486
- value: l.goal,
487
- onChange: (e) => u({
488
- ...l,
589
+ value: f.goal,
590
+ onChange: (e) => p({
591
+ ...f,
489
592
  goal: e.target.value
490
593
  })
491
594
  })] })
492
595
  ]
493
596
  }),
494
- d && /* @__PURE__ */ m(r, { message: d }),
495
- /* @__PURE__ */ m(C, { children: /* @__PURE__ */ m(_, {
597
+ j && /* @__PURE__ */ _(r, { message: j }),
598
+ /* @__PURE__ */ _(E, { children: /* @__PURE__ */ _(b, {
496
599
  onClick: async () => {
497
- g(null);
600
+ M(null);
498
601
  try {
499
- let e = (await t(N({ variables: { input: {
500
- name: l.name.trim(),
501
- projectId: M,
502
- startDate: l.startDate || void 0,
503
- endDate: l.endDate || void 0,
504
- goal: l.goal.trim() || void 0,
505
- capacity: F
602
+ let e = (await t(B({ variables: { input: {
603
+ name: f.name.trim(),
604
+ ...m === "team" ? { teamId: x } : { projectId: z },
605
+ startDate: f.startDate || void 0,
606
+ endDate: f.endDate || void 0,
607
+ goal: f.goal.trim() || void 0,
608
+ capacity: H
506
609
  } } }))).data?.planmagnetCreateSprint.id;
507
- u(U), s(!1), e && n(e);
610
+ p(K), d(!1), e && n(e);
508
611
  } catch (e) {
509
- g(e instanceof Error ? e.message : "The sprint could not be created.");
612
+ M(e instanceof Error ? e.message : "The sprint could not be created.");
510
613
  }
511
614
  },
512
- disabled: !R,
615
+ disabled: !Y,
513
616
  "data-testid": "new-sprint-submit",
514
- children: P ? "Creating…" : "Create sprint"
617
+ children: V ? "Creating…" : "Create sprint"
515
618
  }) })
516
619
  ]
517
620
  })]
518
621
  });
519
622
  }
520
623
  //#endregion
521
- export { W as NewSprintDialog, P as SprintLifecycleActions, z as SprintWorkItemsPanel };
624
+ export { q as NewSprintDialog, L as SprintLifecycleActions, H as SprintWorkItemsPanel };
522
625
 
523
626
  //# sourceMappingURL=SprintControls.js.map