@agent-native/core 0.128.1 → 0.128.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 +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/server/email-template.ts +33 -0
- package/corpus/templates/chat/_gitignore +2 -0
- package/corpus/templates/clips/AGENTS.md +6 -1
- package/corpus/templates/clips/actions/complete-transactional-email-summary.ts +56 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +258 -76
- package/corpus/templates/clips/actions/lib/direct-video.ts +96 -0
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +53 -2
- package/corpus/templates/clips/actions/lib/loom-video.ts +2 -62
- package/corpus/templates/clips/actions/lib/video-download-limits.ts +62 -0
- package/corpus/templates/clips/actions/list-transactional-email-ai-requests.ts +249 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +65 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +55 -0
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +28 -126
- package/corpus/templates/clips/app/global.css +23 -0
- package/corpus/templates/clips/app/hooks/use-transactional-email-bridge.ts +98 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +20 -0
- package/corpus/templates/clips/app/routes/_app.tsx +2 -0
- package/corpus/templates/clips/app/routes/import.tsx +396 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +8 -6
- package/corpus/templates/clips/app/routes/record.tsx +13 -71
- package/corpus/templates/clips/changelog/2026-07-25-two-clip-emails-now-include-a-concise-summary-generated-secu.md +6 -0
- package/corpus/templates/clips/data/clips-transactional-emails/config.json +3 -0
- package/corpus/templates/clips/server/jobs/transactional-emails.ts +1034 -0
- package/corpus/templates/clips/server/lib/transactional-email-store.ts +865 -0
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +270 -0
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/routes/api/view-event.post.ts +59 -2
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +8 -2
- package/corpus/templates/content/AGENTS.md +8 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +28 -3
- package/corpus/templates/content/actions/_property-utils.ts +32 -2
- package/corpus/templates/content/actions/configure-document-property.ts +12 -2
- package/corpus/templates/content/actions/delete-document-property.ts +13 -3
- package/corpus/templates/content/actions/duplicate-document-property.ts +13 -3
- package/corpus/templates/content/actions/list-content-spaces.ts +5 -2
- package/corpus/templates/content/actions/list-document-properties.ts +12 -3
- package/corpus/templates/content/actions/move-database-item.ts +74 -55
- package/corpus/templates/content/actions/reorder-document-property.ts +20 -4
- package/corpus/templates/content/actions/set-document-property.ts +10 -1
- package/corpus/templates/content/actions/update-content-database-personal-view.ts +7 -0
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +31 -21
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +30 -3
- package/corpus/templates/content/app/components/editor/DocumentInfoPanel.tsx +8 -1
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +72 -20
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +79 -10
- package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +8 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +6 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +246 -26
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +491 -197
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +3 -3
- package/corpus/templates/content/app/components/sidebar/sidebar-reorder.tsx +409 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +117 -3
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +1 -0
- package/corpus/templates/content/app/hooks/use-document-properties.ts +62 -18
- package/corpus/templates/content/app/hooks/use-documents.ts +13 -5
- package/corpus/templates/content/app/i18n-data.ts +261 -3
- package/corpus/templates/content/app/routes/_app.page.$id.tsx +9 -2
- package/corpus/templates/content/changelog/2026-07-24-database-page-properties-keep-their-context.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-sidebar-references-can-now-be-personally-reordered.md +6 -0
- package/corpus/templates/content/docs/solutions/2026-07-24-database-property-context-switch-diagnosis.md +249 -0
- package/corpus/templates/content/docs/solutions/content-sidebar-order-shape.md +389 -0
- package/corpus/templates/content/shared/api.ts +28 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/editor/DragHandle.ts +63 -9
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/email-template.d.ts +7 -0
- package/dist/server/email-template.d.ts.map +1 -1
- package/dist/server/email-template.js +24 -0
- package/dist/server/email-template.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/chat/_gitignore +2 -0
- package/package.json +4 -3
- package/src/server/email-template.ts +33 -0
- package/src/templates/chat/_gitignore +2 -0
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
ContentDatabasePersonalViewOverrides,
|
|
6
6
|
ContentDatabaseResponse,
|
|
7
7
|
ContentDatabaseViewConfig,
|
|
8
|
+
ContentSidebarOrderMode,
|
|
9
|
+
ContentSidebarViewOrder,
|
|
8
10
|
} from "@shared/api";
|
|
9
11
|
import {
|
|
10
12
|
IconChevronDown,
|
|
@@ -51,6 +53,12 @@ import {
|
|
|
51
53
|
} from "@/components/ui/tooltip";
|
|
52
54
|
import { cn } from "@/lib/utils";
|
|
53
55
|
|
|
56
|
+
import {
|
|
57
|
+
SidebarDropIndicator,
|
|
58
|
+
SidebarReorderProvider,
|
|
59
|
+
useSidebarReorderItem,
|
|
60
|
+
type SidebarReorderLabels,
|
|
61
|
+
} from "../../sidebar/sidebar-reorder";
|
|
54
62
|
import { applyDatabaseView } from "./filter-sort";
|
|
55
63
|
import {
|
|
56
64
|
databaseViewGroupingProperty,
|
|
@@ -64,6 +72,75 @@ import {
|
|
|
64
72
|
normalizeClientDatabaseViewConfig,
|
|
65
73
|
} from "./view-config";
|
|
66
74
|
|
|
75
|
+
export interface ContentFilesSidebarManualReorder {
|
|
76
|
+
onReorder: (
|
|
77
|
+
itemIds: string[],
|
|
78
|
+
moved: { itemId: string; position: number },
|
|
79
|
+
) => void;
|
|
80
|
+
labels: SidebarReorderLabels;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ContentFilesSidebarRenderReorder {
|
|
84
|
+
controls: ReturnType<typeof useSidebarReorderItem>;
|
|
85
|
+
labels: SidebarReorderLabels;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function databaseSidebarReorderItems(
|
|
89
|
+
items: ContentDatabaseItem[],
|
|
90
|
+
untitledLabel: string,
|
|
91
|
+
hierarchical: boolean,
|
|
92
|
+
) {
|
|
93
|
+
return items.map((item) => ({
|
|
94
|
+
id: item.id,
|
|
95
|
+
label: item.document.title || untitledLabel,
|
|
96
|
+
parentId: hierarchical ? item.document.parentId : null,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function contentSidebarOrderedItems(
|
|
101
|
+
items: ContentDatabaseItem[],
|
|
102
|
+
order: ContentSidebarViewOrder,
|
|
103
|
+
) {
|
|
104
|
+
const itemIds = new Map(
|
|
105
|
+
order.itemIds.map((itemId, index) => [itemId, index]),
|
|
106
|
+
);
|
|
107
|
+
const stableItemId = (
|
|
108
|
+
left: ContentDatabaseItem,
|
|
109
|
+
right: ContentDatabaseItem,
|
|
110
|
+
) => left.id.localeCompare(right.id);
|
|
111
|
+
const newestFirst = (left: string, right: string) =>
|
|
112
|
+
new Date(right).getTime() - new Date(left).getTime();
|
|
113
|
+
|
|
114
|
+
return [...items].sort((left, right) => {
|
|
115
|
+
if (order.mode === "custom") {
|
|
116
|
+
const leftIndex = itemIds.get(left.id);
|
|
117
|
+
const rightIndex = itemIds.get(right.id);
|
|
118
|
+
if (leftIndex !== undefined || rightIndex !== undefined) {
|
|
119
|
+
if (leftIndex === undefined) return 1;
|
|
120
|
+
if (rightIndex === undefined) return -1;
|
|
121
|
+
if (leftIndex !== rightIndex) return leftIndex - rightIndex;
|
|
122
|
+
}
|
|
123
|
+
return left.position - right.position || stableItemId(left, right);
|
|
124
|
+
}
|
|
125
|
+
if (order.mode === "last_edited") {
|
|
126
|
+
return (
|
|
127
|
+
newestFirst(left.document.updatedAt, right.document.updatedAt) ||
|
|
128
|
+
stableItemId(left, right)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (order.mode === "created") {
|
|
132
|
+
return (
|
|
133
|
+
newestFirst(left.document.createdAt, right.document.createdAt) ||
|
|
134
|
+
stableItemId(left, right)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
return (
|
|
138
|
+
(left.document.title || "").localeCompare(right.document.title || "") ||
|
|
139
|
+
stableItemId(left, right)
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
67
144
|
function applyPersonalSidebarViewOverrides(
|
|
68
145
|
savedViewConfig: ContentDatabaseViewConfig,
|
|
69
146
|
overrides: ContentDatabasePersonalViewOverrides | null | undefined,
|
|
@@ -99,6 +176,8 @@ export function ContentFilesSidebarView({
|
|
|
99
176
|
activeDocumentId,
|
|
100
177
|
labels,
|
|
101
178
|
onSelectView,
|
|
179
|
+
sidebarOrder,
|
|
180
|
+
manualReorder,
|
|
102
181
|
onOpenItem,
|
|
103
182
|
onCreateChildPage,
|
|
104
183
|
onCreateChildDatabase,
|
|
@@ -114,6 +193,9 @@ export function ContentFilesSidebarView({
|
|
|
114
193
|
isLoading: boolean;
|
|
115
194
|
activeDocumentId?: string | null;
|
|
116
195
|
onSelectView?: (viewId: string) => void;
|
|
196
|
+
/** A parent-owned, user-scoped Files order. It never writes database membership. */
|
|
197
|
+
sidebarOrder?: ContentSidebarViewOrder;
|
|
198
|
+
manualReorder?: ContentFilesSidebarManualReorder;
|
|
117
199
|
onOpenItem?: (item: ContentDatabaseItem) => boolean;
|
|
118
200
|
onCreateChildPage?: (item: ContentDatabaseItem) => void;
|
|
119
201
|
onCreateChildDatabase?: (item: ContentDatabaseItem) => void;
|
|
@@ -121,7 +203,10 @@ export function ContentFilesSidebarView({
|
|
|
121
203
|
onToggleFavorite?: (item: ContentDatabaseItem) => void;
|
|
122
204
|
expandedDocumentIds?: ReadonlySet<string>;
|
|
123
205
|
onDocumentExpandedChange?: (documentId: string, expanded: boolean) => void;
|
|
124
|
-
renderItem?: (
|
|
206
|
+
renderItem?: (
|
|
207
|
+
item: ContentDatabaseItem,
|
|
208
|
+
reorder?: ContentFilesSidebarRenderReorder,
|
|
209
|
+
) => ReactNode;
|
|
125
210
|
scroll?: boolean;
|
|
126
211
|
labels: Omit<
|
|
127
212
|
Parameters<typeof DatabaseSidebarView>[0],
|
|
@@ -160,16 +245,19 @@ export function ContentFilesSidebarView({
|
|
|
160
245
|
useEffect(() => {
|
|
161
246
|
setConstraintsCleared(false);
|
|
162
247
|
}, [activeFilterKey, activeView.id]);
|
|
163
|
-
const
|
|
248
|
+
const filteredItems = usableData
|
|
164
249
|
? applyDatabaseView(
|
|
165
250
|
usableData.items,
|
|
166
251
|
usableData.properties,
|
|
167
252
|
"",
|
|
168
253
|
constraintsCleared ? [] : activeView.filters,
|
|
169
|
-
activeView.sorts,
|
|
254
|
+
sidebarOrder ? [] : activeView.sorts,
|
|
170
255
|
activeView.filterMode ?? "and",
|
|
171
256
|
)
|
|
172
257
|
: [];
|
|
258
|
+
const items = sidebarOrder
|
|
259
|
+
? contentSidebarOrderedItems(filteredItems, sidebarOrder)
|
|
260
|
+
: filteredItems;
|
|
173
261
|
const groups = databaseVisibleGroups(
|
|
174
262
|
databaseViewItemGroups(
|
|
175
263
|
items,
|
|
@@ -185,6 +273,12 @@ export function ContentFilesSidebarView({
|
|
|
185
273
|
const hierarchyUniverseItems = hasFilesHierarchy
|
|
186
274
|
? usableData?.items
|
|
187
275
|
: undefined;
|
|
276
|
+
const manualReorderEnabled =
|
|
277
|
+
Boolean(manualReorder) &&
|
|
278
|
+
(sidebarOrder?.mode ?? "custom") === "custom" &&
|
|
279
|
+
activeView.sorts.length === 0 &&
|
|
280
|
+
activeView.filters.length === 0 &&
|
|
281
|
+
!databaseViewGroupingProperty(activeView, usableData?.properties ?? []);
|
|
188
282
|
return (
|
|
189
283
|
<div className="min-w-0">
|
|
190
284
|
{viewConfig.views.length > 1 && (
|
|
@@ -235,6 +329,7 @@ export function ContentFilesSidebarView({
|
|
|
235
329
|
renderItem={renderItem}
|
|
236
330
|
hierarchyItems={hierarchyItems}
|
|
237
331
|
hierarchyUniverseItems={hierarchyUniverseItems}
|
|
332
|
+
manualReorder={manualReorderEnabled ? manualReorder : undefined}
|
|
238
333
|
scroll={scroll}
|
|
239
334
|
/>
|
|
240
335
|
</div>
|
|
@@ -260,6 +355,7 @@ export function DatabaseSidebarView({
|
|
|
260
355
|
renderItem,
|
|
261
356
|
hierarchyItems,
|
|
262
357
|
hierarchyUniverseItems,
|
|
358
|
+
manualReorder,
|
|
263
359
|
scroll = true,
|
|
264
360
|
noMatchesLabel,
|
|
265
361
|
clearLabel,
|
|
@@ -281,9 +377,13 @@ export function DatabaseSidebarView({
|
|
|
281
377
|
onToggleFavorite?: (item: ContentDatabaseItem) => void;
|
|
282
378
|
expandedDocumentIds?: ReadonlySet<string>;
|
|
283
379
|
onDocumentExpandedChange?: (documentId: string, expanded: boolean) => void;
|
|
284
|
-
renderItem?: (
|
|
380
|
+
renderItem?: (
|
|
381
|
+
item: ContentDatabaseItem,
|
|
382
|
+
reorder?: ContentFilesSidebarRenderReorder,
|
|
383
|
+
) => ReactNode;
|
|
285
384
|
hierarchyItems?: ContentDatabaseItem[];
|
|
286
385
|
hierarchyUniverseItems?: ContentDatabaseItem[];
|
|
386
|
+
manualReorder?: ContentFilesSidebarManualReorder;
|
|
287
387
|
scroll?: boolean;
|
|
288
388
|
noMatchesLabel: string;
|
|
289
389
|
clearLabel: string;
|
|
@@ -336,7 +436,7 @@ export function DatabaseSidebarView({
|
|
|
336
436
|
);
|
|
337
437
|
return (
|
|
338
438
|
<div key={node.item.id} className="min-w-0">
|
|
339
|
-
<
|
|
439
|
+
<SidebarDatabaseRow
|
|
340
440
|
item={node.item}
|
|
341
441
|
openPagesIn={openPagesIn}
|
|
342
442
|
onPreview={onPreview}
|
|
@@ -353,6 +453,7 @@ export function DatabaseSidebarView({
|
|
|
353
453
|
onToggleExpanded={(nextOpen) =>
|
|
354
454
|
setDocumentOpen(node.item.document.id, nextOpen)
|
|
355
455
|
}
|
|
456
|
+
manualReorder={manualReorder}
|
|
356
457
|
/>
|
|
357
458
|
{open && node.children.length > 0 ? (
|
|
358
459
|
<div>
|
|
@@ -401,7 +502,7 @@ export function DatabaseSidebarView({
|
|
|
401
502
|
const navigation = (
|
|
402
503
|
<nav
|
|
403
504
|
aria-label={navigationLabel}
|
|
404
|
-
className="grid min-w-0 gap-1 overflow-x-hidden
|
|
505
|
+
className="grid min-w-0 gap-1 overflow-x-hidden py-1 ps-1"
|
|
405
506
|
>
|
|
406
507
|
{grouped
|
|
407
508
|
? groups.map((group) => {
|
|
@@ -426,11 +527,14 @@ export function DatabaseSidebarView({
|
|
|
426
527
|
<CollapsibleContent className="grid gap-0.5 pl-2">
|
|
427
528
|
{group.items.map((item) =>
|
|
428
529
|
renderItem ? (
|
|
429
|
-
<
|
|
430
|
-
{
|
|
431
|
-
|
|
530
|
+
<SidebarRenderedItem
|
|
531
|
+
key={item.id}
|
|
532
|
+
item={item}
|
|
533
|
+
renderItem={renderItem}
|
|
534
|
+
manualReorder={manualReorder}
|
|
535
|
+
/>
|
|
432
536
|
) : (
|
|
433
|
-
<
|
|
537
|
+
<SidebarDatabaseRow
|
|
434
538
|
key={item.id}
|
|
435
539
|
item={item}
|
|
436
540
|
openPagesIn={openPagesIn}
|
|
@@ -442,6 +546,7 @@ export function DatabaseSidebarView({
|
|
|
442
546
|
onDeleteItem={onDeleteItem}
|
|
443
547
|
onToggleFavorite={onToggleFavorite}
|
|
444
548
|
untitledLabel={untitledLabel}
|
|
549
|
+
manualReorder={manualReorder}
|
|
445
550
|
/>
|
|
446
551
|
),
|
|
447
552
|
)}
|
|
@@ -453,11 +558,14 @@ export function DatabaseSidebarView({
|
|
|
453
558
|
? itemTree.map((node) => renderTreeNode(node, 0))
|
|
454
559
|
: items.map((item) =>
|
|
455
560
|
renderItem ? (
|
|
456
|
-
<
|
|
457
|
-
{
|
|
458
|
-
|
|
561
|
+
<SidebarRenderedItem
|
|
562
|
+
key={item.id}
|
|
563
|
+
item={item}
|
|
564
|
+
renderItem={renderItem}
|
|
565
|
+
manualReorder={manualReorder}
|
|
566
|
+
/>
|
|
459
567
|
) : (
|
|
460
|
-
<
|
|
568
|
+
<SidebarDatabaseRow
|
|
461
569
|
key={item.id}
|
|
462
570
|
item={item}
|
|
463
571
|
openPagesIn={openPagesIn}
|
|
@@ -469,16 +577,117 @@ export function DatabaseSidebarView({
|
|
|
469
577
|
onDeleteItem={onDeleteItem}
|
|
470
578
|
onToggleFavorite={onToggleFavorite}
|
|
471
579
|
untitledLabel={untitledLabel}
|
|
580
|
+
manualReorder={manualReorder}
|
|
472
581
|
/>
|
|
473
582
|
),
|
|
474
583
|
)}
|
|
475
584
|
</nav>
|
|
476
585
|
);
|
|
477
|
-
|
|
478
|
-
|
|
586
|
+
const reorderItems = databaseSidebarReorderItems(
|
|
587
|
+
hierarchyItems ?? items,
|
|
588
|
+
untitledLabel,
|
|
589
|
+
Boolean(hierarchyItems),
|
|
590
|
+
);
|
|
591
|
+
const reorderableNavigation = manualReorder ? (
|
|
592
|
+
<SidebarReorderProvider
|
|
593
|
+
items={reorderItems}
|
|
594
|
+
labels={manualReorder.labels}
|
|
595
|
+
onReorder={manualReorder.onReorder}
|
|
596
|
+
>
|
|
597
|
+
{navigation}
|
|
598
|
+
</SidebarReorderProvider>
|
|
479
599
|
) : (
|
|
480
600
|
navigation
|
|
481
601
|
);
|
|
602
|
+
return scroll ? (
|
|
603
|
+
<ScrollArea className="max-h-[32rem] w-full">
|
|
604
|
+
{reorderableNavigation}
|
|
605
|
+
</ScrollArea>
|
|
606
|
+
) : (
|
|
607
|
+
reorderableNavigation
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function SidebarRenderedItem({
|
|
612
|
+
item,
|
|
613
|
+
renderItem,
|
|
614
|
+
manualReorder,
|
|
615
|
+
}: {
|
|
616
|
+
item: ContentDatabaseItem;
|
|
617
|
+
renderItem: (
|
|
618
|
+
item: ContentDatabaseItem,
|
|
619
|
+
reorder?: ContentFilesSidebarRenderReorder,
|
|
620
|
+
) => ReactNode;
|
|
621
|
+
manualReorder?: ContentFilesSidebarManualReorder;
|
|
622
|
+
}) {
|
|
623
|
+
return manualReorder ? (
|
|
624
|
+
<ReorderableRenderedSidebarItem
|
|
625
|
+
item={item}
|
|
626
|
+
renderItem={renderItem}
|
|
627
|
+
labels={manualReorder.labels}
|
|
628
|
+
/>
|
|
629
|
+
) : (
|
|
630
|
+
<div className="min-w-0">{renderItem(item)}</div>
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function ReorderableRenderedSidebarItem({
|
|
635
|
+
item,
|
|
636
|
+
renderItem,
|
|
637
|
+
labels,
|
|
638
|
+
}: {
|
|
639
|
+
item: ContentDatabaseItem;
|
|
640
|
+
renderItem: (
|
|
641
|
+
item: ContentDatabaseItem,
|
|
642
|
+
reorder?: ContentFilesSidebarRenderReorder,
|
|
643
|
+
) => ReactNode;
|
|
644
|
+
labels: SidebarReorderLabels;
|
|
645
|
+
}) {
|
|
646
|
+
const controls = useSidebarReorderItem(item.id);
|
|
647
|
+
return (
|
|
648
|
+
<div
|
|
649
|
+
ref={controls.setNodeRef}
|
|
650
|
+
style={controls.style}
|
|
651
|
+
className="relative min-w-0"
|
|
652
|
+
>
|
|
653
|
+
<SidebarDropIndicator placement={controls.dropIndicator} />
|
|
654
|
+
{renderItem(item, { controls, labels })}
|
|
655
|
+
</div>
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function SidebarDatabaseRow({
|
|
660
|
+
manualReorder,
|
|
661
|
+
...props
|
|
662
|
+
}: Parameters<typeof DatabaseSidebarRow>[0] & {
|
|
663
|
+
manualReorder?: ContentFilesSidebarManualReorder;
|
|
664
|
+
}) {
|
|
665
|
+
return manualReorder ? (
|
|
666
|
+
<ReorderableDatabaseSidebarRow
|
|
667
|
+
{...props}
|
|
668
|
+
reorderLabels={manualReorder.labels}
|
|
669
|
+
/>
|
|
670
|
+
) : (
|
|
671
|
+
<DatabaseSidebarRow {...props} />
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
function ReorderableDatabaseSidebarRow({
|
|
676
|
+
reorderLabels,
|
|
677
|
+
...props
|
|
678
|
+
}: Parameters<typeof DatabaseSidebarRow>[0] & {
|
|
679
|
+
reorderLabels: SidebarReorderLabels;
|
|
680
|
+
}) {
|
|
681
|
+
const reorder = useSidebarReorderItem(props.item.id);
|
|
682
|
+
return (
|
|
683
|
+
<div ref={reorder.setNodeRef} style={reorder.style} className="relative">
|
|
684
|
+
<SidebarDropIndicator placement={reorder.dropIndicator} />
|
|
685
|
+
<DatabaseSidebarRow
|
|
686
|
+
{...props}
|
|
687
|
+
reorder={{ controls: reorder, labels: reorderLabels }}
|
|
688
|
+
/>
|
|
689
|
+
</div>
|
|
690
|
+
);
|
|
482
691
|
}
|
|
483
692
|
|
|
484
693
|
function DatabaseSidebarRow({
|
|
@@ -496,6 +705,7 @@ function DatabaseSidebarRow({
|
|
|
496
705
|
hasChildren = false,
|
|
497
706
|
expanded = false,
|
|
498
707
|
onToggleExpanded,
|
|
708
|
+
reorder,
|
|
499
709
|
}: {
|
|
500
710
|
item: ContentDatabaseItem;
|
|
501
711
|
openPagesIn: ContentDatabaseOpenPagesIn;
|
|
@@ -511,6 +721,10 @@ function DatabaseSidebarRow({
|
|
|
511
721
|
hasChildren?: boolean;
|
|
512
722
|
expanded?: boolean;
|
|
513
723
|
onToggleExpanded?: (open: boolean) => void;
|
|
724
|
+
reorder?: {
|
|
725
|
+
controls: ReturnType<typeof useSidebarReorderItem>;
|
|
726
|
+
labels: SidebarReorderLabels;
|
|
727
|
+
};
|
|
514
728
|
}) {
|
|
515
729
|
const t = useT();
|
|
516
730
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
@@ -521,8 +735,7 @@ function DatabaseSidebarRow({
|
|
|
521
735
|
item.document.accessRole === "admin";
|
|
522
736
|
const canCreateChild = canEdit && Boolean(onCreateChildPage);
|
|
523
737
|
const hasMenuActions =
|
|
524
|
-
(
|
|
525
|
-
(canManage && Boolean(onDeleteItem));
|
|
738
|
+
Boolean(onToggleFavorite) || (canManage && Boolean(onDeleteItem));
|
|
526
739
|
function handleClick(event: MouseEvent<HTMLAnchorElement>) {
|
|
527
740
|
if (
|
|
528
741
|
event.defaultPrevented ||
|
|
@@ -555,7 +768,7 @@ function DatabaseSidebarRow({
|
|
|
555
768
|
style={{
|
|
556
769
|
insetInlineStart: `${databaseSidebarRowIndent(depth, hasChildren)}px`,
|
|
557
770
|
}}
|
|
558
|
-
aria-label={`${expanded ? "
|
|
771
|
+
aria-label={`${expanded ? t("sidebar.collapse") : t("sidebar.expand")} ${title}`}
|
|
559
772
|
aria-expanded={expanded}
|
|
560
773
|
onPointerUp={(event) => event.currentTarget.blur()}
|
|
561
774
|
onClick={() => onToggleExpanded?.(!expanded)}
|
|
@@ -570,8 +783,14 @@ function DatabaseSidebarRow({
|
|
|
570
783
|
) : null}
|
|
571
784
|
<Link
|
|
572
785
|
to={`/page/${item.document.id}`}
|
|
786
|
+
{...reorder?.controls.attributes}
|
|
787
|
+
{...reorder?.controls.listeners}
|
|
788
|
+
data-sidebar-reorder-item-id={reorder?.controls.itemId}
|
|
789
|
+
role="link"
|
|
573
790
|
className={cn(
|
|
574
791
|
"flex h-7 min-w-0 items-center gap-1.5 rounded pe-1.5 text-sm text-foreground/85 hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
792
|
+
reorder && "touch-none cursor-pointer select-none",
|
|
793
|
+
reorder?.controls.isDragging && "cursor-grabbing",
|
|
575
794
|
active && "font-semibold text-foreground",
|
|
576
795
|
)}
|
|
577
796
|
style={{
|
|
@@ -598,7 +817,8 @@ function DatabaseSidebarRow({
|
|
|
598
817
|
<span
|
|
599
818
|
className={cn(
|
|
600
819
|
"min-w-0 flex-1 truncate",
|
|
601
|
-
(hasMenuActions || canCreateChild) &&
|
|
820
|
+
(hasMenuActions || canCreateChild) &&
|
|
821
|
+
"group-hover:pe-12 group-focus-within:pe-12",
|
|
602
822
|
)}
|
|
603
823
|
>
|
|
604
824
|
{title}
|
|
@@ -606,20 +826,20 @@ function DatabaseSidebarRow({
|
|
|
606
826
|
</Link>
|
|
607
827
|
|
|
608
828
|
{(hasMenuActions || canCreateChild) && (
|
|
609
|
-
<div className="pointer-events-none absolute end-
|
|
829
|
+
<div className="pointer-events-none absolute end-0 top-1/2 z-10 flex -translate-y-1/2 items-center gap-0.5 rounded bg-sidebar px-0.5 opacity-0 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100">
|
|
610
830
|
{hasMenuActions && (
|
|
611
831
|
<DropdownMenu>
|
|
612
832
|
<DropdownMenuTrigger asChild>
|
|
613
833
|
<button
|
|
614
834
|
type="button"
|
|
615
835
|
className="flex size-6 items-center justify-center rounded text-foreground hover:bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
616
|
-
aria-label={
|
|
836
|
+
aria-label={t("sidebar.moreActionsFor", { label: title })}
|
|
617
837
|
>
|
|
618
838
|
<IconDots size={14} />
|
|
619
839
|
</button>
|
|
620
840
|
</DropdownMenuTrigger>
|
|
621
841
|
<DropdownMenuContent align="start" className="w-48">
|
|
622
|
-
{
|
|
842
|
+
{onToggleFavorite ? (
|
|
623
843
|
<DropdownMenuItem onSelect={() => onToggleFavorite(item)}>
|
|
624
844
|
<IconStar
|
|
625
845
|
className={cn(
|
|
@@ -628,11 +848,11 @@ function DatabaseSidebarRow({
|
|
|
628
848
|
)}
|
|
629
849
|
/>
|
|
630
850
|
{item.document.isFavorite
|
|
631
|
-
? "
|
|
632
|
-
: "
|
|
851
|
+
? t("sidebar.unpinFromSidebar")
|
|
852
|
+
: t("sidebar.pinToSidebar")}
|
|
633
853
|
</DropdownMenuItem>
|
|
634
854
|
) : null}
|
|
635
|
-
{
|
|
855
|
+
{onToggleFavorite && canManage && onDeleteItem ? (
|
|
636
856
|
<DropdownMenuSeparator />
|
|
637
857
|
) : null}
|
|
638
858
|
{canManage && onDeleteItem ? (
|