@arbidocs/blocks 0.3.116 → 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 +142 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -2
- package/dist/index.d.ts +39 -2
- package/dist/index.js +144 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -604,7 +604,25 @@ function ConnectionProvider({
|
|
|
604
604
|
await arbi.selectWorkspace(target.external_id);
|
|
605
605
|
setWorkspaceId(target.external_id);
|
|
606
606
|
}
|
|
607
|
-
|
|
607
|
+
let resolved = { name: email.split("@")[0], email };
|
|
608
|
+
try {
|
|
609
|
+
const me = arbi.user.identity();
|
|
610
|
+
const members = await arbi.workspaces.listUsers();
|
|
611
|
+
const self = members.find((m) => m.user.external_id === me?.externalId)?.user;
|
|
612
|
+
if (self) {
|
|
613
|
+
const fullName = [self.given_name, self.family_name].filter(Boolean).join(" ").trim();
|
|
614
|
+
resolved = {
|
|
615
|
+
name: fullName || email.split("@")[0],
|
|
616
|
+
email: self.email || email,
|
|
617
|
+
externalId: self.external_id,
|
|
618
|
+
picture: self.picture ?? null
|
|
619
|
+
};
|
|
620
|
+
} else if (me?.externalId) {
|
|
621
|
+
resolved.externalId = me.externalId;
|
|
622
|
+
}
|
|
623
|
+
} catch {
|
|
624
|
+
}
|
|
625
|
+
setUser(resolved);
|
|
608
626
|
setStatus("authenticated");
|
|
609
627
|
} catch (e) {
|
|
610
628
|
setError(e instanceof Error ? e.message : "Sign-in failed. Check your credentials.");
|
|
@@ -2450,6 +2468,74 @@ function AppShell({
|
|
|
2450
2468
|
}
|
|
2451
2469
|
);
|
|
2452
2470
|
}
|
|
2471
|
+
function AppHeader({
|
|
2472
|
+
onSearch,
|
|
2473
|
+
onAsk,
|
|
2474
|
+
searchPlaceholder = "Ask AI or search\u2026",
|
|
2475
|
+
searchKbd = "\u2318K",
|
|
2476
|
+
askLabel = "Ask AI",
|
|
2477
|
+
leading,
|
|
2478
|
+
actions,
|
|
2479
|
+
user,
|
|
2480
|
+
userItems,
|
|
2481
|
+
onLogout,
|
|
2482
|
+
onNotificationNavigate,
|
|
2483
|
+
notificationTones,
|
|
2484
|
+
classNames,
|
|
2485
|
+
testIdPrefix = "app"
|
|
2486
|
+
}) {
|
|
2487
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2488
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2489
|
+
"button",
|
|
2490
|
+
{
|
|
2491
|
+
type: "button",
|
|
2492
|
+
onClick: onSearch,
|
|
2493
|
+
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",
|
|
2494
|
+
"data-testid": tid(testIdPrefix, "global-search"),
|
|
2495
|
+
children: [
|
|
2496
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: searchPlaceholder }),
|
|
2498
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "rounded border border-border px-1.5 py-0.5 text-[10px]", children: searchKbd })
|
|
2499
|
+
]
|
|
2500
|
+
}
|
|
2501
|
+
),
|
|
2502
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
|
|
2503
|
+
leading,
|
|
2504
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2505
|
+
react.Button,
|
|
2506
|
+
{
|
|
2507
|
+
size: "sm",
|
|
2508
|
+
onClick: onAsk ?? onSearch,
|
|
2509
|
+
className: classNames?.askButton,
|
|
2510
|
+
"data-testid": tid(testIdPrefix, "ask-ai"),
|
|
2511
|
+
children: [
|
|
2512
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-4" }),
|
|
2513
|
+
askLabel
|
|
2514
|
+
]
|
|
2515
|
+
}
|
|
2516
|
+
),
|
|
2517
|
+
actions,
|
|
2518
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2519
|
+
react.NotificationBell,
|
|
2520
|
+
{
|
|
2521
|
+
testId: tid(testIdPrefix, "notifications"),
|
|
2522
|
+
onNavigate: onNotificationNavigate,
|
|
2523
|
+
toneClassNames: notificationTones
|
|
2524
|
+
}
|
|
2525
|
+
),
|
|
2526
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2527
|
+
react.UserMenu,
|
|
2528
|
+
{
|
|
2529
|
+
user,
|
|
2530
|
+
items: userItems,
|
|
2531
|
+
onLogout,
|
|
2532
|
+
testId: tid(testIdPrefix, "user-menu"),
|
|
2533
|
+
logoutTestId: tid(testIdPrefix, "logout")
|
|
2534
|
+
}
|
|
2535
|
+
)
|
|
2536
|
+
] })
|
|
2537
|
+
] });
|
|
2538
|
+
}
|
|
2453
2539
|
var LiveDataContext = react$1.createContext(false);
|
|
2454
2540
|
function useLiveDataActive() {
|
|
2455
2541
|
return react$1.useContext(LiveDataContext);
|
|
@@ -3219,6 +3305,9 @@ function useImageGen() {
|
|
|
3219
3305
|
reset: task.reset
|
|
3220
3306
|
};
|
|
3221
3307
|
}
|
|
3308
|
+
function toJpgName(name) {
|
|
3309
|
+
return name.replace(/\.[^.]+$/, "") + ".jpg";
|
|
3310
|
+
}
|
|
3222
3311
|
var IMAGE_EXT = /\.(png|jpe?g|webp|gif|avif|svg)$/i;
|
|
3223
3312
|
function ImageFieldControl({
|
|
3224
3313
|
value,
|
|
@@ -3232,9 +3321,12 @@ function ImageFieldControl({
|
|
|
3232
3321
|
const [url, setUrl] = react$1.useState("");
|
|
3233
3322
|
const [prompt, setPrompt] = react$1.useState("");
|
|
3234
3323
|
const [busy, setBusy] = react$1.useState(false);
|
|
3324
|
+
const [cropSrc, setCropSrc] = react$1.useState(null);
|
|
3325
|
+
const [cropName, setCropName] = react$1.useState("image.jpg");
|
|
3235
3326
|
const arbi = react.useArbi();
|
|
3236
3327
|
const gen = useImageGen();
|
|
3237
3328
|
const queryClient = reactQuery.useQueryClient();
|
|
3329
|
+
const currentAssetImage = useAssetImage(isAssetRef(value) ? assetRefId(value) : "");
|
|
3238
3330
|
const tp = (...q) => tid(`${testIdPrefix}-image`, name, ...q);
|
|
3239
3331
|
const refreshAssets = () => queryClient.invalidateQueries({ queryKey: ["arbi", "documents", workspaceId] });
|
|
3240
3332
|
const { data: docs } = react.useDocuments(workspaceId);
|
|
@@ -3249,13 +3341,24 @@ function ImageFieldControl({
|
|
|
3249
3341
|
[imageDocs]
|
|
3250
3342
|
);
|
|
3251
3343
|
const { data: thumbs } = react.useThumbnails(imageIds);
|
|
3252
|
-
const onUpload =
|
|
3344
|
+
const onUpload = (e) => {
|
|
3253
3345
|
const file = e.target.files?.[0];
|
|
3254
3346
|
if (!file) return;
|
|
3347
|
+
setCropName(toJpgName(file.name));
|
|
3348
|
+
setCropSrc(URL.createObjectURL(file));
|
|
3349
|
+
e.target.value = "";
|
|
3350
|
+
};
|
|
3351
|
+
const openReframe = () => {
|
|
3352
|
+
if (!currentAssetImage) return;
|
|
3353
|
+
setCropName("reframe.jpg");
|
|
3354
|
+
setCropSrc(currentAssetImage);
|
|
3355
|
+
};
|
|
3356
|
+
const uploadBlobAsAsset = async (blob, name2) => {
|
|
3255
3357
|
setBusy(true);
|
|
3256
3358
|
try {
|
|
3257
3359
|
await arbi.selectWorkspace(workspaceId);
|
|
3258
|
-
const
|
|
3360
|
+
const file = new File([blob], name2, { type: blob.type });
|
|
3361
|
+
const res = await arbi.documents.uploadFile(file, name2, { folder });
|
|
3259
3362
|
const id = res.doc_ext_ids?.[0];
|
|
3260
3363
|
if (id) {
|
|
3261
3364
|
onChange(asAssetRef(id));
|
|
@@ -3265,6 +3368,12 @@ function ImageFieldControl({
|
|
|
3265
3368
|
setBusy(false);
|
|
3266
3369
|
}
|
|
3267
3370
|
};
|
|
3371
|
+
const onCropComplete = async (result) => {
|
|
3372
|
+
const src = cropSrc;
|
|
3373
|
+
setCropSrc(null);
|
|
3374
|
+
await uploadBlobAsAsset(result.blob, cropName);
|
|
3375
|
+
if (src?.startsWith("blob:")) URL.revokeObjectURL(src);
|
|
3376
|
+
};
|
|
3268
3377
|
const onGenerate = async () => {
|
|
3269
3378
|
if (!prompt.trim() || gen.isGenerating) return;
|
|
3270
3379
|
const id = await gen.generate(prompt);
|
|
@@ -3282,7 +3391,22 @@ function ImageFieldControl({
|
|
|
3282
3391
|
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";
|
|
3283
3392
|
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"}`;
|
|
3284
3393
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", "data-testid": tp(), children: [
|
|
3285
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3394
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3395
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockImage, { src: value, aspect: "16:9", rounded: "md", testId: tp("preview") }),
|
|
3396
|
+
currentAssetImage ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3397
|
+
"button",
|
|
3398
|
+
{
|
|
3399
|
+
type: "button",
|
|
3400
|
+
onClick: openReframe,
|
|
3401
|
+
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",
|
|
3402
|
+
"data-testid": tp("reframe"),
|
|
3403
|
+
children: [
|
|
3404
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crop, { className: "size-3" }),
|
|
3405
|
+
" Crop"
|
|
3406
|
+
]
|
|
3407
|
+
}
|
|
3408
|
+
) : null
|
|
3409
|
+
] }),
|
|
3286
3410
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: MODES.map((m) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3287
3411
|
"button",
|
|
3288
3412
|
{
|
|
@@ -3399,6 +3523,19 @@ function ImageFieldControl({
|
|
|
3399
3523
|
"data-testid": tp("clear"),
|
|
3400
3524
|
children: "Clear"
|
|
3401
3525
|
}
|
|
3526
|
+
),
|
|
3527
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3528
|
+
react.ImageCropModal,
|
|
3529
|
+
{
|
|
3530
|
+
open: !!cropSrc,
|
|
3531
|
+
image: cropSrc,
|
|
3532
|
+
title: "Frame your image",
|
|
3533
|
+
aspectOptions: react.DEFAULT_ASPECT_OPTIONS,
|
|
3534
|
+
cropShape: "rect",
|
|
3535
|
+
output: { maxSize: 1600 },
|
|
3536
|
+
onComplete: onCropComplete,
|
|
3537
|
+
onCancel: () => setCropSrc(null)
|
|
3538
|
+
}
|
|
3402
3539
|
)
|
|
3403
3540
|
] });
|
|
3404
3541
|
}
|
|
@@ -5490,6 +5627,7 @@ Object.defineProperty(exports, "toRedlineMarkdown", {
|
|
|
5490
5627
|
exports.ASSET_REF_PREFIX = ASSET_REF_PREFIX;
|
|
5491
5628
|
exports.Accordion = Accordion;
|
|
5492
5629
|
exports.AgentsPanel = AgentsPanel;
|
|
5630
|
+
exports.AppHeader = AppHeader;
|
|
5493
5631
|
exports.AppShell = AppShell;
|
|
5494
5632
|
exports.AssetResolverProvider = AssetResolverProvider;
|
|
5495
5633
|
exports.AvatarBlock = AvatarBlock;
|