@burdenoff/microfe-brainyrich 2026.705.1 → 2026.706.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/brainyrich/BrainyRichRoot.js +13 -13
  2. package/dist/brainyrich/components/ActorName.js +38 -0
  3. package/dist/brainyrich/components/ActorName.js.map +1 -0
  4. package/dist/brainyrich/components/ConfirmDialog.js +25 -0
  5. package/dist/brainyrich/components/ConfirmDialog.js.map +1 -0
  6. package/dist/brainyrich/components/LoadMore.js +24 -0
  7. package/dist/brainyrich/components/LoadMore.js.map +1 -0
  8. package/dist/brainyrich/components/index.js +5 -0
  9. package/dist/brainyrich/components/notify.js +38 -0
  10. package/dist/brainyrich/components/notify.js.map +1 -0
  11. package/dist/brainyrich/components/pickers.js +232 -0
  12. package/dist/brainyrich/components/pickers.js.map +1 -0
  13. package/dist/brainyrich/components/reuse/CommentThread.js +208 -0
  14. package/dist/brainyrich/components/reuse/CommentThread.js.map +1 -0
  15. package/dist/brainyrich/components/reuse/DocumentsPanel.js +237 -0
  16. package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -0
  17. package/dist/brainyrich/components/reuse/TagField.js +206 -0
  18. package/dist/brainyrich/components/reuse/TagField.js.map +1 -0
  19. package/dist/brainyrich/components/reuse/transport.js +24 -0
  20. package/dist/brainyrich/components/reuse/transport.js.map +1 -0
  21. package/dist/brainyrich/hooks/useBrainyRichApi.js +644 -372
  22. package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
  23. package/dist/brainyrich/pages/AccountsPage.js +346 -293
  24. package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
  25. package/dist/brainyrich/pages/AiAssistantPage.js +339 -320
  26. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  27. package/dist/brainyrich/pages/AnalyticsPage.js +178 -164
  28. package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
  29. package/dist/brainyrich/pages/DashboardPage.js +195 -169
  30. package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
  31. package/dist/brainyrich/pages/FamilyPage.js +247 -198
  32. package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
  33. package/dist/brainyrich/pages/GoalsPage.js +478 -442
  34. package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
  35. package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
  36. package/dist/brainyrich/pages/PortfoliosPage.js +438 -396
  37. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  38. package/dist/brainyrich/pages/ReportsPage.js +246 -213
  39. package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
  40. package/dist/brainyrich/pages/RiskPage.js +321 -173
  41. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  42. package/dist/brainyrich/pages/TaxPage.js +258 -225
  43. package/dist/brainyrich/pages/TaxPage.js.map +1 -1
  44. package/dist/brainyrich/pages/_shared.js.map +1 -1
  45. package/dist/node_modules/sonner/dist/index.js +163 -0
  46. package/dist/node_modules/sonner/dist/index.js.map +1 -0
  47. package/package.json +3 -2
@@ -1,11 +1,16 @@
1
- import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useDismissInsight as n, useInsights as r, usePortfolios as i, useRebalanceProposals as a, useResolveInsight as ee, useTransitionRebalanceProposal as te } from "../hooks/useBrainyRichApi.js";
2
- import { EmptyState as o, ErrorState as s, KpiGrid as ne, LoadingState as re, SectionShell as ie, formatDate as c, formatPct as l, statusBadgeVariant as u } from "./_shared.js";
1
+ import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useDismissInsight as n, usePagedInsights as r, usePortfolios as i, useRebalanceProposals as ee, useResolveInsight as te, useTransitionRebalanceProposal as ne } from "../hooks/useBrainyRichApi.js";
2
+ import { LoadMore as re } from "../components/LoadMore.js";
3
+ import { ConfirmDialog as ie } from "../components/ConfirmDialog.js";
4
+ import { ActorName as a } from "../components/ActorName.js";
5
+ import "../components/index.js";
6
+ import { EmptyState as o, ErrorState as ae, KpiGrid as oe, LoadingState as se, SectionShell as ce, formatDate as s, formatPct as c, statusBadgeVariant as l } from "./_shared.js";
7
+ import { CommentThread as u } from "../components/reuse/CommentThread.js";
3
8
  import { useMemo as d, useState as f } from "react";
4
- import { AlertTriangle as ae, ArrowRight as oe, Check as p, MoreHorizontal as m, Plus as se, Scale as h, ShieldAlert as ce, ShieldCheck as g, X as le } from "lucide-react";
5
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
6
- import { Badge as y, Button as b, Card as x, CardContent as S, CardDescription as C, CardHeader as w, CardTitle as T, Dialog as ue, DialogClose as de, DialogContent as fe, DialogDescription as pe, DialogFooter as me, DialogHeader as he, DialogTitle as ge, DropdownMenu as E, DropdownMenuContent as D, DropdownMenuItem as O, DropdownMenuLabel as _e, DropdownMenuSeparator as ve, DropdownMenuTrigger as k, Input as ye, Label as A, Select as be, SelectContent as xe, SelectItem as Se, SelectTrigger as Ce, SelectValue as we, Table as Te, TableBody as Ee, TableCell as j, TableHead as M, TableHeader as De, TableRow as N, Textarea as P } from "@burdenoff/fe-libs/ui";
9
+ import { AlertTriangle as le, ArrowRight as ue, Check as de, Eye as fe, MoreHorizontal as pe, Plus as me, Scale as p, ShieldAlert as he, ShieldCheck as ge, X as _e } from "lucide-react";
10
+ import { Fragment as ve, jsx as m, jsxs as h } from "react/jsx-runtime";
11
+ import { Badge as g, Button as _, Card as v, CardContent as y, CardDescription as b, CardHeader as x, CardTitle as S, Dialog as C, DialogClose as ye, DialogContent as w, DialogDescription as T, DialogFooter as be, DialogHeader as E, DialogTitle as D, DropdownMenu as O, DropdownMenuContent as k, DropdownMenuItem as A, DropdownMenuLabel as xe, DropdownMenuSeparator as Se, DropdownMenuTrigger as j, Input as Ce, Label as M, Select as we, SelectContent as Te, SelectItem as Ee, SelectTrigger as De, SelectValue as Oe, Table as ke, TableBody as Ae, TableCell as N, TableHead as P, TableHeader as je, TableRow as F, Textarea as I } from "@burdenoff/fe-libs/ui";
7
12
  //#region src/brainyrich/pages/RiskPage.tsx
8
- var Oe = {
13
+ var Me = {
9
14
  DRAFT: ["PROPOSED", "CANCELLED"],
10
15
  PROPOSED: [
11
16
  "APPROVED",
@@ -16,17 +21,17 @@ var Oe = {
16
21
  REJECTED: [],
17
22
  EXECUTED: [],
18
23
  CANCELLED: []
19
- }, ke = new Set([
24
+ }, Ne = new Set([
20
25
  "DRIFT",
21
26
  "CONCENTRATION_RISK",
22
27
  "REBALANCE_DUE",
23
28
  "CASH_DRAG",
24
29
  "FEE_ANOMALY"
25
30
  ]);
26
- function F(e) {
31
+ function L(e) {
27
32
  return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
28
33
  }
29
- function Ae(e) {
34
+ function R(e) {
30
35
  if (e == null) return "—";
31
36
  if (Array.isArray(e)) return `${e.length} trade${e.length === 1 ? "" : "s"}`;
32
37
  if (typeof e == "object") {
@@ -35,394 +40,537 @@ function Ae(e) {
35
40
  }
36
41
  return String(e);
37
42
  }
38
- var I = {
43
+ var Pe = {
39
44
  portfolioId: "",
40
45
  driftPct: "",
41
46
  rationale: "",
42
47
  trades: ""
43
48
  };
44
- function je(e) {
49
+ function Fe(e) {
45
50
  if (e.trim() === "") return;
46
51
  let t = Number(e);
47
52
  return Number.isFinite(t) ? t : void 0;
48
53
  }
49
- function L() {
50
- let { data: p, isLoading: L, isError: Ne, refetch: Pe } = a(), { data: R } = i(), { data: z, isLoading: Fe, isError: Ie, refetch: Le } = r(), B = t(), V = te(), H = e(), U = n(), W = ee(), [Re, G] = f(!1), [K, q] = f(I), [J, Y] = f(null), X = d(() => {
54
+ function Ie() {
55
+ let { data: a, isLoading: u, isError: de, refetch: Ie } = ee(), { data: z } = i(), { items: ze, hasMore: Be, loadMore: Ve, isLoading: He, isFetchingNextPage: Ue, isError: We, refetch: Ge } = r(), B = t(), V = ne(), Ke = e(), qe = n(), Je = te(), [Ye, H] = f(!1), [U, W] = f(Pe), [Xe, G] = f(null), [K, Ze] = f(null), [q, J] = f(null), Y = d(() => {
51
56
  let e = /* @__PURE__ */ new Map();
52
- for (let t of R) e.set(t.id, t);
57
+ for (let t of z) e.set(t.id, t);
53
58
  return e;
54
- }, [R]), Z = d(() => z.filter((e) => ke.has(e.type)), [z]), ze = p.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), Q = Z.filter((e) => e.status === "OPEN"), Be = p.length > 0 ? p.reduce((e, t) => e + (t.driftPct ?? 0), 0) / p.length : null, $ = R.length > 0;
55
- function Ve() {
56
- q(I), Y(null), G(!0);
59
+ }, [z]), X = d(() => ze.filter((e) => Ne.has(e.type)), [ze]), Qe = a.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), Z = X.filter((e) => e.status === "OPEN"), $e = a.length > 0 ? a.reduce((e, t) => e + (t.driftPct ?? 0), 0) / a.length : null, Q = z.length > 0;
60
+ function $() {
61
+ W(Pe), G(null), H(!0);
57
62
  }
58
- function He() {
59
- if (!K.portfolioId) return;
63
+ function et() {
64
+ if (!U.portfolioId) return;
60
65
  let e;
61
- if (K.trades.trim() !== "") try {
62
- e = JSON.parse(K.trades);
66
+ if (U.trades.trim() !== "") try {
67
+ e = JSON.parse(U.trades);
63
68
  } catch {
64
- Y("Trades must be valid JSON.");
69
+ G("Trades must be valid JSON.");
65
70
  return;
66
71
  }
67
- let t = X.get(K.portfolioId);
72
+ let t = Y.get(U.portfolioId);
68
73
  B.mutate({
69
- portfolioId: K.portfolioId,
74
+ portfolioId: U.portfolioId,
70
75
  householdId: t?.householdId ?? null,
71
- driftPct: je(K.driftPct),
72
- rationale: K.rationale.trim() || null,
76
+ driftPct: Fe(U.driftPct),
77
+ rationale: U.rationale.trim() || null,
73
78
  ...e === void 0 ? {} : { trades: e }
74
- }, { onSuccess: () => G(!1) });
79
+ }, { onSuccess: () => H(!1) });
75
80
  }
76
- function Ue(e) {
77
- let t = X.get(e.portfolioId)?.driftThresholdPct;
81
+ function tt(e, t) {
82
+ if (t === "REJECTED" || t === "CANCELLED") {
83
+ J({
84
+ proposal: e,
85
+ status: t
86
+ });
87
+ return;
88
+ }
89
+ V.mutate({
90
+ id: e.id,
91
+ status: t
92
+ });
93
+ }
94
+ function nt(e) {
95
+ let t = Y.get(e.portfolioId)?.driftThresholdPct;
78
96
  return t != null && Number.isFinite(t) && e.driftPct >= t;
79
97
  }
80
- return /* @__PURE__ */ v(ie, {
98
+ return /* @__PURE__ */ h(ce, {
81
99
  title: "Risk & Rebalancing",
82
100
  description: "Review drift-driven rebalance proposals and act on portfolio risk insights.",
83
- badges: [`${ze.length} active`, `${Q.length} open insight${Q.length === 1 ? "" : "s"}`],
101
+ badges: [`${Qe.length} active`, `${Z.length} open insight${Z.length === 1 ? "" : "s"}`],
84
102
  actionLabel: "New proposal",
85
- onAction: Ve,
103
+ onAction: $,
86
104
  children: [
87
- /* @__PURE__ */ _(ne, { items: [
105
+ /* @__PURE__ */ m(oe, { items: [
88
106
  {
89
107
  label: "Total proposals",
90
- value: String(p.length)
108
+ value: String(a.length)
91
109
  },
92
110
  {
93
111
  label: "Active proposals",
94
- value: String(ze.length)
112
+ value: String(Qe.length)
95
113
  },
96
114
  {
97
115
  label: "Average drift",
98
- value: Be === null ? "—" : l(Be)
116
+ value: $e === null ? "—" : c($e)
99
117
  },
100
118
  {
101
119
  label: "Open risk insights",
102
- value: String(Q.length)
120
+ value: String(Z.length)
103
121
  }
104
122
  ] }),
105
- /* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
123
+ /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ h(S, {
106
124
  className: "flex items-center gap-2",
107
- children: [/* @__PURE__ */ _(h, {
125
+ children: [/* @__PURE__ */ m(p, {
108
126
  className: "h-5 w-5",
109
127
  "aria-hidden": "true"
110
128
  }), "Rebalance proposals"]
111
- }), /* @__PURE__ */ _(C, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ _(S, { children: L ? /* @__PURE__ */ _(re, {}) : Ne ? /* @__PURE__ */ _(s, { onRetry: () => Pe() }) : p.length === 0 ? /* @__PURE__ */ _(o, {
112
- icon: /* @__PURE__ */ _(h, {
129
+ }), /* @__PURE__ */ m(b, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ m(y, { children: u ? /* @__PURE__ */ m(se, {}) : de ? /* @__PURE__ */ m(ae, { onRetry: () => Ie() }) : a.length === 0 ? /* @__PURE__ */ m(o, {
130
+ icon: /* @__PURE__ */ m(p, {
113
131
  className: "size-6",
114
132
  "aria-hidden": "true"
115
133
  }),
116
134
  title: "No rebalance proposals",
117
- description: $ ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
118
- action: $ ? /* @__PURE__ */ v(b, {
135
+ description: Q ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
136
+ action: Q ? /* @__PURE__ */ h(_, {
119
137
  size: "sm",
120
- onClick: Ve,
121
- children: [/* @__PURE__ */ _(se, {
138
+ onClick: $,
139
+ children: [/* @__PURE__ */ m(me, {
122
140
  className: "size-4",
123
141
  "aria-hidden": "true"
124
142
  }), "New proposal"]
125
143
  }) : void 0
126
- }) : /* @__PURE__ */ _("div", {
144
+ }) : /* @__PURE__ */ m("div", {
127
145
  className: "overflow-x-auto",
128
- children: /* @__PURE__ */ v(Te, { children: [/* @__PURE__ */ _(De, { children: /* @__PURE__ */ v(N, { children: [
129
- /* @__PURE__ */ _(M, { children: "Portfolio" }),
130
- /* @__PURE__ */ _(M, {
146
+ children: /* @__PURE__ */ h(ke, { children: [/* @__PURE__ */ m(je, { children: /* @__PURE__ */ h(F, { children: [
147
+ /* @__PURE__ */ m(P, { children: "Portfolio" }),
148
+ /* @__PURE__ */ m(P, {
131
149
  className: "text-right",
132
150
  children: "Drift"
133
151
  }),
134
- /* @__PURE__ */ _(M, { children: "Status" }),
135
- /* @__PURE__ */ _(M, { children: "Rationale" }),
136
- /* @__PURE__ */ _(M, { children: "Trades" }),
137
- /* @__PURE__ */ _(M, { children: "Created" }),
138
- /* @__PURE__ */ _(M, {
152
+ /* @__PURE__ */ m(P, { children: "Status" }),
153
+ /* @__PURE__ */ m(P, { children: "Rationale" }),
154
+ /* @__PURE__ */ m(P, { children: "Trades" }),
155
+ /* @__PURE__ */ m(P, { children: "Created" }),
156
+ /* @__PURE__ */ m(P, {
139
157
  className: "w-12 text-right",
140
158
  children: "Actions"
141
159
  })
142
- ] }) }), /* @__PURE__ */ _(Ee, { children: p.map((e) => {
143
- let t = X.get(e.portfolioId), n = Ue(e), r = Oe[e.status];
144
- return /* @__PURE__ */ v(N, { children: [
145
- /* @__PURE__ */ v(j, { children: [/* @__PURE__ */ _("p", {
160
+ ] }) }), /* @__PURE__ */ m(Ae, { children: a.map((e) => {
161
+ let t = Y.get(e.portfolioId), n = nt(e), r = Me[e.status];
162
+ return /* @__PURE__ */ h(F, { children: [
163
+ /* @__PURE__ */ h(N, { children: [/* @__PURE__ */ m("p", {
146
164
  className: "font-medium text-text-primary",
147
165
  children: t?.name ?? "Unknown portfolio"
148
- }), /* @__PURE__ */ v("p", {
166
+ }), /* @__PURE__ */ h("p", {
149
167
  className: "text-xs text-text-secondary",
150
- children: [t?.baseCurrency ?? "—", t?.driftThresholdPct == null ? "" : ` · threshold ${l(t.driftThresholdPct)}`]
168
+ children: [t?.baseCurrency ?? "—", t?.driftThresholdPct == null ? "" : ` · threshold ${c(t.driftThresholdPct)}`]
151
169
  })] }),
152
- /* @__PURE__ */ v(j, {
170
+ /* @__PURE__ */ h(N, {
153
171
  className: "text-right",
154
- children: [/* @__PURE__ */ v("span", {
172
+ children: [/* @__PURE__ */ h("span", {
155
173
  className: `inline-flex items-center justify-end gap-1 font-semibold ${n ? "text-status-error-text" : "text-text-primary"}`,
156
- children: [n ? /* @__PURE__ */ _(ae, {
174
+ children: [n ? /* @__PURE__ */ m(le, {
157
175
  className: "size-4",
158
176
  "aria-hidden": "true"
159
- }) : null, l(e.driftPct)]
160
- }), n ? /* @__PURE__ */ _("p", {
177
+ }) : null, c(e.driftPct)]
178
+ }), n ? /* @__PURE__ */ m("p", {
161
179
  className: "text-xs text-status-error-text",
162
180
  children: "Over threshold"
163
181
  }) : null]
164
182
  }),
165
- /* @__PURE__ */ _(j, { children: /* @__PURE__ */ _(y, {
166
- variant: u(e.status),
167
- children: F(e.status)
183
+ /* @__PURE__ */ m(N, { children: /* @__PURE__ */ m(g, {
184
+ variant: l(e.status),
185
+ children: L(e.status)
168
186
  }) }),
169
- /* @__PURE__ */ _(j, {
187
+ /* @__PURE__ */ m(N, {
170
188
  className: "max-w-xs",
171
- children: /* @__PURE__ */ _("p", {
189
+ children: /* @__PURE__ */ m("p", {
172
190
  className: "truncate text-sm text-text-secondary",
173
191
  children: e.rationale ?? "—"
174
192
  })
175
193
  }),
176
- /* @__PURE__ */ _(j, {
194
+ /* @__PURE__ */ m(N, {
177
195
  className: "text-sm text-text-secondary",
178
- children: Ae(e.trades)
196
+ children: R(e.trades)
179
197
  }),
180
- /* @__PURE__ */ _(j, {
198
+ /* @__PURE__ */ m(N, {
181
199
  className: "text-sm text-text-secondary",
182
- children: c(e.createdAt)
200
+ children: s(e.createdAt)
183
201
  }),
184
- /* @__PURE__ */ _(j, {
202
+ /* @__PURE__ */ m(N, {
185
203
  className: "text-right",
186
- children: r.length === 0 ? /* @__PURE__ */ _("span", {
187
- className: "text-xs text-text-muted",
188
- children: "—"
189
- }) : /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(k, {
204
+ children: /* @__PURE__ */ h(O, { children: [/* @__PURE__ */ m(j, {
190
205
  asChild: !0,
191
- children: /* @__PURE__ */ _(b, {
206
+ children: /* @__PURE__ */ m(_, {
192
207
  variant: "ghost",
193
208
  size: "sm",
194
- "aria-label": `Lifecycle actions for ${t?.name ?? "proposal"}`,
195
- children: /* @__PURE__ */ _(m, {
209
+ "aria-label": `Actions for ${t?.name ?? "proposal"}`,
210
+ children: /* @__PURE__ */ m(pe, {
196
211
  className: "size-4",
197
212
  "aria-hidden": "true"
198
213
  })
199
214
  })
200
- }), /* @__PURE__ */ v(D, {
215
+ }), /* @__PURE__ */ h(k, {
201
216
  align: "end",
202
- children: [
203
- /* @__PURE__ */ _(_e, { children: "Advance to" }),
204
- /* @__PURE__ */ _(ve, {}),
217
+ children: [/* @__PURE__ */ h(A, {
218
+ onClick: () => Ze(e),
219
+ children: [/* @__PURE__ */ m(fe, {
220
+ className: "size-4",
221
+ "aria-hidden": "true"
222
+ }), "View details"]
223
+ }), r.length > 0 ? /* @__PURE__ */ h(ve, { children: [
224
+ /* @__PURE__ */ m(Se, {}),
225
+ /* @__PURE__ */ m(xe, { children: "Advance to" }),
205
226
  r.map((t) => {
206
227
  let n = t === "REJECTED" || t === "CANCELLED";
207
- return /* @__PURE__ */ v(O, {
228
+ return /* @__PURE__ */ h(A, {
208
229
  disabled: V.isPending,
209
230
  className: n ? "text-status-error-text" : void 0,
210
- onClick: () => V.mutate({
211
- id: e.id,
212
- status: t
213
- }),
214
- children: [_(n ? le : oe, {
231
+ onClick: () => tt(e, t),
232
+ children: [m(n ? _e : ue, {
215
233
  className: "size-4",
216
234
  "aria-hidden": "true"
217
- }), F(t)]
235
+ }), L(t)]
218
236
  }, t);
219
237
  })
220
- ]
238
+ ] }) : null]
221
239
  })] })
222
240
  })
223
241
  ] }, e.id);
224
242
  }) })] })
225
243
  }) })] }),
226
- /* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
244
+ /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ h(S, {
227
245
  className: "flex items-center gap-2",
228
- children: [/* @__PURE__ */ _(ce, {
246
+ children: [/* @__PURE__ */ m(he, {
229
247
  className: "h-5 w-5",
230
248
  "aria-hidden": "true"
231
249
  }), "Risk insights"]
232
- }), /* @__PURE__ */ _(C, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ _(S, { children: Fe ? /* @__PURE__ */ _(re, {}) : Ie ? /* @__PURE__ */ _(s, { onRetry: () => Le() }) : Z.length === 0 ? /* @__PURE__ */ _(o, {
233
- icon: /* @__PURE__ */ _(g, {
250
+ }), /* @__PURE__ */ m(b, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ m(y, { children: He ? /* @__PURE__ */ m(se, {}) : We ? /* @__PURE__ */ m(ae, { onRetry: () => Ge() }) : X.length === 0 ? /* @__PURE__ */ m(o, {
251
+ icon: /* @__PURE__ */ m(ge, {
234
252
  className: "size-6",
235
253
  "aria-hidden": "true"
236
254
  }),
237
255
  title: "No risk insights",
238
256
  description: "No drift, concentration, cash-drag or fee-anomaly signals are open right now."
239
- }) : /* @__PURE__ */ _("div", {
257
+ }) : /* @__PURE__ */ h("div", {
240
258
  className: "space-y-3",
241
- children: Z.map((e) => /* @__PURE__ */ _(Me, {
259
+ children: [X.map((e) => /* @__PURE__ */ m(Re, {
242
260
  insight: e,
243
- onAcknowledge: () => H.mutate(e.id),
244
- onResolve: () => W.mutate(e.id),
245
- onDismiss: () => U.mutate(e.id),
246
- actionPending: H.isPending || W.isPending || U.isPending
247
- }, e.id))
261
+ onAcknowledge: () => Ke.mutate(e.id),
262
+ onResolve: () => Je.mutate(e.id),
263
+ onDismiss: () => qe.mutate(e.id),
264
+ actionPending: Ke.isPending || Je.isPending || qe.isPending
265
+ }, e.id)), /* @__PURE__ */ m(re, {
266
+ hasMore: Be,
267
+ onClick: Ve,
268
+ loading: Ue,
269
+ label: "Load more insights"
270
+ })]
248
271
  }) })] }),
249
- /* @__PURE__ */ _(ue, {
250
- open: Re,
251
- onOpenChange: G,
252
- children: /* @__PURE__ */ v(fe, { children: [
253
- /* @__PURE__ */ v(he, { children: [/* @__PURE__ */ _(ge, { children: "New rebalance proposal" }), /* @__PURE__ */ _(pe, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
254
- $ ? /* @__PURE__ */ v("div", {
272
+ /* @__PURE__ */ m(C, {
273
+ open: Ye,
274
+ onOpenChange: H,
275
+ children: /* @__PURE__ */ h(w, { children: [
276
+ /* @__PURE__ */ h(E, { children: [/* @__PURE__ */ m(D, { children: "New rebalance proposal" }), /* @__PURE__ */ m(T, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
277
+ Q ? /* @__PURE__ */ h("div", {
255
278
  className: "grid gap-4",
256
279
  children: [
257
- /* @__PURE__ */ v("div", {
280
+ /* @__PURE__ */ h("div", {
258
281
  className: "space-y-2",
259
- children: [/* @__PURE__ */ _(A, {
282
+ children: [/* @__PURE__ */ m(M, {
260
283
  htmlFor: "prop-portfolio",
261
284
  children: "Portfolio"
262
- }), /* @__PURE__ */ v(be, {
263
- value: K.portfolioId,
264
- onValueChange: (e) => q((t) => ({
285
+ }), /* @__PURE__ */ h(we, {
286
+ value: U.portfolioId,
287
+ onValueChange: (e) => W((t) => ({
265
288
  ...t,
266
289
  portfolioId: e
267
290
  })),
268
- children: [/* @__PURE__ */ _(Ce, {
291
+ children: [/* @__PURE__ */ m(De, {
269
292
  id: "prop-portfolio",
270
- children: /* @__PURE__ */ _(we, { placeholder: "Select a portfolio" })
271
- }), /* @__PURE__ */ _(xe, { children: R.map((e) => /* @__PURE__ */ _(Se, {
293
+ children: /* @__PURE__ */ m(Oe, { placeholder: "Select a portfolio" })
294
+ }), /* @__PURE__ */ m(Te, { children: z.map((e) => /* @__PURE__ */ m(Ee, {
272
295
  value: e.id,
273
296
  children: e.name
274
297
  }, e.id)) })]
275
298
  })]
276
299
  }),
277
- /* @__PURE__ */ v("div", {
300
+ /* @__PURE__ */ h("div", {
278
301
  className: "space-y-2",
279
- children: [/* @__PURE__ */ _(A, {
302
+ children: [/* @__PURE__ */ m(M, {
280
303
  htmlFor: "prop-drift",
281
304
  children: "Drift %"
282
- }), /* @__PURE__ */ _(ye, {
305
+ }), /* @__PURE__ */ m(Ce, {
283
306
  id: "prop-drift",
284
307
  type: "number",
285
- value: K.driftPct,
286
- onChange: (e) => q((t) => ({
308
+ value: U.driftPct,
309
+ onChange: (e) => W((t) => ({
287
310
  ...t,
288
311
  driftPct: e.target.value
289
312
  })),
290
313
  placeholder: "e.g. 6.5"
291
314
  })]
292
315
  }),
293
- /* @__PURE__ */ v("div", {
316
+ /* @__PURE__ */ h("div", {
294
317
  className: "space-y-2",
295
- children: [/* @__PURE__ */ _(A, {
318
+ children: [/* @__PURE__ */ m(M, {
296
319
  htmlFor: "prop-rationale",
297
320
  children: "Rationale"
298
- }), /* @__PURE__ */ _(P, {
321
+ }), /* @__PURE__ */ m(I, {
299
322
  id: "prop-rationale",
300
- value: K.rationale,
301
- onChange: (e) => q((t) => ({
323
+ value: U.rationale,
324
+ onChange: (e) => W((t) => ({
302
325
  ...t,
303
326
  rationale: e.target.value
304
327
  })),
305
328
  placeholder: "Why is this rebalance needed?"
306
329
  })]
307
330
  }),
308
- /* @__PURE__ */ v("div", {
331
+ /* @__PURE__ */ h("div", {
309
332
  className: "space-y-2",
310
333
  children: [
311
- /* @__PURE__ */ _(A, {
334
+ /* @__PURE__ */ m(M, {
312
335
  htmlFor: "prop-trades",
313
336
  children: "Trades (JSON, optional)"
314
337
  }),
315
- /* @__PURE__ */ _(P, {
338
+ /* @__PURE__ */ m(I, {
316
339
  id: "prop-trades",
317
- value: K.trades,
340
+ value: U.trades,
318
341
  onChange: (e) => {
319
- Y(null), q((t) => ({
342
+ G(null), W((t) => ({
320
343
  ...t,
321
344
  trades: e.target.value
322
345
  }));
323
346
  },
324
347
  placeholder: "e.g. [{\"symbol\":\"VOO\",\"action\":\"SELL\",\"quantity\":10}]"
325
348
  }),
326
- J ? /* @__PURE__ */ _("p", {
349
+ Xe ? /* @__PURE__ */ m("p", {
327
350
  className: "text-xs text-status-error-text",
328
- children: J
351
+ children: Xe
329
352
  }) : null
330
353
  ]
331
354
  })
332
355
  ]
333
- }) : /* @__PURE__ */ _(o, {
334
- title: "No portfolios available",
335
- description: "Create a portfolio before proposing a rebalance."
356
+ }) : /* @__PURE__ */ m(o, {
357
+ icon: /* @__PURE__ */ m(p, {
358
+ className: "size-6",
359
+ "aria-hidden": "true"
360
+ }),
361
+ title: "Create a portfolio first",
362
+ description: "A rebalance proposal targets a portfolio. Add a portfolio on the Portfolios page, then return here to propose a rebalance."
336
363
  }),
337
- /* @__PURE__ */ v(me, { children: [/* @__PURE__ */ _(de, {
364
+ /* @__PURE__ */ h(be, { children: [/* @__PURE__ */ m(ye, {
338
365
  asChild: !0,
339
- children: /* @__PURE__ */ _(b, {
366
+ children: /* @__PURE__ */ m(_, {
340
367
  variant: "outline",
341
368
  children: "Cancel"
342
369
  })
343
- }), /* @__PURE__ */ _(b, {
344
- onClick: He,
345
- disabled: !K.portfolioId || B.isPending,
370
+ }), /* @__PURE__ */ m(_, {
371
+ onClick: et,
372
+ disabled: !U.portfolioId || B.isPending,
346
373
  children: B.isPending ? "Creating…" : "Create proposal"
347
374
  })] })
348
375
  ] })
376
+ }),
377
+ /* @__PURE__ */ m(Le, {
378
+ proposal: K,
379
+ portfolio: K ? Y.get(K.portfolioId) ?? null : null,
380
+ onOpenChange: (e) => {
381
+ e || Ze(null);
382
+ }
383
+ }),
384
+ /* @__PURE__ */ m(ie, {
385
+ open: q !== null,
386
+ onOpenChange: (e) => {
387
+ e || J(null);
388
+ },
389
+ title: q?.status === "REJECTED" ? "Reject this proposal?" : "Cancel this proposal?",
390
+ description: q ? `This moves the rebalance proposal for ${Y.get(q.proposal.portfolioId)?.name ?? "this portfolio"} to ${L(q.status)}. This cannot be undone.` : void 0,
391
+ confirmLabel: q?.status === "REJECTED" ? "Reject" : "Cancel proposal",
392
+ cancelLabel: "Keep",
393
+ destructive: !0,
394
+ pending: V.isPending,
395
+ onConfirm: () => {
396
+ q && V.mutate({
397
+ id: q.proposal.id,
398
+ status: q.status
399
+ }, { onSuccess: () => J(null) });
400
+ }
349
401
  })
350
402
  ]
351
403
  });
352
404
  }
353
- function Me({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
354
- let a = e.status === "RESOLVED" || e.status === "DISMISSED";
355
- return /* @__PURE__ */ v("div", {
405
+ function Le({ proposal: e, portfolio: t, onOpenChange: n }) {
406
+ return /* @__PURE__ */ m(C, {
407
+ open: e !== null,
408
+ onOpenChange: n,
409
+ children: /* @__PURE__ */ m(w, {
410
+ className: "max-h-[85vh] overflow-y-auto",
411
+ children: e ? /* @__PURE__ */ h(ve, { children: [
412
+ /* @__PURE__ */ h(E, { children: [/* @__PURE__ */ h(D, {
413
+ className: "flex flex-wrap items-center gap-2",
414
+ children: [t?.name ?? "Rebalance proposal", /* @__PURE__ */ m(g, {
415
+ variant: l(e.status),
416
+ children: L(e.status)
417
+ })]
418
+ }), /* @__PURE__ */ h(T, { children: [
419
+ "Drift ",
420
+ c(e.driftPct),
421
+ t?.driftThresholdPct == null ? "" : ` · threshold ${c(t.driftThresholdPct)}`,
422
+ " · created ",
423
+ s(e.createdAt)
424
+ ] })] }),
425
+ /* @__PURE__ */ h("dl", {
426
+ className: "grid grid-cols-2 gap-4 text-sm",
427
+ children: [
428
+ /* @__PURE__ */ h("div", {
429
+ className: "space-y-1",
430
+ children: [/* @__PURE__ */ m("dt", {
431
+ className: "text-xs font-medium text-text-muted",
432
+ children: "Proposed by"
433
+ }), /* @__PURE__ */ m("dd", {
434
+ className: "text-text-primary",
435
+ children: e.proposedById ? /* @__PURE__ */ m(a, { id: e.proposedById }) : /* @__PURE__ */ m("span", {
436
+ className: "text-text-muted",
437
+ children: "—"
438
+ })
439
+ })]
440
+ }),
441
+ /* @__PURE__ */ h("div", {
442
+ className: "space-y-1",
443
+ children: [/* @__PURE__ */ m("dt", {
444
+ className: "text-xs font-medium text-text-muted",
445
+ children: "Approved by"
446
+ }), /* @__PURE__ */ m("dd", {
447
+ className: "text-text-primary",
448
+ children: e.approvedById ? /* @__PURE__ */ m(a, { id: e.approvedById }) : /* @__PURE__ */ m("span", {
449
+ className: "text-text-muted",
450
+ children: "—"
451
+ })
452
+ })]
453
+ }),
454
+ /* @__PURE__ */ h("div", {
455
+ className: "space-y-1",
456
+ children: [/* @__PURE__ */ m("dt", {
457
+ className: "text-xs font-medium text-text-muted",
458
+ children: "Trades"
459
+ }), /* @__PURE__ */ m("dd", {
460
+ className: "text-text-primary",
461
+ children: R(e.trades)
462
+ })]
463
+ }),
464
+ /* @__PURE__ */ h("div", {
465
+ className: "space-y-1",
466
+ children: [/* @__PURE__ */ m("dt", {
467
+ className: "text-xs font-medium text-text-muted",
468
+ children: "Executed"
469
+ }), /* @__PURE__ */ m("dd", {
470
+ className: "text-text-primary",
471
+ children: e.executedAt ? s(e.executedAt) : /* @__PURE__ */ m("span", {
472
+ className: "text-text-muted",
473
+ children: "—"
474
+ })
475
+ })]
476
+ })
477
+ ]
478
+ }),
479
+ /* @__PURE__ */ h("div", {
480
+ className: "space-y-1",
481
+ children: [/* @__PURE__ */ m("p", {
482
+ className: "text-xs font-medium text-text-muted",
483
+ children: "Rationale (summary)"
484
+ }), /* @__PURE__ */ m("p", {
485
+ className: "text-sm text-text-secondary",
486
+ children: e.rationale ?? "—"
487
+ })]
488
+ }),
489
+ /* @__PURE__ */ m("div", {
490
+ className: "border-t border-border-subtle pt-4",
491
+ children: /* @__PURE__ */ m(u, {
492
+ entityType: "brainyrich-rebalance",
493
+ entityId: e.id,
494
+ heading: "Discussion"
495
+ })
496
+ })
497
+ ] }) : null
498
+ })
499
+ });
500
+ }
501
+ function Re({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
502
+ let ee = e.status === "RESOLVED" || e.status === "DISMISSED";
503
+ return /* @__PURE__ */ h("div", {
356
504
  className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4",
357
- children: [/* @__PURE__ */ v("div", {
505
+ children: [/* @__PURE__ */ h("div", {
358
506
  className: "min-w-0 space-y-1",
359
507
  children: [
360
- /* @__PURE__ */ v("div", {
508
+ /* @__PURE__ */ h("div", {
361
509
  className: "flex flex-wrap items-center gap-2",
362
510
  children: [
363
- /* @__PURE__ */ _("p", {
511
+ /* @__PURE__ */ m("p", {
364
512
  className: "font-medium text-text-primary",
365
513
  children: e.title
366
514
  }),
367
- /* @__PURE__ */ _(y, {
368
- variant: u(e.severity),
369
- children: F(e.severity)
515
+ /* @__PURE__ */ m(g, {
516
+ variant: l(e.severity),
517
+ children: L(e.severity)
370
518
  }),
371
- /* @__PURE__ */ _(y, {
519
+ /* @__PURE__ */ m(g, {
372
520
  variant: "outline",
373
- children: F(e.type)
521
+ children: L(e.type)
374
522
  }),
375
- /* @__PURE__ */ _(y, {
376
- variant: u(e.status),
377
- children: F(e.status)
523
+ /* @__PURE__ */ m(g, {
524
+ variant: l(e.status),
525
+ children: L(e.status)
378
526
  })
379
527
  ]
380
528
  }),
381
- e.detail ? /* @__PURE__ */ _("p", {
529
+ e.detail ? /* @__PURE__ */ m("p", {
382
530
  className: "text-sm text-text-secondary",
383
531
  children: e.detail
384
532
  }) : null,
385
- /* @__PURE__ */ v("p", {
533
+ /* @__PURE__ */ h("p", {
386
534
  className: "text-xs text-text-muted",
387
- children: ["Detected ", c(e.createdAt)]
535
+ children: ["Detected ", s(e.createdAt)]
388
536
  })
389
537
  ]
390
- }), a ? /* @__PURE__ */ _("span", {
538
+ }), ee ? /* @__PURE__ */ m("span", {
391
539
  className: "mt-1 text-xs text-text-muted",
392
540
  children: "Closed"
393
- }) : /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(k, {
541
+ }) : /* @__PURE__ */ h(O, { children: [/* @__PURE__ */ m(j, {
394
542
  asChild: !0,
395
- children: /* @__PURE__ */ _(b, {
543
+ children: /* @__PURE__ */ m(_, {
396
544
  variant: "ghost",
397
545
  size: "sm",
398
546
  "aria-label": `Actions for ${e.title}`,
399
547
  disabled: i,
400
- children: /* @__PURE__ */ _(m, {
548
+ children: /* @__PURE__ */ m(pe, {
401
549
  className: "size-4",
402
550
  "aria-hidden": "true"
403
551
  })
404
552
  })
405
- }), /* @__PURE__ */ v(D, {
553
+ }), /* @__PURE__ */ h(k, {
406
554
  align: "end",
407
555
  children: [
408
- e.status === "OPEN" ? /* @__PURE__ */ v(O, {
556
+ e.status === "OPEN" ? /* @__PURE__ */ h(A, {
409
557
  onClick: t,
410
- children: [/* @__PURE__ */ _(p, {
558
+ children: [/* @__PURE__ */ m(de, {
411
559
  className: "size-4",
412
560
  "aria-hidden": "true"
413
561
  }), "Acknowledge"]
414
562
  }) : null,
415
- /* @__PURE__ */ v(O, {
563
+ /* @__PURE__ */ h(A, {
416
564
  onClick: n,
417
- children: [/* @__PURE__ */ _(g, {
565
+ children: [/* @__PURE__ */ m(ge, {
418
566
  className: "size-4",
419
567
  "aria-hidden": "true"
420
568
  }), "Resolve"]
421
569
  }),
422
- /* @__PURE__ */ v(O, {
570
+ /* @__PURE__ */ h(A, {
423
571
  className: "text-status-error-text",
424
572
  onClick: r,
425
- children: [/* @__PURE__ */ _(le, {
573
+ children: [/* @__PURE__ */ m(_e, {
426
574
  className: "size-4",
427
575
  "aria-hidden": "true"
428
576
  }), "Dismiss"]
@@ -432,6 +580,6 @@ function Me({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPe
432
580
  });
433
581
  }
434
582
  //#endregion
435
- export { L as RiskPage };
583
+ export { Ie as RiskPage };
436
584
 
437
585
  //# sourceMappingURL=RiskPage.js.map