@agent-native/core 0.114.0 → 0.114.2
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +15 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/create.ts +23 -0
- package/corpus/core/src/cli/skills.ts +24 -0
- package/corpus/core/src/client/build-compatibility.ts +77 -0
- package/corpus/core/src/client/route-chunk-recovery/index.ts +1 -0
- package/corpus/core/src/client/use-action.ts +32 -1
- package/corpus/core/src/deploy/build.ts +4 -1
- package/corpus/core/src/org/context.ts +56 -30
- package/corpus/core/src/server/action-routes.ts +52 -2
- package/corpus/core/src/server/auth-plugin.ts +9 -4
- package/corpus/core/src/server/better-auth-instance.ts +5 -1
- package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
- package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/core/src/templates/default/AGENTS.md +4 -1
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/core/src/templates/headless/AGENTS.md +5 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/corpus/core/src/templates/workspace-core/AGENTS.md +3 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +3 -1
- package/corpus/core/src/vite/client.ts +17 -0
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/analytics/AGENTS.md +5 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/assets/AGENTS.md +5 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/brain/AGENTS.md +5 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/calendar/AGENTS.md +5 -0
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/chat/AGENTS.md +4 -1
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/clips/AGENTS.md +5 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/content/AGENTS.md +7 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +49 -5
- package/corpus/templates/content/actions/_content-document-access.ts +21 -0
- package/corpus/templates/content/actions/_content-favorites.ts +91 -0
- package/corpus/templates/content/actions/_content-files.ts +79 -23
- package/corpus/templates/content/actions/_content-sidebar-state.ts +24 -0
- package/corpus/templates/content/actions/_content-space-access.ts +15 -17
- package/corpus/templates/content/actions/_content-space-catalog-guards.ts +20 -0
- package/corpus/templates/content/actions/_content-spaces.ts +364 -167
- package/corpus/templates/content/actions/_database-source-utils.ts +8 -0
- package/corpus/templates/content/actions/_database-utils.ts +249 -15
- package/corpus/templates/content/actions/_delete-content-space.ts +84 -0
- package/corpus/templates/content/actions/_files-system-properties.ts +499 -0
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -1
- package/corpus/templates/content/actions/_property-utils.ts +18 -9
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +3 -0
- package/corpus/templates/content/actions/configure-document-property.ts +3 -0
- package/corpus/templates/content/actions/create-content-database.ts +2 -2
- package/corpus/templates/content/actions/create-content-space.ts +34 -0
- package/corpus/templates/content/actions/create-document.ts +4 -1
- package/corpus/templates/content/actions/delete-content-space.ts +19 -0
- package/corpus/templates/content/actions/delete-database-items.ts +28 -1
- package/corpus/templates/content/actions/delete-document-property.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +39 -2
- package/corpus/templates/content/actions/duplicate-database-item.ts +6 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +6 -0
- package/corpus/templates/content/actions/duplicate-document-property.ts +3 -0
- package/corpus/templates/content/actions/get-content-database.ts +11 -2
- package/corpus/templates/content/actions/get-content-sidebar-state.ts +23 -0
- package/corpus/templates/content/actions/get-document.ts +32 -7
- package/corpus/templates/content/actions/import-content-source.ts +33 -1
- package/corpus/templates/content/actions/list-content-spaces.ts +34 -2
- package/corpus/templates/content/actions/list-documents.ts +39 -7
- package/corpus/templates/content/actions/reorder-document-property.ts +9 -0
- package/corpus/templates/content/actions/set-document-property.ts +41 -23
- package/corpus/templates/content/actions/share-local-file-document.ts +15 -0
- package/corpus/templates/content/actions/submit-content-database-form.ts +7 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +14 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +1 -0
- package/corpus/templates/content/actions/update-content-sidebar-state.ts +27 -0
- package/corpus/templates/content/actions/update-document.ts +158 -66
- package/corpus/templates/content/app/components/EmptyState.tsx +4 -57
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +8 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +519 -178
- package/corpus/templates/content/app/components/editor/DocumentInfoPanel.tsx +39 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +1 -1
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +266 -7
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +430 -152
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +467 -66
- package/corpus/templates/content/app/components/editor/database/view-config.ts +9 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +720 -196
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +173 -1
- package/corpus/templates/content/app/components/sidebar/document-sidebar-sections.ts +1 -1
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +91 -16
- package/corpus/templates/content/app/entry.client.tsx +5 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +84 -3
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +60 -2
- package/corpus/templates/content/app/hooks/use-create-page.ts +30 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +270 -19
- package/corpus/templates/content/app/i18n-data.ts +243 -20
- package/corpus/templates/content/app/lib/local-folder-picker-safety.ts +54 -0
- package/corpus/templates/content/app/lib/local-folder-picker-support.ts +18 -0
- package/corpus/templates/content/app/routes/_app.favorites.tsx +30 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +18 -6
- package/corpus/templates/content/changelog/2026-07-17-workspace-files-now-stay-in-a-loading-state-until-automatic-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-workspace-switching-now-opens-the-selected-files-database-pr.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-workspaces-now-expand-above-their-own-files-list-without-dup.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-create-named-workspaces-each-with-its-own-private-files-data.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-favorites-align-with-workspace-and-file-rows-in-the-sidebar.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-local-folder-selection-no-longer-invokes-the-unsafe-native-p.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-made-content-workspaces-independently-expandable-restored-or.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-page-details-now-live-in-a-shared-info-and-comments-rail-dat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-workspace-database-views-now-control-sidebar-workspace-navig.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-workspace-navigation-now-aligns-favorites-with-workspace-pag.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-favorites-now-open-as-a-table-and-compact-breadcrumbs-make-w.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-files-databases-now-start-unfiltered-sidebar-rows-exactly-fo.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-sidebar-page-trees-now-open-only-when-expanded-remember-thei.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-file-databases-now-use-the-workspace-name-open-as-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-navigation-now-stays-stable-on-hover-uses-folder-i.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-rows-now-use-folder-icons-and-deleting-a-user-crea.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspaces-can-be-created-without-leaving-the-workspaces-dat.md +6 -0
- package/corpus/templates/content/e2e/global-setup.ts +3 -2
- package/corpus/templates/content/parity/matrix.md +28 -28
- package/corpus/templates/content/parity/matrix.ts +8 -2
- package/corpus/templates/content/server/db/index.ts +1 -0
- package/corpus/templates/content/server/db/schema.ts +10 -0
- package/corpus/templates/content/server/lib/documents.ts +12 -7
- package/corpus/templates/content/server/plugins/db.ts +17 -0
- package/corpus/templates/content/shared/api.ts +9 -0
- package/corpus/templates/content/shared/database-form.ts +11 -2
- package/corpus/templates/content/vite.config.ts +1 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/design/AGENTS.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/forms/AGENTS.md +5 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/macros/AGENTS.md +5 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/mail/AGENTS.md +5 -0
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/plan/AGENTS.md +5 -0
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/slides/AGENTS.md +5 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/tasks/AGENTS.md +5 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +21 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +19 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/build-compatibility.d.ts +11 -0
- package/dist/client/build-compatibility.d.ts.map +1 -0
- package/dist/client/build-compatibility.js +56 -0
- package/dist/client/build-compatibility.js.map +1 -0
- package/dist/client/route-chunk-recovery/index.d.ts +1 -0
- package/dist/client/route-chunk-recovery/index.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery/index.js +1 -0
- package/dist/client/route-chunk-recovery/index.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +19 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.js +2 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/context.d.ts +4 -2
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +44 -22
- package/dist/org/context.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
- package/dist/provider-api/actions/provider-api.d.ts +12 -12
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +32 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth-plugin.d.ts.map +1 -1
- package/dist/server/auth-plugin.js +9 -5
- package/dist/server/auth-plugin.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +4 -1
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -1
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +1 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/chat/AGENTS.md +4 -1
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/default/AGENTS.md +4 -1
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/headless/AGENTS.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/dist/templates/workspace-core/AGENTS.md +3 -1
- package/dist/templates/workspace-root/AGENTS.md +3 -1
- package/dist/vite/client.d.ts +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +8 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/create.ts +23 -0
- package/src/cli/skills.ts +24 -0
- package/src/client/build-compatibility.ts +77 -0
- package/src/client/route-chunk-recovery/index.ts +1 -0
- package/src/client/use-action.ts +32 -1
- package/src/deploy/build.ts +4 -1
- package/src/org/context.ts +56 -30
- package/src/server/action-routes.ts +52 -2
- package/src/server/auth-plugin.ts +9 -4
- package/src/server/better-auth-instance.ts +5 -1
- package/src/shared/mcp-embed-headers.ts +1 -1
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/chat/AGENTS.md +4 -1
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/default/AGENTS.md +4 -1
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/headless/AGENTS.md +5 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/src/templates/workspace-core/AGENTS.md +3 -1
- package/src/templates/workspace-root/AGENTS.md +3 -1
- package/src/vite/client.ts +17 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import type { Document } from "@shared/api";
|
|
3
|
+
|
|
4
|
+
import { DescriptionField } from "./DescriptionField";
|
|
5
|
+
import { DocumentProperties } from "./DocumentProperties";
|
|
6
|
+
|
|
7
|
+
interface DocumentInfoPanelProps {
|
|
8
|
+
document: Document;
|
|
9
|
+
canEdit: boolean;
|
|
10
|
+
onSaveDescription: (description: string) => Promise<unknown> | unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function DocumentInfoPanel({
|
|
14
|
+
document,
|
|
15
|
+
canEdit,
|
|
16
|
+
onSaveDescription,
|
|
17
|
+
}: DocumentInfoPanelProps) {
|
|
18
|
+
const t = useT();
|
|
19
|
+
const isLocalFileDocument = document.source?.mode === "local-files";
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="px-4 pb-8 pt-3" data-document-info-panel>
|
|
23
|
+
<DescriptionField
|
|
24
|
+
description={document.description}
|
|
25
|
+
canEdit={canEdit}
|
|
26
|
+
label={t("editor.properties.description")}
|
|
27
|
+
placeholder={
|
|
28
|
+
document.database
|
|
29
|
+
? t("editor.properties.addDatabaseDescription")
|
|
30
|
+
: t("editor.properties.addPageDescription")
|
|
31
|
+
}
|
|
32
|
+
onSave={onSaveDescription}
|
|
33
|
+
/>
|
|
34
|
+
{document.databaseMembership && !isLocalFileDocument ? (
|
|
35
|
+
<DocumentProperties documentId={document.id} canEdit={canEdit} />
|
|
36
|
+
) : null}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -916,7 +916,7 @@ function PropertyRow({
|
|
|
916
916
|
|
|
917
917
|
return (
|
|
918
918
|
<div className="grid min-h-8 grid-cols-[160px_minmax(0,1fr)] items-start gap-3 rounded px-1 py-1 text-sm hover:bg-muted/40">
|
|
919
|
-
{canEdit ? (
|
|
919
|
+
{canEdit && !property.definition.systemRole ? (
|
|
920
920
|
<PropertyManagementPopover
|
|
921
921
|
property={property}
|
|
922
922
|
documentId={documentId}
|
|
@@ -11,12 +11,14 @@ import {
|
|
|
11
11
|
IconArrowBarDown,
|
|
12
12
|
IconArrowBarUp,
|
|
13
13
|
IconAlertTriangle,
|
|
14
|
+
IconCheck,
|
|
14
15
|
IconCopy,
|
|
15
16
|
IconDownload,
|
|
16
17
|
IconDotsVertical,
|
|
17
18
|
IconExternalLink,
|
|
18
19
|
IconFileTypeHtml,
|
|
19
20
|
IconFileTypePdf,
|
|
21
|
+
IconFolder,
|
|
20
22
|
IconLinkOff,
|
|
21
23
|
IconLoader2,
|
|
22
24
|
IconMarkdown,
|
|
@@ -25,15 +27,34 @@ import {
|
|
|
25
27
|
IconFolderOpen,
|
|
26
28
|
IconPlus,
|
|
27
29
|
IconHistory,
|
|
30
|
+
IconInfoCircle,
|
|
28
31
|
IconLink,
|
|
32
|
+
IconMessageCircle,
|
|
29
33
|
IconRefresh,
|
|
30
34
|
IconShare3,
|
|
35
|
+
IconTrash,
|
|
31
36
|
} from "@tabler/icons-react";
|
|
32
37
|
import { useQueryClient } from "@tanstack/react-query";
|
|
33
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
useCallback,
|
|
40
|
+
useEffect,
|
|
41
|
+
useRef,
|
|
42
|
+
useState,
|
|
43
|
+
type ReactNode,
|
|
44
|
+
} from "react";
|
|
34
45
|
import { useLocation, useNavigate } from "react-router";
|
|
35
46
|
import { toast } from "sonner";
|
|
36
47
|
|
|
48
|
+
import {
|
|
49
|
+
AlertDialog,
|
|
50
|
+
AlertDialogAction,
|
|
51
|
+
AlertDialogCancel,
|
|
52
|
+
AlertDialogContent,
|
|
53
|
+
AlertDialogDescription,
|
|
54
|
+
AlertDialogFooter,
|
|
55
|
+
AlertDialogHeader,
|
|
56
|
+
AlertDialogTitle,
|
|
57
|
+
} from "@/components/ui/alert-dialog";
|
|
37
58
|
import { Button } from "@/components/ui/button";
|
|
38
59
|
import {
|
|
39
60
|
DropdownMenu,
|
|
@@ -188,24 +209,27 @@ function ToolbarBreadcrumb({
|
|
|
188
209
|
untitledLabel,
|
|
189
210
|
onOpen,
|
|
190
211
|
}: {
|
|
191
|
-
items:
|
|
212
|
+
items: ToolbarBreadcrumbItem[];
|
|
192
213
|
currentDocumentId: string;
|
|
193
214
|
ariaLabel: string;
|
|
194
215
|
untitledLabel: string;
|
|
195
216
|
onOpen: (id: string) => void;
|
|
196
217
|
}) {
|
|
218
|
+
const visibleItems = compactToolbarBreadcrumbItems(items);
|
|
197
219
|
return (
|
|
198
220
|
<nav
|
|
199
221
|
aria-label={ariaLabel}
|
|
200
222
|
className="flex min-w-0 flex-1 items-center gap-1 text-sm text-foreground"
|
|
201
223
|
>
|
|
202
|
-
{
|
|
203
|
-
const isLast = index ===
|
|
224
|
+
{visibleItems.map((item, index) => {
|
|
225
|
+
const isLast = index === visibleItems.length - 1;
|
|
204
226
|
const label = item.title.trim() || untitledLabel;
|
|
205
227
|
const content = (
|
|
206
228
|
<>
|
|
207
229
|
{item.icon ? (
|
|
208
230
|
<span className="shrink-0 text-sm leading-none">{item.icon}</span>
|
|
231
|
+
) : item.iconKind === "folder" ? (
|
|
232
|
+
<IconFolder className="size-3.5 shrink-0 text-muted-foreground" />
|
|
209
233
|
) : null}
|
|
210
234
|
<span className="truncate">{label}</span>
|
|
211
235
|
</>
|
|
@@ -216,7 +240,18 @@ function ToolbarBreadcrumb({
|
|
|
216
240
|
key={`${item.id ?? label}-${index}`}
|
|
217
241
|
className="flex min-w-0 items-center gap-1"
|
|
218
242
|
>
|
|
219
|
-
{item.
|
|
243
|
+
{item.menuItems?.length ? (
|
|
244
|
+
<ToolbarBreadcrumbMenu
|
|
245
|
+
item={item}
|
|
246
|
+
label={label}
|
|
247
|
+
currentDocumentId={currentDocumentId}
|
|
248
|
+
current={isLast}
|
|
249
|
+
untitledLabel={untitledLabel}
|
|
250
|
+
onOpen={onOpen}
|
|
251
|
+
>
|
|
252
|
+
{content}
|
|
253
|
+
</ToolbarBreadcrumbMenu>
|
|
254
|
+
) : item.id && item.id !== currentDocumentId ? (
|
|
220
255
|
<button
|
|
221
256
|
type="button"
|
|
222
257
|
className="flex min-w-0 max-w-48 items-center gap-1 rounded px-1.5 py-1 text-left text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
@@ -244,11 +279,134 @@ function ToolbarBreadcrumb({
|
|
|
244
279
|
);
|
|
245
280
|
}
|
|
246
281
|
|
|
282
|
+
export interface ToolbarBreadcrumbItem {
|
|
283
|
+
id?: string;
|
|
284
|
+
title: string;
|
|
285
|
+
icon?: string | null;
|
|
286
|
+
iconKind?: "folder";
|
|
287
|
+
menuItems?: Array<{
|
|
288
|
+
id: string;
|
|
289
|
+
title: string;
|
|
290
|
+
icon?: string | null;
|
|
291
|
+
iconKind?: "folder";
|
|
292
|
+
}>;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function compactToolbarBreadcrumbItems(
|
|
296
|
+
items: ToolbarBreadcrumbItem[],
|
|
297
|
+
): ToolbarBreadcrumbItem[] {
|
|
298
|
+
if (items.length <= 3) return items;
|
|
299
|
+
const hidden = items.slice(1, -2);
|
|
300
|
+
return [
|
|
301
|
+
items[0],
|
|
302
|
+
{
|
|
303
|
+
title: "…",
|
|
304
|
+
menuItems: hidden.flatMap((item) =>
|
|
305
|
+
item.id
|
|
306
|
+
? [
|
|
307
|
+
{
|
|
308
|
+
id: item.id,
|
|
309
|
+
title: item.title,
|
|
310
|
+
icon: item.icon,
|
|
311
|
+
iconKind: item.iconKind,
|
|
312
|
+
},
|
|
313
|
+
]
|
|
314
|
+
: [],
|
|
315
|
+
),
|
|
316
|
+
},
|
|
317
|
+
...items.slice(-2),
|
|
318
|
+
];
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function ToolbarBreadcrumbMenu({
|
|
322
|
+
item,
|
|
323
|
+
label,
|
|
324
|
+
currentDocumentId,
|
|
325
|
+
current,
|
|
326
|
+
untitledLabel,
|
|
327
|
+
onOpen,
|
|
328
|
+
children,
|
|
329
|
+
}: {
|
|
330
|
+
item: ToolbarBreadcrumbItem;
|
|
331
|
+
label: string;
|
|
332
|
+
currentDocumentId: string;
|
|
333
|
+
current: boolean;
|
|
334
|
+
untitledLabel: string;
|
|
335
|
+
onOpen: (id: string) => void;
|
|
336
|
+
children: ReactNode;
|
|
337
|
+
}) {
|
|
338
|
+
const [open, setOpen] = useState(false);
|
|
339
|
+
const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
340
|
+
|
|
341
|
+
function cancelClose() {
|
|
342
|
+
if (!closeTimerRef.current) return;
|
|
343
|
+
clearTimeout(closeTimerRef.current);
|
|
344
|
+
closeTimerRef.current = null;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function scheduleClose() {
|
|
348
|
+
cancelClose();
|
|
349
|
+
closeTimerRef.current = setTimeout(() => setOpen(false), 140);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<DropdownMenu modal={false} open={open} onOpenChange={setOpen}>
|
|
354
|
+
<DropdownMenuTrigger asChild>
|
|
355
|
+
<button
|
|
356
|
+
type="button"
|
|
357
|
+
aria-label={label}
|
|
358
|
+
className={cn(
|
|
359
|
+
"flex min-w-0 max-w-48 items-center gap-1 rounded px-1.5 py-1 text-left hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
360
|
+
current ? "text-foreground" : "text-muted-foreground",
|
|
361
|
+
)}
|
|
362
|
+
onPointerEnter={() => {
|
|
363
|
+
cancelClose();
|
|
364
|
+
setOpen(true);
|
|
365
|
+
}}
|
|
366
|
+
onPointerLeave={scheduleClose}
|
|
367
|
+
>
|
|
368
|
+
{children}
|
|
369
|
+
</button>
|
|
370
|
+
</DropdownMenuTrigger>
|
|
371
|
+
<DropdownMenuContent
|
|
372
|
+
align="start"
|
|
373
|
+
className="w-64"
|
|
374
|
+
onPointerEnter={cancelClose}
|
|
375
|
+
onPointerLeave={scheduleClose}
|
|
376
|
+
>
|
|
377
|
+
{item.menuItems?.map((menuItem) => {
|
|
378
|
+
const menuLabel = menuItem.title.trim() || untitledLabel;
|
|
379
|
+
return (
|
|
380
|
+
<DropdownMenuItem
|
|
381
|
+
key={menuItem.id}
|
|
382
|
+
className="gap-2"
|
|
383
|
+
onSelect={() => onOpen(menuItem.id)}
|
|
384
|
+
>
|
|
385
|
+
<span className="flex size-4 shrink-0 items-center justify-center">
|
|
386
|
+
{menuItem.id === currentDocumentId ? (
|
|
387
|
+
<IconCheck className="size-3.5" />
|
|
388
|
+
) : menuItem.icon ? (
|
|
389
|
+
<span className="text-sm leading-none">{menuItem.icon}</span>
|
|
390
|
+
) : menuItem.iconKind === "folder" ? (
|
|
391
|
+
<IconFolder className="size-3.5 text-muted-foreground" />
|
|
392
|
+
) : (
|
|
393
|
+
<IconFileText className="size-3.5 text-muted-foreground" />
|
|
394
|
+
)}
|
|
395
|
+
</span>
|
|
396
|
+
<span className="min-w-0 flex-1 truncate">{menuLabel}</span>
|
|
397
|
+
</DropdownMenuItem>
|
|
398
|
+
);
|
|
399
|
+
})}
|
|
400
|
+
</DropdownMenuContent>
|
|
401
|
+
</DropdownMenu>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
247
405
|
interface DocumentToolbarProps {
|
|
248
406
|
documentId: string;
|
|
249
407
|
documentTitle?: string;
|
|
250
408
|
documentContent?: string;
|
|
251
|
-
breadcrumbItems?:
|
|
409
|
+
breadcrumbItems?: ToolbarBreadcrumbItem[];
|
|
252
410
|
documentUpdatedAt?: string | null;
|
|
253
411
|
activeUsers?: CollabUser[];
|
|
254
412
|
agentPresent?: boolean;
|
|
@@ -257,6 +415,13 @@ interface DocumentToolbarProps {
|
|
|
257
415
|
canEdit?: boolean;
|
|
258
416
|
hideFromSearch?: boolean;
|
|
259
417
|
source?: DocumentSourceInfo;
|
|
418
|
+
canDelete?: boolean;
|
|
419
|
+
deletePending?: boolean;
|
|
420
|
+
onDelete?: () => Promise<void>;
|
|
421
|
+
utilityPanel: "info" | "comments" | null;
|
|
422
|
+
onUtilityPanelChange: (panel: "info" | "comments" | null) => void;
|
|
423
|
+
showCommentsControl?: boolean;
|
|
424
|
+
onOpenBreadcrumbItem?: (id: string) => void;
|
|
260
425
|
}
|
|
261
426
|
|
|
262
427
|
export function DocumentToolbar({
|
|
@@ -272,6 +437,13 @@ export function DocumentToolbar({
|
|
|
272
437
|
canEdit = true,
|
|
273
438
|
hideFromSearch = false,
|
|
274
439
|
source,
|
|
440
|
+
canDelete = false,
|
|
441
|
+
deletePending = false,
|
|
442
|
+
onDelete,
|
|
443
|
+
utilityPanel,
|
|
444
|
+
onUtilityPanelChange,
|
|
445
|
+
showCommentsControl = true,
|
|
446
|
+
onOpenBreadcrumbItem,
|
|
275
447
|
}: DocumentToolbarProps) {
|
|
276
448
|
const t = useT();
|
|
277
449
|
const navigate = useNavigate();
|
|
@@ -311,6 +483,7 @@ export function DocumentToolbar({
|
|
|
311
483
|
boolean | null
|
|
312
484
|
>(null);
|
|
313
485
|
const [historyOpen, setHistoryOpen] = useState(false);
|
|
486
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
314
487
|
const [searchQuery, setSearchQuery] = useState("");
|
|
315
488
|
const [debouncedQuery, setDebouncedQuery] = useState("");
|
|
316
489
|
const [linkingPageId, setLinkingPageId] = useState<string | null>(null);
|
|
@@ -651,7 +824,13 @@ export function DocumentToolbar({
|
|
|
651
824
|
currentDocumentId={documentId}
|
|
652
825
|
ariaLabel={t("editor.toolbar.pageBreadcrumb")}
|
|
653
826
|
untitledLabel={t("sidebar.untitled")}
|
|
654
|
-
onOpen={(id) =>
|
|
827
|
+
onOpen={(id) => {
|
|
828
|
+
if (onOpenBreadcrumbItem) {
|
|
829
|
+
onOpenBreadcrumbItem(id);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
navigate(`/page/${id}`, { flushSync: true });
|
|
833
|
+
}}
|
|
655
834
|
/>
|
|
656
835
|
|
|
657
836
|
<div className="ml-auto flex min-w-0 items-center gap-0.5 sm:gap-1">
|
|
@@ -756,6 +935,50 @@ export function DocumentToolbar({
|
|
|
756
935
|
<TooltipContent>{t("editor.toolbar.copyPageLink")}</TooltipContent>
|
|
757
936
|
</Tooltip>
|
|
758
937
|
|
|
938
|
+
<Tooltip>
|
|
939
|
+
<TooltipTrigger asChild>
|
|
940
|
+
<button
|
|
941
|
+
type="button"
|
|
942
|
+
className={cn(
|
|
943
|
+
"flex size-9 items-center justify-center rounded-lg text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
944
|
+
utilityPanel === "info" && "bg-accent text-foreground",
|
|
945
|
+
)}
|
|
946
|
+
aria-label={t("editor.toolbar.info")}
|
|
947
|
+
aria-pressed={utilityPanel === "info"}
|
|
948
|
+
onClick={() =>
|
|
949
|
+
onUtilityPanelChange(utilityPanel === "info" ? null : "info")
|
|
950
|
+
}
|
|
951
|
+
>
|
|
952
|
+
<IconInfoCircle size={16} />
|
|
953
|
+
</button>
|
|
954
|
+
</TooltipTrigger>
|
|
955
|
+
<TooltipContent>{t("editor.toolbar.info")}</TooltipContent>
|
|
956
|
+
</Tooltip>
|
|
957
|
+
|
|
958
|
+
{showCommentsControl ? (
|
|
959
|
+
<Tooltip>
|
|
960
|
+
<TooltipTrigger asChild>
|
|
961
|
+
<button
|
|
962
|
+
type="button"
|
|
963
|
+
className={cn(
|
|
964
|
+
"flex size-9 items-center justify-center rounded-lg text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
965
|
+
utilityPanel === "comments" && "bg-accent text-foreground",
|
|
966
|
+
)}
|
|
967
|
+
aria-label={t("comments.title")}
|
|
968
|
+
aria-pressed={utilityPanel === "comments"}
|
|
969
|
+
onClick={() =>
|
|
970
|
+
onUtilityPanelChange(
|
|
971
|
+
utilityPanel === "comments" ? null : "comments",
|
|
972
|
+
)
|
|
973
|
+
}
|
|
974
|
+
>
|
|
975
|
+
<IconMessageCircle size={16} />
|
|
976
|
+
</button>
|
|
977
|
+
</TooltipTrigger>
|
|
978
|
+
<TooltipContent>{t("comments.title")}</TooltipContent>
|
|
979
|
+
</Tooltip>
|
|
980
|
+
) : null}
|
|
981
|
+
|
|
759
982
|
<DropdownMenu modal={false}>
|
|
760
983
|
<Tooltip>
|
|
761
984
|
<TooltipTrigger asChild>
|
|
@@ -1202,11 +1425,47 @@ export function DocumentToolbar({
|
|
|
1202
1425
|
</Popover>
|
|
1203
1426
|
) : null}
|
|
1204
1427
|
</DropdownMenuGroup>
|
|
1428
|
+
{canDelete && onDelete ? (
|
|
1429
|
+
<>
|
|
1430
|
+
<DropdownMenuSeparator />
|
|
1431
|
+
<DropdownMenuItem
|
|
1432
|
+
className="text-destructive focus:text-destructive"
|
|
1433
|
+
onSelect={() => setDeleteDialogOpen(true)}
|
|
1434
|
+
>
|
|
1435
|
+
<IconTrash className="me-2 h-4 w-4" />
|
|
1436
|
+
{t("database.delete")}
|
|
1437
|
+
</DropdownMenuItem>
|
|
1438
|
+
</>
|
|
1439
|
+
) : null}
|
|
1205
1440
|
</DropdownMenuContent>
|
|
1206
1441
|
</DropdownMenu>
|
|
1207
1442
|
<AgentToggleButton />
|
|
1208
1443
|
</div>
|
|
1209
1444
|
</div>
|
|
1445
|
+
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
|
1446
|
+
<AlertDialogContent>
|
|
1447
|
+
<AlertDialogHeader>
|
|
1448
|
+
<AlertDialogTitle>
|
|
1449
|
+
{t("sidebar.deletePageQuestion")}
|
|
1450
|
+
</AlertDialogTitle>
|
|
1451
|
+
<AlertDialogDescription>
|
|
1452
|
+
{t("sidebar.deletePageDescription", {
|
|
1453
|
+
title: documentTitle || t("sidebar.untitled"),
|
|
1454
|
+
})}
|
|
1455
|
+
</AlertDialogDescription>
|
|
1456
|
+
</AlertDialogHeader>
|
|
1457
|
+
<AlertDialogFooter>
|
|
1458
|
+
<AlertDialogCancel>{t("comments.cancel")}</AlertDialogCancel>
|
|
1459
|
+
<AlertDialogAction
|
|
1460
|
+
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
1461
|
+
disabled={deletePending}
|
|
1462
|
+
onClick={() => void onDelete?.()}
|
|
1463
|
+
>
|
|
1464
|
+
{t("database.delete")}
|
|
1465
|
+
</AlertDialogAction>
|
|
1466
|
+
</AlertDialogFooter>
|
|
1467
|
+
</AlertDialogContent>
|
|
1468
|
+
</AlertDialog>
|
|
1210
1469
|
</>
|
|
1211
1470
|
);
|
|
1212
1471
|
}
|