@burdenoff/microfe-planmagnet 2026.1001.4 → 2026.1001.6
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/controls/CompetitorControls.d.ts +71 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/CompetitorControls.js +346 -12
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +5 -0
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.js +363 -218
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
- package/dist/planmagnet/controls/Pickers.d.ts +15 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +61 -1
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.d.ts +36 -0
- package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.js +118 -1
- package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -1
- package/dist/planmagnet/dashboards/DashboardUI.js +1 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.d.ts.map +1 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js +67 -59
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js.map +1 -1
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.d.ts.map +1 -1
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js +1 -1
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +289 -282
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +126 -63
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +14 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +93 -57
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +125 -83
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +226 -126
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +162 -122
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +135 -109
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +15 -3
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js +59 -53
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts +8 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts.map +1 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js +164 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js.map +1 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts +2 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts.map +1 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js +155 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { PersonName as t } from "../people/People.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
3
|
+
import { StatTile as n } from "./analytics/DeliveryHealthCards.js";
|
|
4
|
+
import { enumLabel as r } from "../controls/WorkItemControls.js";
|
|
5
|
+
import { detailPath as i } from "../utils/rowNavigation.js";
|
|
6
|
+
import { PortfolioHeaderActions as a } from "../controls/PortfolioControls.js";
|
|
7
|
+
import { AlertTriangle as o, BarChart3 as s, Briefcase as c, Clock as l, Loader2 as u, Target as d } from "lucide-react";
|
|
8
|
+
import { useParams as f } from "react-router";
|
|
9
|
+
import { gql as p } from "@apollo/client";
|
|
10
|
+
import { useQuery as m } from "@apollo/client/react";
|
|
11
|
+
import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
12
|
+
import { Badge as v, Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C } from "@burdenoff/fe-libs/ui";
|
|
12
13
|
//#region src/planmagnet/pages/PortfoliosPortfolioDetailPagePage.tsx
|
|
13
|
-
var
|
|
14
|
+
var w = p`
|
|
14
15
|
query GetPortfolio($id: ID!) {
|
|
15
16
|
planmagnetPortfolio(id: $id) {
|
|
16
17
|
id
|
|
@@ -39,7 +40,7 @@ var x = d`
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
`,
|
|
43
|
+
`, T = p`
|
|
43
44
|
query GetPortfolioOverview($portfolioId: ID!) {
|
|
44
45
|
planmagnetPortfolioOverview(portfolioId: $portfolioId) {
|
|
45
46
|
portfolioId
|
|
@@ -54,111 +55,136 @@ var x = d`
|
|
|
54
55
|
overdueMilestones
|
|
55
56
|
}
|
|
56
57
|
}
|
|
58
|
+
`, E = p`
|
|
59
|
+
query GetPortfolioRollup($portfolioId: ID!) {
|
|
60
|
+
planmagnetPortfolioRollup(portfolioId: $portfolioId) {
|
|
61
|
+
portfolioId
|
|
62
|
+
totalProjects
|
|
63
|
+
projectsByStatus
|
|
64
|
+
totalBudget
|
|
65
|
+
totalSpent
|
|
66
|
+
budgetUtilization
|
|
67
|
+
averageSprintOnTimeRate
|
|
68
|
+
averageReleaseOnTimeRate
|
|
69
|
+
averageMilestoneOnTimeRate
|
|
70
|
+
calculatedAt
|
|
71
|
+
}
|
|
72
|
+
}
|
|
57
73
|
`;
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
variables: { portfolioId: C },
|
|
64
|
-
skip: !C
|
|
74
|
+
function D({ label: e, rate: t, emptyReason: r }) {
|
|
75
|
+
return /* @__PURE__ */ g(n, {
|
|
76
|
+
label: e,
|
|
77
|
+
value: t == null ? "—" : `${Math.round(t * 100)}%`,
|
|
78
|
+
hint: t == null ? r : void 0
|
|
65
79
|
});
|
|
66
|
-
|
|
80
|
+
}
|
|
81
|
+
function O() {
|
|
82
|
+
let p = e(), O = f().id ?? "", { data: k, loading: A, error: j } = m(w, {
|
|
83
|
+
variables: { id: O },
|
|
84
|
+
skip: !O
|
|
85
|
+
}), { data: M } = m(T, {
|
|
86
|
+
variables: { portfolioId: O },
|
|
87
|
+
skip: !O
|
|
88
|
+
}), { data: N, loading: P, error: F } = m(E, {
|
|
89
|
+
variables: { portfolioId: O },
|
|
90
|
+
skip: !O
|
|
91
|
+
});
|
|
92
|
+
if (A && !k) return /* @__PURE__ */ g("div", {
|
|
67
93
|
className: "flex items-center justify-center p-12",
|
|
68
|
-
children: /* @__PURE__ */
|
|
94
|
+
children: /* @__PURE__ */ g(u, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
69
95
|
});
|
|
70
|
-
if (
|
|
96
|
+
if (j) return /* @__PURE__ */ _("div", {
|
|
71
97
|
className: "p-6 text-destructive",
|
|
72
|
-
children: ["Failed to load portfolio: ",
|
|
98
|
+
children: ["Failed to load portfolio: ", j.message]
|
|
73
99
|
});
|
|
74
|
-
let
|
|
75
|
-
if (!
|
|
100
|
+
let I = k?.planmagnetPortfolio;
|
|
101
|
+
if (!I) return /* @__PURE__ */ g("div", {
|
|
76
102
|
className: "p-6 text-muted-foreground",
|
|
77
103
|
children: "Portfolio not found."
|
|
78
104
|
});
|
|
79
|
-
let
|
|
80
|
-
return /* @__PURE__ */
|
|
105
|
+
let L = M?.planmagnetPortfolioOverview ?? null, R = N?.planmagnetPortfolioRollup ?? null;
|
|
106
|
+
return /* @__PURE__ */ _("div", {
|
|
81
107
|
className: "space-y-6 p-6",
|
|
82
108
|
children: [
|
|
83
|
-
/* @__PURE__ */
|
|
109
|
+
/* @__PURE__ */ _("div", {
|
|
84
110
|
className: "flex items-center justify-between",
|
|
85
|
-
children: [/* @__PURE__ */
|
|
111
|
+
children: [/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("div", {
|
|
86
112
|
className: "flex items-center gap-2",
|
|
87
113
|
children: [
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
/* @__PURE__ */
|
|
114
|
+
/* @__PURE__ */ g(c, { className: "h-5 w-5 text-primary" }),
|
|
115
|
+
/* @__PURE__ */ g("h1", {
|
|
90
116
|
className: "text-2xl font-semibold",
|
|
91
|
-
children:
|
|
117
|
+
children: I.name
|
|
92
118
|
}),
|
|
93
|
-
/* @__PURE__ */
|
|
119
|
+
/* @__PURE__ */ g(v, {
|
|
94
120
|
variant: "outline",
|
|
95
121
|
className: "text-xs",
|
|
96
|
-
children:
|
|
122
|
+
children: r(I.status)
|
|
97
123
|
})
|
|
98
124
|
]
|
|
99
|
-
}),
|
|
125
|
+
}), I.alignment && /* @__PURE__ */ g("p", {
|
|
100
126
|
className: "text-sm text-muted-foreground mt-1",
|
|
101
|
-
children:
|
|
102
|
-
})] }), /* @__PURE__ */
|
|
103
|
-
portfolioId:
|
|
104
|
-
name:
|
|
105
|
-
status:
|
|
127
|
+
children: I.alignment === "CUSTOM" ? I.alignmentLabel ?? "Custom alignment" : r(I.alignment)
|
|
128
|
+
})] }), /* @__PURE__ */ g(a, {
|
|
129
|
+
portfolioId: I.id,
|
|
130
|
+
name: I.name,
|
|
131
|
+
status: I.status
|
|
106
132
|
})]
|
|
107
133
|
}),
|
|
108
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ _("div", {
|
|
109
135
|
className: "grid grid-cols-2 md:grid-cols-4 gap-4",
|
|
110
136
|
children: [
|
|
111
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ g(b, { children: /* @__PURE__ */ _(x, {
|
|
112
138
|
className: "pt-4 text-center",
|
|
113
139
|
children: [
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ g(c, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
141
|
+
/* @__PURE__ */ g("p", {
|
|
116
142
|
className: "text-2xl font-bold mt-1",
|
|
117
|
-
children:
|
|
143
|
+
children: L?.totalPrograms ?? I.programs.length
|
|
118
144
|
}),
|
|
119
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ g("p", {
|
|
120
146
|
className: "text-xs text-muted-foreground",
|
|
121
147
|
children: "Programs"
|
|
122
148
|
})
|
|
123
149
|
]
|
|
124
150
|
}) }),
|
|
125
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ g(b, { children: /* @__PURE__ */ _(x, {
|
|
126
152
|
className: "pt-4 text-center",
|
|
127
153
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ g(d, { className: "h-5 w-5 mx-auto text-primary" }),
|
|
155
|
+
/* @__PURE__ */ g("p", {
|
|
130
156
|
className: "text-2xl font-bold mt-1",
|
|
131
|
-
children:
|
|
157
|
+
children: L?.totalProjects ?? I.projects.length
|
|
132
158
|
}),
|
|
133
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ g("p", {
|
|
134
160
|
className: "text-xs text-muted-foreground",
|
|
135
161
|
children: "Projects"
|
|
136
162
|
})
|
|
137
163
|
]
|
|
138
164
|
}) }),
|
|
139
|
-
/* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ g(b, { children: /* @__PURE__ */ _(x, {
|
|
140
166
|
className: "pt-4 text-center",
|
|
141
167
|
children: [
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ g(o, { className: "h-5 w-5 mx-auto text-destructive" }),
|
|
169
|
+
/* @__PURE__ */ g("p", {
|
|
144
170
|
className: "text-2xl font-bold mt-1",
|
|
145
|
-
children:
|
|
171
|
+
children: L?.atRiskCount ?? 0
|
|
146
172
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ g("p", {
|
|
148
174
|
className: "text-xs text-muted-foreground",
|
|
149
175
|
children: "At Risk"
|
|
150
176
|
})
|
|
151
177
|
]
|
|
152
178
|
}) }),
|
|
153
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ g(b, { children: /* @__PURE__ */ _(x, {
|
|
154
180
|
className: "pt-4 text-center",
|
|
155
181
|
children: [
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ g(l, { className: "h-5 w-5 mx-auto text-status-warning-text" }),
|
|
183
|
+
/* @__PURE__ */ g("p", {
|
|
158
184
|
className: "text-2xl font-bold mt-1",
|
|
159
|
-
children:
|
|
185
|
+
children: L?.overdueMilestones ?? 0
|
|
160
186
|
}),
|
|
161
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ g("p", {
|
|
162
188
|
className: "text-xs text-muted-foreground",
|
|
163
189
|
children: "Overdue Milestones"
|
|
164
190
|
})
|
|
@@ -166,174 +192,248 @@ function C() {
|
|
|
166
192
|
}) })
|
|
167
193
|
]
|
|
168
194
|
}),
|
|
169
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ _(b, {
|
|
196
|
+
"data-testid": "portfolio-rollup-card",
|
|
197
|
+
children: [/* @__PURE__ */ _(S, { children: [/* @__PURE__ */ _(C, {
|
|
198
|
+
className: "flex items-center gap-2",
|
|
199
|
+
children: [/* @__PURE__ */ g(s, { className: "h-4 w-4" }), "Portfolio Rollup"]
|
|
200
|
+
}), /* @__PURE__ */ g("p", {
|
|
201
|
+
className: "text-xs text-muted-foreground",
|
|
202
|
+
children: "Recomputed on every load across every live project in this portfolio."
|
|
203
|
+
})] }), /* @__PURE__ */ g(x, {
|
|
204
|
+
className: "space-y-4",
|
|
205
|
+
children: P && !R ? /* @__PURE__ */ g("p", {
|
|
206
|
+
className: "text-sm text-muted-foreground",
|
|
207
|
+
children: "Loading…"
|
|
208
|
+
}) : F ? /* @__PURE__ */ _("p", {
|
|
209
|
+
className: "text-sm text-status-error-text",
|
|
210
|
+
children: ["Rollup could not be loaded: ", F.message]
|
|
211
|
+
}) : R ? /* @__PURE__ */ _(h, { children: [
|
|
212
|
+
/* @__PURE__ */ _("div", {
|
|
213
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-3",
|
|
214
|
+
children: [/* @__PURE__ */ g(n, {
|
|
215
|
+
label: "Total projects",
|
|
216
|
+
value: String(R.totalProjects)
|
|
217
|
+
}), /* @__PURE__ */ g(n, {
|
|
218
|
+
label: "Status breakdown",
|
|
219
|
+
value: Object.keys(R.projectsByStatus).length === 0 ? "—" : Object.entries(R.projectsByStatus).map(([e, t]) => `${r(e)}: ${t}`).join(", "),
|
|
220
|
+
hint: R.totalProjects === 0 ? "No live projects in this portfolio" : void 0
|
|
221
|
+
})]
|
|
222
|
+
}),
|
|
223
|
+
/* @__PURE__ */ _("div", {
|
|
224
|
+
className: "grid grid-cols-1 sm:grid-cols-3 gap-3",
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ g(n, {
|
|
227
|
+
label: "Planned",
|
|
228
|
+
value: R.totalBudget == null ? "—" : R.totalBudget.toLocaleString(),
|
|
229
|
+
hint: R.totalBudget == null ? "No budgets set on these projects" : void 0
|
|
230
|
+
}),
|
|
231
|
+
/* @__PURE__ */ g(n, {
|
|
232
|
+
label: "Spent",
|
|
233
|
+
value: R.totalSpent == null ? "—" : R.totalSpent.toLocaleString(),
|
|
234
|
+
hint: R.totalSpent == null ? "No budgets set on these projects" : void 0
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ g(n, {
|
|
237
|
+
label: "Utilisation",
|
|
238
|
+
value: R.budgetUtilization == null ? "—" : `${R.budgetUtilization.toFixed(0)}%`,
|
|
239
|
+
hint: R.budgetUtilization == null ? "No budget to compare spend against" : void 0
|
|
240
|
+
})
|
|
241
|
+
]
|
|
242
|
+
}),
|
|
243
|
+
/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h3", {
|
|
244
|
+
className: "text-sm font-medium mb-1",
|
|
245
|
+
children: "Average on-time rate (trailing 30 days)"
|
|
246
|
+
}), /* @__PURE__ */ _("div", {
|
|
247
|
+
className: "grid grid-cols-1 sm:grid-cols-3 gap-3",
|
|
248
|
+
children: [
|
|
249
|
+
/* @__PURE__ */ g(D, {
|
|
250
|
+
label: "Sprints",
|
|
251
|
+
rate: R.averageSprintOnTimeRate,
|
|
252
|
+
emptyReason: "No completed sprint in this window across these projects"
|
|
253
|
+
}),
|
|
254
|
+
/* @__PURE__ */ g(D, {
|
|
255
|
+
label: "Releases",
|
|
256
|
+
rate: R.averageReleaseOnTimeRate,
|
|
257
|
+
emptyReason: "No completed release in this window across these projects"
|
|
258
|
+
}),
|
|
259
|
+
/* @__PURE__ */ g(D, {
|
|
260
|
+
label: "Milestones",
|
|
261
|
+
rate: R.averageMilestoneOnTimeRate,
|
|
262
|
+
emptyReason: "No completed milestone in this window across these projects"
|
|
263
|
+
})
|
|
264
|
+
]
|
|
265
|
+
})] })
|
|
266
|
+
] }) : null
|
|
267
|
+
})]
|
|
268
|
+
}),
|
|
269
|
+
/* @__PURE__ */ _("div", {
|
|
170
270
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
171
|
-
children: [/* @__PURE__ */
|
|
271
|
+
children: [/* @__PURE__ */ _("div", {
|
|
172
272
|
className: "lg:col-span-2 space-y-6",
|
|
173
273
|
children: [
|
|
174
|
-
/* @__PURE__ */
|
|
274
|
+
/* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ g(C, { children: "Overview" }) }), /* @__PURE__ */ _(x, {
|
|
175
275
|
className: "space-y-4",
|
|
176
|
-
children: [/* @__PURE__ */
|
|
276
|
+
children: [/* @__PURE__ */ g("p", {
|
|
177
277
|
className: "text-sm",
|
|
178
|
-
children:
|
|
179
|
-
}),
|
|
278
|
+
children: I.description ?? "No description provided."
|
|
279
|
+
}), L ? /* @__PURE__ */ _("div", {
|
|
180
280
|
className: "grid grid-cols-2 gap-4",
|
|
181
281
|
children: [
|
|
182
|
-
/* @__PURE__ */
|
|
282
|
+
/* @__PURE__ */ _("div", {
|
|
183
283
|
className: "p-3 bg-muted rounded-md",
|
|
184
|
-
children: [/* @__PURE__ */
|
|
284
|
+
children: [/* @__PURE__ */ g("p", {
|
|
185
285
|
className: "text-xs text-muted-foreground",
|
|
186
286
|
children: "Budget Utilization"
|
|
187
|
-
}), /* @__PURE__ */
|
|
287
|
+
}), /* @__PURE__ */ g("p", {
|
|
188
288
|
className: "text-lg font-semibold mt-1",
|
|
189
|
-
children:
|
|
289
|
+
children: L.budgetUtilization == null ? "No budget data" : `${L.budgetUtilization.toFixed(0)}%`
|
|
190
290
|
})]
|
|
191
291
|
}),
|
|
192
|
-
/* @__PURE__ */
|
|
292
|
+
/* @__PURE__ */ _("div", {
|
|
193
293
|
className: "p-3 bg-muted rounded-md",
|
|
194
|
-
children: [/* @__PURE__ */
|
|
294
|
+
children: [/* @__PURE__ */ g("p", {
|
|
195
295
|
className: "text-xs text-muted-foreground",
|
|
196
296
|
children: "Health Score"
|
|
197
|
-
}), /* @__PURE__ */
|
|
297
|
+
}), /* @__PURE__ */ g("p", {
|
|
198
298
|
className: "text-lg font-semibold mt-1",
|
|
199
|
-
children:
|
|
299
|
+
children: L.healthScore == null ? "No projects yet" : L.healthScore.toFixed(0)
|
|
200
300
|
})]
|
|
201
301
|
}),
|
|
202
|
-
/* @__PURE__ */
|
|
302
|
+
/* @__PURE__ */ _("div", {
|
|
203
303
|
className: "p-3 bg-muted rounded-md",
|
|
204
|
-
children: [/* @__PURE__ */
|
|
304
|
+
children: [/* @__PURE__ */ g("p", {
|
|
205
305
|
className: "text-xs text-muted-foreground",
|
|
206
306
|
children: "Total Spent"
|
|
207
|
-
}), /* @__PURE__ */
|
|
307
|
+
}), /* @__PURE__ */ g("p", {
|
|
208
308
|
className: "text-lg font-semibold mt-1",
|
|
209
|
-
children:
|
|
309
|
+
children: L.totalSpent == null ? "N/A" : L.totalSpent.toLocaleString()
|
|
210
310
|
})]
|
|
211
311
|
}),
|
|
212
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ _("div", {
|
|
213
313
|
className: "p-3 bg-muted rounded-md",
|
|
214
|
-
children: [/* @__PURE__ */
|
|
314
|
+
children: [/* @__PURE__ */ g("p", {
|
|
215
315
|
className: "text-xs text-muted-foreground",
|
|
216
316
|
children: "Projects by Status"
|
|
217
|
-
}), /* @__PURE__ */
|
|
317
|
+
}), /* @__PURE__ */ g("p", {
|
|
218
318
|
className: "text-sm mt-1",
|
|
219
|
-
children: Object.keys(
|
|
319
|
+
children: Object.keys(L.projectsByStatus).length > 0 ? Object.entries(L.projectsByStatus).map(([e, t]) => `${r(e)}: ${t}`).join(", ") : "No projects yet"
|
|
220
320
|
})]
|
|
221
321
|
})
|
|
222
322
|
]
|
|
223
|
-
}) : /* @__PURE__ */
|
|
323
|
+
}) : /* @__PURE__ */ g("p", {
|
|
224
324
|
className: "text-sm text-muted-foreground",
|
|
225
325
|
children: "Loading overview…"
|
|
226
326
|
})]
|
|
227
327
|
})] }),
|
|
228
|
-
/* @__PURE__ */
|
|
328
|
+
/* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ _(C, { children: [
|
|
229
329
|
"Programs (",
|
|
230
|
-
|
|
330
|
+
I.programs.length,
|
|
231
331
|
")"
|
|
232
|
-
] }) }), /* @__PURE__ */
|
|
332
|
+
] }) }), /* @__PURE__ */ _(x, {
|
|
233
333
|
className: "space-y-2",
|
|
234
|
-
children: [
|
|
334
|
+
children: [I.programs.length === 0 && /* @__PURE__ */ g("p", {
|
|
235
335
|
className: "text-sm text-muted-foreground",
|
|
236
336
|
children: "No programs are linked to this portfolio yet."
|
|
237
|
-
}),
|
|
337
|
+
}), I.programs.map((e) => /* @__PURE__ */ _("button", {
|
|
238
338
|
type: "button",
|
|
239
339
|
className: "flex w-full items-center justify-between rounded-md border p-3 text-left hover:bg-muted",
|
|
240
|
-
onClick: () =>
|
|
241
|
-
children: [/* @__PURE__ */
|
|
340
|
+
onClick: () => p(i("/products/program-detail-page", e.id)),
|
|
341
|
+
children: [/* @__PURE__ */ g("span", {
|
|
242
342
|
className: "text-sm font-medium",
|
|
243
343
|
children: e.name
|
|
244
|
-
}), /* @__PURE__ */
|
|
344
|
+
}), /* @__PURE__ */ g(v, {
|
|
245
345
|
variant: "outline",
|
|
246
346
|
className: "text-xs",
|
|
247
|
-
children:
|
|
347
|
+
children: r(e.status)
|
|
248
348
|
})]
|
|
249
349
|
}, e.id))]
|
|
250
350
|
})] }),
|
|
251
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ _(C, { children: [
|
|
252
352
|
"Projects (",
|
|
253
|
-
|
|
353
|
+
I.projects.length,
|
|
254
354
|
")"
|
|
255
|
-
] }) }), /* @__PURE__ */
|
|
355
|
+
] }) }), /* @__PURE__ */ _(x, {
|
|
256
356
|
className: "space-y-2",
|
|
257
|
-
children: [
|
|
357
|
+
children: [I.projects.length === 0 && /* @__PURE__ */ _("div", {
|
|
258
358
|
className: "space-y-1",
|
|
259
|
-
children: [/* @__PURE__ */
|
|
359
|
+
children: [/* @__PURE__ */ g("p", {
|
|
260
360
|
className: "text-sm text-muted-foreground",
|
|
261
361
|
children: "No projects are linked to this portfolio yet."
|
|
262
|
-
}), /* @__PURE__ */
|
|
362
|
+
}), /* @__PURE__ */ _("p", {
|
|
263
363
|
className: "text-sm text-muted-foreground",
|
|
264
364
|
children: [
|
|
265
365
|
"Open a project and set its Portfolio field to add it here.",
|
|
266
366
|
" ",
|
|
267
|
-
/* @__PURE__ */
|
|
367
|
+
/* @__PURE__ */ g(y, {
|
|
268
368
|
variant: "link",
|
|
269
369
|
className: "h-auto p-0 text-sm",
|
|
270
|
-
onClick: () =>
|
|
370
|
+
onClick: () => p("/projects/projects-page"),
|
|
271
371
|
children: "Go to Projects"
|
|
272
372
|
})
|
|
273
373
|
]
|
|
274
374
|
})]
|
|
275
|
-
}),
|
|
375
|
+
}), I.projects.map((e) => /* @__PURE__ */ _("button", {
|
|
276
376
|
type: "button",
|
|
277
377
|
className: "flex w-full items-center justify-between rounded-md border p-3 text-left hover:bg-muted",
|
|
278
|
-
onClick: () =>
|
|
279
|
-
children: [/* @__PURE__ */
|
|
378
|
+
onClick: () => p(i("/projects/project-detail-page", e.id)),
|
|
379
|
+
children: [/* @__PURE__ */ g("span", {
|
|
280
380
|
className: "text-sm font-medium",
|
|
281
381
|
children: e.name
|
|
282
|
-
}), /* @__PURE__ */
|
|
382
|
+
}), /* @__PURE__ */ g(v, {
|
|
283
383
|
variant: "outline",
|
|
284
384
|
className: "text-xs",
|
|
285
|
-
children:
|
|
385
|
+
children: r(e.status)
|
|
286
386
|
})]
|
|
287
387
|
}, e.id))]
|
|
288
388
|
})] })
|
|
289
389
|
]
|
|
290
|
-
}), /* @__PURE__ */
|
|
390
|
+
}), /* @__PURE__ */ _("div", {
|
|
291
391
|
className: "space-y-6",
|
|
292
|
-
children: [/* @__PURE__ */
|
|
392
|
+
children: [/* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ g(C, { children: "Details" }) }), /* @__PURE__ */ _(x, {
|
|
293
393
|
className: "space-y-2 text-sm",
|
|
294
394
|
children: [
|
|
295
|
-
/* @__PURE__ */
|
|
395
|
+
/* @__PURE__ */ _("div", {
|
|
296
396
|
className: "flex justify-between",
|
|
297
|
-
children: [/* @__PURE__ */
|
|
397
|
+
children: [/* @__PURE__ */ g("span", {
|
|
298
398
|
className: "text-muted-foreground",
|
|
299
399
|
children: "Owner"
|
|
300
|
-
}), /* @__PURE__ */
|
|
400
|
+
}), /* @__PURE__ */ g(t, { id: I.ownerId })]
|
|
301
401
|
}),
|
|
302
|
-
/* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ _("div", {
|
|
303
403
|
className: "flex justify-between",
|
|
304
|
-
children: [/* @__PURE__ */
|
|
404
|
+
children: [/* @__PURE__ */ g("span", {
|
|
305
405
|
className: "text-muted-foreground",
|
|
306
406
|
children: "Budget"
|
|
307
|
-
}), /* @__PURE__ */
|
|
407
|
+
}), /* @__PURE__ */ g("span", {
|
|
308
408
|
className: "font-medium",
|
|
309
|
-
children:
|
|
409
|
+
children: I.budgetTotal == null ? "Not set" : `${I.currency ?? ""} ${I.budgetTotal.toLocaleString()}`.trim()
|
|
310
410
|
})]
|
|
311
411
|
}),
|
|
312
|
-
/* @__PURE__ */
|
|
412
|
+
/* @__PURE__ */ _("div", {
|
|
313
413
|
className: "flex justify-between",
|
|
314
|
-
children: [/* @__PURE__ */
|
|
414
|
+
children: [/* @__PURE__ */ g("span", {
|
|
315
415
|
className: "text-muted-foreground",
|
|
316
416
|
children: "Fiscal Period"
|
|
317
|
-
}), /* @__PURE__ */
|
|
417
|
+
}), /* @__PURE__ */ g("span", { children: I.fiscalPeriod ?? "Not set" })]
|
|
318
418
|
}),
|
|
319
|
-
/* @__PURE__ */
|
|
419
|
+
/* @__PURE__ */ _("div", {
|
|
320
420
|
className: "flex justify-between",
|
|
321
|
-
children: [/* @__PURE__ */
|
|
421
|
+
children: [/* @__PURE__ */ g("span", {
|
|
322
422
|
className: "text-muted-foreground",
|
|
323
423
|
children: "Created"
|
|
324
|
-
}), /* @__PURE__ */
|
|
424
|
+
}), /* @__PURE__ */ g("span", { children: new Date(I.createdAt).toLocaleDateString() })]
|
|
325
425
|
}),
|
|
326
|
-
/* @__PURE__ */
|
|
426
|
+
/* @__PURE__ */ _("div", {
|
|
327
427
|
className: "flex justify-between",
|
|
328
|
-
children: [/* @__PURE__ */
|
|
428
|
+
children: [/* @__PURE__ */ g("span", {
|
|
329
429
|
className: "text-muted-foreground",
|
|
330
430
|
children: "Updated"
|
|
331
|
-
}), /* @__PURE__ */
|
|
431
|
+
}), /* @__PURE__ */ g("span", { children: new Date(I.updatedAt).toLocaleDateString() })]
|
|
332
432
|
})
|
|
333
433
|
]
|
|
334
|
-
})] }),
|
|
434
|
+
})] }), I.tags.length > 0 && /* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ g(C, { children: "Tags" }) }), /* @__PURE__ */ g(x, {
|
|
335
435
|
className: "flex flex-wrap gap-1",
|
|
336
|
-
children:
|
|
436
|
+
children: I.tags.map((e) => /* @__PURE__ */ g(v, {
|
|
337
437
|
variant: "outline",
|
|
338
438
|
className: "text-xs",
|
|
339
439
|
children: e
|
|
@@ -345,6 +445,6 @@ function C() {
|
|
|
345
445
|
});
|
|
346
446
|
}
|
|
347
447
|
//#endregion
|
|
348
|
-
export {
|
|
448
|
+
export { O as PortfoliosPortfolioDetailPagePage };
|
|
349
449
|
|
|
350
450
|
//# sourceMappingURL=PortfoliosPortfolioDetailPagePage.js.map
|