@burdenoff/microfe-brainyrich 2026.828.2 → 2026.830.2
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/components/viz.d.ts.map +1 -1
- package/dist/brainyrich/components/viz.js +148 -147
- package/dist/brainyrich/components/viz.js.map +1 -1
- package/dist/brainyrich/hooks/useTr.d.ts +17 -0
- package/dist/brainyrich/hooks/useTr.d.ts.map +1 -0
- package/dist/brainyrich/hooks/useTr.js +14 -0
- package/dist/brainyrich/hooks/useTr.js.map +1 -0
- package/dist/brainyrich/pages/AnalyticsPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js +253 -252
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +482 -476
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js +36 -36
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +272 -271
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js +198 -197
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
- package/dist/brainyrich/pages/_shared.js +84 -82
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useCreateTradeInstruction as n, useDismissInsight as r, useGenerateRiskInsights as i, useHarvestTaxLossInsights as a, useMarketQuote as
|
|
2
|
-
import { LoadMore as
|
|
3
|
-
import { ConfirmDialog as
|
|
4
|
-
import { ActorName as
|
|
5
|
-
import {
|
|
1
|
+
import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useCreateTradeInstruction as n, useDismissInsight as r, useGenerateRiskInsights as i, useHarvestTaxLossInsights as a, useMarketQuote as ee, usePagedInsights as o, usePortfolioRiskSignals as te, usePortfolioRiskSummary as ne, usePortfolios as re, useRebalanceProposals as ie, useResolveInsight as ae, useReviewTradeInstruction as oe, useTaxLossOpportunities as se, useTradeInstructions as ce, useTransitionRebalanceProposal as le } from "../hooks/useBrainyRichApi.js";
|
|
2
|
+
import { LoadMore as ue } from "../components/LoadMore.js";
|
|
3
|
+
import { ConfirmDialog as de } from "../components/ConfirmDialog.js";
|
|
4
|
+
import { ActorName as s } from "../components/ActorName.js";
|
|
5
|
+
import { useTr as fe } from "../hooks/useTr.js";
|
|
6
|
+
import { DonutChart as pe, FadeIn as c, GlassCard as me, LifecycleStepper as l, StatTile as u } from "../components/viz.js";
|
|
6
7
|
import "../components/index.js";
|
|
7
|
-
import { EmptyState as d, ErrorState as f, LoadingState as p, MetricGrid as
|
|
8
|
-
import { CommentThread as
|
|
8
|
+
import { EmptyState as d, ErrorState as f, LoadingState as p, MetricGrid as m, SectionShell as he, formatDate as h, formatMoney as g, formatPct as _, readEngineMetrics as ge, statusBadgeVariant as v } from "./_shared.js";
|
|
9
|
+
import { CommentThread as _e } from "../components/reuse/CommentThread.js";
|
|
9
10
|
import { useMemo as y, useState as b } from "react";
|
|
10
|
-
import { Activity as
|
|
11
|
-
import { Fragment as
|
|
12
|
-
import { Badge as D, Button as O, Card as k, CardContent as A, CardDescription as j, CardHeader as M, CardTitle as N, DropdownMenu as
|
|
11
|
+
import { Activity as ve, AlertTriangle as ye, ArrowRight as be, Check as xe, Eye as Se, Gauge as x, Layers as Ce, LineChart as we, MoreHorizontal as Te, Plus as Ee, RefreshCw as De, Scale as Oe, Scissors as ke, Search as Ae, ShieldAlert as S, ShieldCheck as C, Sparkles as je, TrendingUp as Me, X as w } from "lucide-react";
|
|
12
|
+
import { Fragment as Ne, jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
13
|
+
import { Badge as D, Button as O, Card as k, CardContent as A, CardDescription as j, CardHeader as M, CardTitle as N, DropdownMenu as Pe, DropdownMenuContent as Fe, DropdownMenuItem as P, DropdownMenuLabel as Ie, DropdownMenuSeparator as Le, DropdownMenuTrigger as Re, Input as F, Label as I, ResponsiveDialog as ze, ResponsiveDialogClose as Be, ResponsiveDialogContent as Ve, ResponsiveDialogDescription as He, ResponsiveDialogFooter as Ue, ResponsiveDialogHeader as We, ResponsiveDialogTitle as Ge, Select as Ke, SelectContent as qe, SelectItem as Je, SelectTrigger as Ye, SelectValue as Xe, Table as Ze, TableBody as Qe, TableCell as L, TableHead as R, TableHeader as $e, TableRow as z, Textarea as et } from "@burdenoff/fe-libs/ui";
|
|
13
14
|
//#region src/brainyrich/pages/RiskPage.tsx
|
|
14
|
-
var
|
|
15
|
+
var tt = {
|
|
15
16
|
DRAFT: ["PROPOSED", "CANCELLED"],
|
|
16
17
|
PROPOSED: [
|
|
17
18
|
"APPROVED",
|
|
@@ -22,7 +23,7 @@ var et = {
|
|
|
22
23
|
REJECTED: [],
|
|
23
24
|
EXECUTED: [],
|
|
24
25
|
CANCELLED: []
|
|
25
|
-
},
|
|
26
|
+
}, nt = new Set([
|
|
26
27
|
"DRIFT",
|
|
27
28
|
"CONCENTRATION_RISK",
|
|
28
29
|
"REBALANCE_DUE",
|
|
@@ -32,7 +33,7 @@ var et = {
|
|
|
32
33
|
function B(e) {
|
|
33
34
|
return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
|
|
34
35
|
}
|
|
35
|
-
var
|
|
36
|
+
var V = [
|
|
36
37
|
"Draft",
|
|
37
38
|
"Proposed",
|
|
38
39
|
"Approved",
|
|
@@ -80,12 +81,12 @@ function st(e) {
|
|
|
80
81
|
"ticker",
|
|
81
82
|
"asset",
|
|
82
83
|
"instrument"
|
|
83
|
-
]),
|
|
84
|
+
]), ee = r([
|
|
84
85
|
"quantity",
|
|
85
86
|
"qty",
|
|
86
87
|
"shares",
|
|
87
88
|
"units"
|
|
88
|
-
]),
|
|
89
|
+
]), o = r([
|
|
89
90
|
"value",
|
|
90
91
|
"notional",
|
|
91
92
|
"amount",
|
|
@@ -95,17 +96,17 @@ function st(e) {
|
|
|
95
96
|
t.push({
|
|
96
97
|
action: typeof i == "string" ? i : void 0,
|
|
97
98
|
symbol: typeof a == "string" ? a : void 0,
|
|
98
|
-
quantity: typeof
|
|
99
|
-
value: typeof
|
|
99
|
+
quantity: typeof ee == "number" ? ee : void 0,
|
|
100
|
+
value: typeof o == "number" ? o : void 0
|
|
100
101
|
});
|
|
101
102
|
}
|
|
102
103
|
return t;
|
|
103
104
|
}
|
|
104
|
-
function
|
|
105
|
+
function ct(e) {
|
|
105
106
|
let t = (e ?? "").toUpperCase();
|
|
106
107
|
return t.includes("BUY") || t.includes("ADD") ? "text-status-success-text" : t.includes("SELL") || t.includes("TRIM") || t.includes("REDUCE") ? "text-status-error-text" : "text-text-secondary";
|
|
107
108
|
}
|
|
108
|
-
function
|
|
109
|
+
function lt(e) {
|
|
109
110
|
if (e == null) return "—";
|
|
110
111
|
if (Array.isArray(e)) return `${e.length} trade${e.length === 1 ? "" : "s"}`;
|
|
111
112
|
if (typeof e == "object") {
|
|
@@ -114,34 +115,34 @@ function ct(e) {
|
|
|
114
115
|
}
|
|
115
116
|
return String(e);
|
|
116
117
|
}
|
|
117
|
-
var
|
|
118
|
+
var ut = {
|
|
118
119
|
portfolioId: "",
|
|
119
120
|
driftPct: "",
|
|
120
121
|
rationale: "",
|
|
121
122
|
trades: ""
|
|
122
123
|
};
|
|
123
|
-
function
|
|
124
|
+
function dt(e) {
|
|
124
125
|
if (e.trim() === "") return;
|
|
125
126
|
let t = Number(e);
|
|
126
127
|
return Number.isFinite(t) ? t : void 0;
|
|
127
128
|
}
|
|
128
129
|
function H() {
|
|
129
|
-
let { data:
|
|
130
|
+
let s = fe(), { data: l, isLoading: m, isError: ge, refetch: _e } = ie(), { data: V } = re(), [st, ct] = b(void 0), H = st ?? V[0]?.id ?? "", { data: U, isLoading: gt, isError: _t, refetch: vt } = te(H || void 0), yt = i(), { data: W, isFetching: bt, refetch: xt } = ne(H || void 0), { data: G, isLoading: St, isError: Ct, refetch: wt } = se(H || void 0), Tt = a(), K = ce(H || void 0), Et = n(), Dt = oe(), [Ot, kt] = b(""), q = ee(Ot || void 0), [At, jt] = b(""), [Mt, Nt] = b("BUY"), [Pt, Ft] = b(""), [It, Lt] = b(""), { items: Rt, hasMore: zt, loadMore: Bt, isLoading: Vt, isFetchingNextPage: Ht, isError: Ut, refetch: Wt } = o(), Gt = t(), J = le(), Kt = e(), qt = r(), Jt = ae(), [Yt, Xt] = b(!1), [Y, X] = b(ut), [Zt, Qt] = b(null), [$t, en] = b(null), [Z, tn] = b(null), Q = y(() => {
|
|
130
131
|
let e = /* @__PURE__ */ new Map();
|
|
131
|
-
for (let t of
|
|
132
|
+
for (let t of V) e.set(t.id, t);
|
|
132
133
|
return e;
|
|
133
|
-
}, [
|
|
134
|
+
}, [V]), nn = y(() => Rt.filter((e) => nt.has(e.type)), [Rt]), rn = l.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), $ = nn.filter((e) => e.status === "OPEN"), an = l.length > 0 ? l.reduce((e, t) => e + (t.driftPct ?? 0), 0) / l.length : null, on = y(() => l.filter((e) => {
|
|
134
135
|
let t = Q.get(e.portfolioId)?.driftThresholdPct;
|
|
135
136
|
return t != null && Number.isFinite(t) && e.driftPct >= t;
|
|
136
|
-
}).length, [
|
|
137
|
+
}).length, [l, Q]), sn = y(() => [...l].sort((e, t) => new Date(e.createdAt).getTime() - new Date(t.createdAt).getTime()).map((e) => e.driftPct).filter((e) => Number.isFinite(e)), [l]), cn = y(() => {
|
|
137
138
|
let e = /* @__PURE__ */ new Map();
|
|
138
|
-
for (let t of
|
|
139
|
+
for (let t of l) e.set(t.status, (e.get(t.status) ?? 0) + 1);
|
|
139
140
|
return it.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
|
|
140
141
|
label: B(t),
|
|
141
142
|
value: e.get(t) ?? 0,
|
|
142
143
|
tone: rt[t]
|
|
143
144
|
}));
|
|
144
|
-
}, [
|
|
145
|
+
}, [l]), ln = y(() => {
|
|
145
146
|
let e = /* @__PURE__ */ new Map();
|
|
146
147
|
for (let t of $) e.set(t.severity, (e.get(t.severity) ?? 0) + 1);
|
|
147
148
|
return ot.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
|
|
@@ -149,31 +150,31 @@ function H() {
|
|
|
149
150
|
value: e.get(t) ?? 0,
|
|
150
151
|
tone: at[t]
|
|
151
152
|
}));
|
|
152
|
-
}, [$]),
|
|
153
|
-
function
|
|
154
|
-
X(
|
|
153
|
+
}, [$]), un = V.length > 0;
|
|
154
|
+
function dn() {
|
|
155
|
+
X(ut), Qt(null), Xt(!0);
|
|
155
156
|
}
|
|
156
|
-
function
|
|
157
|
+
function fn() {
|
|
157
158
|
if (!Y.portfolioId) return;
|
|
158
159
|
let e;
|
|
159
160
|
if (Y.trades.trim() !== "") try {
|
|
160
161
|
e = JSON.parse(Y.trades);
|
|
161
162
|
} catch {
|
|
162
|
-
|
|
163
|
+
Qt("Trades must be valid JSON.");
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
166
|
let t = Q.get(Y.portfolioId);
|
|
166
|
-
|
|
167
|
+
Gt.mutate({
|
|
167
168
|
portfolioId: Y.portfolioId,
|
|
168
169
|
householdId: t?.householdId ?? null,
|
|
169
|
-
driftPct:
|
|
170
|
+
driftPct: dt(Y.driftPct),
|
|
170
171
|
rationale: Y.rationale.trim() || null,
|
|
171
172
|
...e === void 0 ? {} : { trades: e }
|
|
172
|
-
}, { onSuccess: () =>
|
|
173
|
+
}, { onSuccess: () => Xt(!1) });
|
|
173
174
|
}
|
|
174
|
-
function
|
|
175
|
+
function pn(e, t) {
|
|
175
176
|
if (t === "REJECTED" || t === "CANCELLED") {
|
|
176
|
-
|
|
177
|
+
tn({
|
|
177
178
|
proposal: e,
|
|
178
179
|
status: t
|
|
179
180
|
});
|
|
@@ -184,27 +185,27 @@ function H() {
|
|
|
184
185
|
status: t
|
|
185
186
|
});
|
|
186
187
|
}
|
|
187
|
-
function
|
|
188
|
+
function mn(e) {
|
|
188
189
|
let t = Q.get(e.portfolioId)?.driftThresholdPct;
|
|
189
190
|
return t != null && Number.isFinite(t) && e.driftPct >= t;
|
|
190
191
|
}
|
|
191
192
|
return /* @__PURE__ */ E(he, {
|
|
192
193
|
title: "Risk & Rebalancing",
|
|
193
194
|
description: "Review drift-driven rebalance proposals and act on portfolio risk insights.",
|
|
194
|
-
badges: [`${
|
|
195
|
+
badges: [`${rn.length} active`, `${$.length} open insight${$.length === 1 ? "" : "s"}`],
|
|
195
196
|
actionLabel: "New proposal",
|
|
196
|
-
onAction:
|
|
197
|
+
onAction: dn,
|
|
197
198
|
children: [
|
|
198
199
|
/* @__PURE__ */ E("div", {
|
|
199
200
|
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
200
201
|
children: [
|
|
201
|
-
/* @__PURE__ */ T(
|
|
202
|
+
/* @__PURE__ */ T(c, {
|
|
202
203
|
index: 0,
|
|
203
204
|
children: /* @__PURE__ */ T(u, {
|
|
204
205
|
label: "Average drift",
|
|
205
|
-
value:
|
|
206
|
-
spark:
|
|
207
|
-
sparkTone:
|
|
206
|
+
value: an === null ? "—" : _(an),
|
|
207
|
+
spark: sn.length > 1 ? sn : void 0,
|
|
208
|
+
sparkTone: on > 0 ? "error" : "brand",
|
|
208
209
|
glow: !0,
|
|
209
210
|
icon: /* @__PURE__ */ T(x, {
|
|
210
211
|
className: "size-4",
|
|
@@ -212,29 +213,29 @@ function H() {
|
|
|
212
213
|
})
|
|
213
214
|
})
|
|
214
215
|
}),
|
|
215
|
-
/* @__PURE__ */ T(
|
|
216
|
+
/* @__PURE__ */ T(c, {
|
|
216
217
|
index: 1,
|
|
217
218
|
children: /* @__PURE__ */ T(u, {
|
|
218
219
|
label: "Active proposals",
|
|
219
|
-
value: String(
|
|
220
|
-
icon: /* @__PURE__ */ T(
|
|
220
|
+
value: String(rn.length),
|
|
221
|
+
icon: /* @__PURE__ */ T(ve, {
|
|
221
222
|
className: "size-4",
|
|
222
223
|
"aria-hidden": "true"
|
|
223
224
|
})
|
|
224
225
|
})
|
|
225
226
|
}),
|
|
226
|
-
/* @__PURE__ */ T(
|
|
227
|
+
/* @__PURE__ */ T(c, {
|
|
227
228
|
index: 2,
|
|
228
229
|
children: /* @__PURE__ */ T(u, {
|
|
229
230
|
label: "Total proposals",
|
|
230
|
-
value: String(
|
|
231
|
-
icon: /* @__PURE__ */ T(
|
|
231
|
+
value: String(l.length),
|
|
232
|
+
icon: /* @__PURE__ */ T(Ce, {
|
|
232
233
|
className: "size-4",
|
|
233
234
|
"aria-hidden": "true"
|
|
234
235
|
})
|
|
235
236
|
})
|
|
236
237
|
}),
|
|
237
|
-
/* @__PURE__ */ T(
|
|
238
|
+
/* @__PURE__ */ T(c, {
|
|
238
239
|
index: 3,
|
|
239
240
|
children: /* @__PURE__ */ T(u, {
|
|
240
241
|
label: "Open risk insights",
|
|
@@ -248,32 +249,32 @@ function H() {
|
|
|
248
249
|
})
|
|
249
250
|
]
|
|
250
251
|
}),
|
|
251
|
-
(
|
|
252
|
+
(cn.length > 0 || ln.length > 0) && !m ? /* @__PURE__ */ E("div", {
|
|
252
253
|
className: "grid gap-4 lg:grid-cols-2",
|
|
253
|
-
children: [/* @__PURE__ */ T(
|
|
254
|
+
children: [/* @__PURE__ */ T(c, {
|
|
254
255
|
index: 0,
|
|
255
|
-
children: /* @__PURE__ */ E(
|
|
256
|
+
children: /* @__PURE__ */ E(me, {
|
|
256
257
|
glow: !0,
|
|
257
258
|
className: "h-full",
|
|
258
259
|
children: [/* @__PURE__ */ E("div", {
|
|
259
260
|
className: "mb-3 flex items-center gap-2",
|
|
260
|
-
children: [/* @__PURE__ */ T(
|
|
261
|
+
children: [/* @__PURE__ */ T(Me, {
|
|
261
262
|
className: "size-4 text-text-secondary",
|
|
262
263
|
"aria-hidden": "true"
|
|
263
264
|
}), /* @__PURE__ */ T("h2", {
|
|
264
265
|
className: "text-sm font-semibold text-text-primary",
|
|
265
|
-
children: "Proposal pipeline"
|
|
266
|
+
children: s("brainyrich.risk.proposalPipeline", "Proposal pipeline")
|
|
266
267
|
})]
|
|
267
|
-
}), /* @__PURE__ */ T(
|
|
268
|
-
data:
|
|
269
|
-
centerValue: String(
|
|
268
|
+
}), /* @__PURE__ */ T(pe, {
|
|
269
|
+
data: cn,
|
|
270
|
+
centerValue: String(l.length),
|
|
270
271
|
centerLabel: "proposals",
|
|
271
272
|
height: 200
|
|
272
273
|
})]
|
|
273
274
|
})
|
|
274
|
-
}), /* @__PURE__ */ T(
|
|
275
|
+
}), /* @__PURE__ */ T(c, {
|
|
275
276
|
index: 1,
|
|
276
|
-
children: /* @__PURE__ */ E(
|
|
277
|
+
children: /* @__PURE__ */ E(me, {
|
|
277
278
|
className: "h-full",
|
|
278
279
|
children: [/* @__PURE__ */ E("div", {
|
|
279
280
|
className: "mb-3 flex items-center gap-2",
|
|
@@ -282,10 +283,10 @@ function H() {
|
|
|
282
283
|
"aria-hidden": "true"
|
|
283
284
|
}), /* @__PURE__ */ T("h2", {
|
|
284
285
|
className: "text-sm font-semibold text-text-primary",
|
|
285
|
-
children: "Open risk signals"
|
|
286
|
+
children: s("brainyrich.risk.openSignals", "Open risk signals")
|
|
286
287
|
})]
|
|
287
|
-
}),
|
|
288
|
-
data:
|
|
288
|
+
}), ln.length > 0 ? /* @__PURE__ */ T(pe, {
|
|
289
|
+
data: ln,
|
|
289
290
|
centerValue: String($.length),
|
|
290
291
|
centerLabel: "open",
|
|
291
292
|
height: 200
|
|
@@ -296,7 +297,7 @@ function H() {
|
|
|
296
297
|
"aria-hidden": "true"
|
|
297
298
|
}), /* @__PURE__ */ T("p", {
|
|
298
299
|
className: "text-sm text-text-secondary",
|
|
299
|
-
children: "No open risk signals."
|
|
300
|
+
children: s("brainyrich.risk.noOpenSignals", "No open risk signals.")
|
|
300
301
|
})]
|
|
301
302
|
})]
|
|
302
303
|
})
|
|
@@ -318,13 +319,13 @@ function H() {
|
|
|
318
319
|
children: [/* @__PURE__ */ T(I, {
|
|
319
320
|
htmlFor: "risk-portfolio",
|
|
320
321
|
children: "Portfolio"
|
|
321
|
-
}), /* @__PURE__ */ E(
|
|
322
|
-
value:
|
|
323
|
-
onValueChange:
|
|
324
|
-
children: [/* @__PURE__ */ T(
|
|
322
|
+
}), /* @__PURE__ */ E(Ke, {
|
|
323
|
+
value: H,
|
|
324
|
+
onValueChange: ct,
|
|
325
|
+
children: [/* @__PURE__ */ T(Ye, {
|
|
325
326
|
id: "risk-portfolio",
|
|
326
|
-
children: /* @__PURE__ */ T(
|
|
327
|
-
}), /* @__PURE__ */ T(
|
|
327
|
+
children: /* @__PURE__ */ T(Xe, { placeholder: "Select a portfolio" })
|
|
328
|
+
}), /* @__PURE__ */ T(qe, { children: V.map((e) => /* @__PURE__ */ T(Je, {
|
|
328
329
|
value: e.id,
|
|
329
330
|
children: e.name
|
|
330
331
|
}, e.id)) })]
|
|
@@ -334,9 +335,9 @@ function H() {
|
|
|
334
335
|
variant: "outline",
|
|
335
336
|
size: "sm",
|
|
336
337
|
className: "mt-auto",
|
|
337
|
-
disabled: !
|
|
338
|
-
onClick: () =>
|
|
339
|
-
children: [/* @__PURE__ */ T(
|
|
338
|
+
disabled: !H || gt,
|
|
339
|
+
onClick: () => vt(),
|
|
340
|
+
children: [/* @__PURE__ */ T(De, {
|
|
340
341
|
className: "size-4",
|
|
341
342
|
"aria-hidden": "true"
|
|
342
343
|
}), "Recompute"]
|
|
@@ -345,22 +346,22 @@ function H() {
|
|
|
345
346
|
variant: "outline",
|
|
346
347
|
size: "sm",
|
|
347
348
|
className: "mt-auto",
|
|
348
|
-
disabled: !
|
|
349
|
-
onClick: () =>
|
|
349
|
+
disabled: !H || (U?.signals.length ?? 0) === 0 || yt.isPending,
|
|
350
|
+
onClick: () => yt.mutate(H),
|
|
350
351
|
children: [/* @__PURE__ */ T(S, {
|
|
351
352
|
className: "size-4",
|
|
352
353
|
"aria-hidden": "true"
|
|
353
|
-
}),
|
|
354
|
+
}), yt.isPending ? "Saving…" : "Save as insights"]
|
|
354
355
|
})
|
|
355
356
|
]
|
|
356
|
-
}),
|
|
357
|
+
}), V.length === 0 ? /* @__PURE__ */ T(d, {
|
|
357
358
|
icon: /* @__PURE__ */ T(x, {
|
|
358
359
|
className: "size-6",
|
|
359
360
|
"aria-hidden": "true"
|
|
360
361
|
}),
|
|
361
362
|
title: "No portfolios yet",
|
|
362
363
|
description: "Create a portfolio to compute real risk signals from its holdings."
|
|
363
|
-
}) :
|
|
364
|
+
}) : gt ? /* @__PURE__ */ T(p, {}) : _t ? /* @__PURE__ */ T(f, { onRetry: () => vt() }) : U ? /* @__PURE__ */ E("div", {
|
|
364
365
|
className: "space-y-4",
|
|
365
366
|
children: [
|
|
366
367
|
/* @__PURE__ */ E("div", {
|
|
@@ -368,24 +369,24 @@ function H() {
|
|
|
368
369
|
children: [
|
|
369
370
|
/* @__PURE__ */ T(u, {
|
|
370
371
|
label: "Portfolio value",
|
|
371
|
-
value:
|
|
372
|
-
icon: /* @__PURE__ */ T(
|
|
372
|
+
value: g(U.totalValue),
|
|
373
|
+
icon: /* @__PURE__ */ T(Ce, {
|
|
373
374
|
className: "size-4",
|
|
374
375
|
"aria-hidden": "true"
|
|
375
376
|
})
|
|
376
377
|
}),
|
|
377
378
|
/* @__PURE__ */ T(u, {
|
|
378
379
|
label: "Holdings considered",
|
|
379
|
-
value: String(
|
|
380
|
-
icon: /* @__PURE__ */ T(
|
|
380
|
+
value: String(U.holdingsConsidered),
|
|
381
|
+
icon: /* @__PURE__ */ T(ve, {
|
|
381
382
|
className: "size-4",
|
|
382
383
|
"aria-hidden": "true"
|
|
383
384
|
})
|
|
384
385
|
}),
|
|
385
386
|
/* @__PURE__ */ T(u, {
|
|
386
387
|
label: "Signals breached",
|
|
387
|
-
value: String(
|
|
388
|
-
deltaTone:
|
|
388
|
+
value: String(U.signals.length),
|
|
389
|
+
deltaTone: U.signals.length > 0 ? "negative" : "neutral",
|
|
389
390
|
icon: /* @__PURE__ */ T(S, {
|
|
390
391
|
className: "size-4",
|
|
391
392
|
"aria-hidden": "true"
|
|
@@ -393,7 +394,7 @@ function H() {
|
|
|
393
394
|
})
|
|
394
395
|
]
|
|
395
396
|
}),
|
|
396
|
-
|
|
397
|
+
U.signals.length === 0 ? /* @__PURE__ */ T(d, {
|
|
397
398
|
icon: /* @__PURE__ */ T(C, {
|
|
398
399
|
className: "size-6",
|
|
399
400
|
"aria-hidden": "true"
|
|
@@ -402,7 +403,7 @@ function H() {
|
|
|
402
403
|
description: "This portfolio's concentration, cash, drift and unrealized-loss metrics are all within their configured thresholds."
|
|
403
404
|
}) : /* @__PURE__ */ T("ul", {
|
|
404
405
|
className: "space-y-3",
|
|
405
|
-
children:
|
|
406
|
+
children: U.signals.map((e, t) => /* @__PURE__ */ T(pt, { signal: e }, `${e.kind}-${t}`))
|
|
406
407
|
}),
|
|
407
408
|
/* @__PURE__ */ E("div", {
|
|
408
409
|
className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
|
|
@@ -411,13 +412,13 @@ function H() {
|
|
|
411
412
|
children: [/* @__PURE__ */ E("div", {
|
|
412
413
|
className: "flex items-center gap-2",
|
|
413
414
|
children: [
|
|
414
|
-
/* @__PURE__ */ T(
|
|
415
|
+
/* @__PURE__ */ T(je, {
|
|
415
416
|
className: "size-4 text-text-secondary",
|
|
416
417
|
"aria-hidden": "true"
|
|
417
418
|
}),
|
|
418
419
|
/* @__PURE__ */ T("h3", {
|
|
419
420
|
className: "text-sm font-semibold text-text-primary",
|
|
420
|
-
children: "AI summary"
|
|
421
|
+
children: s("brainyrich.risk.aiSummary", "AI summary")
|
|
421
422
|
}),
|
|
422
423
|
/* @__PURE__ */ T("span", {
|
|
423
424
|
className: "text-xs text-text-muted",
|
|
@@ -427,39 +428,39 @@ function H() {
|
|
|
427
428
|
}), /* @__PURE__ */ E(O, {
|
|
428
429
|
variant: "outline",
|
|
429
430
|
size: "sm",
|
|
430
|
-
disabled: !
|
|
431
|
-
onClick: () =>
|
|
432
|
-
children: [/* @__PURE__ */ T(
|
|
431
|
+
disabled: !H || bt,
|
|
432
|
+
onClick: () => xt(),
|
|
433
|
+
children: [/* @__PURE__ */ T(je, {
|
|
433
434
|
className: "size-4",
|
|
434
435
|
"aria-hidden": "true"
|
|
435
|
-
}),
|
|
436
|
+
}), bt ? "Generating…" : "Generate AI summary"]
|
|
436
437
|
})]
|
|
437
|
-
}),
|
|
438
|
+
}), bt ? /* @__PURE__ */ T("p", {
|
|
438
439
|
className: "mt-2 text-sm text-text-secondary",
|
|
439
440
|
children: "Asking the AI provider…"
|
|
440
|
-
}) :
|
|
441
|
+
}) : W?.generated ? /* @__PURE__ */ E("div", {
|
|
441
442
|
className: "mt-2 space-y-1",
|
|
442
443
|
children: [/* @__PURE__ */ T("p", {
|
|
443
444
|
className: "text-sm text-text-primary",
|
|
444
|
-
children:
|
|
445
|
+
children: W.summary
|
|
445
446
|
}), /* @__PURE__ */ E("p", {
|
|
446
447
|
className: "text-xs text-text-muted",
|
|
447
448
|
children: [
|
|
448
449
|
"AI-generated commentary",
|
|
449
|
-
|
|
450
|
+
W.provider ? ` · ${W.provider}` : "",
|
|
450
451
|
" · based on",
|
|
451
452
|
" ",
|
|
452
|
-
|
|
453
|
+
W.signalsConsidered,
|
|
453
454
|
" computed signal",
|
|
454
|
-
|
|
455
|
+
W.signalsConsidered === 1 ? "" : "s",
|
|
455
456
|
" above"
|
|
456
457
|
]
|
|
457
458
|
})]
|
|
458
|
-
}) :
|
|
459
|
+
}) : W && !W.generated ? /* @__PURE__ */ E("p", {
|
|
459
460
|
className: "mt-2 text-sm text-text-secondary",
|
|
460
461
|
children: [
|
|
461
462
|
"AI summary unavailable — ",
|
|
462
|
-
|
|
463
|
+
W.reason ?? "no provider configured",
|
|
463
464
|
". The deterministic signals above are unaffected."
|
|
464
465
|
]
|
|
465
466
|
}) : /* @__PURE__ */ T("p", {
|
|
@@ -479,7 +480,7 @@ function H() {
|
|
|
479
480
|
})] }),
|
|
480
481
|
/* @__PURE__ */ E(k, { children: [/* @__PURE__ */ E(M, { children: [/* @__PURE__ */ E(N, {
|
|
481
482
|
className: "flex items-center gap-2",
|
|
482
|
-
children: [/* @__PURE__ */ T(
|
|
483
|
+
children: [/* @__PURE__ */ T(ke, {
|
|
483
484
|
className: "h-5 w-5",
|
|
484
485
|
"aria-hidden": "true"
|
|
485
486
|
}), "Tax-loss-harvesting opportunities"]
|
|
@@ -491,9 +492,9 @@ function H() {
|
|
|
491
492
|
/* @__PURE__ */ E(O, {
|
|
492
493
|
variant: "outline",
|
|
493
494
|
size: "sm",
|
|
494
|
-
disabled: !
|
|
495
|
-
onClick: () =>
|
|
496
|
-
children: [/* @__PURE__ */ T(
|
|
495
|
+
disabled: !H || St,
|
|
496
|
+
onClick: () => wt(),
|
|
497
|
+
children: [/* @__PURE__ */ T(De, {
|
|
497
498
|
className: "size-4",
|
|
498
499
|
"aria-hidden": "true"
|
|
499
500
|
}), "Recompute"]
|
|
@@ -501,35 +502,35 @@ function H() {
|
|
|
501
502
|
/* @__PURE__ */ E(O, {
|
|
502
503
|
variant: "outline",
|
|
503
504
|
size: "sm",
|
|
504
|
-
disabled: !
|
|
505
|
-
onClick: () =>
|
|
505
|
+
disabled: !H || (G?.opportunities.length ?? 0) === 0 || Tt.isPending,
|
|
506
|
+
onClick: () => Tt.mutate({ portfolioId: H }),
|
|
506
507
|
children: [/* @__PURE__ */ T(S, {
|
|
507
508
|
className: "size-4",
|
|
508
509
|
"aria-hidden": "true"
|
|
509
|
-
}),
|
|
510
|
+
}), Tt.isPending ? "Saving…" : "Save as insights"]
|
|
510
511
|
}),
|
|
511
|
-
|
|
512
|
+
G ? /* @__PURE__ */ E("span", {
|
|
512
513
|
className: "text-xs text-text-muted",
|
|
513
514
|
children: [
|
|
514
515
|
"Thresholds: ≥",
|
|
515
|
-
|
|
516
|
+
g(G.thresholds.minLossAmount),
|
|
516
517
|
" or ≥",
|
|
517
|
-
|
|
518
|
+
_(G.thresholds.minLossPct),
|
|
518
519
|
" of portfolio value"
|
|
519
520
|
]
|
|
520
521
|
}) : null
|
|
521
522
|
]
|
|
522
|
-
}),
|
|
523
|
-
icon: /* @__PURE__ */ T(
|
|
523
|
+
}), V.length === 0 ? /* @__PURE__ */ T(d, {
|
|
524
|
+
icon: /* @__PURE__ */ T(ke, {
|
|
524
525
|
className: "size-6",
|
|
525
526
|
"aria-hidden": "true"
|
|
526
527
|
}),
|
|
527
528
|
title: "No portfolios yet",
|
|
528
529
|
description: "Create a portfolio to detect real tax-loss-harvesting opportunities from its holdings."
|
|
529
|
-
}) :
|
|
530
|
+
}) : St ? /* @__PURE__ */ T(p, {}) : Ct ? /* @__PURE__ */ T(f, { onRetry: () => wt() }) : G && G.opportunities.length > 0 ? /* @__PURE__ */ T("ul", {
|
|
530
531
|
className: "space-y-3",
|
|
531
|
-
children:
|
|
532
|
-
}) :
|
|
532
|
+
children: G.opportunities.map((e) => /* @__PURE__ */ T(mt, { opportunity: e }, e.symbol))
|
|
533
|
+
}) : G ? /* @__PURE__ */ T(d, {
|
|
533
534
|
icon: /* @__PURE__ */ T(C, {
|
|
534
535
|
className: "size-6",
|
|
535
536
|
"aria-hidden": "true"
|
|
@@ -537,7 +538,7 @@ function H() {
|
|
|
537
538
|
title: "No opportunities at the current thresholds",
|
|
538
539
|
description: "No symbol's unrealized loss clears the configured dollar/percent thresholds."
|
|
539
540
|
}) : /* @__PURE__ */ T(d, {
|
|
540
|
-
icon: /* @__PURE__ */ T(
|
|
541
|
+
icon: /* @__PURE__ */ T(ke, {
|
|
541
542
|
className: "size-6",
|
|
542
543
|
"aria-hidden": "true"
|
|
543
544
|
}),
|
|
@@ -547,7 +548,7 @@ function H() {
|
|
|
547
548
|
})] }),
|
|
548
549
|
/* @__PURE__ */ E(k, { children: [/* @__PURE__ */ E(M, { children: [/* @__PURE__ */ E(N, {
|
|
549
550
|
className: "flex items-center gap-2",
|
|
550
|
-
children: [/* @__PURE__ */ T(
|
|
551
|
+
children: [/* @__PURE__ */ T(we, {
|
|
551
552
|
className: "h-5 w-5",
|
|
552
553
|
"aria-hidden": "true"
|
|
553
554
|
}), "Trade instructions"]
|
|
@@ -565,16 +566,16 @@ function H() {
|
|
|
565
566
|
className: "flex gap-2",
|
|
566
567
|
children: [/* @__PURE__ */ T(F, {
|
|
567
568
|
id: "quote-symbol",
|
|
568
|
-
value:
|
|
569
|
-
onChange: (e) =>
|
|
569
|
+
value: Ot,
|
|
570
|
+
onChange: (e) => kt(e.target.value.toUpperCase()),
|
|
570
571
|
placeholder: "AAPL",
|
|
571
572
|
className: "w-28"
|
|
572
573
|
}), /* @__PURE__ */ E(O, {
|
|
573
574
|
variant: "outline",
|
|
574
575
|
size: "sm",
|
|
575
|
-
disabled: !
|
|
576
|
+
disabled: !Ot || q.isFetching,
|
|
576
577
|
onClick: () => q.refetch(),
|
|
577
|
-
children: [/* @__PURE__ */ T(
|
|
578
|
+
children: [/* @__PURE__ */ T(Ae, {
|
|
578
579
|
className: "size-4",
|
|
579
580
|
"aria-hidden": "true"
|
|
580
581
|
}), "Quote"]
|
|
@@ -588,7 +589,7 @@ function H() {
|
|
|
588
589
|
" ",
|
|
589
590
|
/* @__PURE__ */ T("span", {
|
|
590
591
|
className: "font-semibold",
|
|
591
|
-
children:
|
|
592
|
+
children: g(q.data.price, q.data.currency ?? "USD")
|
|
592
593
|
}),
|
|
593
594
|
" ",
|
|
594
595
|
/* @__PURE__ */ E("span", {
|
|
@@ -611,20 +612,20 @@ function H() {
|
|
|
611
612
|
children: "Symbol"
|
|
612
613
|
}), /* @__PURE__ */ T(F, {
|
|
613
614
|
id: "ti-symbol",
|
|
614
|
-
value:
|
|
615
|
-
onChange: (e) =>
|
|
615
|
+
value: At,
|
|
616
|
+
onChange: (e) => jt(e.target.value.toUpperCase()),
|
|
616
617
|
placeholder: "MSFT"
|
|
617
618
|
})]
|
|
618
619
|
}),
|
|
619
620
|
/* @__PURE__ */ E("div", {
|
|
620
621
|
className: "space-y-1.5",
|
|
621
|
-
children: [/* @__PURE__ */ T(I, { children: "Action" }), /* @__PURE__ */ E(
|
|
622
|
-
value:
|
|
623
|
-
onValueChange: (e) =>
|
|
624
|
-
children: [/* @__PURE__ */ T(
|
|
622
|
+
children: [/* @__PURE__ */ T(I, { children: "Action" }), /* @__PURE__ */ E(Ke, {
|
|
623
|
+
value: Mt,
|
|
624
|
+
onValueChange: (e) => Nt(e),
|
|
625
|
+
children: [/* @__PURE__ */ T(Ye, { children: /* @__PURE__ */ T(Xe, {}) }), /* @__PURE__ */ E(qe, { children: [/* @__PURE__ */ T(Je, {
|
|
625
626
|
value: "BUY",
|
|
626
627
|
children: "Buy"
|
|
627
|
-
}), /* @__PURE__ */ T(
|
|
628
|
+
}), /* @__PURE__ */ T(Je, {
|
|
628
629
|
value: "SELL",
|
|
629
630
|
children: "Sell"
|
|
630
631
|
})] })]
|
|
@@ -640,8 +641,8 @@ function H() {
|
|
|
640
641
|
type: "number",
|
|
641
642
|
min: "0",
|
|
642
643
|
step: "any",
|
|
643
|
-
value:
|
|
644
|
-
onChange: (e) =>
|
|
644
|
+
value: Pt,
|
|
645
|
+
onChange: (e) => Ft(e.target.value)
|
|
645
646
|
})]
|
|
646
647
|
}),
|
|
647
648
|
/* @__PURE__ */ E("div", {
|
|
@@ -651,8 +652,8 @@ function H() {
|
|
|
651
652
|
children: "Rationale"
|
|
652
653
|
}), /* @__PURE__ */ T(F, {
|
|
653
654
|
id: "ti-rationale",
|
|
654
|
-
value:
|
|
655
|
-
onChange: (e) =>
|
|
655
|
+
value: It,
|
|
656
|
+
onChange: (e) => Lt(e.target.value),
|
|
656
657
|
placeholder: "Optional"
|
|
657
658
|
})]
|
|
658
659
|
}),
|
|
@@ -660,34 +661,34 @@ function H() {
|
|
|
660
661
|
className: "sm:col-span-5",
|
|
661
662
|
children: /* @__PURE__ */ E(O, {
|
|
662
663
|
size: "sm",
|
|
663
|
-
disabled: !
|
|
664
|
+
disabled: !H || !At.trim() || !Pt || Number(Pt) <= 0 || Et.isPending,
|
|
664
665
|
onClick: () => {
|
|
665
|
-
|
|
666
|
-
portfolioId:
|
|
667
|
-
symbol:
|
|
668
|
-
action:
|
|
669
|
-
quantity: Number(
|
|
670
|
-
rationale:
|
|
666
|
+
Et.mutate({
|
|
667
|
+
portfolioId: H,
|
|
668
|
+
symbol: At.trim(),
|
|
669
|
+
action: Mt,
|
|
670
|
+
quantity: Number(Pt),
|
|
671
|
+
rationale: It.trim() || void 0
|
|
671
672
|
}, { onSuccess: () => {
|
|
672
|
-
|
|
673
|
+
jt(""), Ft(""), Lt("");
|
|
673
674
|
} });
|
|
674
675
|
},
|
|
675
|
-
children: [/* @__PURE__ */ T(
|
|
676
|
+
children: [/* @__PURE__ */ T(Ee, {
|
|
676
677
|
className: "size-4",
|
|
677
678
|
"aria-hidden": "true"
|
|
678
|
-
}),
|
|
679
|
+
}), Et.isPending ? "Creating…" : "Create instruction"]
|
|
679
680
|
})
|
|
680
681
|
})
|
|
681
682
|
]
|
|
682
683
|
}),
|
|
683
|
-
|
|
684
|
-
icon: /* @__PURE__ */ T(
|
|
684
|
+
H ? K.isLoading ? /* @__PURE__ */ T(p, {}) : K.isError ? /* @__PURE__ */ T(f, { onRetry: () => K.refetch() }) : K.data.length === 0 ? /* @__PURE__ */ T(d, {
|
|
685
|
+
icon: /* @__PURE__ */ T(we, {
|
|
685
686
|
className: "size-6",
|
|
686
687
|
"aria-hidden": "true"
|
|
687
688
|
}),
|
|
688
689
|
title: "No trade instructions yet",
|
|
689
690
|
description: "Create one above, or generate one from a rebalance proposal's trades."
|
|
690
|
-
}) : /* @__PURE__ */ E(
|
|
691
|
+
}) : /* @__PURE__ */ E(Ze, { children: [/* @__PURE__ */ T($e, { children: /* @__PURE__ */ E(z, { children: [
|
|
691
692
|
/* @__PURE__ */ T(R, { children: "Symbol" }),
|
|
692
693
|
/* @__PURE__ */ T(R, { children: "Action" }),
|
|
693
694
|
/* @__PURE__ */ T(R, { children: "Qty" }),
|
|
@@ -698,7 +699,7 @@ function H() {
|
|
|
698
699
|
className: "text-right",
|
|
699
700
|
children: "Review"
|
|
700
701
|
})
|
|
701
|
-
] }) }), /* @__PURE__ */ T(
|
|
702
|
+
] }) }), /* @__PURE__ */ T(Qe, { children: K.data.map((e) => /* @__PURE__ */ E(z, { children: [
|
|
702
703
|
/* @__PURE__ */ T(L, {
|
|
703
704
|
className: "font-medium",
|
|
704
705
|
children: e.symbol
|
|
@@ -708,13 +709,13 @@ function H() {
|
|
|
708
709
|
children: e.action
|
|
709
710
|
}) }),
|
|
710
711
|
/* @__PURE__ */ T(L, { children: e.quantity }),
|
|
711
|
-
/* @__PURE__ */ T(L, { children: e.referencePrice == null ? "—" :
|
|
712
|
+
/* @__PURE__ */ T(L, { children: e.referencePrice == null ? "—" : g(e.referencePrice) }),
|
|
712
713
|
/* @__PURE__ */ T(L, {
|
|
713
714
|
className: "text-xs text-text-muted",
|
|
714
715
|
children: e.priceSource ?? "—"
|
|
715
716
|
}),
|
|
716
717
|
/* @__PURE__ */ T(L, { children: /* @__PURE__ */ T(D, {
|
|
717
|
-
variant:
|
|
718
|
+
variant: v(e.status),
|
|
718
719
|
children: e.status
|
|
719
720
|
}) }),
|
|
720
721
|
/* @__PURE__ */ T(L, {
|
|
@@ -724,20 +725,20 @@ function H() {
|
|
|
724
725
|
children: [/* @__PURE__ */ T(O, {
|
|
725
726
|
size: "sm",
|
|
726
727
|
variant: "ghost",
|
|
727
|
-
disabled:
|
|
728
|
-
onClick: () =>
|
|
728
|
+
disabled: Dt.isPending,
|
|
729
|
+
onClick: () => Dt.mutate({
|
|
729
730
|
id: e.id,
|
|
730
731
|
status: "ACKNOWLEDGED"
|
|
731
732
|
}),
|
|
732
|
-
children: /* @__PURE__ */ T(
|
|
733
|
+
children: /* @__PURE__ */ T(xe, {
|
|
733
734
|
className: "size-4",
|
|
734
735
|
"aria-hidden": "true"
|
|
735
736
|
})
|
|
736
737
|
}), /* @__PURE__ */ T(O, {
|
|
737
738
|
size: "sm",
|
|
738
739
|
variant: "ghost",
|
|
739
|
-
disabled:
|
|
740
|
-
onClick: () =>
|
|
740
|
+
disabled: Dt.isPending,
|
|
741
|
+
onClick: () => Dt.mutate({
|
|
741
742
|
id: e.id,
|
|
742
743
|
status: "DISMISSED"
|
|
743
744
|
}),
|
|
@@ -752,7 +753,7 @@ function H() {
|
|
|
752
753
|
})
|
|
753
754
|
})
|
|
754
755
|
] }, e.id)) })] }) : /* @__PURE__ */ T(d, {
|
|
755
|
-
icon: /* @__PURE__ */ T(
|
|
756
|
+
icon: /* @__PURE__ */ T(we, {
|
|
756
757
|
className: "size-6",
|
|
757
758
|
"aria-hidden": "true"
|
|
758
759
|
}),
|
|
@@ -763,28 +764,28 @@ function H() {
|
|
|
763
764
|
})] }),
|
|
764
765
|
/* @__PURE__ */ E(k, { children: [/* @__PURE__ */ E(M, { children: [/* @__PURE__ */ E(N, {
|
|
765
766
|
className: "flex items-center gap-2",
|
|
766
|
-
children: [/* @__PURE__ */ T(
|
|
767
|
+
children: [/* @__PURE__ */ T(Oe, {
|
|
767
768
|
className: "h-5 w-5",
|
|
768
769
|
"aria-hidden": "true"
|
|
769
770
|
}), "Rebalance proposals"]
|
|
770
|
-
}), /* @__PURE__ */ T(j, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ T(A, { children:
|
|
771
|
-
icon: /* @__PURE__ */ T(
|
|
771
|
+
}), /* @__PURE__ */ T(j, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ T(A, { children: m ? /* @__PURE__ */ T(p, {}) : ge ? /* @__PURE__ */ T(f, { onRetry: () => _e() }) : l.length === 0 ? /* @__PURE__ */ T(d, {
|
|
772
|
+
icon: /* @__PURE__ */ T(Oe, {
|
|
772
773
|
className: "size-6",
|
|
773
774
|
"aria-hidden": "true"
|
|
774
775
|
}),
|
|
775
776
|
title: "No rebalance proposals",
|
|
776
|
-
description:
|
|
777
|
-
action:
|
|
777
|
+
description: un ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
|
|
778
|
+
action: un ? /* @__PURE__ */ E(O, {
|
|
778
779
|
size: "sm",
|
|
779
|
-
onClick:
|
|
780
|
-
children: [/* @__PURE__ */ T(
|
|
780
|
+
onClick: dn,
|
|
781
|
+
children: [/* @__PURE__ */ T(Ee, {
|
|
781
782
|
className: "size-4",
|
|
782
783
|
"aria-hidden": "true"
|
|
783
784
|
}), "New proposal"]
|
|
784
785
|
}) : void 0
|
|
785
786
|
}) : /* @__PURE__ */ T("div", {
|
|
786
787
|
className: "overflow-x-auto",
|
|
787
|
-
children: /* @__PURE__ */ E(
|
|
788
|
+
children: /* @__PURE__ */ E(Ze, { children: [/* @__PURE__ */ T($e, { children: /* @__PURE__ */ E(z, { children: [
|
|
788
789
|
/* @__PURE__ */ T(R, { children: "Portfolio" }),
|
|
789
790
|
/* @__PURE__ */ T(R, {
|
|
790
791
|
className: "text-right",
|
|
@@ -798,10 +799,10 @@ function H() {
|
|
|
798
799
|
className: "w-12 text-right",
|
|
799
800
|
children: "Actions"
|
|
800
801
|
})
|
|
801
|
-
] }) }), /* @__PURE__ */ T(
|
|
802
|
-
let t = Q.get(e.portfolioId), n =
|
|
802
|
+
] }) }), /* @__PURE__ */ T(Qe, { children: l.map((e) => {
|
|
803
|
+
let t = Q.get(e.portfolioId), n = mn(e), r = tt[e.status], i = t?.driftThresholdPct, a = i != null && i > 0 ? Math.min(100, e.driftPct / i * 100) : null;
|
|
803
804
|
return /* @__PURE__ */ E(z, {
|
|
804
|
-
onClick: () =>
|
|
805
|
+
onClick: () => en(e),
|
|
805
806
|
className: "cursor-pointer transition-colors motion-safe:hover:bg-bg-elevated",
|
|
806
807
|
children: [
|
|
807
808
|
/* @__PURE__ */ E(L, { children: [/* @__PURE__ */ T("p", {
|
|
@@ -809,16 +810,16 @@ function H() {
|
|
|
809
810
|
children: t?.name ?? "Unknown portfolio"
|
|
810
811
|
}), /* @__PURE__ */ E("p", {
|
|
811
812
|
className: "text-xs text-text-secondary",
|
|
812
|
-
children: [t?.baseCurrency ?? "—", i == null ? "" : ` · threshold ${
|
|
813
|
+
children: [t?.baseCurrency ?? "—", i == null ? "" : ` · threshold ${_(i)}`]
|
|
813
814
|
})] }),
|
|
814
815
|
/* @__PURE__ */ E(L, {
|
|
815
816
|
className: "text-right",
|
|
816
817
|
children: [/* @__PURE__ */ E("span", {
|
|
817
818
|
className: `inline-flex items-center justify-end gap-1 font-semibold tabular-nums ${n ? "text-status-error-text" : "text-text-primary"}`,
|
|
818
|
-
children: [n ? /* @__PURE__ */ T(
|
|
819
|
+
children: [n ? /* @__PURE__ */ T(ye, {
|
|
819
820
|
className: "size-4",
|
|
820
821
|
"aria-hidden": "true"
|
|
821
|
-
}) : null,
|
|
822
|
+
}) : null, _(e.driftPct)]
|
|
822
823
|
}), a == null ? n ? /* @__PURE__ */ T("p", {
|
|
823
824
|
className: "text-xs text-status-error-text",
|
|
824
825
|
children: "Over threshold"
|
|
@@ -839,7 +840,7 @@ function H() {
|
|
|
839
840
|
})]
|
|
840
841
|
}),
|
|
841
842
|
/* @__PURE__ */ T(L, { children: /* @__PURE__ */ T(D, {
|
|
842
|
-
variant:
|
|
843
|
+
variant: v(e.status),
|
|
843
844
|
children: B(e.status)
|
|
844
845
|
}) }),
|
|
845
846
|
/* @__PURE__ */ T(L, {
|
|
@@ -851,44 +852,44 @@ function H() {
|
|
|
851
852
|
}),
|
|
852
853
|
/* @__PURE__ */ T(L, {
|
|
853
854
|
className: "text-sm text-text-secondary",
|
|
854
|
-
children:
|
|
855
|
+
children: lt(e.trades)
|
|
855
856
|
}),
|
|
856
857
|
/* @__PURE__ */ T(L, {
|
|
857
858
|
className: "text-sm text-text-secondary",
|
|
858
|
-
children:
|
|
859
|
+
children: h(e.createdAt)
|
|
859
860
|
}),
|
|
860
861
|
/* @__PURE__ */ T(L, {
|
|
861
862
|
className: "text-right",
|
|
862
863
|
onClick: (e) => e.stopPropagation(),
|
|
863
|
-
children: /* @__PURE__ */ E(
|
|
864
|
+
children: /* @__PURE__ */ E(Pe, { children: [/* @__PURE__ */ T(Re, {
|
|
864
865
|
asChild: !0,
|
|
865
866
|
children: /* @__PURE__ */ T(O, {
|
|
866
867
|
variant: "ghost",
|
|
867
868
|
size: "sm",
|
|
868
869
|
"aria-label": `Actions for ${t?.name ?? "proposal"}`,
|
|
869
|
-
children: /* @__PURE__ */ T(
|
|
870
|
+
children: /* @__PURE__ */ T(Te, {
|
|
870
871
|
className: "size-4",
|
|
871
872
|
"aria-hidden": "true"
|
|
872
873
|
})
|
|
873
874
|
})
|
|
874
|
-
}), /* @__PURE__ */ E(
|
|
875
|
+
}), /* @__PURE__ */ E(Fe, {
|
|
875
876
|
align: "end",
|
|
876
877
|
children: [/* @__PURE__ */ E(P, {
|
|
877
|
-
onClick: () =>
|
|
878
|
-
children: [/* @__PURE__ */ T(
|
|
878
|
+
onClick: () => en(e),
|
|
879
|
+
children: [/* @__PURE__ */ T(Se, {
|
|
879
880
|
className: "size-4",
|
|
880
881
|
"aria-hidden": "true"
|
|
881
882
|
}), "View details"]
|
|
882
|
-
}), r.length > 0 ? /* @__PURE__ */ E(
|
|
883
|
-
/* @__PURE__ */ T(
|
|
884
|
-
/* @__PURE__ */ T(
|
|
883
|
+
}), r.length > 0 ? /* @__PURE__ */ E(Ne, { children: [
|
|
884
|
+
/* @__PURE__ */ T(Le, {}),
|
|
885
|
+
/* @__PURE__ */ T(Ie, { children: "Advance to" }),
|
|
885
886
|
r.map((t) => {
|
|
886
887
|
let n = t === "REJECTED" || t === "CANCELLED";
|
|
887
888
|
return /* @__PURE__ */ E(P, {
|
|
888
889
|
disabled: J.isPending,
|
|
889
890
|
className: n ? "text-status-error-text" : void 0,
|
|
890
|
-
onClick: () =>
|
|
891
|
-
children: [T(n ? w :
|
|
891
|
+
onClick: () => pn(e, t),
|
|
892
|
+
children: [T(n ? w : be, {
|
|
892
893
|
className: "size-4",
|
|
893
894
|
"aria-hidden": "true"
|
|
894
895
|
}), B(t)]
|
|
@@ -907,7 +908,7 @@ function H() {
|
|
|
907
908
|
className: "h-5 w-5",
|
|
908
909
|
"aria-hidden": "true"
|
|
909
910
|
}), "Risk insights"]
|
|
910
|
-
}), /* @__PURE__ */ T(j, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ T(A, { children:
|
|
911
|
+
}), /* @__PURE__ */ T(j, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ T(A, { children: Vt ? /* @__PURE__ */ T(p, {}) : Ut ? /* @__PURE__ */ T(f, { onRetry: () => Wt() }) : nn.length === 0 ? /* @__PURE__ */ T(d, {
|
|
911
912
|
icon: /* @__PURE__ */ T(C, {
|
|
912
913
|
className: "size-6",
|
|
913
914
|
"aria-hidden": "true"
|
|
@@ -916,28 +917,28 @@ function H() {
|
|
|
916
917
|
description: "No drift, concentration, cash-drag or fee-anomaly signals are open right now."
|
|
917
918
|
}) : /* @__PURE__ */ E("div", {
|
|
918
919
|
className: "space-y-3",
|
|
919
|
-
children: [
|
|
920
|
+
children: [nn.map((e, t) => /* @__PURE__ */ T(c, {
|
|
920
921
|
index: t,
|
|
921
|
-
children: /* @__PURE__ */ T(
|
|
922
|
+
children: /* @__PURE__ */ T(ht, {
|
|
922
923
|
insight: e,
|
|
923
|
-
onAcknowledge: () =>
|
|
924
|
-
onResolve: () =>
|
|
925
|
-
onDismiss: () =>
|
|
926
|
-
actionPending:
|
|
924
|
+
onAcknowledge: () => Kt.mutate(e.id),
|
|
925
|
+
onResolve: () => Jt.mutate(e.id),
|
|
926
|
+
onDismiss: () => qt.mutate(e.id),
|
|
927
|
+
actionPending: Kt.isPending || Jt.isPending || qt.isPending
|
|
927
928
|
})
|
|
928
|
-
}, e.id)), /* @__PURE__ */ T(
|
|
929
|
-
hasMore:
|
|
930
|
-
onClick:
|
|
931
|
-
loading:
|
|
929
|
+
}, e.id)), /* @__PURE__ */ T(ue, {
|
|
930
|
+
hasMore: zt,
|
|
931
|
+
onClick: Bt,
|
|
932
|
+
loading: Ht,
|
|
932
933
|
label: "Load more insights"
|
|
933
934
|
})]
|
|
934
935
|
}) })] }),
|
|
935
|
-
/* @__PURE__ */ T(
|
|
936
|
-
open:
|
|
937
|
-
onOpenChange:
|
|
938
|
-
children: /* @__PURE__ */ E(
|
|
939
|
-
/* @__PURE__ */ E(
|
|
940
|
-
|
|
936
|
+
/* @__PURE__ */ T(ze, {
|
|
937
|
+
open: Yt,
|
|
938
|
+
onOpenChange: Xt,
|
|
939
|
+
children: /* @__PURE__ */ E(Ve, { children: [
|
|
940
|
+
/* @__PURE__ */ E(We, { children: [/* @__PURE__ */ T(Ge, { children: "New rebalance proposal" }), /* @__PURE__ */ T(He, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
|
|
941
|
+
un ? /* @__PURE__ */ E("div", {
|
|
941
942
|
className: "grid gap-4",
|
|
942
943
|
children: [
|
|
943
944
|
/* @__PURE__ */ E("div", {
|
|
@@ -950,16 +951,16 @@ function H() {
|
|
|
950
951
|
className: "text-status-error-text",
|
|
951
952
|
children: "*"
|
|
952
953
|
})]
|
|
953
|
-
}), /* @__PURE__ */ E(
|
|
954
|
+
}), /* @__PURE__ */ E(Ke, {
|
|
954
955
|
value: Y.portfolioId,
|
|
955
956
|
onValueChange: (e) => X((t) => ({
|
|
956
957
|
...t,
|
|
957
958
|
portfolioId: e
|
|
958
959
|
})),
|
|
959
|
-
children: [/* @__PURE__ */ T(
|
|
960
|
+
children: [/* @__PURE__ */ T(Ye, {
|
|
960
961
|
id: "prop-portfolio",
|
|
961
|
-
children: /* @__PURE__ */ T(
|
|
962
|
-
}), /* @__PURE__ */ T(
|
|
962
|
+
children: /* @__PURE__ */ T(Xe, { placeholder: "Select a portfolio" })
|
|
963
|
+
}), /* @__PURE__ */ T(qe, { children: V.map((e) => /* @__PURE__ */ T(Je, {
|
|
963
964
|
value: e.id,
|
|
964
965
|
children: e.name
|
|
965
966
|
}, e.id)) })]
|
|
@@ -986,7 +987,7 @@ function H() {
|
|
|
986
987
|
children: [/* @__PURE__ */ T(I, {
|
|
987
988
|
htmlFor: "prop-rationale",
|
|
988
989
|
children: "Rationale"
|
|
989
|
-
}), /* @__PURE__ */ T(
|
|
990
|
+
}), /* @__PURE__ */ T(et, {
|
|
990
991
|
id: "prop-rationale",
|
|
991
992
|
value: Y.rationale,
|
|
992
993
|
onChange: (e) => X((t) => ({
|
|
@@ -1003,66 +1004,66 @@ function H() {
|
|
|
1003
1004
|
htmlFor: "prop-trades",
|
|
1004
1005
|
children: "Trades (JSON, optional)"
|
|
1005
1006
|
}),
|
|
1006
|
-
/* @__PURE__ */ T(
|
|
1007
|
+
/* @__PURE__ */ T(et, {
|
|
1007
1008
|
id: "prop-trades",
|
|
1008
1009
|
className: "font-mono text-xs",
|
|
1009
1010
|
value: Y.trades,
|
|
1010
1011
|
onChange: (e) => {
|
|
1011
|
-
|
|
1012
|
+
Qt(null), X((t) => ({
|
|
1012
1013
|
...t,
|
|
1013
1014
|
trades: e.target.value
|
|
1014
1015
|
}));
|
|
1015
1016
|
},
|
|
1016
1017
|
placeholder: "e.g. [{\"symbol\":\"VOO\",\"action\":\"SELL\",\"quantity\":10}]"
|
|
1017
1018
|
}),
|
|
1018
|
-
|
|
1019
|
+
Zt ? /* @__PURE__ */ T("p", {
|
|
1019
1020
|
className: "text-xs text-status-error-text",
|
|
1020
|
-
children:
|
|
1021
|
+
children: Zt
|
|
1021
1022
|
}) : null
|
|
1022
1023
|
]
|
|
1023
1024
|
})
|
|
1024
1025
|
]
|
|
1025
1026
|
}) : /* @__PURE__ */ T(d, {
|
|
1026
|
-
icon: /* @__PURE__ */ T(
|
|
1027
|
+
icon: /* @__PURE__ */ T(Oe, {
|
|
1027
1028
|
className: "size-6",
|
|
1028
1029
|
"aria-hidden": "true"
|
|
1029
1030
|
}),
|
|
1030
1031
|
title: "Create a portfolio first",
|
|
1031
1032
|
description: "A rebalance proposal targets a portfolio. Add a portfolio on the Portfolios page, then return here to propose a rebalance."
|
|
1032
1033
|
}),
|
|
1033
|
-
/* @__PURE__ */ E(
|
|
1034
|
+
/* @__PURE__ */ E(Ue, { children: [/* @__PURE__ */ T(Be, {
|
|
1034
1035
|
asChild: !0,
|
|
1035
1036
|
children: /* @__PURE__ */ T(O, {
|
|
1036
1037
|
variant: "outline",
|
|
1037
1038
|
children: "Cancel"
|
|
1038
1039
|
})
|
|
1039
1040
|
}), /* @__PURE__ */ T(O, {
|
|
1040
|
-
onClick:
|
|
1041
|
-
disabled: !Y.portfolioId ||
|
|
1042
|
-
children:
|
|
1041
|
+
onClick: fn,
|
|
1042
|
+
disabled: !Y.portfolioId || Gt.isPending,
|
|
1043
|
+
children: Gt.isPending ? "Creating…" : "Create proposal"
|
|
1043
1044
|
})] })
|
|
1044
1045
|
] })
|
|
1045
1046
|
}),
|
|
1046
1047
|
(() => {
|
|
1047
|
-
let e =
|
|
1048
|
-
return /* @__PURE__ */ T(
|
|
1048
|
+
let e = $t ? l.find((e) => e.id === $t.id) ?? $t : null, t = e ? Rt.filter((t) => t.subjectId === e.portfolioId) : [];
|
|
1049
|
+
return /* @__PURE__ */ T(ft, {
|
|
1049
1050
|
proposal: e,
|
|
1050
1051
|
portfolio: e ? Q.get(e.portfolioId) ?? null : null,
|
|
1051
1052
|
relatedInsights: t,
|
|
1052
|
-
nextStatuses: e ?
|
|
1053
|
+
nextStatuses: e ? tt[e.status] : [],
|
|
1053
1054
|
transitionPending: J.isPending,
|
|
1054
1055
|
onTransition: (t) => {
|
|
1055
|
-
e &&
|
|
1056
|
+
e && pn(e, t);
|
|
1056
1057
|
},
|
|
1057
1058
|
onOpenChange: (e) => {
|
|
1058
|
-
e ||
|
|
1059
|
+
e || en(null);
|
|
1059
1060
|
}
|
|
1060
1061
|
});
|
|
1061
1062
|
})(),
|
|
1062
|
-
/* @__PURE__ */ T(
|
|
1063
|
+
/* @__PURE__ */ T(de, {
|
|
1063
1064
|
open: Z !== null,
|
|
1064
1065
|
onOpenChange: (e) => {
|
|
1065
|
-
e ||
|
|
1066
|
+
e || tn(null);
|
|
1066
1067
|
},
|
|
1067
1068
|
title: Z?.status === "REJECTED" ? "Reject this proposal?" : "Cancel this proposal?",
|
|
1068
1069
|
description: Z ? `This moves the rebalance proposal for ${Q.get(Z.proposal.portfolioId)?.name ?? "this portfolio"} to ${B(Z.status)}. This cannot be undone.` : void 0,
|
|
@@ -1074,26 +1075,26 @@ function H() {
|
|
|
1074
1075
|
Z && J.mutate({
|
|
1075
1076
|
id: Z.proposal.id,
|
|
1076
1077
|
status: Z.status
|
|
1077
|
-
}, { onSuccess: () =>
|
|
1078
|
+
}, { onSuccess: () => tn(null) });
|
|
1078
1079
|
}
|
|
1079
1080
|
})
|
|
1080
1081
|
]
|
|
1081
1082
|
});
|
|
1082
1083
|
}
|
|
1083
|
-
function
|
|
1084
|
-
let
|
|
1085
|
-
return /* @__PURE__ */ T(
|
|
1084
|
+
function ft({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, transitionPending: i, onTransition: a, onOpenChange: ee }) {
|
|
1085
|
+
let o = e ? st(e.trades) : null, te = e != null && t?.driftThresholdPct != null && Number.isFinite(t.driftThresholdPct) && e.driftPct >= t.driftThresholdPct;
|
|
1086
|
+
return /* @__PURE__ */ T(ze, {
|
|
1086
1087
|
open: e !== null,
|
|
1087
|
-
onOpenChange:
|
|
1088
|
-
children: /* @__PURE__ */ T(
|
|
1088
|
+
onOpenChange: ee,
|
|
1089
|
+
children: /* @__PURE__ */ T(Ve, {
|
|
1089
1090
|
className: "max-h-[88vh] max-w-3xl overflow-y-auto",
|
|
1090
|
-
children: e ? /* @__PURE__ */ E(
|
|
1091
|
-
/* @__PURE__ */ E(
|
|
1091
|
+
children: e ? /* @__PURE__ */ E(Ne, { children: [
|
|
1092
|
+
/* @__PURE__ */ E(We, { children: [
|
|
1092
1093
|
/* @__PURE__ */ T("p", {
|
|
1093
1094
|
className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
|
|
1094
1095
|
children: "Detail"
|
|
1095
1096
|
}),
|
|
1096
|
-
/* @__PURE__ */ E(
|
|
1097
|
+
/* @__PURE__ */ E(Ge, {
|
|
1097
1098
|
className: "flex flex-wrap items-center gap-2 text-xl",
|
|
1098
1099
|
children: [
|
|
1099
1100
|
t?.name ?? "Rebalance proposal",
|
|
@@ -1102,21 +1103,21 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1102
1103
|
children: "— Rebalance proposal"
|
|
1103
1104
|
}),
|
|
1104
1105
|
/* @__PURE__ */ T(D, {
|
|
1105
|
-
variant:
|
|
1106
|
+
variant: v(e.status),
|
|
1106
1107
|
children: B(e.status)
|
|
1107
1108
|
})
|
|
1108
1109
|
]
|
|
1109
1110
|
}),
|
|
1110
|
-
/* @__PURE__ */ E(
|
|
1111
|
+
/* @__PURE__ */ E(He, { children: [
|
|
1111
1112
|
"Created ",
|
|
1112
|
-
|
|
1113
|
-
e.executedAt ? ` · executed ${
|
|
1113
|
+
h(e.createdAt),
|
|
1114
|
+
e.executedAt ? ` · executed ${h(e.executedAt)}` : ""
|
|
1114
1115
|
] })
|
|
1115
1116
|
] }),
|
|
1116
1117
|
/* @__PURE__ */ T("div", {
|
|
1117
1118
|
className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
|
|
1118
|
-
children: /* @__PURE__ */ T(
|
|
1119
|
-
steps:
|
|
1119
|
+
children: /* @__PURE__ */ T(l, {
|
|
1120
|
+
steps: V,
|
|
1120
1121
|
current: B(e.status)
|
|
1121
1122
|
})
|
|
1122
1123
|
}),
|
|
@@ -1125,9 +1126,9 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1125
1126
|
children: [
|
|
1126
1127
|
/* @__PURE__ */ T(u, {
|
|
1127
1128
|
label: "Drift",
|
|
1128
|
-
value:
|
|
1129
|
-
deltaTone:
|
|
1130
|
-
glow:
|
|
1129
|
+
value: _(e.driftPct),
|
|
1130
|
+
deltaTone: te ? "negative" : "neutral",
|
|
1131
|
+
glow: te,
|
|
1131
1132
|
icon: /* @__PURE__ */ T(x, {
|
|
1132
1133
|
className: "size-4",
|
|
1133
1134
|
"aria-hidden": "true"
|
|
@@ -1135,7 +1136,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1135
1136
|
}),
|
|
1136
1137
|
/* @__PURE__ */ T(u, {
|
|
1137
1138
|
label: "Threshold",
|
|
1138
|
-
value: t?.driftThresholdPct == null ? "—" :
|
|
1139
|
+
value: t?.driftThresholdPct == null ? "—" : _(t.driftThresholdPct)
|
|
1139
1140
|
}),
|
|
1140
1141
|
/* @__PURE__ */ E("div", {
|
|
1141
1142
|
className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
|
|
@@ -1144,7 +1145,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1144
1145
|
children: "Proposed by"
|
|
1145
1146
|
}), /* @__PURE__ */ T("p", {
|
|
1146
1147
|
className: "mt-1 truncate text-sm font-medium text-text-primary",
|
|
1147
|
-
children: e.proposedById ? /* @__PURE__ */ T(
|
|
1148
|
+
children: e.proposedById ? /* @__PURE__ */ T(s, { id: e.proposedById }) : "—"
|
|
1148
1149
|
})]
|
|
1149
1150
|
}),
|
|
1150
1151
|
/* @__PURE__ */ E("div", {
|
|
@@ -1154,7 +1155,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1154
1155
|
children: "Approved by"
|
|
1155
1156
|
}), /* @__PURE__ */ T("p", {
|
|
1156
1157
|
className: "mt-1 truncate text-sm font-medium text-text-primary",
|
|
1157
|
-
children: e.approvedById ? /* @__PURE__ */ T(
|
|
1158
|
+
children: e.approvedById ? /* @__PURE__ */ T(s, { id: e.approvedById }) : "—"
|
|
1158
1159
|
})]
|
|
1159
1160
|
})
|
|
1160
1161
|
]
|
|
@@ -1164,9 +1165,9 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1164
1165
|
children: [/* @__PURE__ */ T("h3", {
|
|
1165
1166
|
className: "text-sm font-semibold text-text-primary",
|
|
1166
1167
|
children: "Proposed trades"
|
|
1167
|
-
}),
|
|
1168
|
+
}), o && o.length > 0 ? /* @__PURE__ */ T("div", {
|
|
1168
1169
|
className: "overflow-x-auto rounded-lg border border-border-subtle",
|
|
1169
|
-
children: /* @__PURE__ */ E(
|
|
1170
|
+
children: /* @__PURE__ */ E(Ze, { children: [/* @__PURE__ */ T($e, { children: /* @__PURE__ */ E(z, { children: [
|
|
1170
1171
|
/* @__PURE__ */ T(R, { children: "Action" }),
|
|
1171
1172
|
/* @__PURE__ */ T(R, { children: "Symbol" }),
|
|
1172
1173
|
/* @__PURE__ */ T(R, {
|
|
@@ -1177,9 +1178,9 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1177
1178
|
className: "text-right",
|
|
1178
1179
|
children: "Est. value"
|
|
1179
1180
|
})
|
|
1180
|
-
] }) }), /* @__PURE__ */ T(
|
|
1181
|
+
] }) }), /* @__PURE__ */ T(Qe, { children: o.map((e, n) => /* @__PURE__ */ E(z, { children: [
|
|
1181
1182
|
/* @__PURE__ */ T(L, {
|
|
1182
|
-
className: `font-semibold ${
|
|
1183
|
+
className: `font-semibold ${ct(e.action)}`,
|
|
1183
1184
|
children: e.action ? e.action.toUpperCase() : "—"
|
|
1184
1185
|
}),
|
|
1185
1186
|
/* @__PURE__ */ T(L, {
|
|
@@ -1192,12 +1193,12 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1192
1193
|
}),
|
|
1193
1194
|
/* @__PURE__ */ T(L, {
|
|
1194
1195
|
className: "text-right tabular-nums text-text-secondary",
|
|
1195
|
-
children: e.value == null ? "—" :
|
|
1196
|
+
children: e.value == null ? "—" : g(e.value, t?.baseCurrency ?? "USD")
|
|
1196
1197
|
})
|
|
1197
1198
|
] }, n)) })] })
|
|
1198
1199
|
}) : /* @__PURE__ */ E("p", {
|
|
1199
1200
|
className: "text-sm text-text-secondary",
|
|
1200
|
-
children: [
|
|
1201
|
+
children: [lt(e.trades), " — no structured trade breakdown available."]
|
|
1201
1202
|
})]
|
|
1202
1203
|
}),
|
|
1203
1204
|
/* @__PURE__ */ E("div", {
|
|
@@ -1220,7 +1221,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1220
1221
|
disabled: i,
|
|
1221
1222
|
className: t ? "text-status-error-text" : void 0,
|
|
1222
1223
|
onClick: () => a(e),
|
|
1223
|
-
children: [T(t ? w :
|
|
1224
|
+
children: [T(t ? w : be, {
|
|
1224
1225
|
className: "size-4",
|
|
1225
1226
|
"aria-hidden": "true"
|
|
1226
1227
|
}), B(e)]
|
|
@@ -1247,7 +1248,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1247
1248
|
children: e.title
|
|
1248
1249
|
}),
|
|
1249
1250
|
/* @__PURE__ */ T(D, {
|
|
1250
|
-
variant:
|
|
1251
|
+
variant: v(e.severity),
|
|
1251
1252
|
children: B(e.severity)
|
|
1252
1253
|
}),
|
|
1253
1254
|
/* @__PURE__ */ T(D, {
|
|
@@ -1255,7 +1256,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1255
1256
|
children: B(e.type)
|
|
1256
1257
|
}),
|
|
1257
1258
|
/* @__PURE__ */ T(D, {
|
|
1258
|
-
variant:
|
|
1259
|
+
variant: v(e.status),
|
|
1259
1260
|
children: B(e.status)
|
|
1260
1261
|
})
|
|
1261
1262
|
]
|
|
@@ -1268,7 +1269,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1268
1269
|
}) : null,
|
|
1269
1270
|
/* @__PURE__ */ T("div", {
|
|
1270
1271
|
className: "border-t border-border-subtle pt-4",
|
|
1271
|
-
children: /* @__PURE__ */ T(
|
|
1272
|
+
children: /* @__PURE__ */ T(_e, {
|
|
1272
1273
|
entityType: "brainyrich-rebalance",
|
|
1273
1274
|
entityId: e.id,
|
|
1274
1275
|
heading: "Discussion"
|
|
@@ -1278,7 +1279,7 @@ function dt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
|
|
|
1278
1279
|
})
|
|
1279
1280
|
});
|
|
1280
1281
|
}
|
|
1281
|
-
function
|
|
1282
|
+
function pt({ signal: e }) {
|
|
1282
1283
|
let t = ge(e.metrics);
|
|
1283
1284
|
return /* @__PURE__ */ E("li", {
|
|
1284
1285
|
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
@@ -1291,7 +1292,7 @@ function ft({ signal: e }) {
|
|
|
1291
1292
|
children: e.title
|
|
1292
1293
|
}),
|
|
1293
1294
|
/* @__PURE__ */ T(D, {
|
|
1294
|
-
variant:
|
|
1295
|
+
variant: v(e.severity),
|
|
1295
1296
|
children: B(e.severity)
|
|
1296
1297
|
}),
|
|
1297
1298
|
/* @__PURE__ */ T(D, {
|
|
@@ -1309,12 +1310,12 @@ function ft({ signal: e }) {
|
|
|
1309
1310
|
children: [t.formula ? /* @__PURE__ */ T("p", {
|
|
1310
1311
|
className: "break-words text-xs text-text-secondary",
|
|
1311
1312
|
children: t.formula
|
|
1312
|
-
}) : null, /* @__PURE__ */ T(
|
|
1313
|
+
}) : null, /* @__PURE__ */ T(m, { entries: t.entries })]
|
|
1313
1314
|
}) : null
|
|
1314
1315
|
]
|
|
1315
1316
|
});
|
|
1316
1317
|
}
|
|
1317
|
-
function
|
|
1318
|
+
function mt({ opportunity: e }) {
|
|
1318
1319
|
let t = ge(e.metrics);
|
|
1319
1320
|
return /* @__PURE__ */ E("li", {
|
|
1320
1321
|
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
@@ -1327,17 +1328,17 @@ function pt({ opportunity: e }) {
|
|
|
1327
1328
|
children: [
|
|
1328
1329
|
e.symbol,
|
|
1329
1330
|
" — unrealized loss ",
|
|
1330
|
-
|
|
1331
|
+
g(e.unrealizedLoss)
|
|
1331
1332
|
]
|
|
1332
1333
|
}),
|
|
1333
1334
|
/* @__PURE__ */ T(D, {
|
|
1334
|
-
variant:
|
|
1335
|
+
variant: v(e.severity),
|
|
1335
1336
|
children: B(e.severity)
|
|
1336
1337
|
}),
|
|
1337
1338
|
e.washSaleRisk ? /* @__PURE__ */ E(D, {
|
|
1338
1339
|
variant: "outline",
|
|
1339
1340
|
className: "text-status-error-text",
|
|
1340
|
-
children: [/* @__PURE__ */ T(
|
|
1341
|
+
children: [/* @__PURE__ */ T(ye, {
|
|
1341
1342
|
className: "mr-1 size-3",
|
|
1342
1343
|
"aria-hidden": "true"
|
|
1343
1344
|
}), "Wash-sale caution"]
|
|
@@ -1348,12 +1349,12 @@ function pt({ opportunity: e }) {
|
|
|
1348
1349
|
className: "mt-1 text-sm text-text-secondary",
|
|
1349
1350
|
children: [
|
|
1350
1351
|
"Market value ",
|
|
1351
|
-
|
|
1352
|
+
g(e.marketValue),
|
|
1352
1353
|
" vs. cost basis",
|
|
1353
1354
|
" ",
|
|
1354
|
-
|
|
1355
|
+
g(e.costBasis),
|
|
1355
1356
|
" · ",
|
|
1356
|
-
|
|
1357
|
+
_(e.lossPctOfPortfolio),
|
|
1357
1358
|
" of portfolio value"
|
|
1358
1359
|
]
|
|
1359
1360
|
}),
|
|
@@ -1366,12 +1367,12 @@ function pt({ opportunity: e }) {
|
|
|
1366
1367
|
children: [t.formula ? /* @__PURE__ */ T("p", {
|
|
1367
1368
|
className: "break-words text-xs text-text-secondary",
|
|
1368
1369
|
children: t.formula
|
|
1369
|
-
}) : null, /* @__PURE__ */ T(
|
|
1370
|
+
}) : null, /* @__PURE__ */ T(m, { entries: t.entries })]
|
|
1370
1371
|
}) : null
|
|
1371
1372
|
]
|
|
1372
1373
|
});
|
|
1373
1374
|
}
|
|
1374
|
-
function
|
|
1375
|
+
function ht({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
|
|
1375
1376
|
let a = e.status === "RESOLVED" || e.status === "DISMISSED";
|
|
1376
1377
|
return /* @__PURE__ */ E("div", {
|
|
1377
1378
|
className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4 transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]",
|
|
@@ -1386,7 +1387,7 @@ function mt({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPe
|
|
|
1386
1387
|
children: e.title
|
|
1387
1388
|
}),
|
|
1388
1389
|
/* @__PURE__ */ T(D, {
|
|
1389
|
-
variant:
|
|
1390
|
+
variant: v(e.severity),
|
|
1390
1391
|
children: B(e.severity)
|
|
1391
1392
|
}),
|
|
1392
1393
|
/* @__PURE__ */ T(D, {
|
|
@@ -1394,7 +1395,7 @@ function mt({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPe
|
|
|
1394
1395
|
children: B(e.type)
|
|
1395
1396
|
}),
|
|
1396
1397
|
/* @__PURE__ */ T(D, {
|
|
1397
|
-
variant:
|
|
1398
|
+
variant: v(e.status),
|
|
1398
1399
|
children: B(e.status)
|
|
1399
1400
|
})
|
|
1400
1401
|
]
|
|
@@ -1405,30 +1406,30 @@ function mt({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPe
|
|
|
1405
1406
|
}) : null,
|
|
1406
1407
|
/* @__PURE__ */ E("p", {
|
|
1407
1408
|
className: "text-xs text-text-muted",
|
|
1408
|
-
children: ["Detected ",
|
|
1409
|
+
children: ["Detected ", h(e.createdAt)]
|
|
1409
1410
|
})
|
|
1410
1411
|
]
|
|
1411
1412
|
}), a ? /* @__PURE__ */ T("span", {
|
|
1412
1413
|
className: "mt-1 text-xs text-text-muted",
|
|
1413
1414
|
children: "Closed"
|
|
1414
|
-
}) : /* @__PURE__ */ E(
|
|
1415
|
+
}) : /* @__PURE__ */ E(Pe, { children: [/* @__PURE__ */ T(Re, {
|
|
1415
1416
|
asChild: !0,
|
|
1416
1417
|
children: /* @__PURE__ */ T(O, {
|
|
1417
1418
|
variant: "ghost",
|
|
1418
1419
|
size: "sm",
|
|
1419
1420
|
"aria-label": `Actions for ${e.title}`,
|
|
1420
1421
|
disabled: i,
|
|
1421
|
-
children: /* @__PURE__ */ T(
|
|
1422
|
+
children: /* @__PURE__ */ T(Te, {
|
|
1422
1423
|
className: "size-4",
|
|
1423
1424
|
"aria-hidden": "true"
|
|
1424
1425
|
})
|
|
1425
1426
|
})
|
|
1426
|
-
}), /* @__PURE__ */ E(
|
|
1427
|
+
}), /* @__PURE__ */ E(Fe, {
|
|
1427
1428
|
align: "end",
|
|
1428
1429
|
children: [
|
|
1429
1430
|
e.status === "OPEN" ? /* @__PURE__ */ E(P, {
|
|
1430
1431
|
onClick: t,
|
|
1431
|
-
children: [/* @__PURE__ */ T(
|
|
1432
|
+
children: [/* @__PURE__ */ T(xe, {
|
|
1432
1433
|
className: "size-4",
|
|
1433
1434
|
"aria-hidden": "true"
|
|
1434
1435
|
}), "Acknowledge"]
|