@burdenoff/microfe-planmagnet 2026.1001.5 → 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.
Files changed (59) hide show
  1. package/dist/planmagnet/controls/CompetitorControls.d.ts +71 -0
  2. package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -1
  3. package/dist/planmagnet/controls/CompetitorControls.js +346 -12
  4. package/dist/planmagnet/controls/CompetitorControls.js.map +1 -1
  5. package/dist/planmagnet/controls/FeatureControls.d.ts +5 -0
  6. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
  7. package/dist/planmagnet/controls/FeatureControls.js +363 -218
  8. package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
  9. package/dist/planmagnet/controls/Pickers.d.ts +15 -0
  10. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  11. package/dist/planmagnet/controls/Pickers.js +61 -1
  12. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  13. package/dist/planmagnet/controls/PrioritizationControls.d.ts +36 -0
  14. package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -1
  15. package/dist/planmagnet/controls/PrioritizationControls.js +118 -1
  16. package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -1
  17. package/dist/planmagnet/dashboards/DashboardUI.js +1 -1
  18. package/dist/planmagnet/dashboards/cards/SprintCapacityCard.d.ts.map +1 -1
  19. package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js +67 -59
  20. package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js.map +1 -1
  21. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
  22. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +289 -282
  23. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  24. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -1
  25. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +126 -63
  26. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -1
  27. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -1
  28. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +14 -0
  29. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -1
  30. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -1
  31. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +93 -57
  32. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -1
  33. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -1
  34. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +125 -83
  35. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -1
  36. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -1
  37. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +226 -126
  38. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -1
  39. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  40. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +162 -122
  41. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  42. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  43. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +135 -109
  44. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  45. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
  46. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +15 -3
  47. package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
  48. package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
  49. package/dist/planmagnet/pages/TeamTeamPagePage.js +59 -53
  50. package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
  51. package/dist/planmagnet/pages/analytics/MetricsCard.d.ts +8 -0
  52. package/dist/planmagnet/pages/analytics/MetricsCard.d.ts.map +1 -0
  53. package/dist/planmagnet/pages/analytics/MetricsCard.js +164 -0
  54. package/dist/planmagnet/pages/analytics/MetricsCard.js.map +1 -0
  55. package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts +2 -0
  56. package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts.map +1 -0
  57. package/dist/planmagnet/team/UnmatchedCrewIdentities.js +155 -0
  58. package/dist/planmagnet/team/UnmatchedCrewIdentities.js.map +1 -0
  59. package/package.json +1 -1
@@ -1,15 +1,17 @@
1
1
  import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
- import { throwOnError as t } from "../utils/mutationResult.js";
3
- import { detailPath as n } from "../utils/rowNavigation.js";
4
- import { useMemo as r, useState as i } from "react";
5
- import { ArrowLeft as a, Loader2 as o, Save as s } from "lucide-react";
6
- import { useParams as c } from "react-router";
7
- import { gql as l } from "@apollo/client";
8
- import { useMutation as u, useQuery as d } from "@apollo/client/react";
9
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
- import { Button as m, Card as h, CardContent as g, CardHeader as _, CardTitle as v, Input as y } from "@burdenoff/fe-libs/ui";
2
+ import { mutationErrorMessage as t } from "../utils/graphqlErrors.js";
3
+ import { throwOnError as n } from "../utils/mutationResult.js";
4
+ import { detailPath as r } from "../utils/rowNavigation.js";
5
+ import { JsonKeyValueEditor as i, StringListEditor as a, cleanStringList as o, competitorListValid as s, jsonRowsToObject as c, jsonRowsValid as l, jsonToRows as u } from "../controls/CompetitorControls.js";
6
+ import { useMemo as d, useState as f } from "react";
7
+ import { ArrowLeft as ee, Loader2 as p, Save as m } from "lucide-react";
8
+ import { useParams as te } from "react-router";
9
+ import { gql as h } from "@apollo/client";
10
+ import { useMutation as g, useQuery as _ } from "@apollo/client/react";
11
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
12
+ import { Button as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w, Input as T } from "@burdenoff/fe-libs/ui";
11
13
  //#region src/planmagnet/pages/CompetitorsEditCompetitorPagePage.tsx
12
- var b = l`
14
+ var ne = h`
13
15
  query GetCompetitorForEdit($id: ID!) {
14
16
  planmagnetCompetitor(id: $id) {
15
17
  id
@@ -17,9 +19,13 @@ var b = l`
17
19
  website
18
20
  description
19
21
  tags
22
+ strengths
23
+ weaknesses
24
+ pricing
25
+ features
20
26
  }
21
27
  }
22
- `, x = l`
28
+ `, re = h`
23
29
  mutation UpdateCompetitor($id: ID!, $input: PlanmagnetUpdateCompetitorInput!) {
24
30
  planmagnetUpdateCompetitor(id: $id, input: $input) {
25
31
  id
@@ -27,15 +33,19 @@ var b = l`
27
33
  website
28
34
  description
29
35
  tags
36
+ strengths
37
+ weaknesses
38
+ pricing
39
+ features
30
40
  updatedAt
31
41
  }
32
42
  }
33
43
  `;
34
- function S() {
35
- let l = e(), S = c().id ?? "", { data: C, loading: w, error: T } = d(b, {
36
- variables: { id: S },
37
- skip: !S
38
- }), [E, { loading: D }] = u(x, {
44
+ function E() {
45
+ let h = e(), E = te().id ?? "", { data: D, loading: O, error: k } = _(ne, {
46
+ variables: { id: E },
47
+ skip: !E
48
+ }), [A, { loading: j }] = g(re, {
39
49
  refetchQueries: [
40
50
  "ListCompetitors",
41
51
  "GetCompetitorForEdit",
@@ -43,139 +53,171 @@ function S() {
43
53
  "PickerCompetitors"
44
54
  ],
45
55
  awaitRefetchQueries: !0
46
- }), [O, k] = i(null), [A, j] = i(!1), M = C?.planmagnetCompetitor, N = r(() => ({
47
- name: M?.name ?? "",
48
- website: M?.website ?? "",
49
- description: M?.description ?? "",
50
- tags: M?.tags?.join(", ") ?? ""
51
- }), [M]), [P, F] = i({}), I = {
52
- ...N,
53
- ...P
54
- }, L = (e) => F(e);
55
- return w && !C ? /* @__PURE__ */ f("div", {
56
+ }), [M, N] = f(null), [ie, P] = f(!1), F = D?.planmagnetCompetitor, I = d(() => ({
57
+ name: F?.name ?? "",
58
+ website: F?.website ?? "",
59
+ description: F?.description ?? "",
60
+ tags: F?.tags?.join(", ") ?? ""
61
+ }), [F]), [ae, oe] = f({}), L = {
62
+ ...I,
63
+ ...ae
64
+ }, R = (e) => oe(e), z = d(() => F?.strengths ?? [], [F]), B = d(() => F?.weaknesses ?? [], [F]), V = d(() => u(F?.pricing), [F]), H = d(() => u(F?.features), [F]), [U, W] = f(null), [G, K] = f(null), [q, se] = f(null), [J, ce] = f(null), Y = U ?? z, X = G ?? B, Z = q ?? V, Q = J ?? H, $ = s(Y) && s(X) && l(Z) && l(Q);
65
+ return O && !D ? /* @__PURE__ */ v("div", {
56
66
  className: "flex items-center justify-center p-12",
57
- children: /* @__PURE__ */ f(o, { className: "h-8 w-8 animate-spin text-muted-foreground" })
58
- }) : T ? /* @__PURE__ */ p("div", {
67
+ children: /* @__PURE__ */ v(p, { className: "h-8 w-8 animate-spin text-muted-foreground" })
68
+ }) : k ? /* @__PURE__ */ y("div", {
59
69
  className: "p-6 text-destructive",
60
- children: ["Failed to load competitor: ", T.message]
61
- }) : M ? /* @__PURE__ */ p("div", {
70
+ children: ["Failed to load competitor: ", k.message]
71
+ }) : F ? /* @__PURE__ */ y("div", {
62
72
  className: "space-y-6 p-6 max-w-4xl",
63
73
  children: [
64
- /* @__PURE__ */ p("div", {
74
+ /* @__PURE__ */ y("div", {
65
75
  className: "flex items-center justify-between",
66
- children: [/* @__PURE__ */ p("div", {
76
+ children: [/* @__PURE__ */ y("div", {
67
77
  className: "flex items-center gap-3",
68
- children: [/* @__PURE__ */ f(m, {
78
+ children: [/* @__PURE__ */ v(b, {
69
79
  variant: "ghost",
70
80
  size: "sm",
71
81
  "aria-label": "Back to the competitor",
72
- onClick: () => l(n("/products/competitor-detail-page", S)),
73
- children: /* @__PURE__ */ f(a, { className: "h-4 w-4" })
74
- }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
82
+ onClick: () => h(r("/products/competitor-detail-page", E)),
83
+ children: /* @__PURE__ */ v(ee, { className: "h-4 w-4" })
84
+ }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
75
85
  className: "text-2xl font-semibold",
76
86
  children: "Edit Competitor"
77
- }), /* @__PURE__ */ f("p", {
87
+ }), /* @__PURE__ */ v("p", {
78
88
  className: "text-sm text-muted-foreground",
79
- children: M.name
89
+ children: F.name
80
90
  })] })]
81
- }), /* @__PURE__ */ p(m, {
91
+ }), /* @__PURE__ */ y(b, {
82
92
  size: "sm",
83
93
  onClick: async () => {
84
- if (!M || !I.name.trim()) return;
85
- let e = (e) => e.split(",").map((e) => e.trim()).filter(Boolean), n = {
86
- name: I.name.trim(),
94
+ if (!F || !L.name.trim() || !$) return;
95
+ let e = (e) => e.split(",").map((e) => e.trim()).filter(Boolean), r = {
96
+ name: L.name.trim(),
97
+ website: L.website.trim() || null,
98
+ description: L.description.trim() || null,
99
+ tags: e(L.tags)
100
+ }, i = {
101
+ name: I.name,
87
102
  website: I.website.trim() || null,
88
103
  description: I.description.trim() || null,
89
104
  tags: e(I.tags)
90
- }, r = {
91
- name: N.name,
92
- website: N.website.trim() || null,
93
- description: N.description.trim() || null,
94
- tags: e(N.tags)
95
- }, i = Object.fromEntries(Object.entries(n).filter(([e, t]) => JSON.stringify(t) !== JSON.stringify(r[e])));
96
- if (k(null), j(!1), Object.keys(i).length === 0) {
97
- j(!0);
105
+ };
106
+ U !== null && (r.strengths = o(Y), i.strengths = o(z)), G !== null && (r.weaknesses = o(X), i.weaknesses = o(B)), q !== null && (r.pricing = c(Z), i.pricing = F.pricing ?? null), J !== null && (r.features = c(Q), i.features = F.features ?? null);
107
+ let a = Object.fromEntries(Object.entries(r).filter(([e, t]) => JSON.stringify(t) !== JSON.stringify(i[e])));
108
+ if (N(null), P(!1), Object.keys(a).length === 0) {
109
+ P(!0);
98
110
  return;
99
111
  }
100
112
  try {
101
- await t(E({ variables: {
102
- id: S,
103
- input: i
104
- } })), j(!0);
113
+ await n(A({ variables: {
114
+ id: E,
115
+ input: a
116
+ } })), P(!0);
105
117
  } catch (e) {
106
- k(e instanceof Error ? e.message : "The competitor could not be saved.");
118
+ N(t(e, "The competitor could not be saved."));
107
119
  }
108
120
  },
109
- disabled: D || !I.name.trim(),
110
- children: [D ? /* @__PURE__ */ f(o, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ f(s, { className: "mr-1 h-4 w-4" }), "Save Changes"]
121
+ disabled: j || !L.name.trim() || !$,
122
+ children: [j ? /* @__PURE__ */ v(p, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ v(m, { className: "mr-1 h-4 w-4" }), "Save Changes"]
111
123
  })]
112
124
  }),
113
- A && /* @__PURE__ */ f("div", {
125
+ ie && /* @__PURE__ */ v("div", {
114
126
  role: "status",
115
127
  className: "p-3 bg-muted text-status-success-text rounded-md text-sm",
116
128
  children: "Changes saved."
117
129
  }),
118
- O && /* @__PURE__ */ f("div", {
130
+ M && /* @__PURE__ */ v("div", {
119
131
  role: "alert",
120
132
  className: "p-3 rounded-md bg-destructive/10 text-destructive text-sm",
121
- children: O
133
+ children: M
122
134
  }),
123
- /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ f(v, { children: "Competitor Details" }) }), /* @__PURE__ */ p(g, {
135
+ /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Competitor Details" }) }), /* @__PURE__ */ y(S, {
124
136
  className: "space-y-4",
125
137
  children: [
126
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
138
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
127
139
  className: "text-sm font-medium",
128
140
  children: "Name"
129
- }), /* @__PURE__ */ f(y, {
130
- value: I.name,
131
- onChange: (e) => L({
132
- ...I,
141
+ }), /* @__PURE__ */ v(T, {
142
+ value: L.name,
143
+ onChange: (e) => R({
144
+ ...L,
133
145
  name: e.target.value
134
146
  }),
135
147
  className: "mt-1"
136
148
  })] }),
137
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
149
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
138
150
  className: "text-sm font-medium",
139
151
  children: "Website"
140
- }), /* @__PURE__ */ f(y, {
141
- value: I.website,
142
- onChange: (e) => L({
143
- ...I,
152
+ }), /* @__PURE__ */ v(T, {
153
+ value: L.website,
154
+ onChange: (e) => R({
155
+ ...L,
144
156
  website: e.target.value
145
157
  }),
146
158
  className: "mt-1"
147
159
  })] }),
148
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
160
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
149
161
  className: "text-sm font-medium",
150
162
  children: "Description / Notes"
151
- }), /* @__PURE__ */ f("textarea", {
163
+ }), /* @__PURE__ */ v("textarea", {
152
164
  className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]",
153
- value: I.description,
154
- onChange: (e) => L({
155
- ...I,
165
+ value: L.description,
166
+ onChange: (e) => R({
167
+ ...L,
156
168
  description: e.target.value
157
169
  })
158
170
  })] }),
159
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
171
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
160
172
  className: "text-sm font-medium",
161
173
  children: "Tags (comma-separated)"
162
- }), /* @__PURE__ */ f(y, {
163
- value: I.tags,
164
- onChange: (e) => L({
165
- ...I,
174
+ }), /* @__PURE__ */ v(T, {
175
+ value: L.tags,
176
+ onChange: (e) => R({
177
+ ...L,
166
178
  tags: e.target.value
167
179
  }),
168
180
  className: "mt-1"
169
181
  })] })
170
182
  ]
183
+ })] }),
184
+ /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Strengths & Weaknesses" }) }), /* @__PURE__ */ y(S, {
185
+ className: "space-y-4",
186
+ children: [/* @__PURE__ */ v(a, {
187
+ label: "Strengths",
188
+ values: Y,
189
+ onChange: W,
190
+ placeholder: "e.g. Strong enterprise SSO",
191
+ testId: "competitor-strengths"
192
+ }), /* @__PURE__ */ v(a, {
193
+ label: "Weaknesses",
194
+ values: X,
195
+ onChange: K,
196
+ placeholder: "e.g. No mobile app",
197
+ testId: "competitor-weaknesses"
198
+ })]
199
+ })] }),
200
+ /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Pricing & Feature Comparison" }) }), /* @__PURE__ */ y(S, {
201
+ className: "space-y-4",
202
+ children: [/* @__PURE__ */ v(i, {
203
+ label: "Pricing",
204
+ rows: Z,
205
+ onChange: se,
206
+ testId: "competitor-pricing"
207
+ }), /* @__PURE__ */ v(i, {
208
+ label: "Features",
209
+ rows: Q,
210
+ onChange: ce,
211
+ testId: "competitor-features"
212
+ })]
171
213
  })] })
172
214
  ]
173
- }) : /* @__PURE__ */ f("div", {
215
+ }) : /* @__PURE__ */ v("div", {
174
216
  className: "p-6 text-muted-foreground",
175
217
  children: "Competitor not found."
176
218
  });
177
219
  }
178
220
  //#endregion
179
- export { S as CompetitorsEditCompetitorPagePage };
221
+ export { E as CompetitorsEditCompetitorPagePage };
180
222
 
181
223
  //# sourceMappingURL=CompetitorsEditCompetitorPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CompetitorsEditCompetitorPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/CompetitorsEditCompetitorPagePage.tsx"],"sourcesContent":["import { 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, Loader2 } from 'lucide-react';\nimport { useParams } from 'react-router';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\n\nconst GET_COMPETITOR = gql`\n query GetCompetitorForEdit($id: ID!) {\n planmagnetCompetitor(id: $id) {\n id\n name\n website\n description\n tags\n }\n }\n`;\n\nconst UPDATE_COMPETITOR = gql`\n mutation UpdateCompetitor($id: ID!, $input: PlanmagnetUpdateCompetitorInput!) {\n planmagnetUpdateCompetitor(id: $id, input: $input) {\n id\n name\n website\n description\n tags\n updatedAt\n }\n }\n`;\n\nexport function CompetitorsEditCompetitorPagePage() {\n const navigate = usePlanMagnetNavigate();\n const params = useParams<{ id: string }>();\n const competitorId = params.id ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetCompetitor: {\n id: string;\n name: string;\n website: string | null;\n description: string | null;\n tags: string[];\n } | null;\n }>(GET_COMPETITOR, { variables: { id: competitorId }, skip: !competitorId });\n\n const [updateCompetitor, { loading: saving }] = useMutation(UPDATE_COMPETITOR, {\n refetchQueries: [\n 'ListCompetitors',\n 'GetCompetitorForEdit',\n 'GetCompetitor',\n 'PickerCompetitors',\n ],\n awaitRefetchQueries: true,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const competitor = data?.planmagnetCompetitor;\n\n const defaultForm = useMemo(\n () => ({\n name: competitor?.name ?? '',\n website: competitor?.website ?? '',\n description: competitor?.description ?? '',\n tags: competitor?.tags?.join(', ') ?? '',\n }),\n [competitor]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (val: Record<string, string>) => setFormOverrides(val);\n\n const handleSave = async () => {\n if (!competitor || !form.name.trim()) return;\n const tagList = (v: string) =>\n v\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const next: Record<string, unknown> = {\n name: form.name.trim(),\n website: form.website.trim() || null,\n description: form.description.trim() || null,\n tags: tagList(form.tags),\n };\n const before: Record<string, unknown> = {\n name: defaultForm.name,\n website: defaultForm.website.trim() || null,\n description: defaultForm.description.trim() || null,\n tags: tagList(defaultForm.tags),\n };\n const input = Object.fromEntries(\n Object.entries(next).filter(([k, v]) => JSON.stringify(v) !== JSON.stringify(before[k]))\n );\n setSaveError(null);\n setSaved(false);\n if (Object.keys(input).length === 0) {\n setSaved(true);\n return;\n }\n try {\n await throwOnError(updateCompetitor({ variables: { id: competitorId, input } }));\n setSaved(true);\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The competitor could not be saved.');\n }\n };\n\n // Only before the first load: a refetch must not blank the page (it unmounts every component on it and\n // loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load competitor: {error.message}</div>;\n }\n\n if (!competitor) return <div className=\"p-6 text-muted-foreground\">Competitor 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\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the competitor\"\n onClick={() => navigate(detailPath('/products/competitor-detail-page', competitorId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Competitor</h1>\n <p className=\"text-sm text-muted-foreground\">{competitor.name}</p>\n </div>\n </div>\n <Button size=\"sm\" onClick={handleSave} disabled={saving || !form.name.trim()}>\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Save Changes\n </Button>\n </div>\n\n {saved && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n Changes saved.\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Competitor 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>\n <label className=\"text-sm font-medium\">Website</label>\n <Input\n value={form.website}\n onChange={(e) => setForm({ ...form, website: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description / Notes</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CompetitorsEditCompetitorPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/CompetitorsEditCompetitorPagePage.tsx"],"sourcesContent":["import { 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, Loader2 } from 'lucide-react';\nimport { useParams } from 'react-router';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { mutationErrorMessage } from '../utils/graphqlErrors';\nimport {\n JsonKeyValueEditor,\n StringListEditor,\n cleanStringList,\n competitorListValid,\n jsonRowsToObject,\n jsonRowsValid,\n jsonToRows,\n type JsonKeyValueRow,\n} from '../controls/CompetitorControls';\n\nconst GET_COMPETITOR = gql`\n query GetCompetitorForEdit($id: ID!) {\n planmagnetCompetitor(id: $id) {\n id\n name\n website\n description\n tags\n strengths\n weaknesses\n pricing\n features\n }\n }\n`;\n\nconst UPDATE_COMPETITOR = gql`\n mutation UpdateCompetitor($id: ID!, $input: PlanmagnetUpdateCompetitorInput!) {\n planmagnetUpdateCompetitor(id: $id, input: $input) {\n id\n name\n website\n description\n tags\n strengths\n weaknesses\n pricing\n features\n updatedAt\n }\n }\n`;\n\nexport function CompetitorsEditCompetitorPagePage() {\n const navigate = usePlanMagnetNavigate();\n const params = useParams<{ id: string }>();\n const competitorId = params.id ?? '';\n\n const { data, loading, error } = useQuery<{\n planmagnetCompetitor: {\n id: string;\n name: string;\n website: string | null;\n description: string | null;\n tags: string[];\n strengths: string[];\n weaknesses: string[];\n pricing: unknown;\n features: unknown;\n } | null;\n }>(GET_COMPETITOR, { variables: { id: competitorId }, skip: !competitorId });\n\n const [updateCompetitor, { loading: saving }] = useMutation(UPDATE_COMPETITOR, {\n refetchQueries: [\n 'ListCompetitors',\n 'GetCompetitorForEdit',\n 'GetCompetitor',\n 'PickerCompetitors',\n ],\n awaitRefetchQueries: true,\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const competitor = data?.planmagnetCompetitor;\n\n const defaultForm = useMemo(\n () => ({\n name: competitor?.name ?? '',\n website: competitor?.website ?? '',\n description: competitor?.description ?? '',\n tags: competitor?.tags?.join(', ') ?? '',\n }),\n [competitor]\n );\n\n const [formOverrides, setFormOverrides] = useState<Record<string, string>>({});\n const form = { ...defaultForm, ...formOverrides };\n const setForm = (val: Record<string, string>) => setFormOverrides(val);\n\n // PRM-31 — array/object fields can't live in the plain string `form` above; same \"null override = still\n // following the loaded record\" shape, just per-field instead of merged into one object.\n const defaultStrengths = useMemo(() => competitor?.strengths ?? [], [competitor]);\n const defaultWeaknesses = useMemo(() => competitor?.weaknesses ?? [], [competitor]);\n const defaultPricingRows = useMemo(() => jsonToRows(competitor?.pricing), [competitor]);\n const defaultFeaturesRows = useMemo(() => jsonToRows(competitor?.features), [competitor]);\n const [strengthsOverride, setStrengthsOverride] = useState<string[] | null>(null);\n const [weaknessesOverride, setWeaknessesOverride] = useState<string[] | null>(null);\n const [pricingOverride, setPricingOverride] = useState<JsonKeyValueRow[] | null>(null);\n const [featuresOverride, setFeaturesOverride] = useState<JsonKeyValueRow[] | null>(null);\n const strengths = strengthsOverride ?? defaultStrengths;\n const weaknesses = weaknessesOverride ?? defaultWeaknesses;\n const pricingRows = pricingOverride ?? defaultPricingRows;\n const featuresRows = featuresOverride ?? defaultFeaturesRows;\n\n const fieldsValid =\n competitorListValid(strengths) &&\n competitorListValid(weaknesses) &&\n jsonRowsValid(pricingRows) &&\n jsonRowsValid(featuresRows);\n\n const handleSave = async () => {\n if (!competitor || !form.name.trim() || !fieldsValid) return;\n const tagList = (v: string) =>\n v\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const next: Record<string, unknown> = {\n name: form.name.trim(),\n website: form.website.trim() || null,\n description: form.description.trim() || null,\n tags: tagList(form.tags),\n };\n const before: Record<string, unknown> = {\n name: defaultForm.name,\n website: defaultForm.website.trim() || null,\n description: defaultForm.description.trim() || null,\n tags: tagList(defaultForm.tags),\n };\n // PRM-31 — only even considered once the user actually opened that editor and changed something: a\n // pricing/features value this editor cannot fully represent (a nested object/array — see jsonToRows) round-\n // trips through its rows as a flattened string, which must never go out as an unrequested side effect of\n // saving some other, unrelated field.\n if (strengthsOverride !== null) {\n next.strengths = cleanStringList(strengths);\n before.strengths = cleanStringList(defaultStrengths);\n }\n if (weaknessesOverride !== null) {\n next.weaknesses = cleanStringList(weaknesses);\n before.weaknesses = cleanStringList(defaultWeaknesses);\n }\n if (pricingOverride !== null) {\n next.pricing = jsonRowsToObject(pricingRows);\n before.pricing = competitor.pricing ?? null;\n }\n if (featuresOverride !== null) {\n next.features = jsonRowsToObject(featuresRows);\n before.features = competitor.features ?? null;\n }\n const input = Object.fromEntries(\n Object.entries(next).filter(([k, v]) => JSON.stringify(v) !== JSON.stringify(before[k]))\n );\n setSaveError(null);\n setSaved(false);\n if (Object.keys(input).length === 0) {\n setSaved(true);\n return;\n }\n try {\n await throwOnError(updateCompetitor({ variables: { id: competitorId, input } }));\n setSaved(true);\n } catch (e) {\n setSaveError(mutationErrorMessage(e, 'The competitor could not be saved.'));\n }\n };\n\n // Only before the first load: a refetch must not blank the page (it unmounts every component on it and\n // loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load competitor: {error.message}</div>;\n }\n\n if (!competitor) return <div className=\"p-6 text-muted-foreground\">Competitor 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\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Back to the competitor\"\n onClick={() => navigate(detailPath('/products/competitor-detail-page', competitorId))}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Edit Competitor</h1>\n <p className=\"text-sm text-muted-foreground\">{competitor.name}</p>\n </div>\n </div>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={saving || !form.name.trim() || !fieldsValid}\n >\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Save Changes\n </Button>\n </div>\n\n {saved && (\n <div role=\"status\" className=\"p-3 bg-muted text-status-success-text rounded-md text-sm\">\n Changes saved.\n </div>\n )}\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Competitor 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>\n <label className=\"text-sm font-medium\">Website</label>\n <Input\n value={form.website}\n onChange={(e) => setForm({ ...form, website: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description / Notes</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* PRM-31 */}\n <Card>\n <CardHeader>\n <CardTitle>Strengths &amp; Weaknesses</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <StringListEditor\n label=\"Strengths\"\n values={strengths}\n onChange={setStrengthsOverride}\n placeholder=\"e.g. Strong enterprise SSO\"\n testId=\"competitor-strengths\"\n />\n <StringListEditor\n label=\"Weaknesses\"\n values={weaknesses}\n onChange={setWeaknessesOverride}\n placeholder=\"e.g. No mobile app\"\n testId=\"competitor-weaknesses\"\n />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Pricing &amp; Feature Comparison</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <JsonKeyValueEditor\n label=\"Pricing\"\n rows={pricingRows}\n onChange={setPricingOverride}\n testId=\"competitor-pricing\"\n />\n <JsonKeyValueEditor\n label=\"Features\"\n rows={featuresRows}\n onChange={setFeaturesOverride}\n testId=\"competitor-features\"\n />\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PortfoliosPortfolioDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/PortfoliosPortfolioDetailPagePage.tsx"],"names":[],"mappings":"AA6EA,wBAAgB,iCAAiC,4CAmRhD"}
1
+ {"version":3,"file":"PortfoliosPortfolioDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/PortfoliosPortfolioDetailPagePage.tsx"],"names":[],"mappings":"AAkIA,wBAAgB,iCAAiC,4CAsXhD"}