@burdenoff/microfe-planmagnet 2026.925.18 → 2026.926.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.
- package/dist/generated/wspace-types.d.ts +61 -2
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.js +93 -98
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js +72 -79
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js +112 -123
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +92 -98
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.js +88 -96
- package/dist/planmagnet/pages/ProductsProductsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +116 -114
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +82 -88
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js +79 -79
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +150 -154
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +120 -109
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +75 -31
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
- package/dist/planmagnet/roadmaps/planningFocus.d.ts +23 -0
- package/dist/planmagnet/roadmaps/planningFocus.d.ts.map +1 -0
- package/dist/planmagnet/roadmaps/planningFocus.js +76 -0
- package/dist/planmagnet/roadmaps/planningFocus.js.map +1 -0
- package/dist/planmagnet/sprints/SprintDates.d.ts +37 -0
- package/dist/planmagnet/sprints/SprintDates.d.ts.map +1 -0
- package/dist/planmagnet/sprints/SprintDates.js +114 -0
- package/dist/planmagnet/sprints/SprintDates.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { throwOnError as t } from "../utils/mutationResult.js";
|
|
3
|
+
import { useEntityId as n } from "../hooks/useEntityId.js";
|
|
4
|
+
import { SprintLifecycleActions as r } from "../sprints/SprintControls.js";
|
|
5
|
+
import { useMemo as i, useState as a } from "react";
|
|
6
|
+
import { ArrowLeft as o, Save as s } from "lucide-react";
|
|
7
|
+
import { gql as c } from "@apollo/client";
|
|
8
|
+
import { useMutation as l, useQuery as u } from "@apollo/client/react";
|
|
9
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
10
|
+
import { Button as p, Card as m, CardContent as h, CardHeader as g, CardTitle as _, Input as v } from "@burdenoff/fe-libs/ui";
|
|
10
11
|
//#region src/planmagnet/pages/ProjectsPlanningEditPagePage.tsx
|
|
11
|
-
var
|
|
12
|
+
var y = c`
|
|
12
13
|
query GetSprintForEdit($id: ID!, $workspaceId: ID!) {
|
|
13
14
|
planmagnetSprint(id: $id) {
|
|
14
15
|
id
|
|
@@ -27,7 +28,7 @@ var v = s`
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
|
-
`,
|
|
31
|
+
`, b = c`
|
|
31
32
|
mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {
|
|
32
33
|
planmagnetUpdateSprint(id: $id, input: $input) {
|
|
33
34
|
id
|
|
@@ -40,166 +41,176 @@ var v = s`
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
`;
|
|
43
|
-
function
|
|
44
|
-
let { workspaceId:
|
|
44
|
+
function x() {
|
|
45
|
+
let { workspaceId: c } = e(), x = n("sprintId"), { data: S, loading: C, error: w } = u(y, {
|
|
45
46
|
variables: {
|
|
46
|
-
id:
|
|
47
|
-
workspaceId:
|
|
47
|
+
id: x,
|
|
48
|
+
workspaceId: c ?? "default"
|
|
48
49
|
},
|
|
49
|
-
skip: !
|
|
50
|
-
}), [
|
|
51
|
-
name:
|
|
52
|
-
startDate:
|
|
53
|
-
endDate:
|
|
54
|
-
goal:
|
|
55
|
-
capacity:
|
|
56
|
-
}), [
|
|
57
|
-
...
|
|
58
|
-
...
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return b ? S && !x ? /* @__PURE__ */ u("div", {
|
|
50
|
+
skip: !x
|
|
51
|
+
}), [T, E] = a(null), D = S?.planmagnetSprint, O = S?.planmagnetProjects?.items ?? [], k = i(() => ({
|
|
52
|
+
name: D?.name ?? "",
|
|
53
|
+
startDate: D?.startDate ? D.startDate.split("T")[0] : "",
|
|
54
|
+
endDate: D?.endDate ? D.endDate.split("T")[0] : "",
|
|
55
|
+
goal: D?.goal ?? "",
|
|
56
|
+
capacity: D?.capacity?.toString() ?? ""
|
|
57
|
+
}), [D]), [A, j] = a({}), M = {
|
|
58
|
+
...k,
|
|
59
|
+
...A
|
|
60
|
+
}, N = (e) => j((t) => {
|
|
61
|
+
let n = { ...t };
|
|
62
|
+
for (let [t, r] of Object.entries(e)) r !== M[t] && (n[t] = r);
|
|
63
|
+
return n;
|
|
64
|
+
}), [P, F] = a(null), [I, { loading: L }] = l(b, { refetchQueries: [
|
|
65
|
+
"GetSprints",
|
|
66
|
+
"GetSprintDetail",
|
|
67
|
+
"GetSprintForEdit",
|
|
68
|
+
"GetDashboardData"
|
|
69
|
+
] });
|
|
70
|
+
return x ? C && !S ? /* @__PURE__ */ d("div", {
|
|
71
71
|
className: "flex items-center justify-center p-12",
|
|
72
|
-
children: /* @__PURE__ */
|
|
73
|
-
}) :
|
|
72
|
+
children: /* @__PURE__ */ d("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
73
|
+
}) : w ? /* @__PURE__ */ f("div", {
|
|
74
74
|
className: "p-6 text-red-500",
|
|
75
|
-
children: ["Error loading sprint: ",
|
|
76
|
-
}) :
|
|
75
|
+
children: ["Error loading sprint: ", w.message]
|
|
76
|
+
}) : D ? /* @__PURE__ */ f("div", {
|
|
77
77
|
className: "space-y-6 p-6 max-w-4xl",
|
|
78
78
|
children: [
|
|
79
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ f("div", {
|
|
80
80
|
className: "flex items-center justify-between",
|
|
81
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ f("div", {
|
|
82
82
|
className: "flex items-center gap-3",
|
|
83
|
-
children: [/* @__PURE__ */
|
|
83
|
+
children: [/* @__PURE__ */ d(p, {
|
|
84
84
|
variant: "ghost",
|
|
85
85
|
size: "sm",
|
|
86
|
-
children: /* @__PURE__ */
|
|
87
|
-
}), /* @__PURE__ */
|
|
86
|
+
children: /* @__PURE__ */ d(o, { className: "h-4 w-4" })
|
|
87
|
+
}), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
|
|
88
88
|
className: "text-2xl font-semibold",
|
|
89
89
|
children: "Edit Planning Session"
|
|
90
|
-
}), /* @__PURE__ */
|
|
90
|
+
}), /* @__PURE__ */ d("p", {
|
|
91
91
|
className: "text-sm text-muted-foreground",
|
|
92
|
-
children:
|
|
92
|
+
children: D.name
|
|
93
93
|
})] })]
|
|
94
|
-
}), /* @__PURE__ */
|
|
94
|
+
}), /* @__PURE__ */ f(p, {
|
|
95
95
|
size: "sm",
|
|
96
|
-
onClick: () => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
96
|
+
onClick: async () => {
|
|
97
|
+
if (!D) return;
|
|
98
|
+
F(null), E(null);
|
|
99
|
+
let e = {
|
|
100
|
+
...M.startDate !== k.startDate && M.startDate ? { startDate: M.startDate } : {},
|
|
101
|
+
...M.endDate !== k.endDate && M.endDate ? { endDate: M.endDate } : {}
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
await t(I({ variables: {
|
|
105
|
+
id: D.id,
|
|
106
|
+
input: {
|
|
107
|
+
name: M.name || void 0,
|
|
108
|
+
...e,
|
|
109
|
+
goal: M.goal || void 0,
|
|
110
|
+
capacity: M.capacity ? parseInt(M.capacity, 10) : void 0
|
|
111
|
+
}
|
|
112
|
+
} })), E("Sprint updated successfully."), j({});
|
|
113
|
+
} catch (e) {
|
|
114
|
+
F(e instanceof Error ? e.message : "The sprint could not be saved.");
|
|
115
|
+
}
|
|
107
116
|
},
|
|
108
|
-
disabled:
|
|
109
|
-
children: [/* @__PURE__ */
|
|
117
|
+
disabled: L,
|
|
118
|
+
children: [/* @__PURE__ */ d(s, { className: "mr-1 h-4 w-4" }), L ? "Saving..." : "Save Changes"]
|
|
110
119
|
})]
|
|
111
120
|
}),
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
T && /* @__PURE__ */ d("div", {
|
|
122
|
+
role: "status",
|
|
123
|
+
className: "p-3 rounded-md text-sm bg-muted text-status-success-text",
|
|
124
|
+
children: T
|
|
115
125
|
}),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
P && /* @__PURE__ */ f("div", {
|
|
127
|
+
role: "alert",
|
|
128
|
+
className: "p-3 rounded-md text-sm bg-destructive/10 text-destructive",
|
|
129
|
+
children: ["Error: ", P]
|
|
119
130
|
}),
|
|
120
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ f(m, { children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Session Details" }) }), /* @__PURE__ */ f(h, {
|
|
121
132
|
className: "space-y-4",
|
|
122
133
|
children: [
|
|
123
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
124
135
|
className: "text-sm font-medium",
|
|
125
136
|
children: "Name"
|
|
126
|
-
}), /* @__PURE__ */
|
|
127
|
-
value:
|
|
128
|
-
onChange: (e) =>
|
|
129
|
-
...
|
|
137
|
+
}), /* @__PURE__ */ d(v, {
|
|
138
|
+
value: M.name,
|
|
139
|
+
onChange: (e) => N({
|
|
140
|
+
...M,
|
|
130
141
|
name: e.target.value
|
|
131
142
|
}),
|
|
132
143
|
className: "mt-1"
|
|
133
144
|
})] }),
|
|
134
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ f("div", {
|
|
135
146
|
className: "grid grid-cols-2 gap-4",
|
|
136
|
-
children: [/* @__PURE__ */
|
|
147
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
137
148
|
className: "text-sm font-medium",
|
|
138
149
|
children: "Project"
|
|
139
|
-
}), /* @__PURE__ */
|
|
150
|
+
}), /* @__PURE__ */ d("div", {
|
|
140
151
|
className: "mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground",
|
|
141
|
-
children:
|
|
142
|
-
})] }), /* @__PURE__ */
|
|
152
|
+
children: O.find((e) => e.id === D.projectId)?.name ?? D.projectId
|
|
153
|
+
})] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
143
154
|
className: "text-sm font-medium",
|
|
144
155
|
children: "Status"
|
|
145
|
-
}), /* @__PURE__ */
|
|
156
|
+
}), /* @__PURE__ */ f("div", {
|
|
146
157
|
className: "mt-1 flex items-start justify-between gap-2",
|
|
147
|
-
children: [/* @__PURE__ */
|
|
158
|
+
children: [/* @__PURE__ */ d("span", {
|
|
148
159
|
className: "rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize",
|
|
149
|
-
children:
|
|
150
|
-
}), /* @__PURE__ */
|
|
151
|
-
sprintId:
|
|
152
|
-
sprintName:
|
|
153
|
-
status:
|
|
160
|
+
children: D.status.toLowerCase().replace(/_/g, " ")
|
|
161
|
+
}), /* @__PURE__ */ d(r, {
|
|
162
|
+
sprintId: D.id,
|
|
163
|
+
sprintName: D.name,
|
|
164
|
+
status: D.status
|
|
154
165
|
})]
|
|
155
166
|
})] })]
|
|
156
167
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ f("div", {
|
|
158
169
|
className: "grid grid-cols-2 gap-4",
|
|
159
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
160
171
|
className: "text-sm font-medium",
|
|
161
172
|
children: "Start Date"
|
|
162
|
-
}), /* @__PURE__ */
|
|
173
|
+
}), /* @__PURE__ */ d(v, {
|
|
163
174
|
type: "date",
|
|
164
|
-
value:
|
|
165
|
-
onChange: (e) =>
|
|
166
|
-
...
|
|
175
|
+
value: M.startDate,
|
|
176
|
+
onChange: (e) => N({
|
|
177
|
+
...M,
|
|
167
178
|
startDate: e.target.value
|
|
168
179
|
}),
|
|
169
180
|
className: "mt-1"
|
|
170
|
-
})] }), /* @__PURE__ */
|
|
181
|
+
})] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
171
182
|
className: "text-sm font-medium",
|
|
172
183
|
children: "End Date"
|
|
173
|
-
}), /* @__PURE__ */
|
|
184
|
+
}), /* @__PURE__ */ d(v, {
|
|
174
185
|
type: "date",
|
|
175
|
-
value:
|
|
176
|
-
onChange: (e) =>
|
|
177
|
-
...
|
|
186
|
+
value: M.endDate,
|
|
187
|
+
onChange: (e) => N({
|
|
188
|
+
...M,
|
|
178
189
|
endDate: e.target.value
|
|
179
190
|
}),
|
|
180
191
|
className: "mt-1"
|
|
181
192
|
})] })]
|
|
182
193
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
184
195
|
className: "text-sm font-medium",
|
|
185
196
|
children: "Goal"
|
|
186
|
-
}), /* @__PURE__ */
|
|
197
|
+
}), /* @__PURE__ */ d("textarea", {
|
|
187
198
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]",
|
|
188
|
-
value:
|
|
189
|
-
onChange: (e) =>
|
|
190
|
-
...
|
|
199
|
+
value: M.goal,
|
|
200
|
+
onChange: (e) => N({
|
|
201
|
+
...M,
|
|
191
202
|
goal: e.target.value
|
|
192
203
|
}),
|
|
193
204
|
placeholder: "Sprint goal..."
|
|
194
205
|
})] }),
|
|
195
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
196
207
|
className: "text-sm font-medium",
|
|
197
208
|
children: "Capacity (story points)"
|
|
198
|
-
}), /* @__PURE__ */
|
|
209
|
+
}), /* @__PURE__ */ d(v, {
|
|
199
210
|
type: "number",
|
|
200
|
-
value:
|
|
201
|
-
onChange: (e) =>
|
|
202
|
-
...
|
|
211
|
+
value: M.capacity,
|
|
212
|
+
onChange: (e) => N({
|
|
213
|
+
...M,
|
|
203
214
|
capacity: e.target.value
|
|
204
215
|
}),
|
|
205
216
|
className: "mt-1",
|
|
@@ -208,15 +219,15 @@ function b() {
|
|
|
208
219
|
]
|
|
209
220
|
})] })
|
|
210
221
|
]
|
|
211
|
-
}) : /* @__PURE__ */
|
|
222
|
+
}) : /* @__PURE__ */ d("div", {
|
|
212
223
|
className: "p-6 text-muted-foreground",
|
|
213
224
|
children: "Planning session not found."
|
|
214
|
-
}) : /* @__PURE__ */
|
|
225
|
+
}) : /* @__PURE__ */ d("div", {
|
|
215
226
|
className: "p-6 text-muted-foreground",
|
|
216
227
|
children: "No planning session selected. Open one from the list."
|
|
217
228
|
});
|
|
218
229
|
}
|
|
219
230
|
//#endregion
|
|
220
|
-
export {
|
|
231
|
+
export { x as ProjectsPlanningEditPagePage };
|
|
221
232
|
|
|
222
233
|
//# sourceMappingURL=ProjectsPlanningEditPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectsPlanningEditPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningEditPagePage.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 { useEntityId } from '../hooks/useEntityId';\nimport { SprintLifecycleActions } from '../sprints/SprintControls';\n\nconst GET_SPRINT_FOR_EDIT = gql`\n query GetSprintForEdit($id: ID!, $workspaceId: ID!) {\n planmagnetSprint(id: $id) {\n id\n name\n projectId\n status\n startDate\n endDate\n goal\n capacity\n }\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst UPDATE_SPRINT = gql`\n mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {\n planmagnetUpdateSprint(id: $id, input: $input) {\n id\n name\n status\n startDate\n endDate\n goal\n capacity\n }\n }\n`;\n\nexport function ProjectsPlanningEditPagePage() {\n const { workspaceId } = usePlanMagnet();\n const sprintId = useEntityId('sprintId');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_SPRINT_FOR_EDIT, {\n variables: { id: sprintId, workspaceId: workspaceId ?? 'default' },\n skip: !sprintId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const sprint = data?.planmagnetSprint;\n const projects = data?.planmagnetProjects?.items ?? [];\n\n const defaultForm = useMemo(\n () => ({\n name: sprint?.name ?? '',\n startDate: sprint?.startDate ? sprint.startDate.split('T')[0] : '',\n endDate: sprint?.endDate ? sprint.endDate.split('T')[0] : '',\n goal: sprint?.goal ?? '',\n capacity: sprint?.capacity?.toString() ?? '',\n }),\n [sprint]\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 [updateSprint, { loading: saving, error: saveError }] = useMutation(UPDATE_SPRINT, {\n refetchQueries: ['GetSprints', 'GetSprintDetail', 'GetSprintForEdit', 'GetDashboardData'],\n onCompleted: () => {\n setSuccessMessage('Sprint updated successfully.');\n },\n });\n\n const handleSave = () => {\n if (!sprint) return;\n updateSprint({\n variables: {\n id: sprint.id,\n input: {\n name: form.name || undefined,\n startDate: form.startDate || undefined,\n endDate: form.endDate || undefined,\n goal: form.goal || undefined,\n capacity: form.capacity ? parseInt(form.capacity, 10) : undefined,\n },\n },\n });\n };\n\n if (!sprintId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No planning session selected. Open one from the list.\n </div>\n );\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\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 if (error) return <div className=\"p-6 text-red-500\">Error loading sprint: {error.message}</div>;\n if (!sprint) return <div className=\"p-6 text-muted-foreground\">Planning session not found.</div>;\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 Planning Session</h1>\n <p className=\"text-sm text-muted-foreground\">{sprint.name}</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\n {successMessage && (\n <div className=\"p-3 bg-green-50 text-green-800 rounded-md text-sm\">{successMessage}</div>\n )}\n {saveError && (\n <div className=\"p-3 bg-red-50 text-red-800 rounded-md text-sm\">\n Error: {saveError.message}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Session Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <div className=\"mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground\">\n {projects.find((p: { id: string; name: string }) => p.id === sprint.projectId)\n ?.name ?? sprint.projectId}\n </div>\n </div>\n <div>\n {/* Status is not an editable field: planmagnetUpdateSprint does not\n accept it, and sending it failed EVERY save on this page. It\n changes only through the guarded lifecycle actions. */}\n <label className=\"text-sm font-medium\">Status</label>\n <div className=\"mt-1 flex items-start justify-between gap-2\">\n <span className=\"rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize\">\n {sprint.status.toLowerCase().replace(/_/g, ' ')}\n </span>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Start Date</label>\n <Input\n type=\"date\"\n value={form.startDate}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">End Date</label>\n <Input\n type=\"date\"\n value={form.endDate}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Goal</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]\"\n value={form.goal}\n onChange={(e) => setForm({ ...form, goal: e.target.value })}\n placeholder=\"Sprint goal...\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Capacity (story points)</label>\n <Input\n type=\"number\"\n value={form.capacity}\n onChange={(e) => setForm({ ...form, capacity: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. 40\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProjectsPlanningEditPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProjectsPlanningEditPagePage.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 { useEntityId } from '../hooks/useEntityId';\nimport { SprintLifecycleActions } from '../sprints/SprintControls';\nimport { throwOnError } from '../utils/mutationResult';\n\nconst GET_SPRINT_FOR_EDIT = gql`\n query GetSprintForEdit($id: ID!, $workspaceId: ID!) {\n planmagnetSprint(id: $id) {\n id\n name\n projectId\n status\n startDate\n endDate\n goal\n capacity\n }\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst UPDATE_SPRINT = gql`\n mutation UpdateSprint($id: ID!, $input: PlanmagnetUpdateSprintInput!) {\n planmagnetUpdateSprint(id: $id, input: $input) {\n id\n name\n status\n startDate\n endDate\n goal\n capacity\n }\n }\n`;\n\nexport function ProjectsPlanningEditPagePage() {\n const { workspaceId } = usePlanMagnet();\n const sprintId = useEntityId('sprintId');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(GET_SPRINT_FOR_EDIT, {\n variables: { id: sprintId, workspaceId: workspaceId ?? 'default' },\n skip: !sprintId,\n });\n\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const sprint = data?.planmagnetSprint;\n const projects = data?.planmagnetProjects?.items ?? [];\n\n const defaultForm = useMemo(\n () => ({\n name: sprint?.name ?? '',\n startDate: sprint?.startDate ? sprint.startDate.split('T')[0] : '',\n endDate: sprint?.endDate ? sprint.endDate.split('T')[0] : '',\n goal: sprint?.goal ?? '',\n capacity: sprint?.capacity?.toString() ?? '',\n }),\n [sprint]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n // Keep ONLY the fields the user actually edited. Callers pass the whole form\n // ({ ...form, field }); copying every field made untouched dates stale\n // snapshots, so after a refetch (e.g. a CONFLICT) a retry re-sent the old\n // dates and silently reverted a teammate's replan (BOFF-7918 review).\n const setForm = (updates: Record<string, string>) =>\n setFormOverrides((prev) => {\n const next = { ...prev };\n for (const [key, value] of Object.entries(updates)) {\n if (value !== form[key as keyof typeof form]) next[key] = value;\n }\n return next;\n });\n\n const [saveError, setSaveError] = useState<string | null>(null);\n const [updateSprint, { loading: saving }] = useMutation(UPDATE_SPRINT, {\n refetchQueries: ['GetSprints', 'GetSprintDetail', 'GetSprintForEdit', 'GetDashboardData'],\n });\n\n const handleSave = async () => {\n if (!sprint) return;\n setSaveError(null);\n setSuccessMessage(null);\n // Send the planned dates only when the user changed them (BOFF-7918).\n // Every change to a planned date is recorded in the sprint's plan history,\n // so re-sending unchanged dates on a rename must not look like a replan.\n const dateChanges = {\n ...(form.startDate !== defaultForm.startDate && form.startDate\n ? { startDate: form.startDate }\n : {}),\n ...(form.endDate !== defaultForm.endDate && form.endDate ? { endDate: form.endDate } : {}),\n };\n try {\n await throwOnError(\n updateSprint({\n variables: {\n id: sprint.id,\n input: {\n name: form.name || undefined,\n ...dateChanges,\n goal: form.goal || undefined,\n capacity: form.capacity ? parseInt(form.capacity, 10) : undefined,\n },\n },\n })\n );\n // Only after the service ACCEPTED it: under fe-libs' errorPolicy 'all' a\n // refused save resolves, and onCompleted reported success for it.\n setSuccessMessage('Sprint updated successfully.');\n setFormOverrides({});\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The sprint could not be saved.');\n }\n };\n\n if (!sprintId)\n return (\n <div className=\"p-6 text-muted-foreground\">\n No planning session selected. Open one from the list.\n </div>\n );\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\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 if (error) return <div className=\"p-6 text-red-500\">Error loading sprint: {error.message}</div>;\n if (!sprint) return <div className=\"p-6 text-muted-foreground\">Planning session not found.</div>;\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 Planning Session</h1>\n <p className=\"text-sm text-muted-foreground\">{sprint.name}</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\n {successMessage && (\n <div role=\"status\" className=\"p-3 rounded-md text-sm bg-muted text-status-success-text\">\n {successMessage}\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md text-sm bg-destructive/10 text-destructive\">\n Error: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Session Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Name</label>\n <Input\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <div className=\"mt-1 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground\">\n {projects.find((p: { id: string; name: string }) => p.id === sprint.projectId)\n ?.name ?? sprint.projectId}\n </div>\n </div>\n <div>\n {/* Status is not an editable field: planmagnetUpdateSprint does not\n accept it, and sending it failed EVERY save on this page. It\n changes only through the guarded lifecycle actions. */}\n <label className=\"text-sm font-medium\">Status</label>\n <div className=\"mt-1 flex items-start justify-between gap-2\">\n <span className=\"rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground capitalize\">\n {sprint.status.toLowerCase().replace(/_/g, ' ')}\n </span>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Start Date</label>\n <Input\n type=\"date\"\n value={form.startDate}\n onChange={(e) => setForm({ ...form, startDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">End Date</label>\n <Input\n type=\"date\"\n value={form.endDate}\n onChange={(e) => setForm({ ...form, endDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Goal</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]\"\n value={form.goal}\n onChange={(e) => setForm({ ...form, goal: e.target.value })}\n placeholder=\"Sprint goal...\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Capacity (story points)</label>\n <Input\n type=\"number\"\n value={form.capacity}\n onChange={(e) => setForm({ ...form, capacity: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. 40\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SprintsStartSprintPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SprintsStartSprintPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"names":[],"mappings":"AAmGA,wBAAgB,0BAA0B,4CA2PzC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { detailPath as n } from "../utils/rowNavigation.js";
|
|
3
3
|
import { NewSprintDialog as r, SprintLifecycleActions as i } from "../sprints/SprintControls.js";
|
|
4
|
-
import {
|
|
4
|
+
import { SprintDates as a } from "../sprints/SprintDates.js";
|
|
5
|
+
import { Users as o, Zap as s } from "lucide-react";
|
|
5
6
|
import { gql as c } from "@apollo/client";
|
|
6
7
|
import { useQuery as l } from "@apollo/client/react";
|
|
7
8
|
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
@@ -21,6 +22,18 @@ var _ = c`
|
|
|
21
22
|
status
|
|
22
23
|
startDate
|
|
23
24
|
endDate
|
|
25
|
+
startedAt
|
|
26
|
+
completedAt
|
|
27
|
+
baselineStartDate
|
|
28
|
+
baselineEndDate
|
|
29
|
+
planChanges {
|
|
30
|
+
field
|
|
31
|
+
fromValue
|
|
32
|
+
toValue
|
|
33
|
+
sprintStatus
|
|
34
|
+
changedBy
|
|
35
|
+
changedAt
|
|
36
|
+
}
|
|
24
37
|
velocity
|
|
25
38
|
workItems {
|
|
26
39
|
id
|
|
@@ -52,7 +65,7 @@ function y() {
|
|
|
52
65
|
pagination: { first: 50 }
|
|
53
66
|
},
|
|
54
67
|
skip: !c
|
|
55
|
-
}), S = y?.planmagnetSprints?.items ?? [], C = S.filter((e) => e.status === "ACTIVE" || e.status === "REVIEW"), w = S.filter((e) => e.status === "PLANNING"), T =
|
|
68
|
+
}), S = y?.planmagnetSprints?.items ?? [], C = S.filter((e) => e.status === "ACTIVE" || e.status === "REVIEW"), w = S.filter((e) => e.status === "PLANNING"), T = S.filter((e) => e.status === "COMPLETED" || e.status === "CANCELLED"), E = t(), D = (e) => E(n("/projects/planning-detail-page", e));
|
|
56
69
|
return b && !y ? /* @__PURE__ */ u("div", {
|
|
57
70
|
className: "flex items-center justify-center p-12",
|
|
58
71
|
children: /* @__PURE__ */ u("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
@@ -75,7 +88,7 @@ function y() {
|
|
|
75
88
|
C.length,
|
|
76
89
|
" active"
|
|
77
90
|
]
|
|
78
|
-
})] }), /* @__PURE__ */ u(r, { onCreated:
|
|
91
|
+
})] }), /* @__PURE__ */ u(r, { onCreated: D })]
|
|
79
92
|
}),
|
|
80
93
|
C.length > 0 && /* @__PURE__ */ d("div", {
|
|
81
94
|
className: "space-y-4",
|
|
@@ -93,7 +106,7 @@ function y() {
|
|
|
93
106
|
children: [/* @__PURE__ */ u(s, { className: "h-4 w-4 text-primary" }), /* @__PURE__ */ u("button", {
|
|
94
107
|
type: "button",
|
|
95
108
|
className: "hover:underline text-left",
|
|
96
|
-
onClick: () =>
|
|
109
|
+
onClick: () => D(e.id),
|
|
97
110
|
children: e.name
|
|
98
111
|
})]
|
|
99
112
|
}), /* @__PURE__ */ d("div", {
|
|
@@ -112,24 +125,17 @@ function y() {
|
|
|
112
125
|
className: "text-sm text-muted-foreground",
|
|
113
126
|
children: e.goal ?? ""
|
|
114
127
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ u(a, { sprint: e }),
|
|
129
|
+
/* @__PURE__ */ u("div", {
|
|
116
130
|
className: "flex gap-4 text-xs text-muted-foreground",
|
|
117
|
-
children:
|
|
118
|
-
className: "flex items-center gap-1",
|
|
119
|
-
children: [
|
|
120
|
-
/* @__PURE__ */ u(a, { className: "h-3 w-3" }),
|
|
121
|
-
e.startDate ?? "?",
|
|
122
|
-
" - ",
|
|
123
|
-
e.endDate ?? "?"
|
|
124
|
-
]
|
|
125
|
-
}), /* @__PURE__ */ d("span", {
|
|
131
|
+
children: /* @__PURE__ */ d("span", {
|
|
126
132
|
className: "flex items-center gap-1",
|
|
127
133
|
children: [
|
|
128
134
|
/* @__PURE__ */ u(o, { className: "h-3 w-3" }),
|
|
129
135
|
t.teamMemberIds.length,
|
|
130
136
|
" members"
|
|
131
137
|
]
|
|
132
|
-
})
|
|
138
|
+
})
|
|
133
139
|
}),
|
|
134
140
|
/* @__PURE__ */ d("div", {
|
|
135
141
|
className: "grid grid-cols-3 gap-4 text-center",
|
|
@@ -241,7 +247,7 @@ function y() {
|
|
|
241
247
|
children: /* @__PURE__ */ u("button", {
|
|
242
248
|
type: "button",
|
|
243
249
|
className: "hover:underline text-left",
|
|
244
|
-
onClick: () =>
|
|
250
|
+
onClick: () => D(e.id),
|
|
245
251
|
children: e.name
|
|
246
252
|
})
|
|
247
253
|
}), /* @__PURE__ */ d("div", {
|
|
@@ -258,23 +264,61 @@ function y() {
|
|
|
258
264
|
})
|
|
259
265
|
}), /* @__PURE__ */ d(m, {
|
|
260
266
|
className: "space-y-2",
|
|
261
|
-
children: [
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
/* @__PURE__ */ d("span", { children: [t.totalPoints, " points planned"] }),
|
|
273
|
-
/* @__PURE__ */ d("span", { children: [t.teamMemberIds.length, " members"] })
|
|
274
|
-
]
|
|
275
|
-
})]
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ u("p", {
|
|
269
|
+
className: "text-sm text-muted-foreground",
|
|
270
|
+
children: e.goal ?? ""
|
|
271
|
+
}),
|
|
272
|
+
/* @__PURE__ */ u(a, { sprint: e }),
|
|
273
|
+
/* @__PURE__ */ d("div", {
|
|
274
|
+
className: "flex gap-4 text-xs text-muted-foreground",
|
|
275
|
+
children: [/* @__PURE__ */ d("span", { children: [t.totalPoints, " points planned"] }), /* @__PURE__ */ d("span", { children: [t.teamMemberIds.length, " members"] })]
|
|
276
|
+
})
|
|
277
|
+
]
|
|
276
278
|
})] }, e.id);
|
|
277
279
|
})]
|
|
280
|
+
}),
|
|
281
|
+
T.length > 0 && /* @__PURE__ */ d("div", {
|
|
282
|
+
className: "space-y-4",
|
|
283
|
+
"data-testid": "finished-sprints",
|
|
284
|
+
children: [/* @__PURE__ */ u("h2", {
|
|
285
|
+
className: "text-lg font-medium",
|
|
286
|
+
children: "Finished"
|
|
287
|
+
}), T.map((e) => {
|
|
288
|
+
let t = v(e);
|
|
289
|
+
return /* @__PURE__ */ d(p, {
|
|
290
|
+
"data-testid": "finished-sprint",
|
|
291
|
+
children: [/* @__PURE__ */ u(h, {
|
|
292
|
+
className: "pb-2",
|
|
293
|
+
children: /* @__PURE__ */ d("div", {
|
|
294
|
+
className: "flex items-center justify-between",
|
|
295
|
+
children: [/* @__PURE__ */ u(g, {
|
|
296
|
+
className: "text-base",
|
|
297
|
+
children: /* @__PURE__ */ u("button", {
|
|
298
|
+
type: "button",
|
|
299
|
+
className: "hover:underline text-left",
|
|
300
|
+
onClick: () => D(e.id),
|
|
301
|
+
children: e.name
|
|
302
|
+
})
|
|
303
|
+
}), /* @__PURE__ */ u(f, {
|
|
304
|
+
variant: "outline",
|
|
305
|
+
children: e.status === "COMPLETED" ? "Completed" : "Cancelled"
|
|
306
|
+
})]
|
|
307
|
+
})
|
|
308
|
+
}), /* @__PURE__ */ d(m, {
|
|
309
|
+
className: "space-y-2",
|
|
310
|
+
children: [/* @__PURE__ */ u(a, { sprint: e }), /* @__PURE__ */ d("p", {
|
|
311
|
+
className: "text-xs text-muted-foreground",
|
|
312
|
+
children: [
|
|
313
|
+
t.completedPoints,
|
|
314
|
+
"/",
|
|
315
|
+
t.totalPoints,
|
|
316
|
+
" points done"
|
|
317
|
+
]
|
|
318
|
+
})]
|
|
319
|
+
})]
|
|
320
|
+
}, e.id);
|
|
321
|
+
})]
|
|
278
322
|
})
|
|
279
323
|
]
|
|
280
324
|
});
|