@burdenoff/microfe-planmagnet 2026.1001.1 → 2026.1001.3
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/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +163 -150
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +124 -108
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/comments/CommentThread.js +36 -36
- package/dist/planmagnet/comments/RoadmapComments.js +21 -21
- package/dist/planmagnet/controls/AutomationRuleControls.js +24 -24
- package/dist/planmagnet/controls/FeatureControls.js +60 -60
- package/dist/planmagnet/controls/MilestoneControls.d.ts +2 -0
- package/dist/planmagnet/controls/MilestoneControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/MilestoneControls.js +89 -72
- package/dist/planmagnet/controls/MilestoneControls.js.map +1 -1
- package/dist/planmagnet/controls/SyncControls.js +59 -59
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +15 -15
- package/dist/planmagnet/docs/DocSuggestionsPanel.js +12 -12
- package/dist/planmagnet/docs/DocVersionCompare.js +3 -3
- package/dist/planmagnet/forecast/DeliveryForecastCard.d.ts +12 -0
- package/dist/planmagnet/forecast/DeliveryForecastCard.d.ts.map +1 -0
- package/dist/planmagnet/forecast/DeliveryForecastCard.js +208 -0
- package/dist/planmagnet/forecast/DeliveryForecastCard.js.map +1 -0
- package/dist/planmagnet/forecast/ProjectOutlookCard.d.ts +5 -0
- package/dist/planmagnet/forecast/ProjectOutlookCard.d.ts.map +1 -0
- package/dist/planmagnet/forecast/ProjectOutlookCard.js +190 -0
- package/dist/planmagnet/forecast/ProjectOutlookCard.js.map +1 -0
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.d.ts +5 -0
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.d.ts.map +1 -0
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +99 -0
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js.map +1 -0
- package/dist/planmagnet/forecast/ResourceForecastCard.d.ts +8 -0
- package/dist/planmagnet/forecast/ResourceForecastCard.d.ts.map +1 -0
- package/dist/planmagnet/forecast/ResourceForecastCard.js +185 -0
- package/dist/planmagnet/forecast/ResourceForecastCard.js.map +1 -0
- package/dist/planmagnet/forecast/riskFlags.d.ts +35 -0
- package/dist/planmagnet/forecast/riskFlags.d.ts.map +1 -0
- package/dist/planmagnet/forecast/riskFlags.js +37 -0
- package/dist/planmagnet/forecast/riskFlags.js.map +1 -0
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.d.ts +17 -0
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.d.ts.map +1 -0
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.js +218 -0
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.js.map +1 -0
- package/dist/planmagnet/meetings/MeetingsCard.d.ts +7 -0
- package/dist/planmagnet/meetings/MeetingsCard.d.ts.map +1 -0
- package/dist/planmagnet/meetings/MeetingsCard.js +108 -0
- package/dist/planmagnet/meetings/MeetingsCard.js.map +1 -0
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.d.ts +9 -0
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.d.ts.map +1 -0
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.js +232 -0
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.js.map +1 -0
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.d.ts +19 -0
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.d.ts.map +1 -0
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js +226 -0
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js.map +1 -0
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.d.ts +14 -0
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.d.ts.map +1 -0
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.js +81 -0
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.js.map +1 -0
- package/dist/planmagnet/meetings/meetingActions.d.ts +57 -0
- package/dist/planmagnet/meetings/meetingActions.d.ts.map +1 -0
- package/dist/planmagnet/meetings/meetingActions.js +51 -0
- package/dist/planmagnet/meetings/meetingActions.js.map +1 -0
- package/dist/planmagnet/meetings/meetingGraphql.d.ts +29 -0
- package/dist/planmagnet/meetings/meetingGraphql.d.ts.map +1 -0
- package/dist/planmagnet/meetings/meetingGraphql.js +166 -0
- package/dist/planmagnet/meetings/meetingGraphql.js.map +1 -0
- package/dist/planmagnet/meetings/meetingModel.d.ts +74 -0
- package/dist/planmagnet/meetings/meetingModel.d.ts.map +1 -0
- package/dist/planmagnet/meetings/meetingModel.js +88 -0
- package/dist/planmagnet/meetings/meetingModel.js.map +1 -0
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +216 -182
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +11 -11
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +4 -4
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +163 -163
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js +165 -165
- package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js.map +1 -1
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.js +197 -0
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.js.map +1 -0
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.js +173 -0
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +234 -0
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js +73 -52
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +205 -190
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +211 -182
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ReportsReportPagePage.js +22 -22
- package/dist/planmagnet/pages/ReportsReportPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +21 -21
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.js +88 -83
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.d.ts.map +1 -1
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +139 -112
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js.map +1 -1
- package/dist/planmagnet/pages/analytics/StatusFlowCard.js +21 -21
- package/dist/planmagnet/product/ProductControls.js +91 -91
- package/dist/planmagnet/reports/SchedulesPanel.js +33 -33
- package/dist/planmagnet/reports/ShareDialog.js +76 -76
- package/dist/planmagnet/reports/ShareDialog.js.map +1 -1
- package/dist/planmagnet/reports/sharedReportRoute.d.ts +3 -2
- package/dist/planmagnet/reports/sharedReportRoute.d.ts.map +1 -1
- package/dist/planmagnet/reports/sharedReportRoute.js.map +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js +60 -60
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +30 -30
- package/dist/planmagnet/roadmaps/RoadmapReviewPanel.js +21 -21
- package/dist/planmagnet/roadmaps/RoadmapVersionsPanel.js +22 -22
- package/package.json +1 -1
|
@@ -4,14 +4,15 @@ import { ROW_LINK_CLASS as r, detailPath as i, rowLinkProps as a } from "../util
|
|
|
4
4
|
import { useEntityId as o } from "../hooks/useEntityId.js";
|
|
5
5
|
import { PlanMagnetNotFoundPage as s } from "./NotFoundPage.js";
|
|
6
6
|
import { NewSprintDialog as c } from "../sprints/SprintControls.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import { ResourceForecastCard as l } from "../forecast/ResourceForecastCard.js";
|
|
8
|
+
import { TeamHeaderActions as u, TeamMembersPanel as d, TeamProjectsPanel as f } from "../team/TeamControls.js";
|
|
9
|
+
import { Gauge as p, UserRound as m, Users as h, Zap as g } from "lucide-react";
|
|
10
|
+
import { gql as _ } from "@apollo/client";
|
|
11
|
+
import { useQuery as v } from "@apollo/client/react";
|
|
12
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
13
|
+
import { Badge as x, Card as S, CardContent as C, CardHeader as w, CardTitle as T } from "@burdenoff/fe-libs/ui";
|
|
13
14
|
//#region src/planmagnet/pages/TeamTeamDetailPagePage.tsx
|
|
14
|
-
var
|
|
15
|
+
var E = _`
|
|
15
16
|
query GetTeamDetail($id: ID!) {
|
|
16
17
|
planmagnetTeam(id: $id) {
|
|
17
18
|
id
|
|
@@ -31,7 +32,7 @@ var T = g`
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
`,
|
|
35
|
+
`, D = _`
|
|
35
36
|
query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {
|
|
36
37
|
planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {
|
|
37
38
|
items {
|
|
@@ -51,149 +52,153 @@ var T = g`
|
|
|
51
52
|
totalCount
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
`,
|
|
55
|
+
`, O = {
|
|
55
56
|
PLANNING: "bg-blue-100 text-blue-800",
|
|
56
57
|
ACTIVE: "bg-green-100 text-green-800",
|
|
57
58
|
REVIEW: "bg-purple-100 text-purple-800",
|
|
58
59
|
COMPLETED: "bg-gray-100 text-gray-800",
|
|
59
60
|
CANCELLED: "bg-red-100 text-red-800"
|
|
60
61
|
};
|
|
61
|
-
function
|
|
62
|
-
let
|
|
63
|
-
variables: { id:
|
|
64
|
-
skip: !
|
|
65
|
-
}), { data:
|
|
62
|
+
function k() {
|
|
63
|
+
let _ = o("teamId"), { workspaceId: k } = e(), A = t(), { data: j, loading: M, error: N } = v(E, {
|
|
64
|
+
variables: { id: _ },
|
|
65
|
+
skip: !_
|
|
66
|
+
}), { data: P, loading: F } = v(D, {
|
|
66
67
|
variables: {
|
|
67
|
-
workspaceId:
|
|
68
|
-
filter: { teamId:
|
|
68
|
+
workspaceId: k ?? "",
|
|
69
|
+
filter: { teamId: _ }
|
|
69
70
|
},
|
|
70
|
-
skip: !
|
|
71
|
+
skip: !_ || !k
|
|
71
72
|
});
|
|
72
|
-
if (!
|
|
73
|
+
if (!_) return /* @__PURE__ */ y("div", {
|
|
73
74
|
className: "p-6 text-muted-foreground",
|
|
74
75
|
children: "No team selected. Open one from the list."
|
|
75
76
|
});
|
|
76
|
-
if (
|
|
77
|
+
if (M && !j) return /* @__PURE__ */ y("div", {
|
|
77
78
|
className: "flex items-center justify-center p-12",
|
|
78
|
-
children: /* @__PURE__ */
|
|
79
|
+
children: /* @__PURE__ */ y("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
79
80
|
});
|
|
80
|
-
if (
|
|
81
|
+
if (N) return /* @__PURE__ */ b("div", {
|
|
81
82
|
className: "p-6 text-destructive",
|
|
82
|
-
children: ["Error loading team: ",
|
|
83
|
+
children: ["Error loading team: ", N.message]
|
|
83
84
|
});
|
|
84
|
-
let
|
|
85
|
-
if (!
|
|
86
|
-
let
|
|
87
|
-
return /* @__PURE__ */
|
|
85
|
+
let I = j?.planmagnetTeam;
|
|
86
|
+
if (!I) return /* @__PURE__ */ y(s, {});
|
|
87
|
+
let L = P?.planmagnetSprints.items ?? [];
|
|
88
|
+
return /* @__PURE__ */ b("div", {
|
|
88
89
|
className: "space-y-6 p-6",
|
|
89
90
|
children: [
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ b("div", {
|
|
91
92
|
className: "flex items-start justify-between gap-4",
|
|
92
|
-
children: [/* @__PURE__ */
|
|
93
|
+
children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ b("div", {
|
|
93
94
|
className: "flex items-center gap-2",
|
|
94
|
-
children: [/* @__PURE__ */
|
|
95
|
+
children: [/* @__PURE__ */ y(h, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ y("h1", {
|
|
95
96
|
className: "text-2xl font-semibold",
|
|
96
|
-
children:
|
|
97
|
+
children: I.name
|
|
97
98
|
})]
|
|
98
|
-
}), /* @__PURE__ */
|
|
99
|
+
}), /* @__PURE__ */ y("p", {
|
|
99
100
|
className: "text-sm text-muted-foreground mt-1",
|
|
100
|
-
children:
|
|
101
|
-
})] }), /* @__PURE__ */
|
|
102
|
-
teamId:
|
|
103
|
-
name:
|
|
101
|
+
children: I.description ?? "No description"
|
|
102
|
+
})] }), /* @__PURE__ */ y(u, {
|
|
103
|
+
teamId: I.id,
|
|
104
|
+
name: I.name
|
|
104
105
|
})]
|
|
105
106
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ b("div", {
|
|
107
108
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
108
109
|
children: [
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
+
/* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
|
|
110
111
|
className: "pt-4",
|
|
111
|
-
children: [/* @__PURE__ */
|
|
112
|
+
children: [/* @__PURE__ */ b("div", {
|
|
112
113
|
className: "flex items-center gap-2 text-muted-foreground text-xs",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
114
|
-
}), /* @__PURE__ */
|
|
114
|
+
children: [/* @__PURE__ */ y(m, { className: "h-4 w-4" }), "Lead"]
|
|
115
|
+
}), /* @__PURE__ */ y("p", {
|
|
115
116
|
className: "text-sm font-bold mt-1 truncate",
|
|
116
|
-
children:
|
|
117
|
+
children: I.leadId ? /* @__PURE__ */ y(n, { id: I.leadId }) : "No lead"
|
|
117
118
|
})]
|
|
118
119
|
}) }),
|
|
119
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
|
|
120
121
|
className: "pt-4",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
122
|
+
children: [/* @__PURE__ */ b("div", {
|
|
122
123
|
className: "flex items-center gap-2 text-muted-foreground text-xs",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
124
|
-
}), /* @__PURE__ */
|
|
124
|
+
children: [/* @__PURE__ */ y(p, { className: "h-4 w-4" }), "Capacity"]
|
|
125
|
+
}), /* @__PURE__ */ y("p", {
|
|
125
126
|
className: "text-xl font-bold mt-1",
|
|
126
|
-
children:
|
|
127
|
+
children: I.capacity ?? "—"
|
|
127
128
|
})]
|
|
128
129
|
}) }),
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
|
|
130
131
|
className: "pt-4",
|
|
131
|
-
children: [/* @__PURE__ */
|
|
132
|
+
children: [/* @__PURE__ */ b("div", {
|
|
132
133
|
className: "flex items-center gap-2 text-muted-foreground text-xs",
|
|
133
|
-
children: [/* @__PURE__ */
|
|
134
|
-
}), /* @__PURE__ */
|
|
134
|
+
children: [/* @__PURE__ */ y(h, { className: "h-4 w-4" }), "Members"]
|
|
135
|
+
}), /* @__PURE__ */ y("p", {
|
|
135
136
|
className: "text-xl font-bold mt-1",
|
|
136
|
-
children:
|
|
137
|
+
children: I.members.length
|
|
137
138
|
})]
|
|
138
139
|
}) }),
|
|
139
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
|
|
140
141
|
className: "pt-4",
|
|
141
|
-
children: [/* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ b("div", {
|
|
142
143
|
className: "flex items-center gap-2 text-muted-foreground text-xs",
|
|
143
|
-
children: [/* @__PURE__ */
|
|
144
|
-
}), /* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ y(g, { className: "h-4 w-4" }), "Team sprints"]
|
|
145
|
+
}), /* @__PURE__ */ y("p", {
|
|
145
146
|
className: "text-xl font-bold mt-1",
|
|
146
|
-
children:
|
|
147
|
+
children: P?.planmagnetSprints.totalCount ?? (F ? "—" : L.length)
|
|
147
148
|
})]
|
|
148
149
|
}) })
|
|
149
150
|
]
|
|
150
151
|
}),
|
|
151
|
-
/* @__PURE__ */
|
|
152
|
+
/* @__PURE__ */ b("div", {
|
|
152
153
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
153
|
-
children: [/* @__PURE__ */
|
|
154
|
-
teamId:
|
|
155
|
-
members:
|
|
156
|
-
}) })] }), /* @__PURE__ */
|
|
157
|
-
teamId:
|
|
158
|
-
projects:
|
|
154
|
+
children: [/* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Members" }) }), /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(d, {
|
|
155
|
+
teamId: I.id,
|
|
156
|
+
members: I.members
|
|
157
|
+
}) })] }), /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Projects" }) }), /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(f, {
|
|
158
|
+
teamId: I.id,
|
|
159
|
+
projects: I.projects
|
|
159
160
|
}) })] })]
|
|
160
161
|
}),
|
|
161
|
-
/* @__PURE__ */ y(
|
|
162
|
+
/* @__PURE__ */ y(l, {
|
|
163
|
+
workspaceId: k,
|
|
164
|
+
teamId: I.id
|
|
165
|
+
}),
|
|
166
|
+
/* @__PURE__ */ b(S, { children: [/* @__PURE__ */ b(w, {
|
|
162
167
|
className: "flex flex-row items-center justify-between space-y-0",
|
|
163
|
-
children: [/* @__PURE__ */
|
|
168
|
+
children: [/* @__PURE__ */ y(T, { children: "Sprints" }), /* @__PURE__ */ y(c, {
|
|
164
169
|
initialScope: "team",
|
|
165
|
-
initialTeamId:
|
|
166
|
-
onCreated: (e) =>
|
|
170
|
+
initialTeamId: I.id,
|
|
171
|
+
onCreated: (e) => A(i("/projects/planning-detail-page", e))
|
|
167
172
|
})]
|
|
168
|
-
}), /* @__PURE__ */
|
|
173
|
+
}), /* @__PURE__ */ b(C, {
|
|
169
174
|
className: "space-y-2",
|
|
170
175
|
children: [
|
|
171
|
-
|
|
176
|
+
F && L.length === 0 && /* @__PURE__ */ y("p", {
|
|
172
177
|
className: "text-sm text-muted-foreground text-center py-4",
|
|
173
178
|
children: "Loading sprints…"
|
|
174
179
|
}),
|
|
175
|
-
!
|
|
180
|
+
!F && L.length === 0 && /* @__PURE__ */ y("p", {
|
|
176
181
|
className: "text-sm text-muted-foreground text-center py-4",
|
|
177
182
|
children: "No sprints yet. A team sprint can only include work items from this team's projects."
|
|
178
183
|
}),
|
|
179
|
-
|
|
184
|
+
L.map((e) => {
|
|
180
185
|
let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), n = e.workItems.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0);
|
|
181
|
-
return /* @__PURE__ */
|
|
182
|
-
...a(() =>
|
|
186
|
+
return /* @__PURE__ */ b("div", {
|
|
187
|
+
...a(() => A(i("/projects/planning-detail-page", e.id)), e.name),
|
|
183
188
|
className: `flex items-center justify-between border rounded-md p-2.5 ${r}`,
|
|
184
|
-
children: [/* @__PURE__ */
|
|
189
|
+
children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
|
|
185
190
|
className: "text-sm font-medium",
|
|
186
191
|
children: e.name
|
|
187
|
-
}), e.goal && /* @__PURE__ */
|
|
192
|
+
}), e.goal && /* @__PURE__ */ y("p", {
|
|
188
193
|
className: "text-xs text-muted-foreground",
|
|
189
194
|
children: e.goal
|
|
190
|
-
})] }), /* @__PURE__ */
|
|
195
|
+
})] }), /* @__PURE__ */ b("div", {
|
|
191
196
|
className: "flex items-center gap-2",
|
|
192
|
-
children: [/* @__PURE__ */
|
|
197
|
+
children: [/* @__PURE__ */ y("span", {
|
|
193
198
|
className: "text-xs text-muted-foreground",
|
|
194
199
|
children: e.status === "COMPLETED" && e.velocity != null ? `${e.velocity} pts velocity` : `${n}/${t} pts`
|
|
195
|
-
}), /* @__PURE__ */
|
|
196
|
-
className: `text-xs px-2 py-0.5 rounded-full capitalize ${
|
|
200
|
+
}), /* @__PURE__ */ y("span", {
|
|
201
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${O[e.status] ?? "bg-gray-100"}`,
|
|
197
202
|
children: e.status.toLowerCase().replace("_", " ")
|
|
198
203
|
})]
|
|
199
204
|
})]
|
|
@@ -201,17 +206,17 @@ function O() {
|
|
|
201
206
|
})
|
|
202
207
|
]
|
|
203
208
|
})] }),
|
|
204
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ b("p", {
|
|
205
210
|
className: "text-xs text-muted-foreground",
|
|
206
|
-
children: ["Created ", /* @__PURE__ */
|
|
211
|
+
children: ["Created ", /* @__PURE__ */ y(x, {
|
|
207
212
|
variant: "outline",
|
|
208
|
-
children: new Date(
|
|
213
|
+
children: new Date(I.createdAt).toLocaleDateString()
|
|
209
214
|
})]
|
|
210
215
|
})
|
|
211
216
|
]
|
|
212
217
|
});
|
|
213
218
|
}
|
|
214
219
|
//#endregion
|
|
215
|
-
export {
|
|
220
|
+
export { k as TeamTeamDetailPagePage };
|
|
216
221
|
|
|
217
222
|
//# sourceMappingURL=TeamTeamDetailPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamTeamDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Users, UserRound, Gauge, Zap } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ROW_LINK_CLASS, detailPath, rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { TeamHeaderActions, TeamMembersPanel, TeamProjectsPanel } from '../team/TeamControls';\nimport { NewSprintDialog } from '../sprints/SprintControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\n\n/**\n * Team detail (BOFF-8044): members, lead, capacity, projects, and the team's own sprints\n * (sprints whose scope is this team, never a project — sprint scope is PROJECT xor TEAM).\n */\n\nconst GET_TEAM_DETAIL = gql`\n query GetTeamDetail($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n createdAt\n members {\n id\n actorId\n }\n projects {\n id\n name\n key\n }\n }\n }\n`;\n\nconst GET_TEAM_SPRINTS = gql`\n query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {\n items {\n id\n name\n status\n goal\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamDetail {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n createdAt: string;\n members: { id: string; actorId: string }[];\n projects: { id: string; name: string; key: string }[];\n}\n\ninterface TeamSprintNode {\n id: string;\n name: string;\n status: string;\n goal: string | null;\n velocity: number | null;\n startDate: string | null;\n endDate: string | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n}\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function TeamTeamDetailPagePage() {\n const teamId = useEntityId('teamId');\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamDetail | null }>(\n GET_TEAM_DETAIL,\n { variables: { id: teamId }, skip: !teamId }\n );\n const { data: sprintData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints: { items: TeamSprintNode[]; totalCount: number };\n }>(GET_TEAM_SPRINTS, {\n variables: { workspaceId: workspaceId ?? '', filter: { teamId } },\n skip: !teamId || !workspaceId,\n });\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\n }\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\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 if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n\n const team = data?.planmagnetTeam;\n // Deleted, unauthorized or an unknown id all read back the same way (no cross-tenant existence\n // leak) — the real 404 page, not an inline message and not a same-URL redirect (H5).\n if (!team) return <PlanMagnetNotFoundPage />;\n\n const sprints = sprintData?.planmagnetSprints.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{team.name}</h1>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {team.description ?? 'No description'}\n </p>\n </div>\n <TeamHeaderActions teamId={team.id} name={team.name} />\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <UserRound className=\"h-4 w-4\" />\n Lead\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Gauge className=\"h-4 w-4\" />\n Capacity\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.capacity ?? '—'}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Members\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.members.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Team sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {sprintData?.planmagnetSprints.totalCount ?? (sprintsLoading ? '—' : sprints.length)}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Members</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamMembersPanel teamId={team.id} members={team.members} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Projects</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamProjectsPanel teamId={team.id} projects={team.projects} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Sprints</CardTitle>\n <NewSprintDialog\n initialScope=\"team\"\n initialTeamId={team.id}\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">Loading sprints…</p>\n )}\n {!sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No sprints yet. A team sprint can only include work items from this team's\n projects.\n </p>\n )}\n {sprints.map((sprint) => {\n const totalPoints = sprint.workItems.reduce(\n (sum, wi) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const donePoints = sprint.workItems\n .filter((wi) => wi.status === 'DONE')\n .reduce((sum, wi) => sum + (wi.storyPoints ?? 0), 0);\n return (\n <div\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n className={`flex items-center justify-between border rounded-md p-2.5 ${ROW_LINK_CLASS}`}\n >\n <div>\n <p className=\"text-sm font-medium\">{sprint.name}</p>\n {sprint.goal && <p className=\"text-xs text-muted-foreground\">{sprint.goal}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {sprint.status === 'COMPLETED' && sprint.velocity != null\n ? `${sprint.velocity} pts velocity`\n : `${donePoints}/${totalPoints} pts`}\n </span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <p className=\"text-xs text-muted-foreground\">\n Created <Badge variant=\"outline\">{new Date(team.createdAt).toLocaleDateString()}</Badge>\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TeamTeamDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Users, UserRound, Gauge, Zap } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ROW_LINK_CLASS, detailPath, rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { TeamHeaderActions, TeamMembersPanel, TeamProjectsPanel } from '../team/TeamControls';\nimport { NewSprintDialog } from '../sprints/SprintControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\nimport { ResourceForecastCard } from '../forecast/ResourceForecastCard';\n\n/**\n * Team detail (BOFF-8044): members, lead, capacity, projects, and the team's own sprints\n * (sprints whose scope is this team, never a project — sprint scope is PROJECT xor TEAM).\n */\n\nconst GET_TEAM_DETAIL = gql`\n query GetTeamDetail($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n createdAt\n members {\n id\n actorId\n }\n projects {\n id\n name\n key\n }\n }\n }\n`;\n\nconst GET_TEAM_SPRINTS = gql`\n query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {\n items {\n id\n name\n status\n goal\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamDetail {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n createdAt: string;\n members: { id: string; actorId: string }[];\n projects: { id: string; name: string; key: string }[];\n}\n\ninterface TeamSprintNode {\n id: string;\n name: string;\n status: string;\n goal: string | null;\n velocity: number | null;\n startDate: string | null;\n endDate: string | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n}\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function TeamTeamDetailPagePage() {\n const teamId = useEntityId('teamId');\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamDetail | null }>(\n GET_TEAM_DETAIL,\n { variables: { id: teamId }, skip: !teamId }\n );\n const { data: sprintData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints: { items: TeamSprintNode[]; totalCount: number };\n }>(GET_TEAM_SPRINTS, {\n variables: { workspaceId: workspaceId ?? '', filter: { teamId } },\n skip: !teamId || !workspaceId,\n });\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\n }\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\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 if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n\n const team = data?.planmagnetTeam;\n // Deleted, unauthorized or an unknown id all read back the same way (no cross-tenant existence\n // leak) — the real 404 page, not an inline message and not a same-URL redirect (H5).\n if (!team) return <PlanMagnetNotFoundPage />;\n\n const sprints = sprintData?.planmagnetSprints.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{team.name}</h1>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {team.description ?? 'No description'}\n </p>\n </div>\n <TeamHeaderActions teamId={team.id} name={team.name} />\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <UserRound className=\"h-4 w-4\" />\n Lead\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Gauge className=\"h-4 w-4\" />\n Capacity\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.capacity ?? '—'}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Members\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.members.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Team sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {sprintData?.planmagnetSprints.totalCount ?? (sprintsLoading ? '—' : sprints.length)}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Members</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamMembersPanel teamId={team.id} members={team.members} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Projects</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamProjectsPanel teamId={team.id} projects={team.projects} />\n </CardContent>\n </Card>\n </div>\n\n {/* ANR-11: capacity vs. this team's own open backlog, across its live member projects. */}\n <ResourceForecastCard workspaceId={workspaceId} teamId={team.id} />\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Sprints</CardTitle>\n <NewSprintDialog\n initialScope=\"team\"\n initialTeamId={team.id}\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">Loading sprints…</p>\n )}\n {!sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No sprints yet. A team sprint can only include work items from this team's\n projects.\n </p>\n )}\n {sprints.map((sprint) => {\n const totalPoints = sprint.workItems.reduce(\n (sum, wi) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const donePoints = sprint.workItems\n .filter((wi) => wi.status === 'DONE')\n .reduce((sum, wi) => sum + (wi.storyPoints ?? 0), 0);\n return (\n <div\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n className={`flex items-center justify-between border rounded-md p-2.5 ${ROW_LINK_CLASS}`}\n >\n <div>\n <p className=\"text-sm font-medium\">{sprint.name}</p>\n {sprint.goal && <p className=\"text-xs text-muted-foreground\">{sprint.goal}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {sprint.status === 'COMPLETED' && sprint.velocity != null\n ? `${sprint.velocity} pts velocity`\n : `${donePoints}/${totalPoints} pts`}\n </span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <p className=\"text-xs text-muted-foreground\">\n Created <Badge variant=\"outline\">{new Date(team.createdAt).toLocaleDateString()}</Badge>\n </p>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAkBA,IAAM,IAAkB,CAAG;;;;;;;;;;;;;;;;;;;;GAsBrB,IAAmB,CAAG;;;;;;;;;;;;;;;;;;;;GA4CtB,IAAsC;CAC1C,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,WAAW;CACZ;AAED,SAAgB,IAAyB;CACvC,IAAM,IAAS,EAAY,SAAS,EAC9B,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAElC,EAAE,SAAM,YAAS,aAAU,EAC/B,GACA;EAAE,WAAW,EAAE,IAAI,GAAQ;EAAE,MAAM,CAAC;EAAQ,CAC7C,EACK,EAAE,MAAM,GAAY,SAAS,MAAmB,EAEnD,GAAkB;EACnB,WAAW;GAAE,aAAa,KAAe;GAAI,QAAQ,EAAE,WAAQ;GAAE;EACjE,MAAM,CAAC,KAAU,CAAC;EACnB,CAAC;AAEF,KAAI,CAAC,EACH,QACE,kBAAC,OAAD;EAAK,WAAU;YAA4B;EAA+C,CAAA;AAK9F,KAAI,KAAW,CAAC,EACd,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;EAC9F,CAAA;AAGV,KAAI,EACF,QAAO,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,wBAAqB,EAAM,QAAc;;CAGxF,IAAM,IAAO,GAAM;AAGnB,KAAI,CAAC,EAAM,QAAO,kBAAC,GAAD,EAA0B,CAAA;CAE5C,IAAM,IAAU,GAAY,kBAAkB,SAAS,EAAE;AAEzD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAO,WAAU,wBAAyB,CAAA,EAC1C,kBAAC,MAAD;MAAI,WAAU;gBAA0B,EAAK;MAAU,CAAA,CACnD;QACN,kBAAC,KAAD;KAAG,WAAU;eACV,EAAK,eAAe;KACnB,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,GAAD;KAAmB,QAAQ,EAAK;KAAI,MAAM,EAAK;KAAQ,CAAA,CACnD;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,OAE7B;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAK,SAAS,kBAAC,GAAD,EAAY,IAAI,EAAK,QAAU,CAAA,GAAG;OAC/C,CAAA,CACQ;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAAA,WAEzB;UACN,kBAAC,KAAD;OAAG,WAAU;iBAA0B,EAAK,YAAY;OAAQ,CAAA,CACpD;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAAA,UAEzB;UACN,kBAAC,KAAD;OAAG,WAAU;iBAA0B,EAAK,QAAQ;OAAW,CAAA,CACnD;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEvB;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,GAAY,kBAAkB,eAAe,IAAiB,MAAM,EAAQ;OAC3E,CAAA,CACQ;SACT,CAAA;KACH;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,WAAmB,CAAA,EACnB,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;KAAkB,QAAQ,EAAK;KAAI,SAAS,EAAK;KAAW,CAAA,EAChD,CAAA,CACT,EAAA,CAAA,EACP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA,EACpB,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;KAAmB,QAAQ,EAAK;KAAI,UAAU,EAAK;KAAY,CAAA,EACnD,CAAA,CACT,EAAA,CAAA,CACH;;GAGN,kBAAC,GAAD;IAAmC;IAAa,QAAQ,EAAK;IAAM,CAAA;GAEnE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IAAY,WAAU;cAAtB,CACE,kBAAC,GAAD,EAAA,UAAW,WAAmB,CAAA,EAC9B,kBAAC,GAAD;KACE,cAAa;KACb,eAAe,EAAK;KACpB,YAAY,MAAO,EAAS,EAAW,kCAAkC,EAAG,CAAC;KAC7E,CAAA,CACS;OACb,kBAAC,GAAD;IAAa,WAAU;cAAvB;KACG,KAAkB,EAAQ,WAAW,KACpC,kBAAC,KAAD;MAAG,WAAU;gBAAiD;MAAoB,CAAA;KAEnF,CAAC,KAAkB,EAAQ,WAAW,KACrC,kBAAC,KAAD;MAAG,WAAU;gBAAiD;MAG1D,CAAA;KAEL,EAAQ,KAAK,MAAW;MACvB,IAAM,IAAc,EAAO,UAAU,QAClC,GAAK,MAAO,KAAO,EAAG,eAAe,IACtC,EACD,EACK,IAAa,EAAO,UACvB,QAAQ,MAAO,EAAG,WAAW,OAAO,CACpC,QAAQ,GAAK,MAAO,KAAO,EAAG,eAAe,IAAI,EAAE;AACtD,aACE,kBAAC,OAAD;OAEE,GAAI,QACI,EAAS,EAAW,kCAAkC,EAAO,GAAG,CAAC,EACvE,EAAO,KACR;OACD,WAAW,6DAA6D;iBAN1E,CAQE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAuB,EAAO;QAAS,CAAA,EACnD,EAAO,QAAQ,kBAAC,KAAD;QAAG,WAAU;kBAAiC,EAAO;QAAS,CAAA,CAC1E,EAAA,CAAA,EACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAO,WAAW,eAAe,EAAO,YAAY,OACjD,GAAG,EAAO,SAAS,iBACnB,GAAG,EAAW,GAAG,EAAY;SAC5B,CAAA,EACP,kBAAC,QAAD;SACE,WAAW,+CAA+C,EAAY,EAAO,WAAW;mBAEvF,EAAO,OAAO,aAAa,CAAC,QAAQ,KAAK,IAAI;SACzC,CAAA,CACH;UACF;SAvBC,EAAO,GAuBR;OAER;KACU;MACT,EAAA,CAAA;GAEP,kBAAC,KAAD;IAAG,WAAU;cAAb,CAA6C,YACnC,kBAAC,GAAD;KAAO,SAAQ;eAAW,IAAI,KAAK,EAAK,UAAU,CAAC,oBAAoB;KAAS,CAAA,CACtF;;GACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SprintDeliveryCards.d.ts","sourceRoot":"","sources":["../../../../src/planmagnet/pages/analytics/SprintDeliveryCards.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SprintDeliveryCards.d.ts","sourceRoot":"","sources":["../../../../src/planmagnet/pages/analytics/SprintDeliveryCards.tsx"],"names":[],"mappings":"AA0GA,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,2CA2EA;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,SAAS,EACT,mBAAuB,GACxB,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,2CAgIA"}
|