@burdenoff/microfe-planmagnet 2026.926.1 → 2026.927.1

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 (52) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +90 -79
  3. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  4. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.js +124 -127
  6. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  7. package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
  8. package/dist/planmagnet/create/CreateDialogs.js +149 -124
  9. package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
  10. package/dist/planmagnet/pages/NotFoundPage.d.ts +6 -0
  11. package/dist/planmagnet/pages/NotFoundPage.d.ts.map +1 -0
  12. package/dist/planmagnet/pages/NotFoundPage.js +18 -0
  13. package/dist/planmagnet/pages/NotFoundPage.js.map +1 -0
  14. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  15. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +103 -87
  16. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  17. package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.d.ts.map +1 -1
  18. package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.js +111 -91
  19. package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  20. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  21. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +117 -97
  22. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  23. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
  24. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +133 -107
  25. package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
  26. package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
  27. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +161 -115
  28. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
  29. package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
  30. package/dist/planmagnet/pages/TasksEditTaskPagePage.js +117 -102
  31. package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
  32. package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +1 -1
  33. package/dist/planmagnet/pages/TasksTasksPagePage.js +4 -3
  34. package/dist/planmagnet/pages/TasksTasksPagePage.js.map +1 -1
  35. package/dist/planmagnet/pages/TeamInviteMemberPagePage.d.ts.map +1 -1
  36. package/dist/planmagnet/pages/TeamInviteMemberPagePage.js +147 -147
  37. package/dist/planmagnet/pages/TeamInviteMemberPagePage.js.map +1 -1
  38. package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
  39. package/dist/planmagnet/pages/TeamTeamPagePage.js +77 -67
  40. package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
  41. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  42. package/dist/planmagnet/sprints/SprintControls.js +48 -29
  43. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  44. package/dist/planmagnet/utils/email.d.ts +9 -0
  45. package/dist/planmagnet/utils/email.d.ts.map +1 -0
  46. package/dist/planmagnet/utils/email.js +15 -0
  47. package/dist/planmagnet/utils/email.js.map +1 -0
  48. package/dist/planmagnet/utils/formValidation.d.ts +18 -0
  49. package/dist/planmagnet/utils/formValidation.d.ts.map +1 -0
  50. package/dist/planmagnet/utils/formValidation.js +17 -0
  51. package/dist/planmagnet/utils/formValidation.js.map +1 -0
  52. package/package.json +1 -1
@@ -1,12 +1,13 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
- import { useMemo as t, useState as n } from "react";
3
- import { ArrowLeft as r, Save as i } from "lucide-react";
4
- import { gql as a } from "@apollo/client";
5
- import { useMutation as o, useQuery as s } from "@apollo/client/react";
6
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { Button as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m, Input as h } from "@burdenoff/fe-libs/ui";
2
+ import { parseIntField as t } from "../utils/formValidation.js";
3
+ import { useMemo as n, useState as r } from "react";
4
+ import { ArrowLeft as i, Save as a } from "lucide-react";
5
+ import { gql as o } from "@apollo/client";
6
+ import { useMutation as s, useQuery as c } from "@apollo/client/react";
7
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
+ import { Button as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h, Input as g } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/pages/TasksEditTaskPagePage.tsx
9
- var g = a`
10
+ var _ = o`
10
11
  query GetWorkItem($workItemId: ID!) {
11
12
  planmagnetWorkItem(id: $workItemId) {
12
13
  id
@@ -24,7 +25,7 @@ var g = a`
24
25
  updatedAt
25
26
  }
26
27
  }
27
- `, _ = a`
28
+ `, v = o`
28
29
  mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {
29
30
  planmagnetUpdateWorkItem(id: $workItemId, input: $input) {
30
31
  id
@@ -40,113 +41,114 @@ var g = a`
40
41
  }
41
42
  }
42
43
  `;
43
- function v() {
44
- let { workspaceId: a } = e(), v = new URLSearchParams(window.location.search).get("taskId") ?? "", { data: y, loading: b, error: x } = s(g, {
45
- variables: { workItemId: v },
46
- skip: !a || !v
47
- }), [S, { loading: C, error: w }] = o(_, { refetchQueries: ["GetWorkItems", "GetWorkItem"] }), T = y?.planmagnetWorkItem, E = t(() => ({
48
- title: T?.title ?? "",
49
- description: T?.description ?? "",
50
- priority: T?.priority ?? "MEDIUM",
51
- type: T?.type ?? "STORY",
52
- storyPoints: T?.storyPoints?.toString() ?? "0",
53
- labels: (T?.labels ?? []).join(", "),
54
- dueDate: T?.dueDate ?? ""
55
- }), [T]), [D, O] = n({}), k = {
56
- ...E,
57
- ...D
58
- }, A = (e) => O(e), j = async () => {
59
- !a || !v || await S({ variables: {
60
- workItemId: v,
44
+ function y() {
45
+ let { workspaceId: o } = e(), y = new URLSearchParams(window.location.search).get("taskId") ?? "", { data: b, loading: x, error: S } = c(_, {
46
+ variables: { workItemId: y },
47
+ skip: !o || !y
48
+ }), [C, { loading: w, error: T }] = s(v, { refetchQueries: ["GetWorkItems", "GetWorkItem"] }), E = b?.planmagnetWorkItem, D = n(() => ({
49
+ title: E?.title ?? "",
50
+ description: E?.description ?? "",
51
+ priority: E?.priority ?? "MEDIUM",
52
+ type: E?.type ?? "STORY",
53
+ storyPoints: E?.storyPoints?.toString() ?? "0",
54
+ labels: (E?.labels ?? []).join(", "),
55
+ dueDate: E?.dueDate ?? ""
56
+ }), [E]), [O, k] = r({}), A = {
57
+ ...D,
58
+ ...O
59
+ }, j = (e) => k(e), M = t(A.storyPoints, { min: 0 }), N = async () => {
60
+ !o || !y || M.invalid || await C({ variables: {
61
+ workItemId: y,
61
62
  input: {
62
- title: k.title,
63
- description: k.description || void 0,
64
- priority: k.priority,
65
- type: k.type,
66
- storyPoints: k.storyPoints ? parseInt(k.storyPoints, 10) : void 0,
67
- labels: k.labels ? k.labels.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
68
- dueDate: k.dueDate || void 0
63
+ title: A.title,
64
+ description: A.description || void 0,
65
+ priority: A.priority,
66
+ type: A.type,
67
+ storyPoints: M.value,
68
+ labels: A.labels ? A.labels.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
69
+ dueDate: A.dueDate || void 0
69
70
  }
70
71
  } });
71
72
  };
72
- if (b && !y) return /* @__PURE__ */ c("div", {
73
+ if (x && !b) return /* @__PURE__ */ l("div", {
73
74
  className: "flex items-center justify-center p-12",
74
- children: /* @__PURE__ */ c("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
75
+ children: /* @__PURE__ */ l("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
75
76
  });
76
- if (x) return /* @__PURE__ */ l("div", {
77
- className: "p-6 text-red-500",
78
- children: ["Error: ", x.message]
77
+ if (S) return /* @__PURE__ */ u("div", {
78
+ className: "p-6 text-destructive",
79
+ children: ["Error: ", S.message]
79
80
  });
80
- if (!y?.planmagnetWorkItem) return /* @__PURE__ */ c("div", {
81
+ if (!b?.planmagnetWorkItem) return /* @__PURE__ */ l("div", {
81
82
  className: "p-6 text-muted-foreground",
82
83
  children: "Task not found."
83
84
  });
84
- let M = y.planmagnetWorkItem;
85
- return /* @__PURE__ */ l("div", {
85
+ let P = b.planmagnetWorkItem;
86
+ return /* @__PURE__ */ u("div", {
86
87
  className: "space-y-6 p-6 max-w-4xl",
87
88
  children: [
88
- /* @__PURE__ */ l("div", {
89
+ /* @__PURE__ */ u("div", {
89
90
  className: "flex items-center justify-between",
90
- children: [/* @__PURE__ */ l("div", {
91
+ children: [/* @__PURE__ */ u("div", {
91
92
  className: "flex items-center gap-3",
92
- children: [/* @__PURE__ */ c(u, {
93
+ children: [/* @__PURE__ */ l(d, {
93
94
  variant: "ghost",
94
95
  size: "sm",
95
- children: /* @__PURE__ */ c(r, { className: "h-4 w-4" })
96
- }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
96
+ children: /* @__PURE__ */ l(i, { className: "h-4 w-4" })
97
+ }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("h1", {
97
98
  className: "text-2xl font-semibold",
98
99
  children: "Edit Task"
99
- }), /* @__PURE__ */ c("p", {
100
+ }), /* @__PURE__ */ l("p", {
100
101
  className: "text-sm text-muted-foreground",
101
- children: M.title
102
+ children: P.title
102
103
  })] })]
103
- }), /* @__PURE__ */ l(u, {
104
+ }), /* @__PURE__ */ u(d, {
104
105
  size: "sm",
105
- onClick: j,
106
- disabled: C,
107
- children: [/* @__PURE__ */ c(i, { className: "mr-1 h-4 w-4" }), C ? "Saving..." : "Save Changes"]
106
+ onClick: N,
107
+ disabled: w || M.invalid,
108
+ children: [/* @__PURE__ */ l(a, { className: "mr-1 h-4 w-4" }), w ? "Saving..." : "Save Changes"]
108
109
  })]
109
110
  }),
110
- w && /* @__PURE__ */ l("div", {
111
- className: "p-6 text-red-500",
112
- children: ["Error: ", w.message]
111
+ T && /* @__PURE__ */ l("div", {
112
+ role: "alert",
113
+ className: "p-3 bg-destructive/10 text-destructive rounded-md text-sm",
114
+ children: T.message
113
115
  }),
114
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(p, { children: /* @__PURE__ */ c(m, { children: "Task Details" }) }), /* @__PURE__ */ l(f, {
116
+ /* @__PURE__ */ u(f, { children: [/* @__PURE__ */ l(m, { children: /* @__PURE__ */ l(h, { children: "Task Details" }) }), /* @__PURE__ */ u(p, {
115
117
  className: "space-y-4",
116
118
  children: [
117
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
119
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
118
120
  className: "text-sm font-medium",
119
121
  children: "Title"
120
- }), /* @__PURE__ */ c(h, {
121
- value: k.title,
122
- onChange: (e) => A({
123
- ...k,
122
+ }), /* @__PURE__ */ l(g, {
123
+ value: A.title,
124
+ onChange: (e) => j({
125
+ ...A,
124
126
  title: e.target.value
125
127
  }),
126
128
  className: "mt-1"
127
129
  })] }),
128
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
130
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
129
131
  className: "text-sm font-medium",
130
132
  children: "Description"
131
- }), /* @__PURE__ */ c("textarea", {
133
+ }), /* @__PURE__ */ l("textarea", {
132
134
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]",
133
- value: k.description,
134
- onChange: (e) => A({
135
- ...k,
135
+ value: A.description,
136
+ onChange: (e) => j({
137
+ ...A,
136
138
  description: e.target.value
137
139
  })
138
140
  })] }),
139
- /* @__PURE__ */ l("div", {
141
+ /* @__PURE__ */ u("div", {
140
142
  className: "grid grid-cols-3 gap-4",
141
143
  children: [
142
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
144
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
143
145
  className: "text-sm font-medium",
144
146
  children: "Priority"
145
- }), /* @__PURE__ */ c("select", {
147
+ }), /* @__PURE__ */ l("select", {
146
148
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
147
- value: k.priority,
148
- onChange: (e) => A({
149
- ...k,
149
+ value: A.priority,
150
+ onChange: (e) => j({
151
+ ...A,
150
152
  priority: e.target.value
151
153
  }),
152
154
  children: [
@@ -154,19 +156,19 @@ function v() {
154
156
  "MEDIUM",
155
157
  "HIGH",
156
158
  "CRITICAL"
157
- ].map((e) => /* @__PURE__ */ c("option", {
159
+ ].map((e) => /* @__PURE__ */ l("option", {
158
160
  value: e,
159
161
  children: e.toLowerCase()
160
162
  }, e))
161
163
  })] }),
162
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
164
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
163
165
  className: "text-sm font-medium",
164
166
  children: "Type"
165
- }), /* @__PURE__ */ c("select", {
167
+ }), /* @__PURE__ */ l("select", {
166
168
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
167
- value: k.type,
168
- onChange: (e) => A({
169
- ...k,
169
+ value: A.type,
170
+ onChange: (e) => j({
171
+ ...A,
170
172
  type: e.target.value
171
173
  }),
172
174
  children: [
@@ -175,45 +177,58 @@ function v() {
175
177
  "TASK",
176
178
  "EPIC",
177
179
  "SUB_TASK"
178
- ].map((e) => /* @__PURE__ */ c("option", {
180
+ ].map((e) => /* @__PURE__ */ l("option", {
179
181
  value: e,
180
182
  children: e.toLowerCase().replace("_", " ")
181
183
  }, e))
182
184
  })] }),
183
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
184
- className: "text-sm font-medium",
185
- children: "Story Points"
186
- }), /* @__PURE__ */ c(h, {
187
- type: "number",
188
- value: k.storyPoints,
189
- onChange: (e) => A({
190
- ...k,
191
- storyPoints: e.target.value
185
+ /* @__PURE__ */ u("div", { children: [
186
+ /* @__PURE__ */ l("label", {
187
+ htmlFor: "task-story-points",
188
+ className: "text-sm font-medium",
189
+ children: "Story Points"
190
+ }),
191
+ /* @__PURE__ */ l(g, {
192
+ id: "task-story-points",
193
+ type: "number",
194
+ min: 0,
195
+ step: 1,
196
+ value: A.storyPoints,
197
+ onChange: (e) => j({
198
+ ...A,
199
+ storyPoints: e.target.value
200
+ }),
201
+ "aria-invalid": M.invalid,
202
+ className: "mt-1"
192
203
  }),
193
- className: "mt-1"
194
- })] })
204
+ M.invalid && /* @__PURE__ */ l("p", {
205
+ role: "alert",
206
+ className: "mt-1 text-xs text-destructive",
207
+ children: "Story points must be a whole number, 0 or more."
208
+ })
209
+ ] })
195
210
  ]
196
211
  }),
197
- /* @__PURE__ */ l("div", {
212
+ /* @__PURE__ */ u("div", {
198
213
  className: "grid grid-cols-2 gap-4",
199
- children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
214
+ children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
200
215
  className: "text-sm font-medium",
201
216
  children: "Due Date"
202
- }), /* @__PURE__ */ c(h, {
217
+ }), /* @__PURE__ */ l(g, {
203
218
  type: "date",
204
- value: k.dueDate,
205
- onChange: (e) => A({
206
- ...k,
219
+ value: A.dueDate,
220
+ onChange: (e) => j({
221
+ ...A,
207
222
  dueDate: e.target.value
208
223
  }),
209
224
  className: "mt-1"
210
- })] }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
225
+ })] }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
211
226
  className: "text-sm font-medium",
212
227
  children: "Labels"
213
- }), /* @__PURE__ */ c(h, {
214
- value: k.labels,
215
- onChange: (e) => A({
216
- ...k,
228
+ }), /* @__PURE__ */ l(g, {
229
+ value: A.labels,
230
+ onChange: (e) => j({
231
+ ...A,
217
232
  labels: e.target.value
218
233
  }),
219
234
  className: "mt-1"
@@ -225,6 +240,6 @@ function v() {
225
240
  });
226
241
  }
227
242
  //#endregion
228
- export { v as TasksEditTaskPagePage };
243
+ export { y as TasksEditTaskPagePage };
229
244
 
230
245
  //# sourceMappingURL=TasksEditTaskPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TasksEditTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksEditTaskPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItem($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ITEM = gql`\n mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {\n planmagnetUpdateWorkItem(id: $workItemId, input: $input) {\n id\n title\n description\n type\n status\n priority\n storyPoints\n dueDate\n labels\n updatedAt\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n description: string | null;\n type: string;\n status: string;\n priority: string;\n key: string;\n storyPoints: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport function TasksEditTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from the route params.\n // For now we use a placeholder that the host shell should provide.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\n });\n\n const [updateWorkItem, { loading: saving, error: saveError }] = useMutation(UPDATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems', 'GetWorkItem'],\n });\n\n const workItem = data?.planmagnetWorkItem;\n\n const defaultForm = useMemo(\n () => ({\n title: workItem?.title ?? '',\n description: workItem?.description ?? '',\n priority: workItem?.priority ?? 'MEDIUM',\n type: workItem?.type ?? 'STORY',\n storyPoints: workItem?.storyPoints?.toString() ?? '0',\n labels: (workItem?.labels ?? []).join(', '),\n dueDate: workItem?.dueDate ?? '',\n }),\n [workItem]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) => setFormOverrides(updates);\n\n const handleSave = async () => {\n if (!workspaceId || !workItemId) return;\n // mutation-error: shown from the hook's `error`; nothing runs on failure.\n await updateWorkItem({\n variables: {\n workItemId,\n input: {\n title: form.title,\n description: form.description || undefined,\n priority: form.priority,\n type: form.type,\n storyPoints: form.storyPoints ? parseInt(form.storyPoints, 10) : undefined,\n labels: form.labels\n ? form.labels\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean)\n : undefined,\n dueDate: form.dueDate || undefined,\n },\n },\n });\n };\n\n // Only before the first load: a refetch must not blank the page (it\n\n // unmounts every component on it and loses their state).\n\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-red-500\">Error: {error.message}</div>;\n }\n\n if (!data?.planmagnetWorkItem) {\n return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n }\n\n const task = data.planmagnetWorkItem;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Task</h1>\n <p className=\"text-sm text-muted-foreground\">{task.title}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n {saveError && <div className=\"p-6 text-red-500\">Error: {saveError.message}</div>}\n <Card>\n <CardHeader>\n <CardTitle>Task Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Priority</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'].map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Story Points</label>\n <Input\n type=\"number\"\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TasksEditTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksEditTaskPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState, useMemo } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery, useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, ArrowLeft } from 'lucide-react';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { parseIntField } from '../utils/formValidation';\n\nconst GET_WORK_ITEM = gql`\n query GetWorkItem($workItemId: ID!) {\n planmagnetWorkItem(id: $workItemId) {\n id\n title\n description\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nconst UPDATE_WORK_ITEM = gql`\n mutation UpdateWorkItem($workItemId: ID!, $input: PlanmagnetUpdateWorkItemInput!) {\n planmagnetUpdateWorkItem(id: $workItemId, input: $input) {\n id\n title\n description\n type\n status\n priority\n storyPoints\n dueDate\n labels\n updatedAt\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n description: string | null;\n type: string;\n status: string;\n priority: string;\n key: string;\n storyPoints: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport function TasksEditTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n // In a real app, workItemId comes from the route params.\n // For now we use a placeholder that the host shell should provide.\n const workItemId = new URLSearchParams(window.location.search).get('taskId') ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetWorkItem: WorkItemNode;\n }>(GET_WORK_ITEM, {\n variables: { workItemId },\n skip: !workspaceId || !workItemId,\n });\n\n const [updateWorkItem, { loading: saving, error: saveError }] = useMutation(UPDATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems', 'GetWorkItem'],\n });\n\n const workItem = data?.planmagnetWorkItem;\n\n const defaultForm = useMemo(\n () => ({\n title: workItem?.title ?? '',\n description: workItem?.description ?? '',\n priority: workItem?.priority ?? 'MEDIUM',\n type: workItem?.type ?? 'STORY',\n storyPoints: workItem?.storyPoints?.toString() ?? '0',\n labels: (workItem?.labels ?? []).join(', '),\n dueDate: workItem?.dueDate ?? '',\n }),\n [workItem]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (updates: Record<string, string>) => setFormOverrides(updates);\n\n // Story points are a whole number, 0 or more (BOFF-7833); the service refuses anything else.\n const storyPoints = parseIntField(form.storyPoints, { min: 0 });\n\n const handleSave = async () => {\n if (!workspaceId || !workItemId || storyPoints.invalid) return;\n // mutation-error: shown from the hook's `error`; nothing runs on failure.\n await updateWorkItem({\n variables: {\n workItemId,\n input: {\n title: form.title,\n description: form.description || undefined,\n priority: form.priority,\n type: form.type,\n storyPoints: storyPoints.value,\n labels: form.labels\n ? form.labels\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean)\n : undefined,\n dueDate: form.dueDate || undefined,\n },\n },\n });\n };\n\n // Only before the first load: a refetch must not blank the page (it\n\n // unmounts every component on it and loses their state).\n\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Error: {error.message}</div>;\n }\n\n if (!data?.planmagnetWorkItem) {\n return <div className=\"p-6 text-muted-foreground\">Task not found.</div>;\n }\n\n const task = data.planmagnetWorkItem;\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\">\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Task</h1>\n <p className=\"text-sm text-muted-foreground\">{task.title}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || storyPoints.invalid}>\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </div>\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError.message}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle>Task Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Priority</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'].map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"task-story-points\" className=\"text-sm font-medium\">\n Story Points\n </label>\n <Input\n id=\"task-story-points\"\n type=\"number\"\n min={0}\n step={1}\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n aria-invalid={storyPoints.invalid}\n className=\"mt-1\"\n />\n {storyPoints.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Story points must be a whole number, 0 or more.\n </p>\n )}\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAUA,IAAM,IAAgB,CAAG;;;;;;;;;;;;;;;;;;GAoBnB,IAAmB,CAAG;;;;;;;;;;;;;;;;AAiC5B,SAAgB,IAAwB;CACtC,IAAM,EAAE,mBAAgB,GAAe,EAIjC,IAAa,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAAC,IAAI,SAAS,IAAI,IAE1E,EAAE,SAAM,YAAS,aAAU,EAE9B,GAAe;EAChB,WAAW,EAAE,eAAY;EACzB,MAAM,CAAC,KAAe,CAAC;EACxB,CAAC,EAEI,CAAC,GAAgB,EAAE,SAAS,GAAQ,OAAO,OAAe,EAAY,GAAkB,EAC5F,gBAAgB,CAAC,gBAAgB,cAAc,EAChD,CAAC,EAEI,IAAW,GAAM,oBAEjB,IAAc,SACX;EACL,OAAO,GAAU,SAAS;EAC1B,aAAa,GAAU,eAAe;EACtC,UAAU,GAAU,YAAY;EAChC,MAAM,GAAU,QAAQ;EACxB,aAAa,GAAU,aAAa,UAAU,IAAI;EAClD,SAAS,GAAU,UAAU,EAAE,EAAE,KAAK,KAAK;EAC3C,SAAS,GAAU,WAAW;EAC/B,GACD,CAAC,EAAS,CACX,EAEK,CAAC,GAAe,KAAoB,EAAiC,EAAE,CAAC,EACxE,IAAO;EAAE,GAAG;EAAa,GAAG;EAAe,EAC3C,KAAW,MAAoC,EAAiB,EAAQ,EAGxE,IAAc,EAAc,EAAK,aAAa,EAAE,KAAK,GAAG,CAAC,EAEzD,IAAa,YAAY;AACzB,GAAC,KAAe,CAAC,KAAc,EAAY,WAE/C,MAAM,EAAe,EACnB,WAAW;GACT;GACA,OAAO;IACL,OAAO,EAAK;IACZ,aAAa,EAAK,eAAe,KAAA;IACjC,UAAU,EAAK;IACf,MAAM,EAAK;IACX,aAAa,EAAY;IACzB,QAAQ,EAAK,SACT,EAAK,OACF,MAAM,IAAI,CACV,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ,GAClB,KAAA;IACJ,SAAS,EAAK,WAAW,KAAA;IAC1B;GACF,EACF,CAAC;;AAOJ,KAAI,KAAW,CAAC,EACd,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;EAC9F,CAAA;AAIV,KAAI,EACF,QAAO,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,WAAQ,EAAM,QAAc;;AAG3E,KAAI,CAAC,GAAM,mBACT,QAAO,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAAqB,CAAA;CAGzE,IAAM,IAAO,EAAK;AAElB,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAQ,SAAQ;MAAQ,MAAK;gBAC3B,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAyB;MAAc,CAAA,EACrD,kBAAC,KAAD;MAAG,WAAU;gBAAiC,EAAK;MAAU,CAAA,CACzD,EAAA,CAAA,CACF;QACN,kBAAC,GAAD;KAAQ,MAAK;KAAK,SAAS;KAAY,UAAU,KAAU,EAAY;eAAvE,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAChC,IAAS,cAAc,eACjB;OACL;;GACL,KACC,kBAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;cACzB,EAAU;IACP,CAAA;GAER,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,gBAAwB,CAAA,EACxB,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cAAvB;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAsB;MAAa,CAAA,EACpD,kBAAC,GAAD;MACE,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,OAAO,EAAE,OAAO;OAAO,CAAC;MAC5D,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAsB;MAAmB,CAAA,EAC1D,kBAAC,YAAD;MACE,WAAU;MACV,OAAO,EAAK;MACZ,WAAW,MAAM,EAAQ;OAAE,GAAG;OAAM,aAAa,EAAE,OAAO;OAAO,CAAC;MAClE,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAsB;QAAgB,CAAA,EACvD,kBAAC,UAAD;QACE,WAAU;QACV,OAAO,EAAK;QACZ,WAAW,MAAM,EAAQ;SAAE,GAAG;SAAM,UAAU,EAAE,OAAO;SAAO,CAAC;kBAE9D;SAAC;SAAO;SAAU;SAAQ;SAAW,CAAC,KAAK,MAC1C,kBAAC,UAAD;SAAgB,OAAO;mBACpB,EAAE,aAAa;SACT,EAFI,EAEJ,CACT;QACK,CAAA,CACL,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAsB;QAAY,CAAA,EACnD,kBAAC,UAAD;QACE,WAAU;QACV,OAAO,EAAK;QACZ,WAAW,MAAM,EAAQ;SAAE,GAAG;SAAM,MAAM,EAAE,OAAO;SAAO,CAAC;kBAE1D;SAAC;SAAS;SAAO;SAAQ;SAAQ;SAAW,CAAC,KAAK,MACjD,kBAAC,UAAD;SAAgB,OAAO;mBACpB,EAAE,aAAa,CAAC,QAAQ,KAAK,IAAI;SAC3B,EAFI,EAEJ,CACT;QACK,CAAA,CACL,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,SAAD;SAAO,SAAQ;SAAoB,WAAU;mBAAsB;SAE3D,CAAA;QACR,kBAAC,GAAD;SACE,IAAG;SACH,MAAK;SACL,KAAK;SACL,MAAM;SACN,OAAO,EAAK;SACZ,WAAW,MAAM,EAAQ;UAAE,GAAG;UAAM,aAAa,EAAE,OAAO;UAAO,CAAC;SAClE,gBAAc,EAAY;SAC1B,WAAU;SACV,CAAA;QACD,EAAY,WACX,kBAAC,KAAD;SAAG,MAAK;SAAQ,WAAU;mBAAgC;SAEtD,CAAA;QAEF,EAAA,CAAA;OACF;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAsB;OAAgB,CAAA,EACvD,kBAAC,GAAD;OACE,MAAK;OACL,OAAO,EAAK;OACZ,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,SAAS,EAAE,OAAO;QAAO,CAAC;OAC9D,WAAU;OACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAsB;OAAc,CAAA,EACrD,kBAAC,GAAD;OACE,OAAO,EAAK;OACZ,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,QAAQ,EAAE,OAAO;QAAO,CAAC;OAC7D,WAAU;OACV,CAAA,CACE,EAAA,CAAA,CACF;;KACM;MACT,EAAA,CAAA;GACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"TasksTasksPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"names":[],"mappings":"AAwIA,wBAAgB,kBAAkB,4CAyOjC"}
1
+ {"version":3,"file":"TasksTasksPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"names":[],"mappings":"AAyIA,wBAAgB,kBAAkB,4CA0OjC"}
@@ -94,7 +94,7 @@ var h = c`
94
94
  BUG: "bg-red-100 text-red-700",
95
95
  TASK: "bg-blue-100 text-blue-700",
96
96
  EPIC: "bg-purple-100 text-purple-700",
97
- SUBTASK: "bg-gray-100 text-gray-700"
97
+ SUB_TASK: "bg-gray-100 text-gray-700"
98
98
  };
99
99
  function w() {
100
100
  let { workspaceId: c } = e(), w = t(), [T, E] = o("all"), [D, O] = o("all"), [k, A] = o(null), { data: j } = l(v, {
@@ -215,11 +215,12 @@ function w() {
215
215
  "story",
216
216
  "bug",
217
217
  "task",
218
- "epic"
218
+ "epic",
219
+ "sub_task"
219
220
  ].map((e) => /* @__PURE__ */ d("button", {
220
221
  onClick: () => O(e),
221
222
  className: `px-2 py-1 text-xs rounded capitalize ${D === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
222
- children: e
223
+ children: e === "sub_task" ? "sub-task" : e
223
224
  }, e))
224
225
  })
225
226
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"TasksTasksPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Filter } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { ProjectBoard } from '../board/ProjectBoard';\nimport { ExportWorkItemsButton } from '../export/ExportWorkItemsButton';\n\nconst GET_WORK_ITEMS = gql`\n query GetWorkItems(\n $workspaceId: ID!\n $filter: PlanmagnetWorkItemFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n title\n type\n status\n priority\n key\n assigneeId\n reporterId\n sprintId\n storyPoints\n estimateMinutes\n dueDate\n labels\n tags\n createdAt\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n totalCount\n }\n }\n`;\n\n// Server-side counts (QA H2): the list returns at most 100 rows per page, so\n// counting the loaded page undercounted every workspace past 100 items.\nconst GET_WORK_ITEM_COUNTS = gql`\n query GetWorkItemCounts($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {\n planmagnetWorkItemCounts(workspaceId: $workspaceId, filter: $filter) {\n total\n byStatus {\n status\n count\n }\n }\n }\n`;\n\nconst PAGE_SIZE = 100;\n\nconst GET_BOARD_PROJECTS = gql`\n query GetBoardProjects($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n type: string;\n status: string;\n priority: string;\n key: string;\n assigneeId: string | null;\n reporterId: string | null;\n sprintId: string | null;\n storyPoints: number | null;\n estimateMinutes: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n}\n\nconst columns = [\n 'BACKLOG',\n 'TODO',\n 'IN_PROGRESS',\n 'IN_REVIEW',\n 'TESTING',\n 'DONE',\n 'CANCELLED',\n] as const;\n\nconst colLabel: Record<string, string> = {\n BACKLOG: 'Backlog',\n TODO: 'To Do',\n IN_PROGRESS: 'In Progress',\n IN_REVIEW: 'In Review',\n TESTING: 'Testing',\n DONE: 'Done',\n CANCELLED: 'Cancelled',\n};\n\nconst colColor: Record<string, string> = {\n BACKLOG: 'border-t-gray-400',\n TODO: 'border-t-blue-400',\n IN_PROGRESS: 'border-t-yellow-400',\n IN_REVIEW: 'border-t-purple-400',\n TESTING: 'border-t-teal-400',\n DONE: 'border-t-green-400',\n CANCELLED: 'border-t-muted-foreground',\n};\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-700',\n MEDIUM: 'bg-blue-100 text-blue-700',\n HIGH: 'bg-orange-100 text-orange-700',\n CRITICAL: 'bg-red-100 text-red-700',\n};\n\nconst typeColor: Record<string, string> = {\n STORY: 'bg-green-100 text-green-700',\n BUG: 'bg-red-100 text-red-700',\n TASK: 'bg-blue-100 text-blue-700',\n EPIC: 'bg-purple-100 text-purple-700',\n SUBTASK: 'bg-gray-100 text-gray-700',\n};\n\nexport function TasksTasksPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [priorityFilter, setPriorityFilter] = useState<string>('all');\n const [typeFilter, setTypeFilter] = useState<string>('all');\n // P1.2: the Task Board is a project's real board (server-side placement,\n // drag-and-drop, WIP limits). null = not chosen yet -> the first project;\n // '' = the cross-project status overview, which is NOT a board.\n const [boardProject, setBoardProject] = useState<string | null>(null);\n const { data: projectsData } = useQuery(GET_BOARD_PROJECTS, {\n variables: { workspaceId },\n skip: !workspaceId,\n });\n const boardProjects = projectsData?.planmagnetProjects?.items ?? [];\n const selectedProject = boardProject ?? boardProjects[0]?.id ?? '';\n const selectedProjectName = boardProjects.find((p) => p.id === selectedProject)?.name ?? '';\n\n // Filters go to the server so the loaded items AND the counts both reflect\n // every matching item, not just the first page.\n const filter = {\n ...(priorityFilter !== 'all' && { priority: priorityFilter.toUpperCase() }),\n ...(typeFilter !== 'all' && { type: typeFilter.toUpperCase() }),\n };\n const [loadingMore, setLoadingMore] = useState(false);\n\n const { data, loading, error, fetchMore } = useQuery<{\n planmagnetWorkItems: {\n items: WorkItemNode[];\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n totalCount: number;\n };\n }>(GET_WORK_ITEMS, {\n variables: { workspaceId, filter, pagination: { first: PAGE_SIZE } },\n // The list only feeds the cross-project overview; a board loads its own cards.\n skip: !workspaceId || !!selectedProject,\n });\n const { data: countsData } = useQuery<{\n planmagnetWorkItemCounts: { total: number; byStatus: { status: string; count: number }[] };\n }>(GET_WORK_ITEM_COUNTS, { variables: { workspaceId, filter }, skip: !workspaceId });\n\n const loadMore = async () => {\n const after = data?.planmagnetWorkItems?.pageInfo?.endCursor;\n if (!after) return;\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { pagination: { first: PAGE_SIZE, after } },\n updateQuery: (prev, { fetchMoreResult }) => ({\n planmagnetWorkItems: {\n ...fetchMoreResult.planmagnetWorkItems,\n items: [\n ...prev.planmagnetWorkItems.items,\n ...fetchMoreResult.planmagnetWorkItems.items,\n ],\n },\n }),\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n // Only before the first load: a refetch or a filter change must not blank the board.\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-red-500\">Error: {error.message}</div>;\n }\n\n const tasks = data?.planmagnetWorkItems?.items ?? [];\n\n const counts = countsData?.planmagnetWorkItemCounts;\n const total = counts?.total ?? data?.planmagnetWorkItems?.totalCount ?? tasks.length;\n const countFor = (status: string) =>\n counts?.byStatus.find((c) => c.status === status)?.count ??\n tasks.filter((t) => t.status === status).length;\n const hasMore = data?.planmagnetWorkItems?.pageInfo?.hasNextPage ?? false;\n\n return (\n <div className=\"space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Task Board</h1>\n <label className=\"sr-only\" htmlFor=\"task-board-project\">\n Project\n </label>\n <select\n id=\"task-board-project\"\n className=\"mt-2 rounded-md border border-input bg-background px-2 py-1 text-sm\"\n value={selectedProject}\n onChange={(e) => setBoardProject(e.target.value)}\n >\n {boardProjects.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n <option value=\"\">All projects — status overview</option>\n </select>\n <div className=\"mt-2\">\n <ExportWorkItemsButton projectId={selectedProject || undefined} />\n </div>\n <p className=\"text-sm text-muted-foreground\" data-testid=\"task-board-total\">\n {total} tasks across all projects\n {tasks.length < total && ` · showing ${tasks.length}`}\n </p>\n </div>\n </div>\n {selectedProject ? (\n <ProjectBoard projectId={selectedProject} projectName={selectedProjectName} />\n ) : (\n <>\n <div className=\"flex gap-4 items-center flex-wrap\">\n <Filter className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex gap-1\">\n {['all', 'low', 'medium', 'high', 'critical'].map((p) => (\n <button\n key={p}\n onClick={() => setPriorityFilter(p)}\n className={`px-2 py-1 text-xs rounded capitalize ${priorityFilter === p ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {p}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1\">\n {['all', 'story', 'bug', 'task', 'epic'].map((t) => (\n <button\n key={t}\n onClick={() => setTypeFilter(t)}\n className={`px-2 py-1 text-xs rounded capitalize ${typeFilter === t ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {t}\n </button>\n ))}\n </div>\n </div>\n <div className=\"grid grid-cols-7 gap-3 overflow-x-auto\">\n {columns.map((col) => {\n const colTasks = tasks.filter((t) => t.status === col);\n return (\n <div key={col} className=\"min-w-[200px]\">\n <div className={`border-t-2 ${colColor[col]} rounded-t-md p-2 bg-muted/50`}>\n <div className=\"flex justify-between items-center\">\n <span className=\"text-sm font-medium\">{colLabel[col]}</span>\n <span\n className=\"text-xs bg-muted rounded-full px-1.5\"\n data-testid={`task-col-count-${col}`}\n >\n {countFor(col)}\n </span>\n </div>\n </div>\n <div className=\"space-y-2 mt-2\">\n {colTasks.map((task) => (\n <Card\n key={task.id}\n {...rowLinkProps(\n () =>\n navigate(\n `/tasks/task-detail-page?taskId=${encodeURIComponent(task.id)}`\n ),\n task.title\n )}\n >\n <CardContent className=\"p-3 space-y-2\">\n <p className=\"text-sm font-medium leading-tight\">{task.title}</p>\n <p className=\"text-xs text-muted-foreground\">{task.key}</p>\n <div className=\"flex gap-1 flex-wrap\">\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${typeColor[task.type] ?? ''}`}\n >\n {task.type.toLowerCase()}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1\">\n {(task.labels ?? []).slice(0, 2).map((l) => (\n <span key={l} className=\"text-[9px] px-1 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center\">\n {task.storyPoints ?? 0}\n </span>\n </div>\n </div>\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>\n {task.assigneeId ? <PersonName id={task.assigneeId} /> : 'Unassigned'}\n </span>\n <span>\n {task.dueDate ? new Date(task.dueDate).toLocaleDateString() : ''}\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n {hasMore && (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loadingMore}\n className=\"px-3 py-1.5 text-sm rounded-md bg-muted text-foreground hover:bg-muted/80 disabled:opacity-50\"\n data-testid=\"task-board-load-more\"\n >\n {loadingMore ? 'Loading…' : `Load more (${tasks.length} of ${total})`}\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TasksTasksPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksTasksPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Filter } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { ProjectBoard } from '../board/ProjectBoard';\nimport { ExportWorkItemsButton } from '../export/ExportWorkItemsButton';\n\nconst GET_WORK_ITEMS = gql`\n query GetWorkItems(\n $workspaceId: ID!\n $filter: PlanmagnetWorkItemFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n title\n type\n status\n priority\n key\n assigneeId\n reporterId\n sprintId\n storyPoints\n estimateMinutes\n dueDate\n labels\n tags\n createdAt\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n totalCount\n }\n }\n`;\n\n// Server-side counts (QA H2): the list returns at most 100 rows per page, so\n// counting the loaded page undercounted every workspace past 100 items.\nconst GET_WORK_ITEM_COUNTS = gql`\n query GetWorkItemCounts($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {\n planmagnetWorkItemCounts(workspaceId: $workspaceId, filter: $filter) {\n total\n byStatus {\n status\n count\n }\n }\n }\n`;\n\nconst PAGE_SIZE = 100;\n\nconst GET_BOARD_PROJECTS = gql`\n query GetBoardProjects($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\ninterface WorkItemNode {\n id: string;\n title: string;\n type: string;\n status: string;\n priority: string;\n key: string;\n assigneeId: string | null;\n reporterId: string | null;\n sprintId: string | null;\n storyPoints: number | null;\n estimateMinutes: number | null;\n dueDate: string | null;\n labels: string[];\n tags: string[];\n createdAt: string;\n}\n\nconst columns = [\n 'BACKLOG',\n 'TODO',\n 'IN_PROGRESS',\n 'IN_REVIEW',\n 'TESTING',\n 'DONE',\n 'CANCELLED',\n] as const;\n\nconst colLabel: Record<string, string> = {\n BACKLOG: 'Backlog',\n TODO: 'To Do',\n IN_PROGRESS: 'In Progress',\n IN_REVIEW: 'In Review',\n TESTING: 'Testing',\n DONE: 'Done',\n CANCELLED: 'Cancelled',\n};\n\nconst colColor: Record<string, string> = {\n BACKLOG: 'border-t-gray-400',\n TODO: 'border-t-blue-400',\n IN_PROGRESS: 'border-t-yellow-400',\n IN_REVIEW: 'border-t-purple-400',\n TESTING: 'border-t-teal-400',\n DONE: 'border-t-green-400',\n CANCELLED: 'border-t-muted-foreground',\n};\n\nconst priorityColor: Record<string, string> = {\n LOW: 'bg-gray-100 text-gray-700',\n MEDIUM: 'bg-blue-100 text-blue-700',\n HIGH: 'bg-orange-100 text-orange-700',\n CRITICAL: 'bg-red-100 text-red-700',\n};\n\nconst typeColor: Record<string, string> = {\n STORY: 'bg-green-100 text-green-700',\n BUG: 'bg-red-100 text-red-700',\n TASK: 'bg-blue-100 text-blue-700',\n EPIC: 'bg-purple-100 text-purple-700',\n // The API serves SUB_TASK (the stored SUBTASK is mapped by the service), so the old SUBTASK key never matched.\n SUB_TASK: 'bg-gray-100 text-gray-700',\n};\n\nexport function TasksTasksPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [priorityFilter, setPriorityFilter] = useState<string>('all');\n const [typeFilter, setTypeFilter] = useState<string>('all');\n // P1.2: the Task Board is a project's real board (server-side placement,\n // drag-and-drop, WIP limits). null = not chosen yet -> the first project;\n // '' = the cross-project status overview, which is NOT a board.\n const [boardProject, setBoardProject] = useState<string | null>(null);\n const { data: projectsData } = useQuery(GET_BOARD_PROJECTS, {\n variables: { workspaceId },\n skip: !workspaceId,\n });\n const boardProjects = projectsData?.planmagnetProjects?.items ?? [];\n const selectedProject = boardProject ?? boardProjects[0]?.id ?? '';\n const selectedProjectName = boardProjects.find((p) => p.id === selectedProject)?.name ?? '';\n\n // Filters go to the server so the loaded items AND the counts both reflect\n // every matching item, not just the first page.\n const filter = {\n ...(priorityFilter !== 'all' && { priority: priorityFilter.toUpperCase() }),\n ...(typeFilter !== 'all' && { type: typeFilter.toUpperCase() }),\n };\n const [loadingMore, setLoadingMore] = useState(false);\n\n const { data, loading, error, fetchMore } = useQuery<{\n planmagnetWorkItems: {\n items: WorkItemNode[];\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n totalCount: number;\n };\n }>(GET_WORK_ITEMS, {\n variables: { workspaceId, filter, pagination: { first: PAGE_SIZE } },\n // The list only feeds the cross-project overview; a board loads its own cards.\n skip: !workspaceId || !!selectedProject,\n });\n const { data: countsData } = useQuery<{\n planmagnetWorkItemCounts: { total: number; byStatus: { status: string; count: number }[] };\n }>(GET_WORK_ITEM_COUNTS, { variables: { workspaceId, filter }, skip: !workspaceId });\n\n const loadMore = async () => {\n const after = data?.planmagnetWorkItems?.pageInfo?.endCursor;\n if (!after) return;\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { pagination: { first: PAGE_SIZE, after } },\n updateQuery: (prev, { fetchMoreResult }) => ({\n planmagnetWorkItems: {\n ...fetchMoreResult.planmagnetWorkItems,\n items: [\n ...prev.planmagnetWorkItems.items,\n ...fetchMoreResult.planmagnetWorkItems.items,\n ],\n },\n }),\n });\n } finally {\n setLoadingMore(false);\n }\n };\n\n // Only before the first load: a refetch or a filter change must not blank the board.\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-red-500\">Error: {error.message}</div>;\n }\n\n const tasks = data?.planmagnetWorkItems?.items ?? [];\n\n const counts = countsData?.planmagnetWorkItemCounts;\n const total = counts?.total ?? data?.planmagnetWorkItems?.totalCount ?? tasks.length;\n const countFor = (status: string) =>\n counts?.byStatus.find((c) => c.status === status)?.count ??\n tasks.filter((t) => t.status === status).length;\n const hasMore = data?.planmagnetWorkItems?.pageInfo?.hasNextPage ?? false;\n\n return (\n <div className=\"space-y-4 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Task Board</h1>\n <label className=\"sr-only\" htmlFor=\"task-board-project\">\n Project\n </label>\n <select\n id=\"task-board-project\"\n className=\"mt-2 rounded-md border border-input bg-background px-2 py-1 text-sm\"\n value={selectedProject}\n onChange={(e) => setBoardProject(e.target.value)}\n >\n {boardProjects.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n <option value=\"\">All projects — status overview</option>\n </select>\n <div className=\"mt-2\">\n <ExportWorkItemsButton projectId={selectedProject || undefined} />\n </div>\n <p className=\"text-sm text-muted-foreground\" data-testid=\"task-board-total\">\n {total} tasks across all projects\n {tasks.length < total && ` · showing ${tasks.length}`}\n </p>\n </div>\n </div>\n {selectedProject ? (\n <ProjectBoard projectId={selectedProject} projectName={selectedProjectName} />\n ) : (\n <>\n <div className=\"flex gap-4 items-center flex-wrap\">\n <Filter className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex gap-1\">\n {['all', 'low', 'medium', 'high', 'critical'].map((p) => (\n <button\n key={p}\n onClick={() => setPriorityFilter(p)}\n className={`px-2 py-1 text-xs rounded capitalize ${priorityFilter === p ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {p}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1\">\n {/* sub_task → SUB_TASK: filtering by it works since svc 1f4db8e (it was a masked 500). */}\n {['all', 'story', 'bug', 'task', 'epic', 'sub_task'].map((t) => (\n <button\n key={t}\n onClick={() => setTypeFilter(t)}\n className={`px-2 py-1 text-xs rounded capitalize ${typeFilter === t ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}\n >\n {t === 'sub_task' ? 'sub-task' : t}\n </button>\n ))}\n </div>\n </div>\n <div className=\"grid grid-cols-7 gap-3 overflow-x-auto\">\n {columns.map((col) => {\n const colTasks = tasks.filter((t) => t.status === col);\n return (\n <div key={col} className=\"min-w-[200px]\">\n <div className={`border-t-2 ${colColor[col]} rounded-t-md p-2 bg-muted/50`}>\n <div className=\"flex justify-between items-center\">\n <span className=\"text-sm font-medium\">{colLabel[col]}</span>\n <span\n className=\"text-xs bg-muted rounded-full px-1.5\"\n data-testid={`task-col-count-${col}`}\n >\n {countFor(col)}\n </span>\n </div>\n </div>\n <div className=\"space-y-2 mt-2\">\n {colTasks.map((task) => (\n <Card\n key={task.id}\n {...rowLinkProps(\n () =>\n navigate(\n `/tasks/task-detail-page?taskId=${encodeURIComponent(task.id)}`\n ),\n task.title\n )}\n >\n <CardContent className=\"p-3 space-y-2\">\n <p className=\"text-sm font-medium leading-tight\">{task.title}</p>\n <p className=\"text-xs text-muted-foreground\">{task.key}</p>\n <div className=\"flex gap-1 flex-wrap\">\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${priorityColor[task.priority] ?? ''}`}\n >\n {task.priority.toLowerCase()}\n </span>\n <span\n className={`text-[10px] px-1.5 py-0.5 rounded-full capitalize ${typeColor[task.type] ?? ''}`}\n >\n {task.type.toLowerCase()}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex gap-1\">\n {(task.labels ?? []).slice(0, 2).map((l) => (\n <span key={l} className=\"text-[9px] px-1 py-0.5 rounded bg-muted\">\n {l}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-medium bg-primary/10 text-primary rounded-full h-5 w-5 flex items-center justify-center\">\n {task.storyPoints ?? 0}\n </span>\n </div>\n </div>\n <div className=\"flex justify-between text-[10px] text-muted-foreground\">\n <span>\n {task.assigneeId ? <PersonName id={task.assigneeId} /> : 'Unassigned'}\n </span>\n <span>\n {task.dueDate ? new Date(task.dueDate).toLocaleDateString() : ''}\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n {hasMore && (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loadingMore}\n className=\"px-3 py-1.5 text-sm rounded-md bg-muted text-foreground hover:bg-muted/80 disabled:opacity-50\"\n data-testid=\"task-board-load-more\"\n >\n {loadingMore ? 'Loading…' : `Load more (${tasks.length} of ${total})`}\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TeamInviteMemberPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamInviteMemberPagePage.tsx"],"names":[],"mappings":"AAkCA,wBAAgB,wBAAwB,4CA8JvC"}
1
+ {"version":3,"file":"TeamInviteMemberPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamInviteMemberPagePage.tsx"],"names":[],"mappings":"AAgDA,wBAAgB,wBAAwB,4CAyJvC"}