@burdenoff/microfe-brainyrich 2026.825.1 → 2026.828.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/components/reuse/DocumentsPanel.d.ts +4 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts.map +1 -1
- package/dist/brainyrich/components/reuse/DocumentsPanel.js +150 -99
- package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.d.ts +179 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.d.ts.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.js +101 -83
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
- package/dist/brainyrich/pages/AccountsPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AccountsPage.js +159 -148
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AdminFirmPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AdminFirmPage.js +115 -83
- package/dist/brainyrich/pages/AdminFirmPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +251 -230
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/FirmPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/FirmPage.js +148 -116
- package/dist/brainyrich/pages/FirmPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.d.ts +14 -0
- package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +530 -353
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +381 -396
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.d.ts +21 -0
- package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
- package/dist/brainyrich/pages/_shared.js +66 -31
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/generated/global-operations.d.ts +31 -1
- package/dist/generated/global-operations.d.ts.map +1 -1
- package/dist/generated/wspace-operations.d.ts +31 -1
- package/dist/generated/wspace-operations.d.ts.map +1 -1
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/package.json +11 -2
|
@@ -4,27 +4,33 @@ import { Inbox as r, RefreshCw as i, TriangleAlert as a } from "lucide-react";
|
|
|
4
4
|
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
5
|
import { Badge as c, Button as l, Skeleton as u } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/brainyrich/pages/_shared.tsx
|
|
7
|
-
function d(e, t
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
function d(e, t, n) {
|
|
8
|
+
try {
|
|
9
|
+
return new Intl.NumberFormat("en-US", {
|
|
10
|
+
...n,
|
|
11
|
+
...t ? {
|
|
12
|
+
style: "currency",
|
|
13
|
+
currency: t
|
|
14
|
+
} : {}
|
|
15
|
+
}).format(e);
|
|
16
|
+
} catch {
|
|
17
|
+
let r = new Intl.NumberFormat("en-US", n).format(e);
|
|
18
|
+
return t ? `${r} ${t}` : r;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function f(e, t = "USD") {
|
|
22
|
+
return Number.isFinite(e) ? d(e, t, { maximumFractionDigits: 0 }) : "—";
|
|
23
|
+
}
|
|
24
|
+
function p(e, t) {
|
|
25
|
+
return Number.isFinite(e) ? d(e, t, {
|
|
16
26
|
notation: "compact",
|
|
17
|
-
maximumFractionDigits: 1
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} : {}
|
|
22
|
-
}).format(e) : "—";
|
|
23
|
-
}
|
|
24
|
-
function p(e, t = 1) {
|
|
27
|
+
maximumFractionDigits: 1
|
|
28
|
+
}) : "—";
|
|
29
|
+
}
|
|
30
|
+
function m(e, t = 1) {
|
|
25
31
|
return e == null || !Number.isFinite(e) ? "—" : `${e.toFixed(t)}%`;
|
|
26
32
|
}
|
|
27
|
-
function
|
|
33
|
+
function h(e) {
|
|
28
34
|
if (!e) return "—";
|
|
29
35
|
let t = new Date(e);
|
|
30
36
|
return Number.isNaN(t.getTime()) ? "—" : new Intl.DateTimeFormat("en-US", {
|
|
@@ -33,7 +39,7 @@ function m(e) {
|
|
|
33
39
|
day: "numeric"
|
|
34
40
|
}).format(t);
|
|
35
41
|
}
|
|
36
|
-
function
|
|
42
|
+
function g(e) {
|
|
37
43
|
let t = e.toUpperCase();
|
|
38
44
|
return [
|
|
39
45
|
"ACTIVE",
|
|
@@ -62,10 +68,10 @@ function h(e) {
|
|
|
62
68
|
"LOW"
|
|
63
69
|
].includes(t) ? "secondary" : "outline";
|
|
64
70
|
}
|
|
65
|
-
function
|
|
71
|
+
function _(e) {
|
|
66
72
|
return e > 0 ? "text-status-success-text" : e < 0 ? "text-status-error-text" : "text-text-secondary";
|
|
67
73
|
}
|
|
68
|
-
function
|
|
74
|
+
function v({ title: e, description: t, actionLabel: n, onAction: r, actions: i, badges: a = [], children: u }) {
|
|
69
75
|
return /* @__PURE__ */ s("div", {
|
|
70
76
|
className: "space-y-6 p-6",
|
|
71
77
|
children: [/* @__PURE__ */ s("div", {
|
|
@@ -94,14 +100,14 @@ function _({ title: e, description: t, actionLabel: n, onAction: r, actions: i,
|
|
|
94
100
|
}), u]
|
|
95
101
|
});
|
|
96
102
|
}
|
|
97
|
-
var
|
|
103
|
+
var y = {
|
|
98
104
|
default: "bg-primary",
|
|
99
105
|
positive: "bg-status-success-bg",
|
|
100
106
|
negative: "bg-status-error-bg",
|
|
101
107
|
warning: "bg-status-warning-bg",
|
|
102
108
|
accent: "bg-accent-teal"
|
|
103
109
|
};
|
|
104
|
-
function
|
|
110
|
+
function b({ width: r, className: i }) {
|
|
105
111
|
let a = e(), [s, c] = n(a ? r : 0);
|
|
106
112
|
return t(() => {
|
|
107
113
|
let e = requestAnimationFrame(() => c(r));
|
|
@@ -114,7 +120,7 @@ function y({ width: r, className: i }) {
|
|
|
114
120
|
}
|
|
115
121
|
});
|
|
116
122
|
}
|
|
117
|
-
function
|
|
123
|
+
function x({ data: e }) {
|
|
118
124
|
let t = e.filter((e) => Number.isFinite(e.value));
|
|
119
125
|
return t.length === 0 ? /* @__PURE__ */ o("p", {
|
|
120
126
|
className: "text-sm text-text-secondary",
|
|
@@ -132,7 +138,7 @@ function b({ data: e }) {
|
|
|
132
138
|
children: e.label
|
|
133
139
|
}), /* @__PURE__ */ o("span", {
|
|
134
140
|
className: "tabular-nums text-text-secondary",
|
|
135
|
-
children: e.caption ??
|
|
141
|
+
children: e.caption ?? m(e.value)
|
|
136
142
|
})]
|
|
137
143
|
}), /* @__PURE__ */ o("div", {
|
|
138
144
|
className: "h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken",
|
|
@@ -141,16 +147,45 @@ function b({ data: e }) {
|
|
|
141
147
|
"aria-valuemin": 0,
|
|
142
148
|
"aria-valuemax": 100,
|
|
143
149
|
"aria-label": e.label,
|
|
144
|
-
children: /* @__PURE__ */ o(
|
|
150
|
+
children: /* @__PURE__ */ o(b, {
|
|
145
151
|
width: t,
|
|
146
|
-
className: `h-full rounded-full ${
|
|
152
|
+
className: `h-full rounded-full ${y[e.tone ?? "default"]}`
|
|
147
153
|
})
|
|
148
154
|
})]
|
|
149
155
|
}, e.label);
|
|
150
156
|
})
|
|
151
157
|
});
|
|
152
158
|
}
|
|
153
|
-
function
|
|
159
|
+
function S(e) {
|
|
160
|
+
return e == null ? "—" : typeof e == "number" ? Number.isInteger(e) ? e.toLocaleString() : e.toLocaleString(void 0, { maximumFractionDigits: 2 }) : typeof e == "boolean" ? e ? "Yes" : "No" : typeof e == "string" ? e : JSON.stringify(e);
|
|
161
|
+
}
|
|
162
|
+
function C(e) {
|
|
163
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return null;
|
|
164
|
+
let t = Object.entries(e);
|
|
165
|
+
if (t.length === 0) return null;
|
|
166
|
+
let n = e.formula;
|
|
167
|
+
return {
|
|
168
|
+
formula: typeof n == "string" ? n : null,
|
|
169
|
+
entries: t.filter(([e]) => e !== "formula")
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function w({ entries: e }) {
|
|
173
|
+
return e.length === 0 ? null : /* @__PURE__ */ o("dl", {
|
|
174
|
+
className: "grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4",
|
|
175
|
+
children: e.map(([e, t]) => /* @__PURE__ */ s("div", {
|
|
176
|
+
className: "min-w-0",
|
|
177
|
+
children: [/* @__PURE__ */ o("dt", {
|
|
178
|
+
className: "truncate text-[11px] uppercase tracking-wide text-text-muted",
|
|
179
|
+
children: e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/_/g, " ").replace(/^./, (e) => e.toUpperCase())
|
|
180
|
+
}), /* @__PURE__ */ o("dd", {
|
|
181
|
+
className: "truncate text-sm font-medium tabular-nums text-text-primary",
|
|
182
|
+
title: S(t),
|
|
183
|
+
children: S(t)
|
|
184
|
+
})]
|
|
185
|
+
}, e))
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function T({ icon: e, title: t, description: n, action: i }) {
|
|
154
189
|
return /* @__PURE__ */ s("div", {
|
|
155
190
|
className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center",
|
|
156
191
|
children: [
|
|
@@ -176,7 +211,7 @@ function x({ icon: e, title: t, description: n, action: i }) {
|
|
|
176
211
|
]
|
|
177
212
|
});
|
|
178
213
|
}
|
|
179
|
-
function
|
|
214
|
+
function E({ rows: e = 4 }) {
|
|
180
215
|
return /* @__PURE__ */ o("div", {
|
|
181
216
|
className: "space-y-3",
|
|
182
217
|
"aria-busy": "true",
|
|
@@ -194,7 +229,7 @@ function S({ rows: e = 4 }) {
|
|
|
194
229
|
}, t))
|
|
195
230
|
});
|
|
196
231
|
}
|
|
197
|
-
function
|
|
232
|
+
function D({ title: e = "Something went wrong", description: t = "We could not load this data. Please try again.", onRetry: n }) {
|
|
198
233
|
return /* @__PURE__ */ s("div", {
|
|
199
234
|
className: "flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center",
|
|
200
235
|
children: [
|
|
@@ -227,6 +262,6 @@ function C({ title: e = "Something went wrong", description: t = "We could not l
|
|
|
227
262
|
});
|
|
228
263
|
}
|
|
229
264
|
//#endregion
|
|
230
|
-
export {
|
|
265
|
+
export { x as AllocationBars, T as EmptyState, D as ErrorState, E as LoadingState, w as MetricGrid, v as SectionShell, _ as deltaToneClass, p as formatCompact, h as formatDate, f as formatMoney, m as formatPct, C as readEngineMetrics, g as statusBadgeVariant };
|
|
231
266
|
|
|
232
267
|
//# sourceMappingURL=_shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.js","names":[],"sources":["../../../src/brainyrich/pages/_shared.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\nimport { ArrowDownRight, ArrowUpRight, Inbox, Minus, RefreshCw, TriangleAlert } from 'lucide-react';\nimport { Badge, Button, Card, CardContent, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { FadeIn, useReducedMotion } from '../components/viz';\n\n// ============================================================================\n// Formatters\n// ============================================================================\n\n/** USD currency, no cents. Pass a currency code to override. */\nexport function formatMoney(value: number, currency = 'USD'): string {\n if (!Number.isFinite(value)) return '—';\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n maximumFractionDigits: 0,\n }).format(value);\n}\n\n/** Compact money/number, e.g. 1.2M, 950K. */\nexport function formatCompact(value: number, currency?: string): string {\n if (!Number.isFinite(value)) return '—';\n return new Intl.NumberFormat('en-US', {\n notation: 'compact',\n maximumFractionDigits: 1,\n ...(currency ? { style: 'currency', currency } : {}),\n }).format(value);\n}\n\n/** Percentage from a whole-number percent (e.g. 12.5 → \"12.5%\"). */\nexport function formatPct(value: number | null | undefined, fractionDigits = 1): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return `${value.toFixed(fractionDigits)}%`;\n}\n\n/**\n * Guarded date formatter. Only wraps a present ISO string in `new Date()` at\n * render time — never calls `.getTime()` on a raw scalar and never `new Date(0)`.\n * Returns an em-dash for absent/invalid values.\n */\nexport function formatDate(iso?: string | null): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }).format(d);\n}\n\n// ============================================================================\n// Status → badge variant (semantic, no raw colors)\n// ============================================================================\n\n/**\n * Map a domain status/severity string to a shadcn Badge variant. Accepts the\n * Bra* enum members (ACTIVE, AT_RISK, HIGH, …) case-insensitively so pages can\n * pass raw enum values.\n */\nexport function statusBadgeVariant(\n status: string\n): 'default' | 'secondary' | 'destructive' | 'outline' {\n const s = status.toUpperCase();\n if (['ACTIVE', 'ACHIEVED', 'ON_TRACK', 'AHEAD', 'RESOLVED', 'EXECUTED', 'APPROVED'].includes(s))\n return 'default';\n if (['AT_RISK', 'HIGH', 'CRITICAL', 'ABANDONED', 'REJECTED', 'CANCELLED', 'CLOSED'].includes(s))\n return 'destructive';\n if (\n ['ONBOARDING', 'PROSPECT', 'ON_HOLD', 'BEHIND', 'DRAFT', 'PROPOSED', 'MEDIUM', 'LOW'].includes(\n s\n )\n )\n return 'secondary';\n return 'outline';\n}\n\n/** Semantic text-color token for a signed delta (color is never the only signal). */\nexport function deltaToneClass(value: number): string {\n if (value > 0) return 'text-status-success-text';\n if (value < 0) return 'text-status-error-text';\n return 'text-text-secondary';\n}\n\n// ============================================================================\n// Section shell + KPIs\n// ============================================================================\n\ninterface SectionShellProps {\n title: string;\n description: string;\n actionLabel?: string;\n onAction?: () => void;\n actions?: ReactNode;\n badges?: string[];\n children: ReactNode;\n}\n\nexport function SectionShell({\n title,\n description,\n actionLabel,\n onAction,\n actions,\n badges = [],\n children,\n}: SectionShellProps) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n {badges.map((badge) => (\n <Badge key={badge} variant=\"secondary\">\n {badge}\n </Badge>\n ))}\n {actions}\n {actionLabel ? (\n <Button size=\"sm\" onClick={onAction}>\n {actionLabel}\n </Button>\n ) : null}\n </div>\n </div>\n {children}\n </div>\n );\n}\n\nexport interface KpiItem {\n label: string;\n value: string;\n /** Optional signed delta rendered as a DeltaBadge (icon + sign + color). */\n delta?: number;\n /** Optional free-text trend line (neutral tone unless deltaTone provided). */\n trend?: string;\n deltaTone?: 'positive' | 'negative' | 'neutral';\n}\n\nexport function KpiGrid({ items }: { items: KpiItem[] }) {\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {items.map((item, i) => (\n <FadeIn key={item.label} index={i}>\n <Card className=\"h-full transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardContent className=\"space-y-1.5 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {item.label}\n </p>\n <p className=\"text-2xl font-semibold tracking-tight text-text-primary\">\n {item.value}\n </p>\n {item.delta !== undefined ? (\n <DeltaBadge value={item.delta} />\n ) : item.trend ? (\n <p\n className={\n item.deltaTone === 'positive'\n ? 'text-xs text-status-success-text'\n : item.deltaTone === 'negative'\n ? 'text-xs text-status-error-text'\n : 'text-xs text-text-secondary'\n }\n >\n {item.trend}\n </p>\n ) : null}\n </CardContent>\n </Card>\n </FadeIn>\n ))}\n </div>\n );\n}\n\n// ============================================================================\n// Delta badge — icon + sign + semantic color (color never the only signal)\n// ============================================================================\n\nexport function DeltaBadge({\n value,\n suffix = '%',\n className = '',\n}: {\n value: number;\n suffix?: string;\n className?: string;\n}) {\n const positive = value > 0;\n const negative = value < 0;\n const Icon = positive ? ArrowUpRight : negative ? ArrowDownRight : Minus;\n const tone = positive\n ? 'text-status-success-text bg-status-success-bg'\n : negative\n ? 'text-status-error-text bg-status-error-bg'\n : 'text-text-secondary bg-bg-sunken';\n const sign = positive ? '+' : '';\n return (\n <span\n className={`inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium ${tone} ${className}`}\n >\n <Icon className=\"size-3\" aria-hidden=\"true\" />\n {sign}\n {Number.isFinite(value) ? value.toFixed(1) : '—'}\n {suffix}\n </span>\n );\n}\n\n// ============================================================================\n// Allocation bars — tokenized horizontal bar primitive\n// ============================================================================\n\nexport type AllocationTone = 'default' | 'positive' | 'negative' | 'warning' | 'accent';\n\nconst TONE_FILL: Record<AllocationTone, string> = {\n default: 'bg-primary',\n positive: 'bg-status-success-bg',\n negative: 'bg-status-error-bg',\n warning: 'bg-status-warning-bg',\n accent: 'bg-accent-teal',\n};\n\nexport interface AllocationDatum {\n label: string;\n /** Percentage 0–100 for the bar width. */\n value: number;\n tone?: AllocationTone;\n /** Optional right-aligned caption (e.g. formatted money). Defaults to the %. */\n caption?: string;\n}\n\n/**\n * Single allocation bar fill. Starts at 0 width and grows to `width`% after\n * mount via a CSS transition; instant (no transition) under reduced motion.\n */\nfunction AllocationFill({ width, className }: { width: number; className: string }) {\n const reduce = useReducedMotion();\n // Reduced motion starts at the final width (instant); otherwise start at 0 and\n // grow on the next frame via the CSS width transition.\n const [w, setW] = useState(reduce ? width : 0);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => setW(width));\n return () => cancelAnimationFrame(id);\n }, [width]);\n\n return (\n <div\n className={className}\n style={{ width: `${w}%`, transition: reduce ? 'none' : 'width 500ms ease' }}\n />\n );\n}\n\nexport function AllocationBars({ data }: { data: AllocationDatum[] }) {\n const rows = data.filter((d) => Number.isFinite(d.value));\n if (rows.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No allocation data.</p>;\n }\n return (\n <div className=\"space-y-3.5\">\n {rows.map((d) => {\n const width = Math.max(0, Math.min(100, d.value));\n return (\n <div key={d.label} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium text-text-primary\">{d.label}</span>\n <span className=\"tabular-nums text-text-secondary\">\n {d.caption ?? formatPct(d.value)}\n </span>\n </div>\n <div\n className=\"h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={Math.round(width)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={d.label}\n >\n <AllocationFill\n width={width}\n className={`h-full rounded-full ${TONE_FILL[d.tone ?? 'default']}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================================================\n// Empty / Loading / Error states (designed, shared)\n// ============================================================================\n\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon ?? <Inbox className=\"size-6\" aria-hidden=\"true\" />}\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n {description ? (\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n ) : null}\n {action ? <div className=\"mt-4\">{action}</div> : null}\n </div>\n );\n}\n\nexport function LoadingState({ rows = 4 }: { rows?: number }) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\" aria-live=\"polite\">\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <Skeleton className=\"size-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n <Skeleton className=\"h-4 w-16\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function ErrorState({\n title = 'Something went wrong',\n description = 'We could not load this data. Please try again.',\n onRetry,\n}: {\n title?: string;\n description?: string;\n onRetry?: () => void;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-surface text-status-error-text\">\n <TriangleAlert className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n {onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-4\" onClick={onRetry}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n Retry\n </Button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_shared.js","names":[],"sources":["../../../src/brainyrich/pages/_shared.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\nimport { ArrowDownRight, ArrowUpRight, Inbox, Minus, RefreshCw, TriangleAlert } from 'lucide-react';\nimport { Badge, Button, Card, CardContent, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { FadeIn, useReducedMotion } from '../components/viz';\n\n// ============================================================================\n// Formatters\n// ============================================================================\n\n/**\n * `Intl.NumberFormat` throws `RangeError` on a currency code that is not three\n * ASCII letters, and `BraPortfolio.baseCurrency` / `BraHolding.currency` are\n * free-text `String!` columns — a single row saved as \"US\" would otherwise take\n * down every list that formats it. Fall back to the number plus the raw code.\n */\nfunction formatCurrencySafely(\n value: number,\n currency: string | undefined,\n options: Intl.NumberFormatOptions\n): string {\n try {\n return new Intl.NumberFormat('en-US', {\n ...options,\n ...(currency ? { style: 'currency', currency } : {}),\n }).format(value);\n } catch {\n const plain = new Intl.NumberFormat('en-US', options).format(value);\n return currency ? `${plain} ${currency}` : plain;\n }\n}\n\n/** USD currency, no cents. Pass a currency code to override. */\nexport function formatMoney(value: number, currency = 'USD'): string {\n if (!Number.isFinite(value)) return '—';\n return formatCurrencySafely(value, currency, { maximumFractionDigits: 0 });\n}\n\n/** Compact money/number, e.g. 1.2M, 950K. */\nexport function formatCompact(value: number, currency?: string): string {\n if (!Number.isFinite(value)) return '—';\n return formatCurrencySafely(value, currency, {\n notation: 'compact',\n maximumFractionDigits: 1,\n });\n}\n\n/** Percentage from a whole-number percent (e.g. 12.5 → \"12.5%\"). */\nexport function formatPct(value: number | null | undefined, fractionDigits = 1): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return `${value.toFixed(fractionDigits)}%`;\n}\n\n/**\n * Guarded date formatter. Only wraps a present ISO string in `new Date()` at\n * render time — never calls `.getTime()` on a raw scalar and never `new Date(0)`.\n * Returns an em-dash for absent/invalid values.\n */\nexport function formatDate(iso?: string | null): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '—';\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }).format(d);\n}\n\n// ============================================================================\n// Status → badge variant (semantic, no raw colors)\n// ============================================================================\n\n/**\n * Map a domain status/severity string to a shadcn Badge variant. Accepts the\n * Bra* enum members (ACTIVE, AT_RISK, HIGH, …) case-insensitively so pages can\n * pass raw enum values.\n */\nexport function statusBadgeVariant(\n status: string\n): 'default' | 'secondary' | 'destructive' | 'outline' {\n const s = status.toUpperCase();\n if (['ACTIVE', 'ACHIEVED', 'ON_TRACK', 'AHEAD', 'RESOLVED', 'EXECUTED', 'APPROVED'].includes(s))\n return 'default';\n if (['AT_RISK', 'HIGH', 'CRITICAL', 'ABANDONED', 'REJECTED', 'CANCELLED', 'CLOSED'].includes(s))\n return 'destructive';\n if (\n ['ONBOARDING', 'PROSPECT', 'ON_HOLD', 'BEHIND', 'DRAFT', 'PROPOSED', 'MEDIUM', 'LOW'].includes(\n s\n )\n )\n return 'secondary';\n return 'outline';\n}\n\n/** Semantic text-color token for a signed delta (color is never the only signal). */\nexport function deltaToneClass(value: number): string {\n if (value > 0) return 'text-status-success-text';\n if (value < 0) return 'text-status-error-text';\n return 'text-text-secondary';\n}\n\n// ============================================================================\n// Section shell + KPIs\n// ============================================================================\n\ninterface SectionShellProps {\n title: string;\n description: string;\n actionLabel?: string;\n onAction?: () => void;\n actions?: ReactNode;\n badges?: string[];\n children: ReactNode;\n}\n\nexport function SectionShell({\n title,\n description,\n actionLabel,\n onAction,\n actions,\n badges = [],\n children,\n}: SectionShellProps) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n {badges.map((badge) => (\n <Badge key={badge} variant=\"secondary\">\n {badge}\n </Badge>\n ))}\n {actions}\n {actionLabel ? (\n <Button size=\"sm\" onClick={onAction}>\n {actionLabel}\n </Button>\n ) : null}\n </div>\n </div>\n {children}\n </div>\n );\n}\n\nexport interface KpiItem {\n label: string;\n value: string;\n /** Optional signed delta rendered as a DeltaBadge (icon + sign + color). */\n delta?: number;\n /** Optional free-text trend line (neutral tone unless deltaTone provided). */\n trend?: string;\n deltaTone?: 'positive' | 'negative' | 'neutral';\n}\n\nexport function KpiGrid({ items }: { items: KpiItem[] }) {\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {items.map((item, i) => (\n <FadeIn key={item.label} index={i}>\n <Card className=\"h-full transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]\">\n <CardContent className=\"space-y-1.5 p-4\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {item.label}\n </p>\n <p className=\"text-2xl font-semibold tracking-tight text-text-primary\">\n {item.value}\n </p>\n {item.delta !== undefined ? (\n <DeltaBadge value={item.delta} />\n ) : item.trend ? (\n <p\n className={\n item.deltaTone === 'positive'\n ? 'text-xs text-status-success-text'\n : item.deltaTone === 'negative'\n ? 'text-xs text-status-error-text'\n : 'text-xs text-text-secondary'\n }\n >\n {item.trend}\n </p>\n ) : null}\n </CardContent>\n </Card>\n </FadeIn>\n ))}\n </div>\n );\n}\n\n// ============================================================================\n// Delta badge — icon + sign + semantic color (color never the only signal)\n// ============================================================================\n\nexport function DeltaBadge({\n value,\n suffix = '%',\n className = '',\n}: {\n value: number;\n suffix?: string;\n className?: string;\n}) {\n const positive = value > 0;\n const negative = value < 0;\n const Icon = positive ? ArrowUpRight : negative ? ArrowDownRight : Minus;\n const tone = positive\n ? 'text-status-success-text bg-status-success-bg'\n : negative\n ? 'text-status-error-text bg-status-error-bg'\n : 'text-text-secondary bg-bg-sunken';\n const sign = positive ? '+' : '';\n return (\n <span\n className={`inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium ${tone} ${className}`}\n >\n <Icon className=\"size-3\" aria-hidden=\"true\" />\n {sign}\n {Number.isFinite(value) ? value.toFixed(1) : '—'}\n {suffix}\n </span>\n );\n}\n\n// ============================================================================\n// Allocation bars — tokenized horizontal bar primitive\n// ============================================================================\n\nexport type AllocationTone = 'default' | 'positive' | 'negative' | 'warning' | 'accent';\n\nconst TONE_FILL: Record<AllocationTone, string> = {\n default: 'bg-primary',\n positive: 'bg-status-success-bg',\n negative: 'bg-status-error-bg',\n warning: 'bg-status-warning-bg',\n accent: 'bg-accent-teal',\n};\n\nexport interface AllocationDatum {\n label: string;\n /** Percentage 0–100 for the bar width. */\n value: number;\n tone?: AllocationTone;\n /** Optional right-aligned caption (e.g. formatted money). Defaults to the %. */\n caption?: string;\n}\n\n/**\n * Single allocation bar fill. Starts at 0 width and grows to `width`% after\n * mount via a CSS transition; instant (no transition) under reduced motion.\n */\nfunction AllocationFill({ width, className }: { width: number; className: string }) {\n const reduce = useReducedMotion();\n // Reduced motion starts at the final width (instant); otherwise start at 0 and\n // grow on the next frame via the CSS width transition.\n const [w, setW] = useState(reduce ? width : 0);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => setW(width));\n return () => cancelAnimationFrame(id);\n }, [width]);\n\n return (\n <div\n className={className}\n style={{ width: `${w}%`, transition: reduce ? 'none' : 'width 500ms ease' }}\n />\n );\n}\n\nexport function AllocationBars({ data }: { data: AllocationDatum[] }) {\n const rows = data.filter((d) => Number.isFinite(d.value));\n if (rows.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No allocation data.</p>;\n }\n return (\n <div className=\"space-y-3.5\">\n {rows.map((d) => {\n const width = Math.max(0, Math.min(100, d.value));\n return (\n <div key={d.label} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium text-text-primary\">{d.label}</span>\n <span className=\"tabular-nums text-text-secondary\">\n {d.caption ?? formatPct(d.value)}\n </span>\n </div>\n <div\n className=\"h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={Math.round(width)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={d.label}\n >\n <AllocationFill\n width={width}\n className={`h-full rounded-full ${TONE_FILL[d.tone ?? 'default']}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================================================\n// Deterministic-engine metrics (BraRiskSignal.metrics / BraInsight.metrics)\n// ============================================================================\n\n/**\n * Render one entry of a deterministic-engine `metrics` object without inventing\n * formatting rules per-key: numbers render as plain locale numbers (2dp when\n * fractional), booleans as Yes/No, everything else as-is. This is the ONLY way\n * the engine's real inputs and formula reach the screen — never replaced by a\n * derived or opaque display value.\n */\nexport function formatMetricValue(value: unknown): string {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'number') {\n return Number.isInteger(value)\n ? value.toLocaleString()\n : value.toLocaleString(undefined, { maximumFractionDigits: 2 });\n }\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * A `metrics` JSON scalar split into the engine's own `formula` string (when it\n * set one) and the remaining measured entries. Returns `null` when there is\n * nothing to show, so callers render no empty rationale block.\n */\nexport function readEngineMetrics(\n metrics: unknown\n): { formula: string | null; entries: Array<[string, unknown]> } | null {\n if (!metrics || typeof metrics !== 'object' || Array.isArray(metrics)) return null;\n const all = Object.entries(metrics as Record<string, unknown>);\n if (all.length === 0) return null;\n const formulaValue = (metrics as Record<string, unknown>).formula;\n return {\n formula: typeof formulaValue === 'string' ? formulaValue : null,\n entries: all.filter(([key]) => key !== 'formula'),\n };\n}\n\n/** Key/value grid for engine metric entries — matches the risk-signal rows. */\nexport function MetricGrid({ entries }: { entries: Array<[string, unknown]> }) {\n if (entries.length === 0) return null;\n return (\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4\">\n {entries.map(([key, value]) => (\n <div key={key} className=\"min-w-0\">\n <dt className=\"truncate text-[11px] uppercase tracking-wide text-text-muted\">\n {key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/_/g, ' ')\n .replace(/^./, (c) => c.toUpperCase())}\n </dt>\n <dd\n className=\"truncate text-sm font-medium tabular-nums text-text-primary\"\n title={formatMetricValue(value)}\n >\n {formatMetricValue(value)}\n </dd>\n </div>\n ))}\n </dl>\n );\n}\n\n// ============================================================================\n// Empty / Loading / Error states (designed, shared)\n// ============================================================================\n\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-border-subtle bg-bg-surface px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n {icon ?? <Inbox className=\"size-6\" aria-hidden=\"true\" />}\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n {description ? (\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n ) : null}\n {action ? <div className=\"mt-4\">{action}</div> : null}\n </div>\n );\n}\n\nexport function LoadingState({ rows = 4 }: { rows?: number }) {\n return (\n <div className=\"space-y-3\" aria-busy=\"true\" aria-live=\"polite\">\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <Skeleton className=\"size-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n <Skeleton className=\"h-4 w-16\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function ErrorState({\n title = 'Something went wrong',\n description = 'We could not load this data. Please try again.',\n onRetry,\n}: {\n title?: string;\n description?: string;\n onRetry?: () => void;\n}) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-status-error-text/40 bg-status-error-bg px-6 py-12 text-center\">\n <div className=\"mb-4 flex size-12 items-center justify-center rounded-full bg-bg-surface text-status-error-text\">\n <TriangleAlert className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <h3 className=\"text-base font-semibold text-text-primary\">{title}</h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">{description}</p>\n {onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-4\" onClick={onRetry}>\n <RefreshCw className=\"size-4\" aria-hidden=\"true\" />\n Retry\n </Button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import * as Apollo from '@apollo/client';
|
|
2
|
+
export type PlaceholderQueryVariables = Types.Exact<{
|
|
3
|
+
[key: string]: never;
|
|
4
|
+
}>;
|
|
5
|
+
export type PlaceholderQuery = {
|
|
6
|
+
__typename: 'Query';
|
|
7
|
+
};
|
|
8
|
+
export declare const PlaceholderDocument: Apollo.DocumentNode;
|
|
9
|
+
/**
|
|
10
|
+
* __usePlaceholderQuery__
|
|
11
|
+
*
|
|
12
|
+
* To run a query within a React component, call `usePlaceholderQuery` and pass it any options that fit your needs.
|
|
13
|
+
* When your component renders, `usePlaceholderQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
14
|
+
* you can use to render your UI.
|
|
15
|
+
*
|
|
16
|
+
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const { data, loading, error } = usePlaceholderQuery({
|
|
20
|
+
* variables: {
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
*/
|
|
24
|
+
export declare function usePlaceholderQuery(baseOptions?: Apollo.QueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): any;
|
|
25
|
+
export declare function usePlaceholderLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): any;
|
|
26
|
+
export declare function usePlaceholderSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): Apollo.UseSuspenseQueryResult<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>;
|
|
27
|
+
export declare function usePlaceholderSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): Apollo.UseSuspenseQueryResult<Types.PlaceholderQuery | undefined, Types.PlaceholderQueryVariables>;
|
|
28
|
+
export type PlaceholderQueryHookResult = ReturnType<typeof usePlaceholderQuery>;
|
|
29
|
+
export type PlaceholderLazyQueryHookResult = ReturnType<typeof usePlaceholderLazyQuery>;
|
|
30
|
+
export type PlaceholderSuspenseQueryHookResult = ReturnType<typeof usePlaceholderSuspenseQuery>;
|
|
31
|
+
export type PlaceholderQueryResult = Apollo.QueryResult<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>;
|
|
2
32
|
//# sourceMappingURL=global-operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-operations.d.ts","sourceRoot":"","sources":["../../src/generated/global-operations.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"global-operations.d.ts","sourceRoot":"","sources":["../../src/generated/global-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CAAE,CAAC,CAAC;AAG/E,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC;AAGvD,eAAO,MAAM,mBAAmB,qBAI3B,CAAC;AAEN;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,OAG3H;AACP,wBAAgB,uBAAuB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,OAGjI;AAET,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAC5O,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAK3Q,MAAM,MAAM,0BAA0B,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChF,MAAM,MAAM,8BAA8B,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxF,MAAM,MAAM,kCAAkC,GAAG,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChG,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC"}
|
|
@@ -1,2 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import * as Apollo from '@apollo/client';
|
|
2
|
+
export type PlaceholderQueryVariables = Types.Exact<{
|
|
3
|
+
[key: string]: never;
|
|
4
|
+
}>;
|
|
5
|
+
export type PlaceholderQuery = {
|
|
6
|
+
__typename: 'Query';
|
|
7
|
+
};
|
|
8
|
+
export declare const PlaceholderDocument: Apollo.DocumentNode;
|
|
9
|
+
/**
|
|
10
|
+
* __usePlaceholderQuery__
|
|
11
|
+
*
|
|
12
|
+
* To run a query within a React component, call `usePlaceholderQuery` and pass it any options that fit your needs.
|
|
13
|
+
* When your component renders, `usePlaceholderQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
14
|
+
* you can use to render your UI.
|
|
15
|
+
*
|
|
16
|
+
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const { data, loading, error } = usePlaceholderQuery({
|
|
20
|
+
* variables: {
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
*/
|
|
24
|
+
export declare function usePlaceholderQuery(baseOptions?: Apollo.QueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): any;
|
|
25
|
+
export declare function usePlaceholderLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): any;
|
|
26
|
+
export declare function usePlaceholderSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): Apollo.UseSuspenseQueryResult<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>;
|
|
27
|
+
export declare function usePlaceholderSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>): Apollo.UseSuspenseQueryResult<Types.PlaceholderQuery | undefined, Types.PlaceholderQueryVariables>;
|
|
28
|
+
export type PlaceholderQueryHookResult = ReturnType<typeof usePlaceholderQuery>;
|
|
29
|
+
export type PlaceholderLazyQueryHookResult = ReturnType<typeof usePlaceholderLazyQuery>;
|
|
30
|
+
export type PlaceholderSuspenseQueryHookResult = ReturnType<typeof usePlaceholderSuspenseQuery>;
|
|
31
|
+
export type PlaceholderQueryResult = Apollo.QueryResult<Types.PlaceholderQuery, Types.PlaceholderQueryVariables>;
|
|
2
32
|
//# sourceMappingURL=wspace-operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wspace-operations.d.ts","sourceRoot":"","sources":["../../src/generated/wspace-operations.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"wspace-operations.d.ts","sourceRoot":"","sources":["../../src/generated/wspace-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CAAE,CAAC,CAAC;AAG/E,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC;AAGvD,eAAO,MAAM,mBAAmB,qBAI3B,CAAC;AAEN;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,OAG3H;AACP,wBAAgB,uBAAuB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,OAGjI;AAET,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAC5O,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAK3Q,MAAM,MAAM,0BAA0B,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChF,MAAM,MAAM,8BAA8B,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxF,MAAM,MAAM,kCAAkC,GAAG,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChG,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-brainyrich",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.828.1",
|
|
4
4
|
"description": "Burdenoff BrainyRich Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
"lint:sanity": "if [ \"${CI:-}\" = \"true\" ]; then bun run lint; else bun run lint -- --cache --cache-location .eslintcache; fi",
|
|
32
32
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
33
33
|
"type:check": "bash scripts/build-limits.sh tsc --noEmit",
|
|
34
|
-
"
|
|
34
|
+
"test": "bash scripts/build-limits.sh vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"test:coverage": "bash scripts/build-limits.sh vitest run --coverage",
|
|
37
|
+
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build && bun run build-storybook'",
|
|
35
38
|
"schema:pull": "graphql-codegen --project schema-wspace && graphql-codegen --project schema-global",
|
|
36
39
|
"codegen": "graphql-codegen --project wspace && graphql-codegen --project global",
|
|
37
40
|
"codegen:all": "bun run schema:pull && bun run codegen",
|
|
@@ -71,7 +74,13 @@
|
|
|
71
74
|
"@graphql-codegen/typescript-react-apollo": "^4.0.0",
|
|
72
75
|
"@types/react": "^19.0.2",
|
|
73
76
|
"@types/react-dom": "^19.0.2",
|
|
77
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
78
|
+
"@testing-library/react": "^16.1.0",
|
|
79
|
+
"@testing-library/user-event": "^14.5.2",
|
|
74
80
|
"@vitejs/plugin-react": "^4.3.4",
|
|
81
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
82
|
+
"jsdom": "^25.0.1",
|
|
83
|
+
"vitest": "^3.2.4",
|
|
75
84
|
"autoprefixer": "^10.4.20",
|
|
76
85
|
"eslint": "^9.18.0",
|
|
77
86
|
"eslint-plugin-react": "^7.37.5",
|