@nextclaw/ui 0.27.5-beta.0 → 0.27.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/.vite/manifest.json +99 -99
- package/dist/assets/{account-panel-DgqicWMm.js → account-panel-C83GDFuy.js} +1 -1
- package/dist/assets/agents-CJA15zzv.js +1 -0
- package/dist/assets/{agents-CTSR4ZKb.js → agents-Dr2KkEp2.js} +1 -1
- package/dist/assets/{app-presenter-provider-DdD2Q7jZ.js → app-presenter-provider-Cx9MwMtb.js} +12 -12
- package/dist/assets/{appearance-settings-page-CSWYLrsR.js → appearance-settings-page-3IfIzjic.js} +1 -1
- package/dist/assets/apps-CvIlb9Rn.js +1 -0
- package/dist/assets/{confirm-dialog-jz2cQKId.js → confirm-dialog-D30HJBXN.js} +1 -1
- package/dist/assets/{context-menu-C0qywo73.js → context-menu-C6m-WNpl.js} +65 -65
- package/dist/assets/cron-BWZWu80t.js +1 -0
- package/dist/assets/{dialog-DMKYZDFu.js → dialog-DB_l9LK0.js} +1 -1
- package/dist/assets/doc-browser-DQDsmRlr.js +1 -0
- package/dist/assets/inbox-CIsD65lW.js +1 -0
- package/dist/assets/{keyboard-shortcuts-settings-page-BCxB9m69.js → keyboard-shortcuts-settings-page-L4kLGuB8.js} +1 -1
- package/dist/assets/{main-C6VGoYNO.js → main-BNWRrWc_.js} +2 -2
- package/dist/assets/{marketplace-CXCLbyho.js → marketplace-BH1Sq8dL.js} +1 -1
- package/dist/assets/mcp-marketplace-page-BA-InAbJ.js +1 -0
- package/dist/assets/{model-config-page-CeVvZ29o.js → model-config-page-zqVWyIT0.js} +1 -1
- package/dist/assets/panel-apps-CMX4iWwQ.js +1 -0
- package/dist/assets/{panelStandalone-DomappXm.js → panelStandalone-C38o5B4Q.js} +1 -1
- package/dist/assets/{projects-BWM-oEo0.js → projects-DNe43T2d.js} +1 -1
- package/dist/assets/{provider-models-D8WOdsdu.js → provider-models-zGsDUBHG.js} +1 -1
- package/dist/assets/{provider-scoped-model-input-BOPkUOtD.js → provider-scoped-model-input-DpEyP1h8.js} +1 -1
- package/dist/assets/{providers-config-page-BilPL0kF.js → providers-config-page-J-1auWPu.js} +1 -1
- package/dist/assets/{pwa-Cp7pPvsZ.js → pwa-jmuWbrqH.js} +1 -1
- package/dist/assets/remote-C7H2o46-.js +1 -0
- package/dist/assets/{runtime-config-page-Dx6lWn3_.js → runtime-config-page-CJhqeDcu.js} +1 -1
- package/dist/assets/{service-apps-panel-9khaUSFI.js → service-apps-panel-Dj9okUgp.js} +1 -1
- package/dist/assets/{theme-provider-BsJ6HxeX.js → theme-provider-D4rd-tCP.js} +1 -1
- package/dist/index.html +10 -10
- package/dist/panel-standalone.html +4 -4
- package/package.json +7 -7
- package/src/features/marketplace/components/detail-doc/__tests__/marketplace-detail-doc.test.tsx +2 -0
- package/src/features/panel-apps/components/panel-app-runtime-surface.tsx +3 -1
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +25 -10
- package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +25 -3
- package/src/features/right-panel-resources/components/native-object-resource.tsx +3 -1
- package/src/features/right-panel-resources/components/system-object-resource.tsx +15 -1
- package/src/features/right-panel-resources/pages/resource-page.tsx +29 -2
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +16 -13
- package/src/shared/components/doc-browser/doc-browser-renderer.types.ts +3 -0
- package/src/shared/components/doc-browser/doc-browser.tsx +7 -1
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +1 -0
- package/src/shared/components/ui/context-menu/context-menu.tsx +9 -0
- package/dist/assets/agents-i7167DcF.js +0 -1
- package/dist/assets/apps-DUP3aPpu.js +0 -1
- package/dist/assets/cron-DPBUHn7j.js +0 -1
- package/dist/assets/doc-browser-C7kvXGc_.js +0 -1
- package/dist/assets/inbox-C09MQO9k.js +0 -1
- package/dist/assets/mcp-marketplace-page-ZAm380SB.js +0 -1
- package/dist/assets/panel-apps-BQlyeAId.js +0 -1
- package/dist/assets/remote-DngM8iep.js +0 -1
- package/src/features/panel-apps/components/__tests__/panel-app-toolbar.test.tsx +0 -108
- package/src/features/panel-apps/components/panel-app-toolbar.tsx +0 -89
|
@@ -30,18 +30,27 @@ export type ContextMenuItem = ContextMenuItemBase &
|
|
|
30
30
|
children?: never;
|
|
31
31
|
download?: string;
|
|
32
32
|
href: string;
|
|
33
|
+
target?: '_blank';
|
|
34
|
+
rel?: string;
|
|
35
|
+
referrerPolicy?: React.HTMLAttributeReferrerPolicy;
|
|
33
36
|
onSelect?: () => void;
|
|
34
37
|
}
|
|
35
38
|
| {
|
|
36
39
|
children?: never;
|
|
37
40
|
download?: never;
|
|
38
41
|
href?: never;
|
|
42
|
+
target?: never;
|
|
43
|
+
rel?: never;
|
|
44
|
+
referrerPolicy?: never;
|
|
39
45
|
onSelect: () => void;
|
|
40
46
|
}
|
|
41
47
|
| {
|
|
42
48
|
children: readonly ContextMenuGroup[];
|
|
43
49
|
download?: never;
|
|
44
50
|
href?: never;
|
|
51
|
+
target?: never;
|
|
52
|
+
rel?: never;
|
|
53
|
+
referrerPolicy?: never;
|
|
45
54
|
onSelect?: never;
|
|
46
55
|
}
|
|
47
56
|
);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./agents-CTSR4ZKb.js";export{e as AgentsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ot as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as AppsPanel};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{K as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as CronJobResource};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{St as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as DocBrowser};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{z as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as InboxPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{st as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as McpMarketplacePage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as e,v as t}from"./theme-provider-BsJ6HxeX.js";import"./app-presenter-provider-DdD2Q7jZ.js";export{t as PanelAppHostProvider,e as PanelAppRuntimeSurface};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{F as e}from"./app-presenter-provider-DdD2Q7jZ.js";export{e as RemoteAccessPage};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import userEvent from '@testing-library/user-event';
|
|
3
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { PanelAppToolbar } from '@/features/panel-apps/components/panel-app-toolbar';
|
|
5
|
-
|
|
6
|
-
const mainSidebarMutation = vi.hoisted(() => ({
|
|
7
|
-
isPending: false,
|
|
8
|
-
pinned: false,
|
|
9
|
-
mutate: vi.fn(),
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
vi.mock('@/features/panel-apps/hooks/use-panel-apps', () => ({
|
|
13
|
-
usePanelApps: () => ({ data:{ entries:[{ ...entry, mainSidebar: mainSidebarMutation.pinned }] } }),
|
|
14
|
-
useUpdatePanelAppPreferences: () => mainSidebarMutation,
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
const entry = {
|
|
18
|
-
appId: 'ink-assistant',
|
|
19
|
-
clientDeclared: false,
|
|
20
|
-
clientGranted: false,
|
|
21
|
-
contentPath: '/api/panel-apps/ink-assistant/content',
|
|
22
|
-
createdAt: '2026-08-19T00:00:00.000Z',
|
|
23
|
-
favorite: false,
|
|
24
|
-
fileName: 'ink-assistant.panel.html',
|
|
25
|
-
id: 'ink-assistant',
|
|
26
|
-
kind: 'single-file' as const,
|
|
27
|
-
mainSidebar: false,
|
|
28
|
-
openCount: 0,
|
|
29
|
-
sizeBytes: 10,
|
|
30
|
-
title: '墨爪助手',
|
|
31
|
-
updatedAt: '2026-08-19T00:00:00.000Z',
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
describe('PanelAppToolbar', () => {
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
mainSidebarMutation.isPending = false;
|
|
37
|
-
mainSidebarMutation.pinned = false;
|
|
38
|
-
mainSidebarMutation.mutate.mockReset();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('keeps placement in the overflow menu without adding a second back action', async () => {
|
|
42
|
-
const user = userEvent.setup();
|
|
43
|
-
render(
|
|
44
|
-
<PanelAppToolbar
|
|
45
|
-
appTitle="墨爪助手"
|
|
46
|
-
entry={entry}
|
|
47
|
-
onRefresh={vi.fn()}
|
|
48
|
-
/>,
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
expect(screen.getByText('墨爪助手')).toBeTruthy();
|
|
52
|
-
expect(screen.queryByRole('button', { name: 'Apps' })).toBeNull();
|
|
53
|
-
|
|
54
|
-
expect(screen.queryByRole('menuitem', { name: 'Pin to left sidebar' })).toBeNull();
|
|
55
|
-
await user.click(screen.getByRole('button', { name: 'More panel app actions' }));
|
|
56
|
-
await user.click(screen.getByRole('menuitem', { name: 'Layout and position' }));
|
|
57
|
-
const addButton = screen.getByRole('menuitem', { name: 'Pin to left sidebar' });
|
|
58
|
-
expect(addButton.getAttribute('aria-pressed')).toBe('false');
|
|
59
|
-
await user.click(addButton);
|
|
60
|
-
|
|
61
|
-
expect(mainSidebarMutation.mutate).toHaveBeenCalledWith({
|
|
62
|
-
id: 'ink-assistant',
|
|
63
|
-
preferences: { mainSidebar: true },
|
|
64
|
-
});
|
|
65
|
-
expect(screen.queryByRole('menuitem', { name: 'Pin to left sidebar' })).toBeNull();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('uses the same menu item to remove an app already in the main sidebar', async () => {
|
|
69
|
-
mainSidebarMutation.pinned = true;
|
|
70
|
-
const user = userEvent.setup();
|
|
71
|
-
render(
|
|
72
|
-
<PanelAppToolbar
|
|
73
|
-
appTitle="墨爪助手"
|
|
74
|
-
entry={{ ...entry, mainSidebar: true }}
|
|
75
|
-
onRefresh={vi.fn()}
|
|
76
|
-
/>,
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
await user.click(screen.getByRole('button', { name: 'More panel app actions' }));
|
|
80
|
-
await user.click(screen.getByRole('menuitem', { name: 'Layout and position' }));
|
|
81
|
-
const removeButton = screen.getByRole('menuitem', { name: 'Unpin from left sidebar' });
|
|
82
|
-
expect(removeButton.getAttribute('aria-pressed')).toBe('true');
|
|
83
|
-
await user.click(removeButton);
|
|
84
|
-
|
|
85
|
-
expect(mainSidebarMutation.mutate).toHaveBeenCalledWith({
|
|
86
|
-
id: 'ink-assistant',
|
|
87
|
-
preferences: { mainSidebar: false },
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('offers the standalone app link from the toolbar menu', async () => {
|
|
92
|
-
const user = userEvent.setup();
|
|
93
|
-
render(
|
|
94
|
-
<PanelAppToolbar
|
|
95
|
-
appTitle="墨爪助手"
|
|
96
|
-
entry={entry}
|
|
97
|
-
onRefresh={vi.fn()}
|
|
98
|
-
/>,
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
await user.click(screen.getByRole('button', { name: 'More panel app actions' }));
|
|
102
|
-
const link = screen.getByRole('link', { name: 'Open in New Tab' });
|
|
103
|
-
expect(link.getAttribute('href')).toBe('/apps/panel/ink-assistant/standalone');
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
vi.mock("react-router-dom", async (importOriginal) => ({ ...(await importOriginal<object>()),useNavigate: () => vi.fn(), useLocation: () => ({ pathname:'/apps',search:'' }) }));
|
|
108
|
-
vi.mock("@/app/components/app-presenter-provider", () => ({ useAppPresenter: () => ({ pageResourceManager:{ open:vi.fn() } }) }));
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { useMemo, useState } from 'react';
|
|
2
|
-
import { MoreVertical, RefreshCw } from 'lucide-react';
|
|
3
|
-
import { PanelAppMainSidebarMenuItem } from '@/features/panel-apps/components/panel-app-main-sidebar-menu-item';
|
|
4
|
-
import { PanelAppOpenStandaloneMenuItem } from '@/features/panel-apps/components/panel-app-open-standalone-menu-item';
|
|
5
|
-
import { usePanelApps } from '@/features/panel-apps/hooks/use-panel-apps';
|
|
6
|
-
import { readPanelAppIdFromTab } from '@/features/right-panel-resources';
|
|
7
|
-
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
8
|
-
import { Popover, PopoverContent, PopoverTrigger } from '@/shared/components/ui/popover';
|
|
9
|
-
import type { PanelAppEntryView } from '@/shared/lib/api';
|
|
10
|
-
import { t } from '@/shared/lib/i18n';
|
|
11
|
-
|
|
12
|
-
type PanelAppToolbarProps = {
|
|
13
|
-
appTitle: string;
|
|
14
|
-
entry?: PanelAppEntryView;
|
|
15
|
-
onRefresh: () => void;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export function PanelAppToolbar({
|
|
19
|
-
appTitle,
|
|
20
|
-
entry,
|
|
21
|
-
onRefresh,
|
|
22
|
-
}: PanelAppToolbarProps) {
|
|
23
|
-
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<div className="flex items-center justify-between gap-2 border-b border-border/70 bg-card px-3.5 py-2 shrink-0">
|
|
27
|
-
<span
|
|
28
|
-
className="min-w-0 flex-1 truncate text-xs font-medium text-muted-foreground"
|
|
29
|
-
title={appTitle}
|
|
30
|
-
>
|
|
31
|
-
{appTitle}
|
|
32
|
-
</span>
|
|
33
|
-
<IconActionButton
|
|
34
|
-
icon={<RefreshCw className="h-3.5 w-3.5" />}
|
|
35
|
-
label={t('panelAppsRefreshCurrent')}
|
|
36
|
-
onClick={onRefresh}
|
|
37
|
-
size="sm"
|
|
38
|
-
/>
|
|
39
|
-
{entry ? (
|
|
40
|
-
<Popover open={isMenuOpen} onOpenChange={setIsMenuOpen}>
|
|
41
|
-
<PopoverTrigger asChild>
|
|
42
|
-
<IconActionButton
|
|
43
|
-
icon={<MoreVertical className="h-3.5 w-3.5" />}
|
|
44
|
-
label={t('panelAppsMoreActions')}
|
|
45
|
-
size="sm"
|
|
46
|
-
/>
|
|
47
|
-
</PopoverTrigger>
|
|
48
|
-
<PopoverContent align="end" variant="menu">
|
|
49
|
-
<PanelAppOpenStandaloneMenuItem
|
|
50
|
-
entry={entry}
|
|
51
|
-
onSelect={() => setIsMenuOpen(false)}
|
|
52
|
-
/>
|
|
53
|
-
<PanelAppMainSidebarMenuItem
|
|
54
|
-
entry={entry}
|
|
55
|
-
onSelect={() => setIsMenuOpen(false)}
|
|
56
|
-
/>
|
|
57
|
-
</PopoverContent>
|
|
58
|
-
</Popover>
|
|
59
|
-
) : null}
|
|
60
|
-
</div>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function PanelAppDocBrowserToolbar({
|
|
65
|
-
appTitle,
|
|
66
|
-
currentUrl,
|
|
67
|
-
onRefresh,
|
|
68
|
-
resourceUri,
|
|
69
|
-
}: {
|
|
70
|
-
appTitle: string;
|
|
71
|
-
currentUrl: string;
|
|
72
|
-
onRefresh: () => void;
|
|
73
|
-
resourceUri?: string;
|
|
74
|
-
}) {
|
|
75
|
-
const panelApps = usePanelApps();
|
|
76
|
-
const appId = readPanelAppIdFromTab({ currentUrl, resourceUri });
|
|
77
|
-
const entry = useMemo(
|
|
78
|
-
() => panelApps.data?.entries.find((candidate) => candidate.appId === appId),
|
|
79
|
-
[appId, panelApps.data?.entries],
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<PanelAppToolbar
|
|
84
|
-
appTitle={entry?.title ?? appTitle}
|
|
85
|
-
entry={entry}
|
|
86
|
-
onRefresh={onRefresh}
|
|
87
|
-
/>
|
|
88
|
-
);
|
|
89
|
-
}
|