@arbidocs/blocks 0.3.115 → 0.3.116
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/index.cjs +400 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +144 -54
- package/dist/index.d.ts +144 -54
- package/dist/index.js +400 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { create } from 'zustand';
|
|
2
2
|
import { persist } from 'zustand/middleware';
|
|
3
3
|
import { createContext, useState, useEffect, useCallback, useMemo, useContext, useRef } from 'react';
|
|
4
|
-
import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, RotateCcw, Palette, Search, ArrowUpRight, ArrowDownRight, ImageIcon, ArrowRight, Quote, ChevronDown, XCircle, AlertTriangle, CheckCircle2, Check, ArrowLeft, Loader2, ChevronUp, BrainCircuit, Bot, LayoutGrid, FileJson, Save, Download, ImagePlus, Upload, Link2 } from 'lucide-react';
|
|
5
|
-
import { Input, Card, CardHeader, CardTitle, CardContent, useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Button, Avatar, AvatarImage, AvatarFallback, AiMarkdown, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs as Tabs$1, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, useThumbnails } from '@arbidocs/react';
|
|
4
|
+
import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, RotateCcw, Palette, Search, ArrowUpRight, ArrowDownRight, ImageIcon, ArrowRight, Quote, ChevronDown, XCircle, AlertTriangle, CheckCircle2, Check, X, Menu, ArrowLeft, Loader2, ChevronUp, BrainCircuit, Bot, LayoutGrid, FileJson, Save, Download, ImagePlus, Upload, Link2, MessagesSquare } from 'lucide-react';
|
|
5
|
+
import { Input, Card, CardHeader, CardTitle, CardContent, useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Button, Avatar, AvatarImage, AvatarFallback, AiMarkdown, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs as Tabs$1, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, useThumbnails, useConversations } from '@arbidocs/react';
|
|
6
6
|
export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
|
|
7
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
9
9
|
import { AgGridReact } from 'ag-grid-react';
|
|
10
10
|
import { themeQuartz, AllCommunityModule } from 'ag-grid-community';
|
|
11
|
-
import { Link, useParams } from 'react-router-dom';
|
|
11
|
+
import { useLocation, Link, useParams, NavLink } from 'react-router-dom';
|
|
12
12
|
import { Puck, Render } from '@measured/puck';
|
|
13
13
|
|
|
14
14
|
// src/prompts.ts
|
|
@@ -2297,6 +2297,322 @@ function TestimonialGrid({ items, columns = "3", testId }) {
|
|
|
2297
2297
|
i
|
|
2298
2298
|
)) });
|
|
2299
2299
|
}
|
|
2300
|
+
function NavItemLink({ item, onNavigate }) {
|
|
2301
|
+
return /* @__PURE__ */ jsxs(
|
|
2302
|
+
NavLink,
|
|
2303
|
+
{
|
|
2304
|
+
to: item.to,
|
|
2305
|
+
end: item.end,
|
|
2306
|
+
onClick: onNavigate,
|
|
2307
|
+
"data-testid": tid("sidebar-nav", item.id),
|
|
2308
|
+
className: ({ isActive }) => cn(
|
|
2309
|
+
"group flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
|
2310
|
+
isActive ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
|
|
2311
|
+
),
|
|
2312
|
+
children: [
|
|
2313
|
+
/* @__PURE__ */ jsx(item.icon, { className: "size-[18px] shrink-0" }),
|
|
2314
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
|
|
2315
|
+
item.arbi && /* @__PURE__ */ jsx(Sparkles, { className: "size-3.5 text-sidebar-primary", "aria-label": "Powered by ARBI" })
|
|
2316
|
+
]
|
|
2317
|
+
}
|
|
2318
|
+
);
|
|
2319
|
+
}
|
|
2320
|
+
function SidebarBody({
|
|
2321
|
+
sections,
|
|
2322
|
+
footerItems,
|
|
2323
|
+
logo,
|
|
2324
|
+
logoHref,
|
|
2325
|
+
logoLabel,
|
|
2326
|
+
sidebarFooter,
|
|
2327
|
+
onNavigate
|
|
2328
|
+
}) {
|
|
2329
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2330
|
+
logo && /* @__PURE__ */ jsx("div", { className: "flex h-16 items-center border-b border-sidebar-border px-5", children: logoHref ? /* @__PURE__ */ jsx(Link, { to: logoHref, "aria-label": logoLabel, onClick: onNavigate, children: logo }) : logo }),
|
|
2331
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 space-y-6 overflow-y-auto px-3 py-5", children: sections.map((section) => /* @__PURE__ */ jsxs("div", { children: [
|
|
2332
|
+
/* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-sidebar-foreground/55", children: section.heading }),
|
|
2333
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: section.items.map((item) => /* @__PURE__ */ jsx(NavItemLink, { item, onNavigate }, item.id)) })
|
|
2334
|
+
] }, section.heading)) }),
|
|
2335
|
+
(footerItems?.length || sidebarFooter) && /* @__PURE__ */ jsxs("div", { className: "border-t border-sidebar-border px-3 py-3", children: [
|
|
2336
|
+
footerItems?.map((item) => /* @__PURE__ */ jsx(NavItemLink, { item, onNavigate }, item.id)),
|
|
2337
|
+
sidebarFooter
|
|
2338
|
+
] })
|
|
2339
|
+
] });
|
|
2340
|
+
}
|
|
2341
|
+
function AppShell({
|
|
2342
|
+
sections,
|
|
2343
|
+
footerItems,
|
|
2344
|
+
logo,
|
|
2345
|
+
logoHref,
|
|
2346
|
+
logoLabel,
|
|
2347
|
+
sidebarFooter,
|
|
2348
|
+
topbar,
|
|
2349
|
+
rightRail,
|
|
2350
|
+
children,
|
|
2351
|
+
mainClassName,
|
|
2352
|
+
testIdPrefix = "app"
|
|
2353
|
+
}) {
|
|
2354
|
+
const [open, setOpen] = useState(false);
|
|
2355
|
+
const location = useLocation();
|
|
2356
|
+
useEffect(() => {
|
|
2357
|
+
setOpen(false);
|
|
2358
|
+
}, [location.pathname]);
|
|
2359
|
+
const body = (onNavigate) => /* @__PURE__ */ jsx(
|
|
2360
|
+
SidebarBody,
|
|
2361
|
+
{
|
|
2362
|
+
sections,
|
|
2363
|
+
footerItems,
|
|
2364
|
+
logo,
|
|
2365
|
+
logoHref,
|
|
2366
|
+
logoLabel,
|
|
2367
|
+
sidebarFooter,
|
|
2368
|
+
onNavigate
|
|
2369
|
+
}
|
|
2370
|
+
);
|
|
2371
|
+
return /* @__PURE__ */ jsxs(
|
|
2372
|
+
"div",
|
|
2373
|
+
{
|
|
2374
|
+
className: "flex h-screen overflow-hidden bg-background",
|
|
2375
|
+
"data-testid": `${testIdPrefix}-shell`,
|
|
2376
|
+
children: [
|
|
2377
|
+
/* @__PURE__ */ jsx(
|
|
2378
|
+
"aside",
|
|
2379
|
+
{
|
|
2380
|
+
className: "hidden h-full w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar lg:flex",
|
|
2381
|
+
"data-testid": `${testIdPrefix}-sidebar`,
|
|
2382
|
+
children: body()
|
|
2383
|
+
}
|
|
2384
|
+
),
|
|
2385
|
+
open && /* @__PURE__ */ jsxs(
|
|
2386
|
+
"div",
|
|
2387
|
+
{
|
|
2388
|
+
className: "fixed inset-0 z-50 lg:hidden",
|
|
2389
|
+
"data-testid": `${testIdPrefix}-sidebar-mobile`,
|
|
2390
|
+
children: [
|
|
2391
|
+
/* @__PURE__ */ jsx(
|
|
2392
|
+
"div",
|
|
2393
|
+
{
|
|
2394
|
+
className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
|
|
2395
|
+
onClick: () => setOpen(false),
|
|
2396
|
+
"aria-hidden": true
|
|
2397
|
+
}
|
|
2398
|
+
),
|
|
2399
|
+
/* @__PURE__ */ jsxs("aside", { className: "absolute inset-y-0 left-0 flex w-64 max-w-[82%] flex-col border-r border-sidebar-border bg-sidebar shadow-xl", children: [
|
|
2400
|
+
/* @__PURE__ */ jsx(
|
|
2401
|
+
"button",
|
|
2402
|
+
{
|
|
2403
|
+
type: "button",
|
|
2404
|
+
onClick: () => setOpen(false),
|
|
2405
|
+
className: "absolute right-3 top-4 z-10 flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
|
|
2406
|
+
"aria-label": "Close menu",
|
|
2407
|
+
"data-testid": `${testIdPrefix}-sidebar-close`,
|
|
2408
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-5" })
|
|
2409
|
+
}
|
|
2410
|
+
),
|
|
2411
|
+
body(() => setOpen(false))
|
|
2412
|
+
] })
|
|
2413
|
+
]
|
|
2414
|
+
}
|
|
2415
|
+
),
|
|
2416
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
2417
|
+
/* @__PURE__ */ jsxs(
|
|
2418
|
+
"header",
|
|
2419
|
+
{
|
|
2420
|
+
className: "flex h-16 shrink-0 items-center gap-4 border-b border-border bg-card/80 px-6 backdrop-blur",
|
|
2421
|
+
"data-testid": `${testIdPrefix}-topbar`,
|
|
2422
|
+
children: [
|
|
2423
|
+
/* @__PURE__ */ jsx(
|
|
2424
|
+
"button",
|
|
2425
|
+
{
|
|
2426
|
+
type: "button",
|
|
2427
|
+
onClick: () => setOpen(true),
|
|
2428
|
+
className: "flex size-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground lg:hidden",
|
|
2429
|
+
"data-testid": `${testIdPrefix}-nav-toggle`,
|
|
2430
|
+
"aria-label": "Open menu",
|
|
2431
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
|
|
2432
|
+
}
|
|
2433
|
+
),
|
|
2434
|
+
topbar
|
|
2435
|
+
]
|
|
2436
|
+
}
|
|
2437
|
+
),
|
|
2438
|
+
/* @__PURE__ */ jsx(
|
|
2439
|
+
"main",
|
|
2440
|
+
{
|
|
2441
|
+
className: cn("flex-1 overflow-y-auto", mainClassName),
|
|
2442
|
+
"data-testid": `${testIdPrefix}-main`,
|
|
2443
|
+
children
|
|
2444
|
+
}
|
|
2445
|
+
)
|
|
2446
|
+
] }),
|
|
2447
|
+
rightRail
|
|
2448
|
+
]
|
|
2449
|
+
}
|
|
2450
|
+
);
|
|
2451
|
+
}
|
|
2452
|
+
var LiveDataContext = createContext(false);
|
|
2453
|
+
function useLiveDataActive() {
|
|
2454
|
+
return useContext(LiveDataContext);
|
|
2455
|
+
}
|
|
2456
|
+
function LiveDataProvider({ children }) {
|
|
2457
|
+
return /* @__PURE__ */ jsx(LiveDataContext.Provider, { value: true, children });
|
|
2458
|
+
}
|
|
2459
|
+
function WidgetPlaceholder({
|
|
2460
|
+
label,
|
|
2461
|
+
icon: Icon = Sparkles,
|
|
2462
|
+
testId
|
|
2463
|
+
}) {
|
|
2464
|
+
return /* @__PURE__ */ jsxs(
|
|
2465
|
+
"div",
|
|
2466
|
+
{
|
|
2467
|
+
className: "flex items-center gap-3 rounded-xl border border-dashed border-border bg-muted/30 px-5 py-6 text-sm text-muted-foreground",
|
|
2468
|
+
"data-testid": testId,
|
|
2469
|
+
children: [
|
|
2470
|
+
/* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(Icon, { className: "size-4" }) }),
|
|
2471
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2472
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: label }),
|
|
2473
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1", children: "\xB7 live in the app" })
|
|
2474
|
+
] })
|
|
2475
|
+
]
|
|
2476
|
+
}
|
|
2477
|
+
);
|
|
2478
|
+
}
|
|
2479
|
+
function useActiveWorkspaceId() {
|
|
2480
|
+
const { workspaceId, fallbackWorkspaceId } = useConnection();
|
|
2481
|
+
return workspaceId ?? fallbackWorkspaceId ?? void 0;
|
|
2482
|
+
}
|
|
2483
|
+
function timeAgo(iso) {
|
|
2484
|
+
if (!iso) return "";
|
|
2485
|
+
const then = new Date(iso).getTime();
|
|
2486
|
+
if (Number.isNaN(then)) return "";
|
|
2487
|
+
const s = Math.max(0, Math.round((Date.now() - then) / 1e3));
|
|
2488
|
+
if (s < 60) return "just now";
|
|
2489
|
+
const m = Math.round(s / 60);
|
|
2490
|
+
if (m < 60) return `${m}m ago`;
|
|
2491
|
+
const h = Math.round(m / 60);
|
|
2492
|
+
if (h < 24) return `${h}h ago`;
|
|
2493
|
+
return `${Math.round(h / 24)}d ago`;
|
|
2494
|
+
}
|
|
2495
|
+
var METRIC_SOURCES = {
|
|
2496
|
+
documents: { label: "Documents", icon: FileText },
|
|
2497
|
+
conversations: { label: "Agent threads", icon: Bot }
|
|
2498
|
+
};
|
|
2499
|
+
var asMetricSource = (s) => s in METRIC_SOURCES ? s : "documents";
|
|
2500
|
+
function AgentActivityLive({
|
|
2501
|
+
title,
|
|
2502
|
+
limit,
|
|
2503
|
+
testId
|
|
2504
|
+
}) {
|
|
2505
|
+
const wsId = useActiveWorkspaceId();
|
|
2506
|
+
const { data, isLoading } = useConversations(wsId);
|
|
2507
|
+
const rows = [...data ?? []].sort((a, b) => +new Date(b.updated_at ?? 0) - +new Date(a.updated_at ?? 0)).slice(0, limit);
|
|
2508
|
+
return /* @__PURE__ */ jsxs(Card, { variant: "elevated", className: "rounded-xl p-5", "data-testid": testId, children: [
|
|
2509
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center gap-2", children: [
|
|
2510
|
+
/* @__PURE__ */ jsx(Bot, { className: "size-4 text-muted-foreground" }),
|
|
2511
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: title })
|
|
2512
|
+
] }),
|
|
2513
|
+
isLoading ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": `${testId}-loading`, children: "Loading agent threads\u2026" }) : rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": `${testId}-empty`, children: "No agent threads yet." }) : /* @__PURE__ */ jsx("ul", { className: "space-y-2", "data-testid": `${testId}-list`, children: rows.map((c, i) => /* @__PURE__ */ jsxs(
|
|
2514
|
+
"li",
|
|
2515
|
+
{
|
|
2516
|
+
className: "flex items-center justify-between gap-3",
|
|
2517
|
+
"data-testid": `${testId}-item-${i}`,
|
|
2518
|
+
children: [
|
|
2519
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 truncate", children: [
|
|
2520
|
+
/* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
2521
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-sm text-foreground", children: c.title?.trim() || "Untitled thread" })
|
|
2522
|
+
] }),
|
|
2523
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: timeAgo(c.updated_at) })
|
|
2524
|
+
]
|
|
2525
|
+
},
|
|
2526
|
+
c.external_id ?? i
|
|
2527
|
+
)) })
|
|
2528
|
+
] });
|
|
2529
|
+
}
|
|
2530
|
+
function LiveMetricInner({
|
|
2531
|
+
label,
|
|
2532
|
+
source,
|
|
2533
|
+
accent,
|
|
2534
|
+
testId
|
|
2535
|
+
}) {
|
|
2536
|
+
const wsId = useActiveWorkspaceId();
|
|
2537
|
+
const docs = useDocuments(wsId, { enabled: source === "documents" });
|
|
2538
|
+
const convos = useConversations(wsId, { enabled: source === "conversations" });
|
|
2539
|
+
const query = source === "documents" ? docs : convos;
|
|
2540
|
+
const count = Array.isArray(query.data) ? query.data.length : 0;
|
|
2541
|
+
return /* @__PURE__ */ jsx(
|
|
2542
|
+
MetricCard,
|
|
2543
|
+
{
|
|
2544
|
+
label: label || METRIC_SOURCES[source].label,
|
|
2545
|
+
value: query.isLoading ? "\u2014" : String(count),
|
|
2546
|
+
accent,
|
|
2547
|
+
icon: METRIC_SOURCES[source].icon,
|
|
2548
|
+
testId
|
|
2549
|
+
}
|
|
2550
|
+
);
|
|
2551
|
+
}
|
|
2552
|
+
function AgentActivityBlock({
|
|
2553
|
+
title,
|
|
2554
|
+
limit,
|
|
2555
|
+
testId
|
|
2556
|
+
}) {
|
|
2557
|
+
return useLiveDataActive() ? /* @__PURE__ */ jsx(AgentActivityLive, { title, limit, testId }) : /* @__PURE__ */ jsx(WidgetPlaceholder, { label: String(title || "Agent activity"), icon: Bot, testId });
|
|
2558
|
+
}
|
|
2559
|
+
function LiveMetricBlock({
|
|
2560
|
+
label,
|
|
2561
|
+
source,
|
|
2562
|
+
accent,
|
|
2563
|
+
testId
|
|
2564
|
+
}) {
|
|
2565
|
+
const src = asMetricSource(source);
|
|
2566
|
+
return useLiveDataActive() ? /* @__PURE__ */ jsx(LiveMetricInner, { label, source: src, accent, testId }) : /* @__PURE__ */ jsx(
|
|
2567
|
+
WidgetPlaceholder,
|
|
2568
|
+
{
|
|
2569
|
+
label: String(label || METRIC_SOURCES[src].label),
|
|
2570
|
+
icon: METRIC_SOURCES[src].icon,
|
|
2571
|
+
testId
|
|
2572
|
+
}
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
function createLiveWidgets(kit) {
|
|
2576
|
+
const { blockTestId } = kit;
|
|
2577
|
+
const AgentActivityWidget = {
|
|
2578
|
+
label: "Agent activity (live)",
|
|
2579
|
+
fields: {
|
|
2580
|
+
title: { type: "text", label: "Title" },
|
|
2581
|
+
limit: { type: "number", label: "Rows", min: 1, max: 8 }
|
|
2582
|
+
},
|
|
2583
|
+
defaultProps: { title: "Recent agent activity", limit: 4 },
|
|
2584
|
+
render: ({ id, title, limit }) => /* @__PURE__ */ jsx(AgentActivityBlock, { title, limit, testId: blockTestId(id) })
|
|
2585
|
+
};
|
|
2586
|
+
const LiveMetricWidget = {
|
|
2587
|
+
label: "Live metric",
|
|
2588
|
+
fields: {
|
|
2589
|
+
label: { type: "text", label: "Label" },
|
|
2590
|
+
source: {
|
|
2591
|
+
type: "select",
|
|
2592
|
+
label: "Source",
|
|
2593
|
+
options: [
|
|
2594
|
+
{ label: "Documents", value: "documents" },
|
|
2595
|
+
{ label: "Agent threads", value: "conversations" }
|
|
2596
|
+
]
|
|
2597
|
+
},
|
|
2598
|
+
accent: {
|
|
2599
|
+
type: "radio",
|
|
2600
|
+
label: "Accent",
|
|
2601
|
+
options: [
|
|
2602
|
+
{ label: "Default", value: "default" },
|
|
2603
|
+
{ label: "Primary", value: "primary" },
|
|
2604
|
+
{ label: "Success", value: "success" }
|
|
2605
|
+
]
|
|
2606
|
+
}
|
|
2607
|
+
},
|
|
2608
|
+
defaultProps: { label: "", source: "documents", accent: "primary" },
|
|
2609
|
+
render: ({ id, label, source, accent }) => /* @__PURE__ */ jsx(LiveMetricBlock, { label, source, accent, testId: blockTestId(id) })
|
|
2610
|
+
};
|
|
2611
|
+
return {
|
|
2612
|
+
AgentActivity: AgentActivityWidget,
|
|
2613
|
+
LiveMetric: LiveMetricWidget
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2300
2616
|
|
|
2301
2617
|
// src/studio/publish.ts
|
|
2302
2618
|
function blobToDataUrl(blob) {
|
|
@@ -2571,34 +2887,36 @@ function PageRenderer({
|
|
|
2571
2887
|
live,
|
|
2572
2888
|
slug: slugProp,
|
|
2573
2889
|
emptyState,
|
|
2574
|
-
testIdPrefix = "studio"
|
|
2890
|
+
testIdPrefix = "studio",
|
|
2891
|
+
liveData = false,
|
|
2892
|
+
initialData,
|
|
2893
|
+
applyTheme = true
|
|
2575
2894
|
}) {
|
|
2576
2895
|
const params = useParams();
|
|
2577
2896
|
const slug = slugProp ?? params.slug ?? "home";
|
|
2578
2897
|
const arbi = useArbi();
|
|
2579
|
-
const [data, setData] = useState(null);
|
|
2580
|
-
const [loading, setLoading] = useState(
|
|
2898
|
+
const [data, setData] = useState(initialData ?? null);
|
|
2899
|
+
const [loading, setLoading] = useState(!initialData);
|
|
2581
2900
|
useEffect(() => {
|
|
2582
2901
|
let cancelled = false;
|
|
2583
|
-
setLoading(
|
|
2902
|
+
setLoading(!initialData);
|
|
2584
2903
|
void (async () => {
|
|
2585
|
-
const
|
|
2586
|
-
persistence.loadPublished(arbi, live, slug),
|
|
2587
|
-
persistence.loadTheme(arbi, live)
|
|
2588
|
-
]);
|
|
2904
|
+
const theme = applyTheme ? (await persistence.loadTheme(arbi, live)).data : void 0;
|
|
2589
2905
|
if (cancelled) return;
|
|
2590
|
-
const page =
|
|
2906
|
+
const page = initialData ?? (await persistence.loadPublished(arbi, live, slug)).data ?? (await persistence.loadPage(arbi, live, slug)).data;
|
|
2591
2907
|
if (cancelled) return;
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2908
|
+
if (applyTheme) {
|
|
2909
|
+
applyThemeVars(
|
|
2910
|
+
theme ? { ...defaultTheme, ...theme, colors: { ...defaultTheme.colors, ...theme.colors } } : defaultTheme
|
|
2911
|
+
);
|
|
2912
|
+
}
|
|
2595
2913
|
setData(page);
|
|
2596
2914
|
setLoading(false);
|
|
2597
2915
|
})();
|
|
2598
2916
|
return () => {
|
|
2599
2917
|
cancelled = true;
|
|
2600
2918
|
};
|
|
2601
|
-
}, [arbi, live, slug, persistence, defaultTheme]);
|
|
2919
|
+
}, [arbi, live, slug, persistence, defaultTheme, initialData, applyTheme]);
|
|
2602
2920
|
if (loading) {
|
|
2603
2921
|
return /* @__PURE__ */ jsx(
|
|
2604
2922
|
"div",
|
|
@@ -2624,7 +2942,8 @@ function PageRenderer({
|
|
|
2624
2942
|
}
|
|
2625
2943
|
);
|
|
2626
2944
|
}
|
|
2627
|
-
|
|
2945
|
+
const rendered = /* @__PURE__ */ jsx(Render, { config, data });
|
|
2946
|
+
return /* @__PURE__ */ jsx("main", { "data-testid": `page-${testIdPrefix}-render`, children: liveData ? /* @__PURE__ */ jsx(LiveDataProvider, { children: rendered }) : rendered });
|
|
2628
2947
|
}
|
|
2629
2948
|
|
|
2630
2949
|
// src/studio/persistence.ts
|
|
@@ -3156,7 +3475,7 @@ function Section({
|
|
|
3156
3475
|
] });
|
|
3157
3476
|
}
|
|
3158
3477
|
var iconMap = {
|
|
3159
|
-
FileText,
|
|
3478
|
+
FileText: FileText,
|
|
3160
3479
|
Folder,
|
|
3161
3480
|
Users,
|
|
3162
3481
|
Briefcase,
|
|
@@ -4232,6 +4551,13 @@ function createSiteBlocks(kit) {
|
|
|
4232
4551
|
TestimonialGrid: TestimonialGridBlock
|
|
4233
4552
|
};
|
|
4234
4553
|
}
|
|
4554
|
+
var emptySlot2 = [];
|
|
4555
|
+
var METRIC_COLS = {
|
|
4556
|
+
"2": "sm:grid-cols-2",
|
|
4557
|
+
"3": "sm:grid-cols-2 lg:grid-cols-3",
|
|
4558
|
+
"4": "sm:grid-cols-2 lg:grid-cols-4"
|
|
4559
|
+
};
|
|
4560
|
+
var METRIC_GAP = { sm: "gap-3", md: "gap-4", lg: "gap-6" };
|
|
4235
4561
|
function createArbiBlocksConfig(opts = {}) {
|
|
4236
4562
|
const kit = createBlockKit(opts.aiFields, opts.imageField, opts.eyebrowClassName);
|
|
4237
4563
|
const { textField, textareaField, boolRadio, iconField, resolveIcon, blockTestId } = kit;
|
|
@@ -4269,16 +4595,19 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4269
4595
|
fields: {
|
|
4270
4596
|
title: textField("Title"),
|
|
4271
4597
|
eyebrow: textField("Eyebrow"),
|
|
4272
|
-
description: textareaField("Description", void 0, "description")
|
|
4598
|
+
description: textareaField("Description", void 0, "description"),
|
|
4599
|
+
// `actions` is a slot so the top band can host real buttons/badges authored
|
|
4600
|
+
// as blocks (drop a Button in), while the interactive body stays bespoke.
|
|
4601
|
+
actions: { type: "slot", allow: ["Button", "Badge"] }
|
|
4273
4602
|
},
|
|
4274
|
-
defaultProps: { title: "Page title" },
|
|
4275
|
-
|
|
4276
|
-
render: ({ id, title, eyebrow, description }) => /* @__PURE__ */ jsx(
|
|
4603
|
+
defaultProps: { title: "Page title", actions: emptySlot2 },
|
|
4604
|
+
render: ({ id, title, eyebrow, description, actions: Actions }) => /* @__PURE__ */ jsx(
|
|
4277
4605
|
PageHeader,
|
|
4278
4606
|
{
|
|
4279
4607
|
title,
|
|
4280
4608
|
eyebrow,
|
|
4281
4609
|
description,
|
|
4610
|
+
actions: /* @__PURE__ */ jsx(Actions, { className: "flex items-center gap-2" }),
|
|
4282
4611
|
testId: blockTestId(id)
|
|
4283
4612
|
}
|
|
4284
4613
|
)
|
|
@@ -4288,16 +4617,18 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4288
4617
|
fields: {
|
|
4289
4618
|
title: textField("Title"),
|
|
4290
4619
|
description: textareaField("Description", void 0, "description"),
|
|
4291
|
-
icon: iconField()
|
|
4620
|
+
icon: iconField(),
|
|
4621
|
+
// `action` is a slot so an empty state can offer a real call-to-action button.
|
|
4622
|
+
action: { type: "slot", allow: ["Button"] }
|
|
4292
4623
|
},
|
|
4293
|
-
defaultProps: { title: "Nothing here yet" },
|
|
4294
|
-
|
|
4295
|
-
render: ({ id, title, description, icon }) => /* @__PURE__ */ jsx(
|
|
4624
|
+
defaultProps: { title: "Nothing here yet", action: emptySlot2 },
|
|
4625
|
+
render: ({ id, title, description, icon, action: Action }) => /* @__PURE__ */ jsx(
|
|
4296
4626
|
EmptyState,
|
|
4297
4627
|
{
|
|
4298
4628
|
title,
|
|
4299
4629
|
description,
|
|
4300
4630
|
icon: resolveIcon(icon),
|
|
4631
|
+
action: /* @__PURE__ */ jsx(Action, {}),
|
|
4301
4632
|
testId: blockTestId(id)
|
|
4302
4633
|
}
|
|
4303
4634
|
)
|
|
@@ -4350,6 +4681,42 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4350
4681
|
}
|
|
4351
4682
|
)
|
|
4352
4683
|
};
|
|
4684
|
+
const MetricRowBlock = {
|
|
4685
|
+
label: "Metric row",
|
|
4686
|
+
fields: {
|
|
4687
|
+
columns: {
|
|
4688
|
+
type: "radio",
|
|
4689
|
+
label: "Columns",
|
|
4690
|
+
options: [
|
|
4691
|
+
{ label: "2", value: "2" },
|
|
4692
|
+
{ label: "3", value: "3" },
|
|
4693
|
+
{ label: "4", value: "4" }
|
|
4694
|
+
]
|
|
4695
|
+
},
|
|
4696
|
+
gap: {
|
|
4697
|
+
type: "radio",
|
|
4698
|
+
label: "Gap",
|
|
4699
|
+
options: [
|
|
4700
|
+
{ label: "S", value: "sm" },
|
|
4701
|
+
{ label: "M", value: "md" },
|
|
4702
|
+
{ label: "L", value: "lg" }
|
|
4703
|
+
]
|
|
4704
|
+
},
|
|
4705
|
+
// Static KPI tiles and (when registered) live metric widgets both belong in a band.
|
|
4706
|
+
items: { type: "slot", allow: ["MetricCard", "LiveMetric"] }
|
|
4707
|
+
},
|
|
4708
|
+
defaultProps: { columns: "3", gap: "md", items: emptySlot2 },
|
|
4709
|
+
render: ({ id, columns, gap, items: Items }) => /* @__PURE__ */ jsx("div", { "data-testid": blockTestId(id), children: /* @__PURE__ */ jsx(
|
|
4710
|
+
Items,
|
|
4711
|
+
{
|
|
4712
|
+
className: cn(
|
|
4713
|
+
"grid grid-cols-1",
|
|
4714
|
+
METRIC_COLS[columns] ?? METRIC_COLS["3"],
|
|
4715
|
+
METRIC_GAP[gap] ?? METRIC_GAP.md
|
|
4716
|
+
)
|
|
4717
|
+
}
|
|
4718
|
+
) })
|
|
4719
|
+
};
|
|
4353
4720
|
const DataTableBlockConfig = {
|
|
4354
4721
|
label: "Data table",
|
|
4355
4722
|
fields: {
|
|
@@ -4548,11 +4915,13 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4548
4915
|
};
|
|
4549
4916
|
const website = createWebsiteBlocks(kit);
|
|
4550
4917
|
const site = createSiteBlocks(kit);
|
|
4918
|
+
const widgets = opts.liveWidgets ? createLiveWidgets(kit) : {};
|
|
4551
4919
|
const components = {
|
|
4552
4920
|
SectionHeading: SectionHeadingBlock,
|
|
4553
4921
|
PageHeader: PageHeaderBlock,
|
|
4554
4922
|
EmptyState: EmptyStateBlock,
|
|
4555
4923
|
MetricCard: MetricCardBlock,
|
|
4924
|
+
MetricRow: MetricRowBlock,
|
|
4556
4925
|
DataTable: DataTableBlockConfig,
|
|
4557
4926
|
Section: SectionBlock,
|
|
4558
4927
|
Card: CardBlock,
|
|
@@ -4560,7 +4929,8 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4560
4929
|
Badge: BadgeBlock,
|
|
4561
4930
|
Separator: SeparatorBlock,
|
|
4562
4931
|
...website,
|
|
4563
|
-
...site
|
|
4932
|
+
...site,
|
|
4933
|
+
...widgets
|
|
4564
4934
|
};
|
|
4565
4935
|
const config = {
|
|
4566
4936
|
categories: {
|
|
@@ -4594,7 +4964,8 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4594
4964
|
Commerce: { title: "Commerce", components: ["Pricing"] },
|
|
4595
4965
|
Forms: { title: "Forms", components: ["ContactForm"] },
|
|
4596
4966
|
Navigation: { title: "Navigation", components: ["Navbar", "Footer"] },
|
|
4597
|
-
Data: { title: "Data", components: ["MetricCard", "DataTable"] },
|
|
4967
|
+
Data: { title: "Data", components: ["MetricRow", "MetricCard", "DataTable"] },
|
|
4968
|
+
...opts.liveWidgets ? { Widgets: { title: "Widgets", components: ["AgentActivity", "LiveMetric"] } } : {},
|
|
4598
4969
|
Primitives: { title: "Primitives", components: ["Button", "Badge", "Separator"] }
|
|
4599
4970
|
},
|
|
4600
4971
|
components,
|
|
@@ -5079,6 +5450,6 @@ function VerticalBuilder({
|
|
|
5079
5450
|
] });
|
|
5080
5451
|
}
|
|
5081
5452
|
|
|
5082
|
-
export { ASSET_REF_PREFIX, Accordion, AgentsPanel, AssetResolverProvider, AvatarBlock, Banner, BlockImage, CTABanner, Callout, Columns, ConnectionProvider, ContactForm, Container, DataTable, DataTableBlock, EmptyState, FAQ, FeatureGrid, Footer, Gallery, GridView, Hero, LegalArbiProvider, ListBlock, LogoCloud, MediaText, MetricCard, ModuleManager, Navbar, PageHeader, PageRenderer, PricingTable, RichTextBlock, Section, SectionHeading, Spacer, StatGroup, Steps, StudioEditor, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, Toolbar, VerticalBuilder, VideoEmbed, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearThemeVars, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createArbiMaterializer, createBlockKit, createImageField, createModuleRegistry, createModuleStore, createPromptLibrary, createSiteBlocks, createStudioPersistence, createThemeStore, createVerticalExport, createWebsiteBlocks, daysUntil, fmtDate, fmtDateTime, fromNow, gbp, hrs, iconMap, initials, isAssetRef, isAuthenticated, materializePageData, matterToContext, pct, tid, toEmbedUrl, toHslTriplet, useAssetResolverActive, useConnection, useFirmAiTask, useImageGen, useSemanticSearch, useWorkspaceDocs };
|
|
5453
|
+
export { ASSET_REF_PREFIX, Accordion, AgentsPanel, AppShell, AssetResolverProvider, AvatarBlock, Banner, BlockImage, CTABanner, Callout, Columns, ConnectionProvider, ContactForm, Container, DataTable, DataTableBlock, EmptyState, FAQ, FeatureGrid, Footer, Gallery, GridView, Hero, LegalArbiProvider, ListBlock, LiveDataProvider, LogoCloud, MediaText, MetricCard, ModuleManager, Navbar, PageHeader, PageRenderer, PricingTable, RichTextBlock, Section, SectionHeading, Spacer, StatGroup, Steps, StudioEditor, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, Toolbar, VerticalBuilder, VideoEmbed, WidgetPlaceholder, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearThemeVars, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createArbiMaterializer, createBlockKit, createImageField, createLiveWidgets, createModuleRegistry, createModuleStore, createPromptLibrary, createSiteBlocks, createStudioPersistence, createThemeStore, createVerticalExport, createWebsiteBlocks, daysUntil, fmtDate, fmtDateTime, fromNow, gbp, hrs, iconMap, initials, isAssetRef, isAuthenticated, materializePageData, matterToContext, pct, tid, toEmbedUrl, toHslTriplet, useAssetResolverActive, useConnection, useFirmAiTask, useImageGen, useLiveDataActive, useSemanticSearch, useWorkspaceDocs };
|
|
5083
5454
|
//# sourceMappingURL=index.js.map
|
|
5084
5455
|
//# sourceMappingURL=index.js.map
|