@burdenoff/microfe-brainyrich 2026.512.1 → 2026.705.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brainyrich/BrainyRichRoot.js +53 -88
- package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
- package/dist/brainyrich/BrainyRichRoutes.js +15 -35
- package/dist/brainyrich/BrainyRichRoutes.js.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.js +543 -0
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -0
- package/dist/brainyrich/index.js +0 -1
- package/dist/brainyrich/pages/AccountsPage.js +690 -160
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +537 -363
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js +587 -268
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/DashboardPage.js +350 -232
- package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
- package/dist/brainyrich/pages/FamilyPage.js +550 -337
- package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
- package/dist/brainyrich/pages/GoalsPage.js +775 -142
- package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
- package/dist/brainyrich/pages/InvestmentsPage.js +410 -311
- package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +823 -154
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js +388 -251
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +411 -196
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js +622 -221
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.js +222 -41
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/dist/brainyrich/BrainyRichRoot.d.ts +0 -5
- package/dist/brainyrich/BrainyRichRoot.d.ts.map +0 -1
- package/dist/brainyrich/BrainyRichRoutes.d.ts +0 -2
- package/dist/brainyrich/BrainyRichRoutes.d.ts.map +0 -1
- package/dist/brainyrich/index.d.ts +0 -5
- package/dist/brainyrich/index.d.ts.map +0 -1
- package/dist/brainyrich/pages/AccountsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AccountsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AdvisorsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AdvisorsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AdvisorsPage.js +0 -375
- package/dist/brainyrich/pages/AdvisorsPage.js.map +0 -1
- package/dist/brainyrich/pages/AiAssistantPage.d.ts +0 -2
- package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AnalyticsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AnalyticsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AssistantPage.d.ts +0 -2
- package/dist/brainyrich/pages/AssistantPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AssistantPage.js +0 -332
- package/dist/brainyrich/pages/AssistantPage.js.map +0 -1
- package/dist/brainyrich/pages/DashboardPage.d.ts +0 -2
- package/dist/brainyrich/pages/DashboardPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/EstatePage.d.ts +0 -2
- package/dist/brainyrich/pages/EstatePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/EstatePage.js +0 -269
- package/dist/brainyrich/pages/EstatePage.js.map +0 -1
- package/dist/brainyrich/pages/FamilyPage.d.ts +0 -2
- package/dist/brainyrich/pages/FamilyPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/GoalsPage.d.ts +0 -2
- package/dist/brainyrich/pages/GoalsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/InsurancePage.d.ts +0 -2
- package/dist/brainyrich/pages/InsurancePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/InsurancePage.js +0 -181
- package/dist/brainyrich/pages/InsurancePage.js.map +0 -1
- package/dist/brainyrich/pages/InvestmentsPage.d.ts +0 -2
- package/dist/brainyrich/pages/InvestmentsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/MarketplacePage.d.ts +0 -2
- package/dist/brainyrich/pages/MarketplacePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/MarketplacePage.js +0 -450
- package/dist/brainyrich/pages/MarketplacePage.js.map +0 -1
- package/dist/brainyrich/pages/PortfoliosPage.d.ts +0 -2
- package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/ReportsPage.d.ts +0 -2
- package/dist/brainyrich/pages/ReportsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/RiskPage.d.ts +0 -2
- package/dist/brainyrich/pages/RiskPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/TaxPage.d.ts +0 -2
- package/dist/brainyrich/pages/TaxPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/_shared.d.ts +0 -21
- package/dist/brainyrich/pages/_shared.d.ts.map +0 -1
- package/dist/brainyrich/providers/BrainyRichProvider.d.ts +0 -6
- package/dist/brainyrich/providers/BrainyRichProvider.d.ts.map +0 -1
- package/dist/brainyrich/store/brainyrichStore.d.ts +0 -19
- package/dist/brainyrich/store/brainyrichStore.d.ts.map +0 -1
- package/dist/brainyrich/store/brainyrichStore.js +0 -272
- package/dist/brainyrich/store/brainyrichStore.js.map +0 -1
- package/dist/brainyrich/types/index.d.ts +0 -116
- package/dist/brainyrich/types/index.d.ts.map +0 -1
- package/dist/brainyrich/utils/cn.d.ts +0 -4
- package/dist/brainyrich/utils/cn.d.ts.map +0 -1
- package/dist/brainyrich/utils/i18n.d.ts +0 -6
- package/dist/brainyrich/utils/i18n.d.ts.map +0 -1
- package/dist/brainyrich/utils/navigation.d.ts +0 -2
- package/dist/brainyrich/utils/navigation.d.ts.map +0 -1
- package/dist/dev/main.d.ts +0 -2
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts +0 -2
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts +0 -18199
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts +0 -2
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts +0 -43046
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
|
@@ -1,222 +1,437 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { KpiGrid as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
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";
|
|
3
|
+
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";
|
|
6
7
|
//#region src/brainyrich/pages/RiskPage.tsx
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
8
|
+
var Oe = {
|
|
9
|
+
DRAFT: ["PROPOSED", "CANCELLED"],
|
|
10
|
+
PROPOSED: [
|
|
11
|
+
"APPROVED",
|
|
12
|
+
"REJECTED",
|
|
13
|
+
"CANCELLED"
|
|
14
|
+
],
|
|
15
|
+
APPROVED: ["EXECUTED", "CANCELLED"],
|
|
16
|
+
REJECTED: [],
|
|
17
|
+
EXECUTED: [],
|
|
18
|
+
CANCELLED: []
|
|
19
|
+
}, ke = new Set([
|
|
20
|
+
"DRIFT",
|
|
21
|
+
"CONCENTRATION_RISK",
|
|
22
|
+
"REBALANCE_DUE",
|
|
23
|
+
"CASH_DRAG",
|
|
24
|
+
"FEE_ANOMALY"
|
|
25
|
+
]);
|
|
26
|
+
function F(e) {
|
|
27
|
+
return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
|
28
|
+
}
|
|
29
|
+
function Ae(e) {
|
|
30
|
+
if (e == null) return "—";
|
|
31
|
+
if (Array.isArray(e)) return `${e.length} trade${e.length === 1 ? "" : "s"}`;
|
|
32
|
+
if (typeof e == "object") {
|
|
33
|
+
let t = Object.keys(e).length;
|
|
34
|
+
return `${t} field${t === 1 ? "" : "s"}`;
|
|
35
|
+
}
|
|
36
|
+
return String(e);
|
|
37
|
+
}
|
|
38
|
+
var I = {
|
|
39
|
+
portfolioId: "",
|
|
40
|
+
driftPct: "",
|
|
41
|
+
rationale: "",
|
|
42
|
+
trades: ""
|
|
43
|
+
};
|
|
44
|
+
function je(e) {
|
|
45
|
+
if (e.trim() === "") return;
|
|
46
|
+
let t = Number(e);
|
|
47
|
+
return Number.isFinite(t) ? t : void 0;
|
|
48
|
+
}
|
|
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(() => {
|
|
51
|
+
let e = /* @__PURE__ */ new Map();
|
|
52
|
+
for (let t of R) e.set(t.id, t);
|
|
53
|
+
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);
|
|
31
57
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
outperformance: "+2.8%"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
scenario: "Stagflation Scenario",
|
|
53
|
-
portfolio: -12.7,
|
|
54
|
-
market: -16.3,
|
|
55
|
-
outperformance: "+3.6%"
|
|
58
|
+
function He() {
|
|
59
|
+
if (!K.portfolioId) return;
|
|
60
|
+
let e;
|
|
61
|
+
if (K.trades.trim() !== "") try {
|
|
62
|
+
e = JSON.parse(K.trades);
|
|
63
|
+
} catch {
|
|
64
|
+
Y("Trades must be valid JSON.");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let t = X.get(K.portfolioId);
|
|
68
|
+
B.mutate({
|
|
69
|
+
portfolioId: K.portfolioId,
|
|
70
|
+
householdId: t?.householdId ?? null,
|
|
71
|
+
driftPct: je(K.driftPct),
|
|
72
|
+
rationale: K.rationale.trim() || null,
|
|
73
|
+
...e === void 0 ? {} : { trades: e }
|
|
74
|
+
}, { onSuccess: () => G(!1) });
|
|
56
75
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
status: "Implemented",
|
|
61
|
-
effectiveness: "High"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
strategy: "Hedging (Options)",
|
|
65
|
-
status: "Partial",
|
|
66
|
-
effectiveness: "Medium"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
strategy: "Stop-Loss Orders",
|
|
70
|
-
status: "Active",
|
|
71
|
-
effectiveness: "Medium"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
strategy: "Quarterly Rebalancing",
|
|
75
|
-
status: "Scheduled",
|
|
76
|
-
effectiveness: "High"
|
|
76
|
+
function Ue(e) {
|
|
77
|
+
let t = X.get(e.portfolioId)?.driftThresholdPct;
|
|
78
|
+
return t != null && Number.isFinite(t) && e.driftPct >= t;
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
actionLabel: "Run Stress Test",
|
|
85
|
-
badges: [`${T.length} Active Alerts`],
|
|
80
|
+
return /* @__PURE__ */ v(ie, {
|
|
81
|
+
title: "Risk & Rebalancing",
|
|
82
|
+
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"}`],
|
|
84
|
+
actionLabel: "New proposal",
|
|
85
|
+
onAction: Ve,
|
|
86
86
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
87
|
+
/* @__PURE__ */ _(ne, { items: [
|
|
88
88
|
{
|
|
89
|
-
label: "
|
|
90
|
-
value:
|
|
91
|
-
trend: "Moderate Risk"
|
|
89
|
+
label: "Total proposals",
|
|
90
|
+
value: String(p.length)
|
|
92
91
|
},
|
|
93
92
|
{
|
|
94
|
-
label: "
|
|
95
|
-
value:
|
|
96
|
-
trend: "95% confidence, 1-day"
|
|
93
|
+
label: "Active proposals",
|
|
94
|
+
value: String(ze.length)
|
|
97
95
|
},
|
|
98
96
|
{
|
|
99
|
-
label: "
|
|
100
|
-
value: "
|
|
101
|
-
trend: "Risk-adjusted return"
|
|
97
|
+
label: "Average drift",
|
|
98
|
+
value: Be === null ? "—" : l(Be)
|
|
102
99
|
},
|
|
103
100
|
{
|
|
104
|
-
label: "
|
|
105
|
-
value:
|
|
106
|
-
trend: "Overall grade"
|
|
101
|
+
label: "Open risk insights",
|
|
102
|
+
value: String(Q.length)
|
|
107
103
|
}
|
|
108
104
|
] }),
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
-
className: "
|
|
111
|
-
children: [/* @__PURE__ */
|
|
112
|
-
className: "
|
|
113
|
-
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
105
|
+
/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
|
|
106
|
+
className: "flex items-center gap-2",
|
|
107
|
+
children: [/* @__PURE__ */ _(h, {
|
|
108
|
+
className: "h-5 w-5",
|
|
109
|
+
"aria-hidden": "true"
|
|
110
|
+
}), "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, {
|
|
113
|
+
className: "size-6",
|
|
114
|
+
"aria-hidden": "true"
|
|
115
|
+
}),
|
|
116
|
+
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, {
|
|
119
|
+
size: "sm",
|
|
120
|
+
onClick: Ve,
|
|
121
|
+
children: [/* @__PURE__ */ _(se, {
|
|
122
|
+
className: "size-4",
|
|
123
|
+
"aria-hidden": "true"
|
|
124
|
+
}), "New proposal"]
|
|
125
|
+
}) : void 0
|
|
126
|
+
}) : /* @__PURE__ */ _("div", {
|
|
127
|
+
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, {
|
|
131
|
+
className: "text-right",
|
|
132
|
+
children: "Drift"
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ _(M, { children: "Status" }),
|
|
135
|
+
/* @__PURE__ */ _(M, { children: "Rationale" }),
|
|
136
|
+
/* @__PURE__ */ _(M, { children: "Trades" }),
|
|
137
|
+
/* @__PURE__ */ _(M, { children: "Created" }),
|
|
138
|
+
/* @__PURE__ */ _(M, {
|
|
139
|
+
className: "w-12 text-right",
|
|
140
|
+
children: "Actions"
|
|
141
|
+
})
|
|
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", {
|
|
146
|
+
className: "font-medium text-text-primary",
|
|
147
|
+
children: t?.name ?? "Unknown portfolio"
|
|
148
|
+
}), /* @__PURE__ */ v("p", {
|
|
149
|
+
className: "text-xs text-text-secondary",
|
|
150
|
+
children: [t?.baseCurrency ?? "—", t?.driftThresholdPct == null ? "" : ` · threshold ${l(t.driftThresholdPct)}`]
|
|
151
|
+
})] }),
|
|
152
|
+
/* @__PURE__ */ v(j, {
|
|
125
153
|
className: "text-right",
|
|
126
|
-
children: [/* @__PURE__ */
|
|
127
|
-
className:
|
|
128
|
-
children:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
className: "text-
|
|
154
|
-
children: e.
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
children: [/* @__PURE__ */ v("span", {
|
|
155
|
+
className: `inline-flex items-center justify-end gap-1 font-semibold ${n ? "text-status-error-text" : "text-text-primary"}`,
|
|
156
|
+
children: [n ? /* @__PURE__ */ _(ae, {
|
|
157
|
+
className: "size-4",
|
|
158
|
+
"aria-hidden": "true"
|
|
159
|
+
}) : null, l(e.driftPct)]
|
|
160
|
+
}), n ? /* @__PURE__ */ _("p", {
|
|
161
|
+
className: "text-xs text-status-error-text",
|
|
162
|
+
children: "Over threshold"
|
|
163
|
+
}) : null]
|
|
164
|
+
}),
|
|
165
|
+
/* @__PURE__ */ _(j, { children: /* @__PURE__ */ _(y, {
|
|
166
|
+
variant: u(e.status),
|
|
167
|
+
children: F(e.status)
|
|
168
|
+
}) }),
|
|
169
|
+
/* @__PURE__ */ _(j, {
|
|
170
|
+
className: "max-w-xs",
|
|
171
|
+
children: /* @__PURE__ */ _("p", {
|
|
172
|
+
className: "truncate text-sm text-text-secondary",
|
|
173
|
+
children: e.rationale ?? "—"
|
|
174
|
+
})
|
|
175
|
+
}),
|
|
176
|
+
/* @__PURE__ */ _(j, {
|
|
177
|
+
className: "text-sm text-text-secondary",
|
|
178
|
+
children: Ae(e.trades)
|
|
179
|
+
}),
|
|
180
|
+
/* @__PURE__ */ _(j, {
|
|
181
|
+
className: "text-sm text-text-secondary",
|
|
182
|
+
children: c(e.createdAt)
|
|
183
|
+
}),
|
|
184
|
+
/* @__PURE__ */ _(j, {
|
|
185
|
+
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, {
|
|
190
|
+
asChild: !0,
|
|
191
|
+
children: /* @__PURE__ */ _(b, {
|
|
192
|
+
variant: "ghost",
|
|
193
|
+
size: "sm",
|
|
194
|
+
"aria-label": `Lifecycle actions for ${t?.name ?? "proposal"}`,
|
|
195
|
+
children: /* @__PURE__ */ _(m, {
|
|
196
|
+
className: "size-4",
|
|
197
|
+
"aria-hidden": "true"
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
}), /* @__PURE__ */ v(D, {
|
|
201
|
+
align: "end",
|
|
202
|
+
children: [
|
|
203
|
+
/* @__PURE__ */ _(_e, { children: "Advance to" }),
|
|
204
|
+
/* @__PURE__ */ _(ve, {}),
|
|
205
|
+
r.map((t) => {
|
|
206
|
+
let n = t === "REJECTED" || t === "CANCELLED";
|
|
207
|
+
return /* @__PURE__ */ v(O, {
|
|
208
|
+
disabled: V.isPending,
|
|
209
|
+
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, {
|
|
215
|
+
className: "size-4",
|
|
216
|
+
"aria-hidden": "true"
|
|
217
|
+
}), F(t)]
|
|
218
|
+
}, t);
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
})] })
|
|
222
|
+
})
|
|
223
|
+
] }, e.id);
|
|
224
|
+
}) })] })
|
|
225
|
+
}) })] }),
|
|
226
|
+
/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
|
|
160
227
|
className: "flex items-center gap-2",
|
|
161
|
-
children: [/* @__PURE__ */
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
228
|
+
children: [/* @__PURE__ */ _(ce, {
|
|
229
|
+
className: "h-5 w-5",
|
|
230
|
+
"aria-hidden": "true"
|
|
231
|
+
}), "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, {
|
|
234
|
+
className: "size-6",
|
|
235
|
+
"aria-hidden": "true"
|
|
167
236
|
}),
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
237
|
+
title: "No risk insights",
|
|
238
|
+
description: "No drift, concentration, cash-drag or fee-anomaly signals are open right now."
|
|
239
|
+
}) : /* @__PURE__ */ _("div", {
|
|
240
|
+
className: "space-y-3",
|
|
241
|
+
children: Z.map((e) => /* @__PURE__ */ _(Me, {
|
|
242
|
+
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))
|
|
248
|
+
}) })] }),
|
|
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", {
|
|
255
|
+
className: "grid gap-4",
|
|
256
|
+
children: [
|
|
257
|
+
/* @__PURE__ */ v("div", {
|
|
258
|
+
className: "space-y-2",
|
|
259
|
+
children: [/* @__PURE__ */ _(A, {
|
|
260
|
+
htmlFor: "prop-portfolio",
|
|
261
|
+
children: "Portfolio"
|
|
262
|
+
}), /* @__PURE__ */ v(be, {
|
|
263
|
+
value: K.portfolioId,
|
|
264
|
+
onValueChange: (e) => q((t) => ({
|
|
265
|
+
...t,
|
|
266
|
+
portfolioId: e
|
|
267
|
+
})),
|
|
268
|
+
children: [/* @__PURE__ */ _(Ce, {
|
|
269
|
+
id: "prop-portfolio",
|
|
270
|
+
children: /* @__PURE__ */ _(we, { placeholder: "Select a portfolio" })
|
|
271
|
+
}), /* @__PURE__ */ _(xe, { children: R.map((e) => /* @__PURE__ */ _(Se, {
|
|
272
|
+
value: e.id,
|
|
273
|
+
children: e.name
|
|
274
|
+
}, e.id)) })]
|
|
275
|
+
})]
|
|
276
|
+
}),
|
|
277
|
+
/* @__PURE__ */ v("div", {
|
|
278
|
+
className: "space-y-2",
|
|
279
|
+
children: [/* @__PURE__ */ _(A, {
|
|
280
|
+
htmlFor: "prop-drift",
|
|
281
|
+
children: "Drift %"
|
|
282
|
+
}), /* @__PURE__ */ _(ye, {
|
|
283
|
+
id: "prop-drift",
|
|
284
|
+
type: "number",
|
|
285
|
+
value: K.driftPct,
|
|
286
|
+
onChange: (e) => q((t) => ({
|
|
287
|
+
...t,
|
|
288
|
+
driftPct: e.target.value
|
|
289
|
+
})),
|
|
290
|
+
placeholder: "e.g. 6.5"
|
|
291
|
+
})]
|
|
292
|
+
}),
|
|
293
|
+
/* @__PURE__ */ v("div", {
|
|
294
|
+
className: "space-y-2",
|
|
295
|
+
children: [/* @__PURE__ */ _(A, {
|
|
296
|
+
htmlFor: "prop-rationale",
|
|
297
|
+
children: "Rationale"
|
|
298
|
+
}), /* @__PURE__ */ _(P, {
|
|
299
|
+
id: "prop-rationale",
|
|
300
|
+
value: K.rationale,
|
|
301
|
+
onChange: (e) => q((t) => ({
|
|
302
|
+
...t,
|
|
303
|
+
rationale: e.target.value
|
|
304
|
+
})),
|
|
305
|
+
placeholder: "Why is this rebalance needed?"
|
|
306
|
+
})]
|
|
307
|
+
}),
|
|
308
|
+
/* @__PURE__ */ v("div", {
|
|
309
|
+
className: "space-y-2",
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ _(A, {
|
|
312
|
+
htmlFor: "prop-trades",
|
|
313
|
+
children: "Trades (JSON, optional)"
|
|
314
|
+
}),
|
|
315
|
+
/* @__PURE__ */ _(P, {
|
|
316
|
+
id: "prop-trades",
|
|
317
|
+
value: K.trades,
|
|
318
|
+
onChange: (e) => {
|
|
319
|
+
Y(null), q((t) => ({
|
|
320
|
+
...t,
|
|
321
|
+
trades: e.target.value
|
|
322
|
+
}));
|
|
323
|
+
},
|
|
324
|
+
placeholder: "e.g. [{\"symbol\":\"VOO\",\"action\":\"SELL\",\"quantity\":10}]"
|
|
325
|
+
}),
|
|
326
|
+
J ? /* @__PURE__ */ _("p", {
|
|
327
|
+
className: "text-xs text-status-error-text",
|
|
328
|
+
children: J
|
|
329
|
+
}) : null
|
|
330
|
+
]
|
|
331
|
+
})
|
|
332
|
+
]
|
|
333
|
+
}) : /* @__PURE__ */ _(o, {
|
|
334
|
+
title: "No portfolios available",
|
|
335
|
+
description: "Create a portfolio before proposing a rebalance."
|
|
336
|
+
}),
|
|
337
|
+
/* @__PURE__ */ v(me, { children: [/* @__PURE__ */ _(de, {
|
|
338
|
+
asChild: !0,
|
|
339
|
+
children: /* @__PURE__ */ _(b, {
|
|
340
|
+
variant: "outline",
|
|
341
|
+
children: "Cancel"
|
|
342
|
+
})
|
|
343
|
+
}), /* @__PURE__ */ _(b, {
|
|
344
|
+
onClick: He,
|
|
345
|
+
disabled: !K.portfolioId || B.isPending,
|
|
346
|
+
children: B.isPending ? "Creating…" : "Create proposal"
|
|
347
|
+
})] })
|
|
348
|
+
] })
|
|
349
|
+
})
|
|
350
|
+
]
|
|
351
|
+
});
|
|
352
|
+
}
|
|
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", {
|
|
356
|
+
className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
357
|
+
children: [/* @__PURE__ */ v("div", {
|
|
358
|
+
className: "min-w-0 space-y-1",
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ v("div", {
|
|
361
|
+
className: "flex flex-wrap items-center gap-2",
|
|
362
|
+
children: [
|
|
363
|
+
/* @__PURE__ */ _("p", {
|
|
364
|
+
className: "font-medium text-text-primary",
|
|
365
|
+
children: e.title
|
|
366
|
+
}),
|
|
367
|
+
/* @__PURE__ */ _(y, {
|
|
368
|
+
variant: u(e.severity),
|
|
369
|
+
children: F(e.severity)
|
|
370
|
+
}),
|
|
371
|
+
/* @__PURE__ */ _(y, {
|
|
372
|
+
variant: "outline",
|
|
373
|
+
children: F(e.type)
|
|
374
|
+
}),
|
|
375
|
+
/* @__PURE__ */ _(y, {
|
|
376
|
+
variant: u(e.status),
|
|
377
|
+
children: F(e.status)
|
|
378
|
+
})
|
|
379
|
+
]
|
|
171
380
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
className: "text-
|
|
174
|
-
children:
|
|
381
|
+
e.detail ? /* @__PURE__ */ _("p", {
|
|
382
|
+
className: "text-sm text-text-secondary",
|
|
383
|
+
children: e.detail
|
|
384
|
+
}) : null,
|
|
385
|
+
/* @__PURE__ */ v("p", {
|
|
386
|
+
className: "text-xs text-text-muted",
|
|
387
|
+
children: ["Detected ", c(e.createdAt)]
|
|
175
388
|
})
|
|
176
|
-
]
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
389
|
+
]
|
|
390
|
+
}), a ? /* @__PURE__ */ _("span", {
|
|
391
|
+
className: "mt-1 text-xs text-text-muted",
|
|
392
|
+
children: "Closed"
|
|
393
|
+
}) : /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(k, {
|
|
394
|
+
asChild: !0,
|
|
395
|
+
children: /* @__PURE__ */ _(b, {
|
|
396
|
+
variant: "ghost",
|
|
397
|
+
size: "sm",
|
|
398
|
+
"aria-label": `Actions for ${e.title}`,
|
|
399
|
+
disabled: i,
|
|
400
|
+
children: /* @__PURE__ */ _(m, {
|
|
401
|
+
className: "size-4",
|
|
402
|
+
"aria-hidden": "true"
|
|
403
|
+
})
|
|
404
|
+
})
|
|
405
|
+
}), /* @__PURE__ */ v(D, {
|
|
406
|
+
align: "end",
|
|
407
|
+
children: [
|
|
408
|
+
e.status === "OPEN" ? /* @__PURE__ */ v(O, {
|
|
409
|
+
onClick: t,
|
|
410
|
+
children: [/* @__PURE__ */ _(p, {
|
|
411
|
+
className: "size-4",
|
|
412
|
+
"aria-hidden": "true"
|
|
413
|
+
}), "Acknowledge"]
|
|
414
|
+
}) : null,
|
|
415
|
+
/* @__PURE__ */ v(O, {
|
|
416
|
+
onClick: n,
|
|
417
|
+
children: [/* @__PURE__ */ _(g, {
|
|
418
|
+
className: "size-4",
|
|
419
|
+
"aria-hidden": "true"
|
|
420
|
+
}), "Resolve"]
|
|
188
421
|
}),
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
-
className: "text-
|
|
191
|
-
|
|
422
|
+
/* @__PURE__ */ v(O, {
|
|
423
|
+
className: "text-status-error-text",
|
|
424
|
+
onClick: r,
|
|
425
|
+
children: [/* @__PURE__ */ _(le, {
|
|
426
|
+
className: "size-4",
|
|
427
|
+
"aria-hidden": "true"
|
|
428
|
+
}), "Dismiss"]
|
|
192
429
|
})
|
|
193
|
-
]
|
|
194
|
-
|
|
195
|
-
className: "flex items-center gap-2",
|
|
196
|
-
children: [/* @__PURE__ */ c(s, { className: "h-5 w-5" }), "Mitigation Strategies"]
|
|
197
|
-
}), /* @__PURE__ */ c(p, { children: "Current risk management measures and their effectiveness" })] }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c("div", {
|
|
198
|
-
className: "grid gap-3 md:grid-cols-2",
|
|
199
|
-
children: w.map((e) => /* @__PURE__ */ l("div", {
|
|
200
|
-
className: "rounded-lg border p-3",
|
|
201
|
-
children: [/* @__PURE__ */ l("div", {
|
|
202
|
-
className: "flex items-center justify-between mb-1",
|
|
203
|
-
children: [/* @__PURE__ */ c("p", {
|
|
204
|
-
className: "font-medium text-sm",
|
|
205
|
-
children: e.strategy
|
|
206
|
-
}), /* @__PURE__ */ c(u, {
|
|
207
|
-
variant: e.status === "Implemented" || e.status === "Active" || e.status === "Scheduled" ? "default" : "secondary",
|
|
208
|
-
children: e.status
|
|
209
|
-
})]
|
|
210
|
-
}), /* @__PURE__ */ l("p", {
|
|
211
|
-
className: "text-xs text-muted-foreground",
|
|
212
|
-
children: ["Effectiveness: ", e.effectiveness]
|
|
213
|
-
})]
|
|
214
|
-
}, e.strategy))
|
|
215
|
-
}) })] })
|
|
216
|
-
]
|
|
430
|
+
]
|
|
431
|
+
})] })]
|
|
217
432
|
});
|
|
218
433
|
}
|
|
219
434
|
//#endregion
|
|
220
|
-
export {
|
|
435
|
+
export { L as RiskPage };
|
|
221
436
|
|
|
222
437
|
//# sourceMappingURL=RiskPage.js.map
|