@arbidocs/blocks 0.3.115 → 0.3.117
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 +542 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +182 -55
- package/dist/index.d.ts +182 -55
- package/dist/index.js +541 -33
- 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, Crop, 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, NotificationBell, UserMenu, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs as Tabs$1, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, useThumbnails, ImageCropModal, DEFAULT_ASPECT_OPTIONS, 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
|
|
@@ -603,7 +603,25 @@ function ConnectionProvider({
|
|
|
603
603
|
await arbi.selectWorkspace(target.external_id);
|
|
604
604
|
setWorkspaceId(target.external_id);
|
|
605
605
|
}
|
|
606
|
-
|
|
606
|
+
let resolved = { name: email.split("@")[0], email };
|
|
607
|
+
try {
|
|
608
|
+
const me = arbi.user.identity();
|
|
609
|
+
const members = await arbi.workspaces.listUsers();
|
|
610
|
+
const self = members.find((m) => m.user.external_id === me?.externalId)?.user;
|
|
611
|
+
if (self) {
|
|
612
|
+
const fullName = [self.given_name, self.family_name].filter(Boolean).join(" ").trim();
|
|
613
|
+
resolved = {
|
|
614
|
+
name: fullName || email.split("@")[0],
|
|
615
|
+
email: self.email || email,
|
|
616
|
+
externalId: self.external_id,
|
|
617
|
+
picture: self.picture ?? null
|
|
618
|
+
};
|
|
619
|
+
} else if (me?.externalId) {
|
|
620
|
+
resolved.externalId = me.externalId;
|
|
621
|
+
}
|
|
622
|
+
} catch {
|
|
623
|
+
}
|
|
624
|
+
setUser(resolved);
|
|
607
625
|
setStatus("authenticated");
|
|
608
626
|
} catch (e) {
|
|
609
627
|
setError(e instanceof Error ? e.message : "Sign-in failed. Check your credentials.");
|
|
@@ -2297,6 +2315,390 @@ function TestimonialGrid({ items, columns = "3", testId }) {
|
|
|
2297
2315
|
i
|
|
2298
2316
|
)) });
|
|
2299
2317
|
}
|
|
2318
|
+
function NavItemLink({ item, onNavigate }) {
|
|
2319
|
+
return /* @__PURE__ */ jsxs(
|
|
2320
|
+
NavLink,
|
|
2321
|
+
{
|
|
2322
|
+
to: item.to,
|
|
2323
|
+
end: item.end,
|
|
2324
|
+
onClick: onNavigate,
|
|
2325
|
+
"data-testid": tid("sidebar-nav", item.id),
|
|
2326
|
+
className: ({ isActive }) => cn(
|
|
2327
|
+
"group flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
|
2328
|
+
isActive ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
|
|
2329
|
+
),
|
|
2330
|
+
children: [
|
|
2331
|
+
/* @__PURE__ */ jsx(item.icon, { className: "size-[18px] shrink-0" }),
|
|
2332
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
|
|
2333
|
+
item.arbi && /* @__PURE__ */ jsx(Sparkles, { className: "size-3.5 text-sidebar-primary", "aria-label": "Powered by ARBI" })
|
|
2334
|
+
]
|
|
2335
|
+
}
|
|
2336
|
+
);
|
|
2337
|
+
}
|
|
2338
|
+
function SidebarBody({
|
|
2339
|
+
sections,
|
|
2340
|
+
footerItems,
|
|
2341
|
+
logo,
|
|
2342
|
+
logoHref,
|
|
2343
|
+
logoLabel,
|
|
2344
|
+
sidebarFooter,
|
|
2345
|
+
onNavigate
|
|
2346
|
+
}) {
|
|
2347
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2348
|
+
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 }),
|
|
2349
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 space-y-6 overflow-y-auto px-3 py-5", children: sections.map((section) => /* @__PURE__ */ jsxs("div", { children: [
|
|
2350
|
+
/* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-sidebar-foreground/55", children: section.heading }),
|
|
2351
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: section.items.map((item) => /* @__PURE__ */ jsx(NavItemLink, { item, onNavigate }, item.id)) })
|
|
2352
|
+
] }, section.heading)) }),
|
|
2353
|
+
(footerItems?.length || sidebarFooter) && /* @__PURE__ */ jsxs("div", { className: "border-t border-sidebar-border px-3 py-3", children: [
|
|
2354
|
+
footerItems?.map((item) => /* @__PURE__ */ jsx(NavItemLink, { item, onNavigate }, item.id)),
|
|
2355
|
+
sidebarFooter
|
|
2356
|
+
] })
|
|
2357
|
+
] });
|
|
2358
|
+
}
|
|
2359
|
+
function AppShell({
|
|
2360
|
+
sections,
|
|
2361
|
+
footerItems,
|
|
2362
|
+
logo,
|
|
2363
|
+
logoHref,
|
|
2364
|
+
logoLabel,
|
|
2365
|
+
sidebarFooter,
|
|
2366
|
+
topbar,
|
|
2367
|
+
rightRail,
|
|
2368
|
+
children,
|
|
2369
|
+
mainClassName,
|
|
2370
|
+
testIdPrefix = "app"
|
|
2371
|
+
}) {
|
|
2372
|
+
const [open, setOpen] = useState(false);
|
|
2373
|
+
const location = useLocation();
|
|
2374
|
+
useEffect(() => {
|
|
2375
|
+
setOpen(false);
|
|
2376
|
+
}, [location.pathname]);
|
|
2377
|
+
const body = (onNavigate) => /* @__PURE__ */ jsx(
|
|
2378
|
+
SidebarBody,
|
|
2379
|
+
{
|
|
2380
|
+
sections,
|
|
2381
|
+
footerItems,
|
|
2382
|
+
logo,
|
|
2383
|
+
logoHref,
|
|
2384
|
+
logoLabel,
|
|
2385
|
+
sidebarFooter,
|
|
2386
|
+
onNavigate
|
|
2387
|
+
}
|
|
2388
|
+
);
|
|
2389
|
+
return /* @__PURE__ */ jsxs(
|
|
2390
|
+
"div",
|
|
2391
|
+
{
|
|
2392
|
+
className: "flex h-screen overflow-hidden bg-background",
|
|
2393
|
+
"data-testid": `${testIdPrefix}-shell`,
|
|
2394
|
+
children: [
|
|
2395
|
+
/* @__PURE__ */ jsx(
|
|
2396
|
+
"aside",
|
|
2397
|
+
{
|
|
2398
|
+
className: "hidden h-full w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar lg:flex",
|
|
2399
|
+
"data-testid": `${testIdPrefix}-sidebar`,
|
|
2400
|
+
children: body()
|
|
2401
|
+
}
|
|
2402
|
+
),
|
|
2403
|
+
open && /* @__PURE__ */ jsxs(
|
|
2404
|
+
"div",
|
|
2405
|
+
{
|
|
2406
|
+
className: "fixed inset-0 z-50 lg:hidden",
|
|
2407
|
+
"data-testid": `${testIdPrefix}-sidebar-mobile`,
|
|
2408
|
+
children: [
|
|
2409
|
+
/* @__PURE__ */ jsx(
|
|
2410
|
+
"div",
|
|
2411
|
+
{
|
|
2412
|
+
className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
|
|
2413
|
+
onClick: () => setOpen(false),
|
|
2414
|
+
"aria-hidden": true
|
|
2415
|
+
}
|
|
2416
|
+
),
|
|
2417
|
+
/* @__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: [
|
|
2418
|
+
/* @__PURE__ */ jsx(
|
|
2419
|
+
"button",
|
|
2420
|
+
{
|
|
2421
|
+
type: "button",
|
|
2422
|
+
onClick: () => setOpen(false),
|
|
2423
|
+
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",
|
|
2424
|
+
"aria-label": "Close menu",
|
|
2425
|
+
"data-testid": `${testIdPrefix}-sidebar-close`,
|
|
2426
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-5" })
|
|
2427
|
+
}
|
|
2428
|
+
),
|
|
2429
|
+
body(() => setOpen(false))
|
|
2430
|
+
] })
|
|
2431
|
+
]
|
|
2432
|
+
}
|
|
2433
|
+
),
|
|
2434
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
2435
|
+
/* @__PURE__ */ jsxs(
|
|
2436
|
+
"header",
|
|
2437
|
+
{
|
|
2438
|
+
className: "flex h-16 shrink-0 items-center gap-4 border-b border-border bg-card/80 px-6 backdrop-blur",
|
|
2439
|
+
"data-testid": `${testIdPrefix}-topbar`,
|
|
2440
|
+
children: [
|
|
2441
|
+
/* @__PURE__ */ jsx(
|
|
2442
|
+
"button",
|
|
2443
|
+
{
|
|
2444
|
+
type: "button",
|
|
2445
|
+
onClick: () => setOpen(true),
|
|
2446
|
+
className: "flex size-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground lg:hidden",
|
|
2447
|
+
"data-testid": `${testIdPrefix}-nav-toggle`,
|
|
2448
|
+
"aria-label": "Open menu",
|
|
2449
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
|
|
2450
|
+
}
|
|
2451
|
+
),
|
|
2452
|
+
topbar
|
|
2453
|
+
]
|
|
2454
|
+
}
|
|
2455
|
+
),
|
|
2456
|
+
/* @__PURE__ */ jsx(
|
|
2457
|
+
"main",
|
|
2458
|
+
{
|
|
2459
|
+
className: cn("flex-1 overflow-y-auto", mainClassName),
|
|
2460
|
+
"data-testid": `${testIdPrefix}-main`,
|
|
2461
|
+
children
|
|
2462
|
+
}
|
|
2463
|
+
)
|
|
2464
|
+
] }),
|
|
2465
|
+
rightRail
|
|
2466
|
+
]
|
|
2467
|
+
}
|
|
2468
|
+
);
|
|
2469
|
+
}
|
|
2470
|
+
function AppHeader({
|
|
2471
|
+
onSearch,
|
|
2472
|
+
onAsk,
|
|
2473
|
+
searchPlaceholder = "Ask AI or search\u2026",
|
|
2474
|
+
searchKbd = "\u2318K",
|
|
2475
|
+
askLabel = "Ask AI",
|
|
2476
|
+
leading,
|
|
2477
|
+
actions,
|
|
2478
|
+
user,
|
|
2479
|
+
userItems,
|
|
2480
|
+
onLogout,
|
|
2481
|
+
onNotificationNavigate,
|
|
2482
|
+
notificationTones,
|
|
2483
|
+
classNames,
|
|
2484
|
+
testIdPrefix = "app"
|
|
2485
|
+
}) {
|
|
2486
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2487
|
+
/* @__PURE__ */ jsxs(
|
|
2488
|
+
"button",
|
|
2489
|
+
{
|
|
2490
|
+
type: "button",
|
|
2491
|
+
onClick: onSearch,
|
|
2492
|
+
className: classNames?.search ?? "relative hidden max-w-md flex-1 items-center rounded-md border border-input bg-background py-2 pl-9 pr-3 text-left text-sm text-muted-foreground transition-colors hover:bg-accent md:flex",
|
|
2493
|
+
"data-testid": tid(testIdPrefix, "global-search"),
|
|
2494
|
+
children: [
|
|
2495
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2496
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: searchPlaceholder }),
|
|
2497
|
+
/* @__PURE__ */ jsx("kbd", { className: "rounded border border-border px-1.5 py-0.5 text-[10px]", children: searchKbd })
|
|
2498
|
+
]
|
|
2499
|
+
}
|
|
2500
|
+
),
|
|
2501
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
|
|
2502
|
+
leading,
|
|
2503
|
+
/* @__PURE__ */ jsxs(
|
|
2504
|
+
Button,
|
|
2505
|
+
{
|
|
2506
|
+
size: "sm",
|
|
2507
|
+
onClick: onAsk ?? onSearch,
|
|
2508
|
+
className: classNames?.askButton,
|
|
2509
|
+
"data-testid": tid(testIdPrefix, "ask-ai"),
|
|
2510
|
+
children: [
|
|
2511
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "size-4" }),
|
|
2512
|
+
askLabel
|
|
2513
|
+
]
|
|
2514
|
+
}
|
|
2515
|
+
),
|
|
2516
|
+
actions,
|
|
2517
|
+
/* @__PURE__ */ jsx(
|
|
2518
|
+
NotificationBell,
|
|
2519
|
+
{
|
|
2520
|
+
testId: tid(testIdPrefix, "notifications"),
|
|
2521
|
+
onNavigate: onNotificationNavigate,
|
|
2522
|
+
toneClassNames: notificationTones
|
|
2523
|
+
}
|
|
2524
|
+
),
|
|
2525
|
+
/* @__PURE__ */ jsx(
|
|
2526
|
+
UserMenu,
|
|
2527
|
+
{
|
|
2528
|
+
user,
|
|
2529
|
+
items: userItems,
|
|
2530
|
+
onLogout,
|
|
2531
|
+
testId: tid(testIdPrefix, "user-menu"),
|
|
2532
|
+
logoutTestId: tid(testIdPrefix, "logout")
|
|
2533
|
+
}
|
|
2534
|
+
)
|
|
2535
|
+
] })
|
|
2536
|
+
] });
|
|
2537
|
+
}
|
|
2538
|
+
var LiveDataContext = createContext(false);
|
|
2539
|
+
function useLiveDataActive() {
|
|
2540
|
+
return useContext(LiveDataContext);
|
|
2541
|
+
}
|
|
2542
|
+
function LiveDataProvider({ children }) {
|
|
2543
|
+
return /* @__PURE__ */ jsx(LiveDataContext.Provider, { value: true, children });
|
|
2544
|
+
}
|
|
2545
|
+
function WidgetPlaceholder({
|
|
2546
|
+
label,
|
|
2547
|
+
icon: Icon = Sparkles,
|
|
2548
|
+
testId
|
|
2549
|
+
}) {
|
|
2550
|
+
return /* @__PURE__ */ jsxs(
|
|
2551
|
+
"div",
|
|
2552
|
+
{
|
|
2553
|
+
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",
|
|
2554
|
+
"data-testid": testId,
|
|
2555
|
+
children: [
|
|
2556
|
+
/* @__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" }) }),
|
|
2557
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2558
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: label }),
|
|
2559
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1", children: "\xB7 live in the app" })
|
|
2560
|
+
] })
|
|
2561
|
+
]
|
|
2562
|
+
}
|
|
2563
|
+
);
|
|
2564
|
+
}
|
|
2565
|
+
function useActiveWorkspaceId() {
|
|
2566
|
+
const { workspaceId, fallbackWorkspaceId } = useConnection();
|
|
2567
|
+
return workspaceId ?? fallbackWorkspaceId ?? void 0;
|
|
2568
|
+
}
|
|
2569
|
+
function timeAgo(iso) {
|
|
2570
|
+
if (!iso) return "";
|
|
2571
|
+
const then = new Date(iso).getTime();
|
|
2572
|
+
if (Number.isNaN(then)) return "";
|
|
2573
|
+
const s = Math.max(0, Math.round((Date.now() - then) / 1e3));
|
|
2574
|
+
if (s < 60) return "just now";
|
|
2575
|
+
const m = Math.round(s / 60);
|
|
2576
|
+
if (m < 60) return `${m}m ago`;
|
|
2577
|
+
const h = Math.round(m / 60);
|
|
2578
|
+
if (h < 24) return `${h}h ago`;
|
|
2579
|
+
return `${Math.round(h / 24)}d ago`;
|
|
2580
|
+
}
|
|
2581
|
+
var METRIC_SOURCES = {
|
|
2582
|
+
documents: { label: "Documents", icon: FileText },
|
|
2583
|
+
conversations: { label: "Agent threads", icon: Bot }
|
|
2584
|
+
};
|
|
2585
|
+
var asMetricSource = (s) => s in METRIC_SOURCES ? s : "documents";
|
|
2586
|
+
function AgentActivityLive({
|
|
2587
|
+
title,
|
|
2588
|
+
limit,
|
|
2589
|
+
testId
|
|
2590
|
+
}) {
|
|
2591
|
+
const wsId = useActiveWorkspaceId();
|
|
2592
|
+
const { data, isLoading } = useConversations(wsId);
|
|
2593
|
+
const rows = [...data ?? []].sort((a, b) => +new Date(b.updated_at ?? 0) - +new Date(a.updated_at ?? 0)).slice(0, limit);
|
|
2594
|
+
return /* @__PURE__ */ jsxs(Card, { variant: "elevated", className: "rounded-xl p-5", "data-testid": testId, children: [
|
|
2595
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center gap-2", children: [
|
|
2596
|
+
/* @__PURE__ */ jsx(Bot, { className: "size-4 text-muted-foreground" }),
|
|
2597
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: title })
|
|
2598
|
+
] }),
|
|
2599
|
+
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(
|
|
2600
|
+
"li",
|
|
2601
|
+
{
|
|
2602
|
+
className: "flex items-center justify-between gap-3",
|
|
2603
|
+
"data-testid": `${testId}-item-${i}`,
|
|
2604
|
+
children: [
|
|
2605
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 truncate", children: [
|
|
2606
|
+
/* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
2607
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-sm text-foreground", children: c.title?.trim() || "Untitled thread" })
|
|
2608
|
+
] }),
|
|
2609
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: timeAgo(c.updated_at) })
|
|
2610
|
+
]
|
|
2611
|
+
},
|
|
2612
|
+
c.external_id ?? i
|
|
2613
|
+
)) })
|
|
2614
|
+
] });
|
|
2615
|
+
}
|
|
2616
|
+
function LiveMetricInner({
|
|
2617
|
+
label,
|
|
2618
|
+
source,
|
|
2619
|
+
accent,
|
|
2620
|
+
testId
|
|
2621
|
+
}) {
|
|
2622
|
+
const wsId = useActiveWorkspaceId();
|
|
2623
|
+
const docs = useDocuments(wsId, { enabled: source === "documents" });
|
|
2624
|
+
const convos = useConversations(wsId, { enabled: source === "conversations" });
|
|
2625
|
+
const query = source === "documents" ? docs : convos;
|
|
2626
|
+
const count = Array.isArray(query.data) ? query.data.length : 0;
|
|
2627
|
+
return /* @__PURE__ */ jsx(
|
|
2628
|
+
MetricCard,
|
|
2629
|
+
{
|
|
2630
|
+
label: label || METRIC_SOURCES[source].label,
|
|
2631
|
+
value: query.isLoading ? "\u2014" : String(count),
|
|
2632
|
+
accent,
|
|
2633
|
+
icon: METRIC_SOURCES[source].icon,
|
|
2634
|
+
testId
|
|
2635
|
+
}
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
function AgentActivityBlock({
|
|
2639
|
+
title,
|
|
2640
|
+
limit,
|
|
2641
|
+
testId
|
|
2642
|
+
}) {
|
|
2643
|
+
return useLiveDataActive() ? /* @__PURE__ */ jsx(AgentActivityLive, { title, limit, testId }) : /* @__PURE__ */ jsx(WidgetPlaceholder, { label: String(title || "Agent activity"), icon: Bot, testId });
|
|
2644
|
+
}
|
|
2645
|
+
function LiveMetricBlock({
|
|
2646
|
+
label,
|
|
2647
|
+
source,
|
|
2648
|
+
accent,
|
|
2649
|
+
testId
|
|
2650
|
+
}) {
|
|
2651
|
+
const src = asMetricSource(source);
|
|
2652
|
+
return useLiveDataActive() ? /* @__PURE__ */ jsx(LiveMetricInner, { label, source: src, accent, testId }) : /* @__PURE__ */ jsx(
|
|
2653
|
+
WidgetPlaceholder,
|
|
2654
|
+
{
|
|
2655
|
+
label: String(label || METRIC_SOURCES[src].label),
|
|
2656
|
+
icon: METRIC_SOURCES[src].icon,
|
|
2657
|
+
testId
|
|
2658
|
+
}
|
|
2659
|
+
);
|
|
2660
|
+
}
|
|
2661
|
+
function createLiveWidgets(kit) {
|
|
2662
|
+
const { blockTestId } = kit;
|
|
2663
|
+
const AgentActivityWidget = {
|
|
2664
|
+
label: "Agent activity (live)",
|
|
2665
|
+
fields: {
|
|
2666
|
+
title: { type: "text", label: "Title" },
|
|
2667
|
+
limit: { type: "number", label: "Rows", min: 1, max: 8 }
|
|
2668
|
+
},
|
|
2669
|
+
defaultProps: { title: "Recent agent activity", limit: 4 },
|
|
2670
|
+
render: ({ id, title, limit }) => /* @__PURE__ */ jsx(AgentActivityBlock, { title, limit, testId: blockTestId(id) })
|
|
2671
|
+
};
|
|
2672
|
+
const LiveMetricWidget = {
|
|
2673
|
+
label: "Live metric",
|
|
2674
|
+
fields: {
|
|
2675
|
+
label: { type: "text", label: "Label" },
|
|
2676
|
+
source: {
|
|
2677
|
+
type: "select",
|
|
2678
|
+
label: "Source",
|
|
2679
|
+
options: [
|
|
2680
|
+
{ label: "Documents", value: "documents" },
|
|
2681
|
+
{ label: "Agent threads", value: "conversations" }
|
|
2682
|
+
]
|
|
2683
|
+
},
|
|
2684
|
+
accent: {
|
|
2685
|
+
type: "radio",
|
|
2686
|
+
label: "Accent",
|
|
2687
|
+
options: [
|
|
2688
|
+
{ label: "Default", value: "default" },
|
|
2689
|
+
{ label: "Primary", value: "primary" },
|
|
2690
|
+
{ label: "Success", value: "success" }
|
|
2691
|
+
]
|
|
2692
|
+
}
|
|
2693
|
+
},
|
|
2694
|
+
defaultProps: { label: "", source: "documents", accent: "primary" },
|
|
2695
|
+
render: ({ id, label, source, accent }) => /* @__PURE__ */ jsx(LiveMetricBlock, { label, source, accent, testId: blockTestId(id) })
|
|
2696
|
+
};
|
|
2697
|
+
return {
|
|
2698
|
+
AgentActivity: AgentActivityWidget,
|
|
2699
|
+
LiveMetric: LiveMetricWidget
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2300
2702
|
|
|
2301
2703
|
// src/studio/publish.ts
|
|
2302
2704
|
function blobToDataUrl(blob) {
|
|
@@ -2571,34 +2973,36 @@ function PageRenderer({
|
|
|
2571
2973
|
live,
|
|
2572
2974
|
slug: slugProp,
|
|
2573
2975
|
emptyState,
|
|
2574
|
-
testIdPrefix = "studio"
|
|
2976
|
+
testIdPrefix = "studio",
|
|
2977
|
+
liveData = false,
|
|
2978
|
+
initialData,
|
|
2979
|
+
applyTheme = true
|
|
2575
2980
|
}) {
|
|
2576
2981
|
const params = useParams();
|
|
2577
2982
|
const slug = slugProp ?? params.slug ?? "home";
|
|
2578
2983
|
const arbi = useArbi();
|
|
2579
|
-
const [data, setData] = useState(null);
|
|
2580
|
-
const [loading, setLoading] = useState(
|
|
2984
|
+
const [data, setData] = useState(initialData ?? null);
|
|
2985
|
+
const [loading, setLoading] = useState(!initialData);
|
|
2581
2986
|
useEffect(() => {
|
|
2582
2987
|
let cancelled = false;
|
|
2583
|
-
setLoading(
|
|
2988
|
+
setLoading(!initialData);
|
|
2584
2989
|
void (async () => {
|
|
2585
|
-
const
|
|
2586
|
-
persistence.loadPublished(arbi, live, slug),
|
|
2587
|
-
persistence.loadTheme(arbi, live)
|
|
2588
|
-
]);
|
|
2990
|
+
const theme = applyTheme ? (await persistence.loadTheme(arbi, live)).data : void 0;
|
|
2589
2991
|
if (cancelled) return;
|
|
2590
|
-
const page =
|
|
2992
|
+
const page = initialData ?? (await persistence.loadPublished(arbi, live, slug)).data ?? (await persistence.loadPage(arbi, live, slug)).data;
|
|
2591
2993
|
if (cancelled) return;
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2994
|
+
if (applyTheme) {
|
|
2995
|
+
applyThemeVars(
|
|
2996
|
+
theme ? { ...defaultTheme, ...theme, colors: { ...defaultTheme.colors, ...theme.colors } } : defaultTheme
|
|
2997
|
+
);
|
|
2998
|
+
}
|
|
2595
2999
|
setData(page);
|
|
2596
3000
|
setLoading(false);
|
|
2597
3001
|
})();
|
|
2598
3002
|
return () => {
|
|
2599
3003
|
cancelled = true;
|
|
2600
3004
|
};
|
|
2601
|
-
}, [arbi, live, slug, persistence, defaultTheme]);
|
|
3005
|
+
}, [arbi, live, slug, persistence, defaultTheme, initialData, applyTheme]);
|
|
2602
3006
|
if (loading) {
|
|
2603
3007
|
return /* @__PURE__ */ jsx(
|
|
2604
3008
|
"div",
|
|
@@ -2624,7 +3028,8 @@ function PageRenderer({
|
|
|
2624
3028
|
}
|
|
2625
3029
|
);
|
|
2626
3030
|
}
|
|
2627
|
-
|
|
3031
|
+
const rendered = /* @__PURE__ */ jsx(Render, { config, data });
|
|
3032
|
+
return /* @__PURE__ */ jsx("main", { "data-testid": `page-${testIdPrefix}-render`, children: liveData ? /* @__PURE__ */ jsx(LiveDataProvider, { children: rendered }) : rendered });
|
|
2628
3033
|
}
|
|
2629
3034
|
|
|
2630
3035
|
// src/studio/persistence.ts
|
|
@@ -2899,6 +3304,9 @@ function useImageGen() {
|
|
|
2899
3304
|
reset: task.reset
|
|
2900
3305
|
};
|
|
2901
3306
|
}
|
|
3307
|
+
function toJpgName(name) {
|
|
3308
|
+
return name.replace(/\.[^.]+$/, "") + ".jpg";
|
|
3309
|
+
}
|
|
2902
3310
|
var IMAGE_EXT = /\.(png|jpe?g|webp|gif|avif|svg)$/i;
|
|
2903
3311
|
function ImageFieldControl({
|
|
2904
3312
|
value,
|
|
@@ -2912,9 +3320,12 @@ function ImageFieldControl({
|
|
|
2912
3320
|
const [url, setUrl] = useState("");
|
|
2913
3321
|
const [prompt, setPrompt] = useState("");
|
|
2914
3322
|
const [busy, setBusy] = useState(false);
|
|
3323
|
+
const [cropSrc, setCropSrc] = useState(null);
|
|
3324
|
+
const [cropName, setCropName] = useState("image.jpg");
|
|
2915
3325
|
const arbi = useArbi();
|
|
2916
3326
|
const gen = useImageGen();
|
|
2917
3327
|
const queryClient = useQueryClient();
|
|
3328
|
+
const currentAssetImage = useAssetImage(isAssetRef(value) ? assetRefId(value) : "");
|
|
2918
3329
|
const tp = (...q) => tid(`${testIdPrefix}-image`, name, ...q);
|
|
2919
3330
|
const refreshAssets = () => queryClient.invalidateQueries({ queryKey: ["arbi", "documents", workspaceId] });
|
|
2920
3331
|
const { data: docs } = useDocuments(workspaceId);
|
|
@@ -2929,13 +3340,24 @@ function ImageFieldControl({
|
|
|
2929
3340
|
[imageDocs]
|
|
2930
3341
|
);
|
|
2931
3342
|
const { data: thumbs } = useThumbnails(imageIds);
|
|
2932
|
-
const onUpload =
|
|
3343
|
+
const onUpload = (e) => {
|
|
2933
3344
|
const file = e.target.files?.[0];
|
|
2934
3345
|
if (!file) return;
|
|
3346
|
+
setCropName(toJpgName(file.name));
|
|
3347
|
+
setCropSrc(URL.createObjectURL(file));
|
|
3348
|
+
e.target.value = "";
|
|
3349
|
+
};
|
|
3350
|
+
const openReframe = () => {
|
|
3351
|
+
if (!currentAssetImage) return;
|
|
3352
|
+
setCropName("reframe.jpg");
|
|
3353
|
+
setCropSrc(currentAssetImage);
|
|
3354
|
+
};
|
|
3355
|
+
const uploadBlobAsAsset = async (blob, name2) => {
|
|
2935
3356
|
setBusy(true);
|
|
2936
3357
|
try {
|
|
2937
3358
|
await arbi.selectWorkspace(workspaceId);
|
|
2938
|
-
const
|
|
3359
|
+
const file = new File([blob], name2, { type: blob.type });
|
|
3360
|
+
const res = await arbi.documents.uploadFile(file, name2, { folder });
|
|
2939
3361
|
const id = res.doc_ext_ids?.[0];
|
|
2940
3362
|
if (id) {
|
|
2941
3363
|
onChange(asAssetRef(id));
|
|
@@ -2945,6 +3367,12 @@ function ImageFieldControl({
|
|
|
2945
3367
|
setBusy(false);
|
|
2946
3368
|
}
|
|
2947
3369
|
};
|
|
3370
|
+
const onCropComplete = async (result) => {
|
|
3371
|
+
const src = cropSrc;
|
|
3372
|
+
setCropSrc(null);
|
|
3373
|
+
await uploadBlobAsAsset(result.blob, cropName);
|
|
3374
|
+
if (src?.startsWith("blob:")) URL.revokeObjectURL(src);
|
|
3375
|
+
};
|
|
2948
3376
|
const onGenerate = async () => {
|
|
2949
3377
|
if (!prompt.trim() || gen.isGenerating) return;
|
|
2950
3378
|
const id = await gen.generate(prompt);
|
|
@@ -2962,7 +3390,22 @@ function ImageFieldControl({
|
|
|
2962
3390
|
const inputClass = "w-full rounded-md border border-border bg-card px-2.5 py-1.5 text-sm text-foreground outline-none focus:border-primary";
|
|
2963
3391
|
const tabClass = (on) => `inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium ${on ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`;
|
|
2964
3392
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", "data-testid": tp(), children: [
|
|
2965
|
-
/* @__PURE__ */
|
|
3393
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
3394
|
+
/* @__PURE__ */ jsx(BlockImage, { src: value, aspect: "16:9", rounded: "md", testId: tp("preview") }),
|
|
3395
|
+
currentAssetImage ? /* @__PURE__ */ jsxs(
|
|
3396
|
+
"button",
|
|
3397
|
+
{
|
|
3398
|
+
type: "button",
|
|
3399
|
+
onClick: openReframe,
|
|
3400
|
+
className: "absolute right-1.5 top-1.5 inline-flex items-center gap-1 rounded-md bg-background/85 px-2 py-1 text-xs font-medium text-foreground shadow-sm backdrop-blur hover:bg-background",
|
|
3401
|
+
"data-testid": tp("reframe"),
|
|
3402
|
+
children: [
|
|
3403
|
+
/* @__PURE__ */ jsx(Crop, { className: "size-3" }),
|
|
3404
|
+
" Crop"
|
|
3405
|
+
]
|
|
3406
|
+
}
|
|
3407
|
+
) : null
|
|
3408
|
+
] }),
|
|
2966
3409
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: MODES.map((m) => /* @__PURE__ */ jsxs(
|
|
2967
3410
|
"button",
|
|
2968
3411
|
{
|
|
@@ -3079,6 +3522,19 @@ function ImageFieldControl({
|
|
|
3079
3522
|
"data-testid": tp("clear"),
|
|
3080
3523
|
children: "Clear"
|
|
3081
3524
|
}
|
|
3525
|
+
),
|
|
3526
|
+
/* @__PURE__ */ jsx(
|
|
3527
|
+
ImageCropModal,
|
|
3528
|
+
{
|
|
3529
|
+
open: !!cropSrc,
|
|
3530
|
+
image: cropSrc,
|
|
3531
|
+
title: "Frame your image",
|
|
3532
|
+
aspectOptions: DEFAULT_ASPECT_OPTIONS,
|
|
3533
|
+
cropShape: "rect",
|
|
3534
|
+
output: { maxSize: 1600 },
|
|
3535
|
+
onComplete: onCropComplete,
|
|
3536
|
+
onCancel: () => setCropSrc(null)
|
|
3537
|
+
}
|
|
3082
3538
|
)
|
|
3083
3539
|
] });
|
|
3084
3540
|
}
|
|
@@ -3156,7 +3612,7 @@ function Section({
|
|
|
3156
3612
|
] });
|
|
3157
3613
|
}
|
|
3158
3614
|
var iconMap = {
|
|
3159
|
-
FileText,
|
|
3615
|
+
FileText: FileText,
|
|
3160
3616
|
Folder,
|
|
3161
3617
|
Users,
|
|
3162
3618
|
Briefcase,
|
|
@@ -4232,6 +4688,13 @@ function createSiteBlocks(kit) {
|
|
|
4232
4688
|
TestimonialGrid: TestimonialGridBlock
|
|
4233
4689
|
};
|
|
4234
4690
|
}
|
|
4691
|
+
var emptySlot2 = [];
|
|
4692
|
+
var METRIC_COLS = {
|
|
4693
|
+
"2": "sm:grid-cols-2",
|
|
4694
|
+
"3": "sm:grid-cols-2 lg:grid-cols-3",
|
|
4695
|
+
"4": "sm:grid-cols-2 lg:grid-cols-4"
|
|
4696
|
+
};
|
|
4697
|
+
var METRIC_GAP = { sm: "gap-3", md: "gap-4", lg: "gap-6" };
|
|
4235
4698
|
function createArbiBlocksConfig(opts = {}) {
|
|
4236
4699
|
const kit = createBlockKit(opts.aiFields, opts.imageField, opts.eyebrowClassName);
|
|
4237
4700
|
const { textField, textareaField, boolRadio, iconField, resolveIcon, blockTestId } = kit;
|
|
@@ -4269,16 +4732,19 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4269
4732
|
fields: {
|
|
4270
4733
|
title: textField("Title"),
|
|
4271
4734
|
eyebrow: textField("Eyebrow"),
|
|
4272
|
-
description: textareaField("Description", void 0, "description")
|
|
4735
|
+
description: textareaField("Description", void 0, "description"),
|
|
4736
|
+
// `actions` is a slot so the top band can host real buttons/badges authored
|
|
4737
|
+
// as blocks (drop a Button in), while the interactive body stays bespoke.
|
|
4738
|
+
actions: { type: "slot", allow: ["Button", "Badge"] }
|
|
4273
4739
|
},
|
|
4274
|
-
defaultProps: { title: "Page title" },
|
|
4275
|
-
|
|
4276
|
-
render: ({ id, title, eyebrow, description }) => /* @__PURE__ */ jsx(
|
|
4740
|
+
defaultProps: { title: "Page title", actions: emptySlot2 },
|
|
4741
|
+
render: ({ id, title, eyebrow, description, actions: Actions }) => /* @__PURE__ */ jsx(
|
|
4277
4742
|
PageHeader,
|
|
4278
4743
|
{
|
|
4279
4744
|
title,
|
|
4280
4745
|
eyebrow,
|
|
4281
4746
|
description,
|
|
4747
|
+
actions: /* @__PURE__ */ jsx(Actions, { className: "flex items-center gap-2" }),
|
|
4282
4748
|
testId: blockTestId(id)
|
|
4283
4749
|
}
|
|
4284
4750
|
)
|
|
@@ -4288,16 +4754,18 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4288
4754
|
fields: {
|
|
4289
4755
|
title: textField("Title"),
|
|
4290
4756
|
description: textareaField("Description", void 0, "description"),
|
|
4291
|
-
icon: iconField()
|
|
4757
|
+
icon: iconField(),
|
|
4758
|
+
// `action` is a slot so an empty state can offer a real call-to-action button.
|
|
4759
|
+
action: { type: "slot", allow: ["Button"] }
|
|
4292
4760
|
},
|
|
4293
|
-
defaultProps: { title: "Nothing here yet" },
|
|
4294
|
-
|
|
4295
|
-
render: ({ id, title, description, icon }) => /* @__PURE__ */ jsx(
|
|
4761
|
+
defaultProps: { title: "Nothing here yet", action: emptySlot2 },
|
|
4762
|
+
render: ({ id, title, description, icon, action: Action }) => /* @__PURE__ */ jsx(
|
|
4296
4763
|
EmptyState,
|
|
4297
4764
|
{
|
|
4298
4765
|
title,
|
|
4299
4766
|
description,
|
|
4300
4767
|
icon: resolveIcon(icon),
|
|
4768
|
+
action: /* @__PURE__ */ jsx(Action, {}),
|
|
4301
4769
|
testId: blockTestId(id)
|
|
4302
4770
|
}
|
|
4303
4771
|
)
|
|
@@ -4350,6 +4818,42 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4350
4818
|
}
|
|
4351
4819
|
)
|
|
4352
4820
|
};
|
|
4821
|
+
const MetricRowBlock = {
|
|
4822
|
+
label: "Metric row",
|
|
4823
|
+
fields: {
|
|
4824
|
+
columns: {
|
|
4825
|
+
type: "radio",
|
|
4826
|
+
label: "Columns",
|
|
4827
|
+
options: [
|
|
4828
|
+
{ label: "2", value: "2" },
|
|
4829
|
+
{ label: "3", value: "3" },
|
|
4830
|
+
{ label: "4", value: "4" }
|
|
4831
|
+
]
|
|
4832
|
+
},
|
|
4833
|
+
gap: {
|
|
4834
|
+
type: "radio",
|
|
4835
|
+
label: "Gap",
|
|
4836
|
+
options: [
|
|
4837
|
+
{ label: "S", value: "sm" },
|
|
4838
|
+
{ label: "M", value: "md" },
|
|
4839
|
+
{ label: "L", value: "lg" }
|
|
4840
|
+
]
|
|
4841
|
+
},
|
|
4842
|
+
// Static KPI tiles and (when registered) live metric widgets both belong in a band.
|
|
4843
|
+
items: { type: "slot", allow: ["MetricCard", "LiveMetric"] }
|
|
4844
|
+
},
|
|
4845
|
+
defaultProps: { columns: "3", gap: "md", items: emptySlot2 },
|
|
4846
|
+
render: ({ id, columns, gap, items: Items }) => /* @__PURE__ */ jsx("div", { "data-testid": blockTestId(id), children: /* @__PURE__ */ jsx(
|
|
4847
|
+
Items,
|
|
4848
|
+
{
|
|
4849
|
+
className: cn(
|
|
4850
|
+
"grid grid-cols-1",
|
|
4851
|
+
METRIC_COLS[columns] ?? METRIC_COLS["3"],
|
|
4852
|
+
METRIC_GAP[gap] ?? METRIC_GAP.md
|
|
4853
|
+
)
|
|
4854
|
+
}
|
|
4855
|
+
) })
|
|
4856
|
+
};
|
|
4353
4857
|
const DataTableBlockConfig = {
|
|
4354
4858
|
label: "Data table",
|
|
4355
4859
|
fields: {
|
|
@@ -4548,11 +5052,13 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4548
5052
|
};
|
|
4549
5053
|
const website = createWebsiteBlocks(kit);
|
|
4550
5054
|
const site = createSiteBlocks(kit);
|
|
5055
|
+
const widgets = opts.liveWidgets ? createLiveWidgets(kit) : {};
|
|
4551
5056
|
const components = {
|
|
4552
5057
|
SectionHeading: SectionHeadingBlock,
|
|
4553
5058
|
PageHeader: PageHeaderBlock,
|
|
4554
5059
|
EmptyState: EmptyStateBlock,
|
|
4555
5060
|
MetricCard: MetricCardBlock,
|
|
5061
|
+
MetricRow: MetricRowBlock,
|
|
4556
5062
|
DataTable: DataTableBlockConfig,
|
|
4557
5063
|
Section: SectionBlock,
|
|
4558
5064
|
Card: CardBlock,
|
|
@@ -4560,7 +5066,8 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4560
5066
|
Badge: BadgeBlock,
|
|
4561
5067
|
Separator: SeparatorBlock,
|
|
4562
5068
|
...website,
|
|
4563
|
-
...site
|
|
5069
|
+
...site,
|
|
5070
|
+
...widgets
|
|
4564
5071
|
};
|
|
4565
5072
|
const config = {
|
|
4566
5073
|
categories: {
|
|
@@ -4594,7 +5101,8 @@ function createArbiBlocksConfig(opts = {}) {
|
|
|
4594
5101
|
Commerce: { title: "Commerce", components: ["Pricing"] },
|
|
4595
5102
|
Forms: { title: "Forms", components: ["ContactForm"] },
|
|
4596
5103
|
Navigation: { title: "Navigation", components: ["Navbar", "Footer"] },
|
|
4597
|
-
Data: { title: "Data", components: ["MetricCard", "DataTable"] },
|
|
5104
|
+
Data: { title: "Data", components: ["MetricRow", "MetricCard", "DataTable"] },
|
|
5105
|
+
...opts.liveWidgets ? { Widgets: { title: "Widgets", components: ["AgentActivity", "LiveMetric"] } } : {},
|
|
4598
5106
|
Primitives: { title: "Primitives", components: ["Button", "Badge", "Separator"] }
|
|
4599
5107
|
},
|
|
4600
5108
|
components,
|
|
@@ -5079,6 +5587,6 @@ function VerticalBuilder({
|
|
|
5079
5587
|
] });
|
|
5080
5588
|
}
|
|
5081
5589
|
|
|
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 };
|
|
5590
|
+
export { ASSET_REF_PREFIX, Accordion, AgentsPanel, AppHeader, 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
5591
|
//# sourceMappingURL=index.js.map
|
|
5084
5592
|
//# sourceMappingURL=index.js.map
|