@agent-native/toolkit 0.206.0 → 0.206.1-nightly-20261009213000
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/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +3 -3
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +1 -0
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +1 -0
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +43 -0
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +219 -75
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +18 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +12 -4
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts +6 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +6 -3
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +8 -2
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +8 -2
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +8 -2
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +8 -2
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +8 -2
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +8 -2
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +8 -2
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +8 -2
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +8 -2
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +8 -2
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +8 -2
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +8 -2
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/sharing/ShareButton.d.ts +9 -0
- package/dist/app/sharing/ShareButton.d.ts.map +1 -1
- package/dist/app/sharing/ShareButton.js +23 -11
- package/dist/app/sharing/ShareButton.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/components.tsx +6 -3
- package/src/app/agentkit/react/context.tsx +2 -0
- package/src/app/agentkit/react/styles.css +43 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +425 -15
- package/src/app/chat/AgentKitAssistantChat.tsx +306 -95
- package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +89 -5
- package/src/app/chat/agentkit-chat/guided-questions.tsx +17 -6
- package/src/app/chat/chat/run-recovery.spec.tsx +48 -0
- package/src/app/chat/chat/run-recovery.tsx +23 -1
- package/src/app/i18n/catalogs/ar-SA.ts +14 -2
- package/src/app/i18n/catalogs/de-DE.ts +12 -2
- package/src/app/i18n/catalogs/en-US.ts +13 -2
- package/src/app/i18n/catalogs/es-ES.ts +12 -2
- package/src/app/i18n/catalogs/fr-FR.ts +12 -2
- package/src/app/i18n/catalogs/hi-IN.ts +12 -2
- package/src/app/i18n/catalogs/ja-JP.ts +12 -2
- package/src/app/i18n/catalogs/ko-KR.ts +12 -2
- package/src/app/i18n/catalogs/pt-BR.ts +12 -2
- package/src/app/i18n/catalogs/zh-CN.ts +8 -2
- package/src/app/i18n/catalogs/zh-TW.ts +8 -2
- package/src/app/settings/model/ProviderDialog.spec.tsx +1 -0
- package/src/app/sharing/ShareButton.spec.tsx +148 -0
- package/src/app/sharing/ShareButton.tsx +44 -15
- package/src/app/sharing/useShareButtonController.spec.tsx +25 -1
|
@@ -479,9 +479,14 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
479
479
|
"composer.skill.uploadFile": "上傳技能檔案",
|
|
480
480
|
"composer.upload": "上傳",
|
|
481
481
|
"composer.uploadFailed": "無法上傳所選檔案。",
|
|
482
|
-
"composer.fileTooLarge": "
|
|
483
|
-
"composer.sessionExpired": "
|
|
482
|
+
"composer.fileTooLarge": "此檔案超過 {{size}} MB 的上傳大小限制。",
|
|
483
|
+
"composer.sessionExpired": "工作階段已逾期。請重新登入,然後再傳送訊息。",
|
|
484
484
|
"composer.unsupportedFileType": "不支援此檔案類型。",
|
|
485
|
+
"composer.uploadUnavailable": "目前無法上傳檔案。請稍後再試。",
|
|
486
|
+
"composer.uploadOffline": "上傳無法連線至伺服器。請檢查網路連線後再試一次。",
|
|
487
|
+
"composer.submissionNotReady": "聊天尚未準備好傳送。請稍候片刻再傳送。",
|
|
488
|
+
"composer.submissionScopeChanged": "此聊天在訊息傳送前已變更。請重新傳送。",
|
|
489
|
+
"composer.attachmentNotSaved": "未隨此聊天儲存",
|
|
485
490
|
"composer.useAttachedContext": "使用附加的上下文。",
|
|
486
491
|
"mentions.commands": "命令",
|
|
487
492
|
"mentions.learnMore": "深入瞭解",
|
|
@@ -1081,6 +1086,7 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
1081
1086
|
"recovery.continueUnavailable": "此執行已無法繼續。傳送訊息以繼續。",
|
|
1082
1087
|
"recovery.retryAttachmentUnavailable":
|
|
1083
1088
|
"此要求包含無法重試的檔案。請在訊息輸入框中重新附加檔案,然後再試一次。",
|
|
1089
|
+
"recovery.retryWithoutAttachment": "不含附件重試",
|
|
1084
1090
|
"recovery.deferredSubmissionFailed":
|
|
1085
1091
|
"無法傳送這則訊息。請檢查連線或聊天設定,然後再試一次。",
|
|
1086
1092
|
"recovery.credentialRejected":
|
|
@@ -1395,6 +1395,154 @@ describe("ShareButton", () => {
|
|
|
1395
1395
|
expect(queriedActions).not.toContain("list-resource-access-requests");
|
|
1396
1396
|
});
|
|
1397
1397
|
|
|
1398
|
+
it("keeps to the basic share actions when the session cannot run the rest", async () => {
|
|
1399
|
+
sharesData.current = { ...sharesData.current, agentReadable: true };
|
|
1400
|
+
accessRequestsData.current = [patRequest];
|
|
1401
|
+
await act(async () => {
|
|
1402
|
+
root.render(
|
|
1403
|
+
<TooltipProvider>
|
|
1404
|
+
<QueryClientProvider client={queryClient}>
|
|
1405
|
+
<ShareButton
|
|
1406
|
+
resourceType="deck"
|
|
1407
|
+
resourceId="deck-1"
|
|
1408
|
+
basicSharingOnly
|
|
1409
|
+
/>
|
|
1410
|
+
</QueryClientProvider>
|
|
1411
|
+
</TooltipProvider>,
|
|
1412
|
+
);
|
|
1413
|
+
});
|
|
1414
|
+
|
|
1415
|
+
const text = container.textContent ?? "";
|
|
1416
|
+
expect(text).toContain("People with access");
|
|
1417
|
+
expect(text).not.toContain("Access requests");
|
|
1418
|
+
expect(text).not.toContain("Share with agents");
|
|
1419
|
+
expect(queriedActions).not.toContain("list-resource-access-requests");
|
|
1420
|
+
expect(queriedActions).toContain("list-resource-shares");
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
it("does not search the organization for people when keeping to the basic share actions", async () => {
|
|
1424
|
+
const fetchMock = vi.fn(async () => Response.json({ members: [] }));
|
|
1425
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
1426
|
+
await act(async () => {
|
|
1427
|
+
root.render(
|
|
1428
|
+
<TooltipProvider>
|
|
1429
|
+
<QueryClientProvider client={queryClient}>
|
|
1430
|
+
<ShareButton
|
|
1431
|
+
resourceType="deck"
|
|
1432
|
+
resourceId="deck-1"
|
|
1433
|
+
basicSharingOnly
|
|
1434
|
+
/>
|
|
1435
|
+
</QueryClientProvider>
|
|
1436
|
+
</TooltipProvider>,
|
|
1437
|
+
);
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
const input = container.querySelector(
|
|
1441
|
+
'input[placeholder="Add people by email"]',
|
|
1442
|
+
) as HTMLInputElement;
|
|
1443
|
+
act(() => input.focus());
|
|
1444
|
+
setInputValue(input, "guest@example.com");
|
|
1445
|
+
await act(async () => {
|
|
1446
|
+
await new Promise((resolve) => setTimeout(resolve, 180));
|
|
1447
|
+
});
|
|
1448
|
+
|
|
1449
|
+
expect(
|
|
1450
|
+
fetchMock.mock.calls.some((call) =>
|
|
1451
|
+
String(call[0]).includes("/_agent-native/org/members"),
|
|
1452
|
+
),
|
|
1453
|
+
).toBe(false);
|
|
1454
|
+
expect(container.textContent).not.toContain("Could not load people.");
|
|
1455
|
+
});
|
|
1456
|
+
|
|
1457
|
+
it("does not offer the admin role or an email note when keeping to the basic share actions", async () => {
|
|
1458
|
+
await act(async () => {
|
|
1459
|
+
root.render(
|
|
1460
|
+
<QueryClientProvider client={queryClient}>
|
|
1461
|
+
<ShareButton
|
|
1462
|
+
resourceType="deck"
|
|
1463
|
+
resourceId="deck-1"
|
|
1464
|
+
basicSharingOnly
|
|
1465
|
+
/>
|
|
1466
|
+
</QueryClientProvider>,
|
|
1467
|
+
);
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1470
|
+
const input = container.querySelector(
|
|
1471
|
+
'input[placeholder="Add people by email"]',
|
|
1472
|
+
) as HTMLInputElement;
|
|
1473
|
+
setInputValue(input, "guest@example.com");
|
|
1474
|
+
expect(container.textContent).toContain("Notify people");
|
|
1475
|
+
expect(container.textContent).not.toContain("Add a message");
|
|
1476
|
+
|
|
1477
|
+
const roleTrigger = container.querySelector(
|
|
1478
|
+
'button[aria-label="Role"]',
|
|
1479
|
+
) as HTMLButtonElement | null;
|
|
1480
|
+
await act(async () => roleTrigger?.click());
|
|
1481
|
+
const options = Array.from(
|
|
1482
|
+
document.querySelectorAll<HTMLElement>('[role="option"]'),
|
|
1483
|
+
).map((option) => option.textContent ?? "");
|
|
1484
|
+
expect(options.some((option) => option.includes("Editor"))).toBe(true);
|
|
1485
|
+
expect(options.some((option) => option.includes("Admin"))).toBe(false);
|
|
1486
|
+
});
|
|
1487
|
+
|
|
1488
|
+
it("offers the admin role and an email note outside the basic share actions", async () => {
|
|
1489
|
+
await act(async () => {
|
|
1490
|
+
root.render(
|
|
1491
|
+
<QueryClientProvider client={queryClient}>
|
|
1492
|
+
<ShareButton resourceType="deck" resourceId="deck-1" />
|
|
1493
|
+
</QueryClientProvider>,
|
|
1494
|
+
);
|
|
1495
|
+
});
|
|
1496
|
+
|
|
1497
|
+
const input = container.querySelector(
|
|
1498
|
+
'input[placeholder="Add people by email"]',
|
|
1499
|
+
) as HTMLInputElement;
|
|
1500
|
+
setInputValue(input, "guest@example.com");
|
|
1501
|
+
expect(container.textContent).toContain("Add a message");
|
|
1502
|
+
|
|
1503
|
+
const roleTrigger = container.querySelector(
|
|
1504
|
+
'button[aria-label="Role"]',
|
|
1505
|
+
) as HTMLButtonElement | null;
|
|
1506
|
+
await act(async () => roleTrigger?.click());
|
|
1507
|
+
expect(
|
|
1508
|
+
Array.from(
|
|
1509
|
+
document.querySelectorAll<HTMLElement>('[role="option"]'),
|
|
1510
|
+
).some((option) => option.textContent?.includes("Admin")),
|
|
1511
|
+
).toBe(true);
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
it("lets a host size the joined copy control through quickCopy.className", async () => {
|
|
1515
|
+
await act(async () => {
|
|
1516
|
+
root.render(
|
|
1517
|
+
<TooltipProvider>
|
|
1518
|
+
<QueryClientProvider client={queryClient}>
|
|
1519
|
+
<ShareButton
|
|
1520
|
+
resourceType="document"
|
|
1521
|
+
resourceId="doc-1"
|
|
1522
|
+
quickCopy={{
|
|
1523
|
+
label: "Copy page link",
|
|
1524
|
+
copiedLabel: "Copied page link",
|
|
1525
|
+
onCopy: async () => true,
|
|
1526
|
+
className: "widget-joined-share",
|
|
1527
|
+
}}
|
|
1528
|
+
/>
|
|
1529
|
+
</QueryClientProvider>
|
|
1530
|
+
</TooltipProvider>,
|
|
1531
|
+
);
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
const joined = container.querySelector(".widget-joined-share");
|
|
1535
|
+
expect(joined).not.toBeNull();
|
|
1536
|
+
expect(
|
|
1537
|
+
joined?.contains(
|
|
1538
|
+
container.querySelector('button[aria-label="Copy page link"]'),
|
|
1539
|
+
),
|
|
1540
|
+
).toBe(true);
|
|
1541
|
+
expect(
|
|
1542
|
+
joined?.contains(container.querySelector('button[aria-label="Share"]')),
|
|
1543
|
+
).toBe(true);
|
|
1544
|
+
});
|
|
1545
|
+
|
|
1398
1546
|
// Keep the non-source-locale provider test last: react-i18next's global
|
|
1399
1547
|
// fallback instance otherwise leaks the selected language into tests that
|
|
1400
1548
|
// intentionally exercise providerless compatibility.
|
|
@@ -80,6 +80,14 @@ export interface ShareButtonProps {
|
|
|
80
80
|
shareUrl?: string;
|
|
81
81
|
/** Use a bottom sheet for the share surface below the small-screen breakpoint. */
|
|
82
82
|
mobileSheet?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The session can run only the basic share actions (list, share, unshare,
|
|
85
|
+
* visibility), as a scoped MCP App widget session can. Omits the access
|
|
86
|
+
* request review, the agent-context link and the people suggestions, which
|
|
87
|
+
* need other routes, and the admin role and email note, which such a
|
|
88
|
+
* session may not send; an email is still added by typing it.
|
|
89
|
+
*/
|
|
90
|
+
basicSharingOnly?: boolean;
|
|
83
91
|
/** Open the share surface without rendering a trigger button. */
|
|
84
92
|
hideTrigger?: boolean;
|
|
85
93
|
/** Override the optional temporary agent-context link label. */
|
|
@@ -93,6 +101,7 @@ export interface ShareButtonProps {
|
|
|
93
101
|
label: string;
|
|
94
102
|
copiedLabel: string;
|
|
95
103
|
onCopy: () => Promise<boolean | void> | boolean | void;
|
|
104
|
+
className?: string;
|
|
96
105
|
};
|
|
97
106
|
/** Optional label for the primary copyable link section. */
|
|
98
107
|
shareUrlLabel?: string;
|
|
@@ -220,6 +229,18 @@ function visibilityMeta(
|
|
|
220
229
|
};
|
|
221
230
|
}
|
|
222
231
|
|
|
232
|
+
// A scoped host session cannot grant the admin role, so it is not offered.
|
|
233
|
+
const BASIC_SHARING_ROLES: readonly Role[] = ["viewer", "commenter", "editor"];
|
|
234
|
+
|
|
235
|
+
function allowedRolesFor(
|
|
236
|
+
props: Pick<ShareButtonProps, "allowedRoles" | "basicSharingOnly">,
|
|
237
|
+
): readonly Role[] | undefined {
|
|
238
|
+
return (
|
|
239
|
+
props.allowedRoles ??
|
|
240
|
+
(props.basicSharingOnly ? BASIC_SHARING_ROLES : undefined)
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
223
244
|
function roleOptions(
|
|
224
245
|
t: ShareTranslate,
|
|
225
246
|
): Array<{ value: Role; label: string; description: string }> {
|
|
@@ -312,7 +333,7 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
312
333
|
onShareSuccess: props.onShareSuccess,
|
|
313
334
|
shareTabs: props.shareTabs,
|
|
314
335
|
shareUrl: props.shareUrl,
|
|
315
|
-
allowedRoles: props
|
|
336
|
+
allowedRoles: allowedRolesFor(props),
|
|
316
337
|
hideInSearchControl: props.hideInSearchControl,
|
|
317
338
|
});
|
|
318
339
|
useEffect(() => {
|
|
@@ -355,6 +376,7 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
355
376
|
copyLabel={props.quickCopy.label}
|
|
356
377
|
copiedLabel={props.quickCopy.copiedLabel}
|
|
357
378
|
onCopy={props.quickCopy.onCopy}
|
|
379
|
+
className={props.quickCopy.className}
|
|
358
380
|
/>
|
|
359
381
|
) : (
|
|
360
382
|
<SheetTrigger asChild>{trigger}</SheetTrigger>
|
|
@@ -391,6 +413,7 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
391
413
|
copyLabel={props.quickCopy.label}
|
|
392
414
|
copiedLabel={props.quickCopy.copiedLabel}
|
|
393
415
|
onCopy={props.quickCopy.onCopy}
|
|
416
|
+
className={props.quickCopy.className}
|
|
394
417
|
/>
|
|
395
418
|
</PopoverAnchor>
|
|
396
419
|
) : (
|
|
@@ -469,12 +492,13 @@ function SharePanel(
|
|
|
469
492
|
const generalAccessLabel =
|
|
470
493
|
props.generalAccessLabel ??
|
|
471
494
|
t("agentChat.share.generalAccess", { defaultValue: "General access" });
|
|
472
|
-
const accessRequests =
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
495
|
+
const accessRequests =
|
|
496
|
+
canManage && !props.basicSharingOnly ? (
|
|
497
|
+
<AccessRequestsSection
|
|
498
|
+
resourceType={props.resourceType}
|
|
499
|
+
resourceId={props.resourceId}
|
|
500
|
+
/>
|
|
501
|
+
) : null;
|
|
478
502
|
const shareLinks = (
|
|
479
503
|
<>
|
|
480
504
|
{props.shareUrl ? (
|
|
@@ -610,8 +634,10 @@ function SharePanel(
|
|
|
610
634
|
<div className="w-full sm:min-w-0 sm:flex-1">
|
|
611
635
|
<MemberAutocomplete
|
|
612
636
|
value={inviteEmail}
|
|
613
|
-
open={suggestionsOpen}
|
|
614
|
-
onOpenChange={
|
|
637
|
+
open={suggestionsOpen && !props.basicSharingOnly}
|
|
638
|
+
onOpenChange={(open) => {
|
|
639
|
+
if (!props.basicSharingOnly) setSuggestionsOpen(open);
|
|
640
|
+
}}
|
|
615
641
|
onValueChange={(next) => {
|
|
616
642
|
onInviteEmailChange(next);
|
|
617
643
|
if (shareError) setShareError(null);
|
|
@@ -656,7 +682,7 @@ function SharePanel(
|
|
|
656
682
|
value={role}
|
|
657
683
|
onChange={setRole}
|
|
658
684
|
roleCopy={props.roleCopy}
|
|
659
|
-
allowedRoles={props
|
|
685
|
+
allowedRoles={allowedRolesFor(props)}
|
|
660
686
|
/>
|
|
661
687
|
<button
|
|
662
688
|
type="button"
|
|
@@ -688,7 +714,7 @@ function SharePanel(
|
|
|
688
714
|
defaultValue: "Notify people",
|
|
689
715
|
})}
|
|
690
716
|
</label>
|
|
691
|
-
{notifyPeople ? (
|
|
717
|
+
{notifyPeople && !props.basicSharingOnly ? (
|
|
692
718
|
<button
|
|
693
719
|
type="button"
|
|
694
720
|
aria-expanded={messageOpen}
|
|
@@ -706,7 +732,10 @@ function SharePanel(
|
|
|
706
732
|
) : null}
|
|
707
733
|
</div>
|
|
708
734
|
) : null}
|
|
709
|
-
{hasInviteEmail &&
|
|
735
|
+
{hasInviteEmail &&
|
|
736
|
+
notifyPeople &&
|
|
737
|
+
messageOpen &&
|
|
738
|
+
!props.basicSharingOnly ? (
|
|
710
739
|
<div className="rounded-md border border-border/70 bg-muted/20 p-2.5">
|
|
711
740
|
<textarea
|
|
712
741
|
aria-label={t("agentChat.share.message", {
|
|
@@ -777,7 +806,7 @@ function SharePanel(
|
|
|
777
806
|
disabled={inFlight.has(keyOf(s))}
|
|
778
807
|
plain
|
|
779
808
|
roleCopy={props.roleCopy}
|
|
780
|
-
allowedRoles={props
|
|
809
|
+
allowedRoles={allowedRolesFor(props)}
|
|
781
810
|
/>
|
|
782
811
|
) : (
|
|
783
812
|
<span className="text-xs text-muted-foreground">
|
|
@@ -818,7 +847,7 @@ function SharePanel(
|
|
|
818
847
|
</div>
|
|
819
848
|
) : null}
|
|
820
849
|
|
|
821
|
-
{!props.agentTabContent ? (
|
|
850
|
+
{!props.agentTabContent && !props.basicSharingOnly ? (
|
|
822
851
|
<AgentShareSection
|
|
823
852
|
enabled={data?.agentReadable === true}
|
|
824
853
|
resourceType={props.resourceType}
|
|
@@ -849,7 +878,7 @@ function SharePanel(
|
|
|
849
878
|
const agentPanel = (
|
|
850
879
|
<div className="space-y-4">
|
|
851
880
|
{props.agentTabContent}
|
|
852
|
-
{!loadFailed && !isLoading ? (
|
|
881
|
+
{!loadFailed && !isLoading && !props.basicSharingOnly ? (
|
|
853
882
|
<AgentShareSection
|
|
854
883
|
enabled={data?.agentReadable === true}
|
|
855
884
|
resourceType={props.resourceType}
|
|
@@ -12,6 +12,7 @@ import { createRoot, type Root } from "react-dom/client";
|
|
|
12
12
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
13
13
|
|
|
14
14
|
const mocks = vi.hoisted(() => ({
|
|
15
|
+
useActionQuery: vi.fn(),
|
|
15
16
|
query: {
|
|
16
17
|
data: undefined as ShareButtonSharesResponse | undefined,
|
|
17
18
|
refetch: vi.fn(async () => undefined),
|
|
@@ -22,7 +23,7 @@ const mocks = vi.hoisted(() => ({
|
|
|
22
23
|
}));
|
|
23
24
|
|
|
24
25
|
vi.mock("@agent-native/core/client/use-action", () => ({
|
|
25
|
-
useActionQuery:
|
|
26
|
+
useActionQuery: mocks.useActionQuery,
|
|
26
27
|
useActionMutation: vi.fn((name: string) => {
|
|
27
28
|
if (name === "set-resource-visibility") return mocks.setVisibility;
|
|
28
29
|
if (name === "share-resource") return mocks.share;
|
|
@@ -84,6 +85,7 @@ describe("useShareButtonController", () => {
|
|
|
84
85
|
],
|
|
85
86
|
};
|
|
86
87
|
mocks.query.refetch.mockClear();
|
|
88
|
+
mocks.useActionQuery.mockReset().mockReturnValue(mocks.query);
|
|
87
89
|
mocks.setVisibility.mutate.mockReset();
|
|
88
90
|
mocks.share.mutate.mockReset();
|
|
89
91
|
mocks.unshare.mutate.mockReset();
|
|
@@ -106,6 +108,28 @@ describe("useShareButtonController", () => {
|
|
|
106
108
|
controller = undefined;
|
|
107
109
|
});
|
|
108
110
|
|
|
111
|
+
it("loads share state only while the popover is open", async () => {
|
|
112
|
+
const result = await render();
|
|
113
|
+
const latestShareQueryOptions = () =>
|
|
114
|
+
mocks.useActionQuery.mock.calls
|
|
115
|
+
.filter(([name]) => name === "list-resource-shares")
|
|
116
|
+
.at(-1)?.[2];
|
|
117
|
+
|
|
118
|
+
expect(latestShareQueryOptions()).toEqual({
|
|
119
|
+
enabled: false,
|
|
120
|
+
staleTime: 0,
|
|
121
|
+
});
|
|
122
|
+
expect(mocks.query.refetch).not.toHaveBeenCalled();
|
|
123
|
+
|
|
124
|
+
act(() => result.handleOpenChange(true));
|
|
125
|
+
|
|
126
|
+
expect(latestShareQueryOptions()).toEqual({
|
|
127
|
+
enabled: true,
|
|
128
|
+
staleTime: 0,
|
|
129
|
+
});
|
|
130
|
+
expect(mocks.query.refetch).not.toHaveBeenCalled();
|
|
131
|
+
});
|
|
132
|
+
|
|
109
133
|
it("guards rapid duplicate invites for the same principal", async () => {
|
|
110
134
|
const result = await render();
|
|
111
135
|
act(() => {
|