@agent-native/core 0.178.0 → 0.178.1-nightly-20260909221943
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/templates/clips/.agents/skills/dictate/SKILL.md +1 -0
- package/corpus/templates/clips/DESIGN.md +10 -7
- package/corpus/templates/clips/actions/list-organization-state.ts +56 -3
- package/corpus/templates/clips/actions/list-recordings.ts +2 -0
- package/corpus/templates/clips/actions/search-dictations.ts +81 -0
- package/corpus/templates/clips/app/components/agent-destination-logos.tsx +50 -0
- package/corpus/templates/clips/app/components/bug-report/bug-report-dialog.tsx +60 -0
- package/corpus/templates/clips/app/components/bug-report/bug-report-form.tsx +206 -0
- package/corpus/templates/clips/app/components/clips-command-menu.tsx +653 -0
- package/corpus/templates/clips/app/components/library/empty-state.tsx +52 -17
- package/corpus/templates/clips/app/components/library/folder-card.tsx +34 -0
- package/corpus/templates/clips/app/components/library/folder-tree.tsx +109 -64
- package/corpus/templates/clips/app/components/library/library-action-hrefs.ts +27 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +295 -103
- package/corpus/templates/clips/app/components/library/library-layout.tsx +381 -203
- package/corpus/templates/clips/app/components/library/library-primary-actions.tsx +48 -0
- package/corpus/templates/clips/app/components/library/page-header.tsx +48 -8
- package/corpus/templates/clips/app/components/library/recording-card.tsx +58 -55
- package/corpus/templates/clips/app/components/library/search-bar.tsx +5 -19
- package/corpus/templates/clips/app/components/library/sidebar-feedback-button.tsx +48 -0
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +2 -2
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +344 -260
- package/corpus/templates/clips/app/components/player/viewer-controls.tsx +2 -2
- package/corpus/templates/clips/app/components/recorder/camera-visualizer.tsx +0 -33
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +5 -1
- package/corpus/templates/clips/app/components/ui/tabs.tsx +1 -1
- package/corpus/templates/clips/app/hooks/use-command-search.ts +53 -0
- package/corpus/templates/clips/app/hooks/use-navigation-state.ts +32 -13
- package/corpus/templates/clips/app/hooks/use-upload-video-picker.tsx +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +7 -0
- package/corpus/templates/clips/app/lib/agent-share.ts +16 -0
- package/corpus/templates/clips/app/lib/command-events.ts +7 -0
- package/corpus/templates/clips/app/root.tsx +6 -82
- package/corpus/templates/clips/app/routes/_app.dictate.tsx +25 -5
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +2 -30
- package/corpus/templates/clips/app/routes/_app.library.folder.$folderId.tsx +13 -2
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +4 -17
- package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +111 -114
- package/corpus/templates/clips/app/routes/_app.spaces.$spaceId.folder.$folderId.tsx +25 -2
- package/corpus/templates/clips/app/routes/_app.spaces.$spaceId.tsx +14 -61
- package/corpus/templates/clips/app/routes/_app.spaces._index.tsx +34 -24
- package/corpus/templates/clips/app/routes/_app.trash.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.tsx +2 -4
- package/corpus/templates/clips/app/routes/bug-report.tsx +11 -189
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +148 -123
- package/corpus/templates/clips/changelog/2026-09-08-comments-and-desktop-window-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-08-global-command-search.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-09-agent-sidebar-fits-below-toolbar.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-09-desktop-switches-stay-clear-in-dark-mode.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-09-recording-agent-uses-global-panel.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +2 -2
- package/corpus/templates/clips/desktop/src/components/MediaDeviceRow.tsx +5 -3
- package/corpus/templates/clips/desktop/src/components/SourceRow.tsx +1 -0
- package/corpus/templates/clips/desktop/src/components/Switch.tsx +2 -5
- package/corpus/templates/clips/desktop/src/components/ui/switch.tsx +21 -3
- package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +72 -52
- package/corpus/templates/clips/desktop/src/styles.css +18 -19
- package/corpus/templates/clips/desktop/src/tailwind.css +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +18 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +3 -5
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +14 -3
- package/corpus/templates/design/AGENTS.md +2 -1
- package/corpus/templates/design/actions/export-png.ts +119 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +47 -13
- package/corpus/templates/design/server/plugins/agent-chat.ts +3 -1
- package/corpus/templates/factory/actions/dispatch-factory-item.ts +51 -22
- package/corpus/templates/factory/actions/list-triage-items.ts +21 -11
- package/corpus/templates/factory/actions/poll-slack-channel.ts +7 -2
- package/corpus/templates/factory/changelog/2026-09-09-slack-feedback-keeps-claimed-markers-after-poll.md +6 -0
- package/corpus/templates/factory/changelog/2026-09-09-slack-feedback-preserves-started-claimed-threads.md +6 -0
- package/corpus/templates/factory/changelog/2026-09-09-slack-feedback-skips-claimed-parents.md +6 -0
- package/corpus/templates/factory/server/lib/factory-automation-config.ts +1 -1
- package/corpus/templates/factory/server/lib/slack-feedback-prompt.ts +47 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +5 -4
- package/corpus/templates/factory/server/triage/review-skill-alignment.ts +12 -7
- package/corpus/templates/factory/server/triage/slack-review-window.ts +39 -0
- package/dist/client/CommandMenu.js +13 -1
- package/dist/client/analytics.js +10 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/vite/client.js +25 -7
- package/dist/vite/sentry-source-maps.d.ts +12 -0
- package/dist/vite/sentry-source-maps.js +105 -0
- package/package.json +2 -1
|
@@ -25,24 +25,22 @@ import {
|
|
|
25
25
|
IconUsersGroup,
|
|
26
26
|
IconBrandChrome,
|
|
27
27
|
IconDownload,
|
|
28
|
+
IconChevronDown,
|
|
28
29
|
IconMenu2,
|
|
29
30
|
IconLayoutSidebarLeftCollapse,
|
|
30
31
|
IconLayoutSidebarLeftExpand,
|
|
31
|
-
IconLayoutSidebarRight,
|
|
32
32
|
IconShare,
|
|
33
33
|
IconDots,
|
|
34
34
|
IconEdit,
|
|
35
35
|
} from "@tabler/icons-react";
|
|
36
|
-
import {
|
|
37
|
-
Fragment,
|
|
38
|
-
ReactNode,
|
|
39
|
-
useEffect,
|
|
40
|
-
useMemo,
|
|
41
|
-
useRef,
|
|
42
|
-
useState,
|
|
43
|
-
} from "react";
|
|
36
|
+
import { ReactNode, useEffect, useMemo, useRef, useState } from "react";
|
|
44
37
|
import { NavLink, useLocation, useNavigate, useParams } from "react-router";
|
|
45
38
|
|
|
39
|
+
import {
|
|
40
|
+
Collapsible,
|
|
41
|
+
CollapsibleContent,
|
|
42
|
+
CollapsibleTrigger,
|
|
43
|
+
} from "@/components/ui/collapsible";
|
|
46
44
|
import {
|
|
47
45
|
ContextMenu,
|
|
48
46
|
ContextMenuContent,
|
|
@@ -78,15 +76,30 @@ import { cn } from "@/lib/utils";
|
|
|
78
76
|
|
|
79
77
|
import { FolderTree, type FolderNode } from "./folder-tree";
|
|
80
78
|
import { PageHeaderSlotProvider } from "./page-header";
|
|
79
|
+
import { SidebarFeedbackButton } from "./sidebar-feedback-button";
|
|
81
80
|
import { SpaceDialogs } from "./space-dialogs";
|
|
82
81
|
|
|
83
82
|
interface LibraryLayoutProps {
|
|
84
83
|
children: ReactNode;
|
|
85
|
-
/** Disable the workspace Agent rail when a route embeds Agent in its own panel. */
|
|
86
|
-
showAgentSidebar?: boolean;
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
const SIDEBAR_COLLAPSED_STORAGE_KEY = "clips:left-sidebar-collapsed";
|
|
87
|
+
type SidebarGroupKey = "library" | "spaces";
|
|
88
|
+
|
|
89
|
+
function isSidebarGroupActive(
|
|
90
|
+
pathname: string,
|
|
91
|
+
group: SidebarGroupKey,
|
|
92
|
+
matchesRoute: boolean,
|
|
93
|
+
) {
|
|
94
|
+
if (!matchesRoute) return false;
|
|
95
|
+
if (group === "library" && pathname.startsWith("/library/folder/")) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (group === "spaces" && pathname.startsWith("/spaces/")) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
90
103
|
|
|
91
104
|
function readSidebarCollapsedPreference() {
|
|
92
105
|
if (typeof window === "undefined") return false;
|
|
@@ -101,18 +114,81 @@ function readSidebarCollapsedPreference() {
|
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
function ClipsAgentToggleButton() {
|
|
117
|
+
return <AgentToggleButton showWhenOpen />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface ExpandedSidebarNavGroupProps {
|
|
121
|
+
to: string;
|
|
122
|
+
label: string;
|
|
123
|
+
icon: React.ComponentType<{ className?: string }>;
|
|
124
|
+
active: boolean;
|
|
125
|
+
count?: number;
|
|
126
|
+
open: boolean;
|
|
127
|
+
onOpenChange: (open: boolean) => void;
|
|
128
|
+
children: ReactNode;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function ExpandedSidebarNavGroup({
|
|
132
|
+
to,
|
|
133
|
+
label,
|
|
134
|
+
icon: Icon,
|
|
135
|
+
active,
|
|
136
|
+
count,
|
|
137
|
+
open,
|
|
138
|
+
onOpenChange,
|
|
139
|
+
children,
|
|
140
|
+
}: ExpandedSidebarNavGroupProps) {
|
|
141
|
+
const t = useT();
|
|
142
|
+
|
|
104
143
|
return (
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
144
|
+
<Collapsible
|
|
145
|
+
open={open}
|
|
146
|
+
onOpenChange={onOpenChange}
|
|
147
|
+
className="group/sidebar-nav"
|
|
148
|
+
>
|
|
149
|
+
<div
|
|
150
|
+
className={cn(
|
|
151
|
+
"group flex items-center rounded",
|
|
152
|
+
active
|
|
153
|
+
? "bg-primary/10 font-medium text-primary"
|
|
154
|
+
: "text-primary hover:bg-accent/60",
|
|
155
|
+
)}
|
|
156
|
+
>
|
|
157
|
+
<NavLink
|
|
158
|
+
to={to}
|
|
159
|
+
className="flex min-w-0 flex-1 items-center gap-2 px-2 py-1.5 text-xs text-primary"
|
|
160
|
+
>
|
|
161
|
+
<Icon className="size-4 shrink-0 text-primary" />
|
|
162
|
+
<span className="flex-1 truncate text-primary">{label}</span>
|
|
163
|
+
{count !== undefined && count > 0 && (
|
|
164
|
+
<span className="shrink-0 tabular-nums text-[11px] text-primary/80">
|
|
165
|
+
{count}
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
168
|
+
</NavLink>
|
|
169
|
+
<CollapsibleTrigger asChild>
|
|
170
|
+
<button
|
|
171
|
+
type="button"
|
|
172
|
+
aria-label={`${t(open ? "settings.collapse" : "settings.expand")}: ${label}`}
|
|
173
|
+
className="me-1 flex size-7 shrink-0 items-center justify-center rounded text-primary hover:bg-accent hover:text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
174
|
+
>
|
|
175
|
+
<IconChevronDown
|
|
176
|
+
className={cn(
|
|
177
|
+
"size-3.5 transition-transform motion-reduce:transition-none",
|
|
178
|
+
open && "rotate-180",
|
|
179
|
+
)}
|
|
180
|
+
/>
|
|
181
|
+
</button>
|
|
182
|
+
</CollapsibleTrigger>
|
|
183
|
+
</div>
|
|
184
|
+
<CollapsibleContent className="clips-collapsible-content">
|
|
185
|
+
<div className="ms-3.5 border-s border-border/70 ps-2">{children}</div>
|
|
186
|
+
</CollapsibleContent>
|
|
187
|
+
</Collapsible>
|
|
109
188
|
);
|
|
110
189
|
}
|
|
111
190
|
|
|
112
|
-
export function LibraryLayout({
|
|
113
|
-
children,
|
|
114
|
-
showAgentSidebar = true,
|
|
115
|
-
}: LibraryLayoutProps) {
|
|
191
|
+
export function LibraryLayout({ children }: LibraryLayoutProps) {
|
|
116
192
|
const location = useLocation();
|
|
117
193
|
const navigate = useNavigate();
|
|
118
194
|
const t = useT();
|
|
@@ -170,9 +246,26 @@ export function LibraryLayout({
|
|
|
170
246
|
parentId: f.parentId ?? null,
|
|
171
247
|
spaceId: f.spaceId ?? null,
|
|
172
248
|
name: f.name,
|
|
249
|
+
recordingCount: Number(f.recordingCount ?? 0),
|
|
173
250
|
})),
|
|
174
251
|
[libFolders],
|
|
175
252
|
);
|
|
253
|
+
const spaceFolderLists = useMemo(() => {
|
|
254
|
+
const foldersBySpace = new Map<string, FolderNode[]>();
|
|
255
|
+
for (const folder of libFolders?.folders ?? []) {
|
|
256
|
+
if (!folder.spaceId) continue;
|
|
257
|
+
const folders = foldersBySpace.get(folder.spaceId) ?? [];
|
|
258
|
+
folders.push({
|
|
259
|
+
id: folder.id,
|
|
260
|
+
parentId: folder.parentId ?? null,
|
|
261
|
+
spaceId: folder.spaceId,
|
|
262
|
+
name: folder.name,
|
|
263
|
+
recordingCount: Number(folder.recordingCount ?? 0),
|
|
264
|
+
});
|
|
265
|
+
foldersBySpace.set(folder.spaceId, folders);
|
|
266
|
+
}
|
|
267
|
+
return foldersBySpace;
|
|
268
|
+
}, [libFolders]);
|
|
176
269
|
|
|
177
270
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
178
271
|
const mobileSidebarRef = useRef<HTMLElement | null>(null);
|
|
@@ -180,6 +273,14 @@ export function LibraryLayout({
|
|
|
180
273
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(
|
|
181
274
|
readSidebarCollapsedPreference,
|
|
182
275
|
);
|
|
276
|
+
const [expandedSidebarGroups, setExpandedSidebarGroups] = useState<
|
|
277
|
+
Record<SidebarGroupKey, boolean>
|
|
278
|
+
>(() => ({
|
|
279
|
+
library:
|
|
280
|
+
location.pathname.startsWith("/library") ||
|
|
281
|
+
location.pathname.startsWith("/r/"),
|
|
282
|
+
spaces: location.pathname.startsWith("/spaces"),
|
|
283
|
+
}));
|
|
183
284
|
const [headerSlot, setHeaderSlot] = useState<HTMLElement | null>(null);
|
|
184
285
|
const showCollapsedSidebar = sidebarCollapsed && !isMobile;
|
|
185
286
|
const workspaceUtilityLinks = [
|
|
@@ -215,7 +316,7 @@ export function LibraryLayout({
|
|
|
215
316
|
? t("navigation.expandSidebar")
|
|
216
317
|
: t("navigation.collapseSidebar")
|
|
217
318
|
}
|
|
218
|
-
className="flex size-
|
|
319
|
+
className="flex size-9 shrink-0 items-center justify-center rounded-md bg-transparent text-primary hover:bg-accent/60 hover:text-primary"
|
|
219
320
|
onClick={() => setSidebarCollapsed((value) => !value)}
|
|
220
321
|
>
|
|
221
322
|
{showCollapsedSidebar ? (
|
|
@@ -240,6 +341,15 @@ export function LibraryLayout({
|
|
|
240
341
|
useEffect(() => {
|
|
241
342
|
setSidebarOpen(false);
|
|
242
343
|
}, [location.pathname]);
|
|
344
|
+
useEffect(() => {
|
|
345
|
+
setExpandedSidebarGroups((groups) => ({
|
|
346
|
+
library:
|
|
347
|
+
groups.library ||
|
|
348
|
+
location.pathname.startsWith("/library") ||
|
|
349
|
+
location.pathname.startsWith("/r/"),
|
|
350
|
+
spaces: groups.spaces || location.pathname.startsWith("/spaces"),
|
|
351
|
+
}));
|
|
352
|
+
}, [location.pathname]);
|
|
243
353
|
useEffect(() => {
|
|
244
354
|
if (!isMobile || !sidebarOpen) return;
|
|
245
355
|
|
|
@@ -312,7 +422,8 @@ export function LibraryLayout({
|
|
|
312
422
|
to: "/library",
|
|
313
423
|
label: t("navigation.library"),
|
|
314
424
|
icon: IconInbox,
|
|
315
|
-
match: (p) =>
|
|
425
|
+
match: (p) =>
|
|
426
|
+
p === "/home" || p.startsWith("/library") || p.startsWith("/r/"),
|
|
316
427
|
count: libraryCount,
|
|
317
428
|
},
|
|
318
429
|
{
|
|
@@ -326,7 +437,7 @@ export function LibraryLayout({
|
|
|
326
437
|
to: "/spaces",
|
|
327
438
|
label: t("navigation.spaces"),
|
|
328
439
|
icon: IconUsersGroup,
|
|
329
|
-
match: (p) => p.startsWith("/spaces"),
|
|
440
|
+
match: (p) => p === "/spaces" || p.startsWith("/spaces/"),
|
|
330
441
|
},
|
|
331
442
|
...(meetingsExperimentEnabled
|
|
332
443
|
? [
|
|
@@ -385,20 +496,20 @@ export function LibraryLayout({
|
|
|
385
496
|
"group flex items-center rounded",
|
|
386
497
|
active
|
|
387
498
|
? "bg-primary/10 font-medium text-primary"
|
|
388
|
-
: "text-
|
|
499
|
+
: "text-primary hover:bg-accent/60",
|
|
389
500
|
)}
|
|
390
501
|
>
|
|
391
502
|
<NavLink
|
|
392
503
|
to={to}
|
|
393
|
-
className="flex min-w-0 flex-1 items-center gap-2 px-2 py-1.5 text-xs"
|
|
504
|
+
className="flex min-w-0 flex-1 items-center gap-2 px-2 py-1.5 text-xs text-primary"
|
|
394
505
|
>
|
|
395
|
-
<Icon className="size-4 shrink-0" />
|
|
396
|
-
<span className="flex-1 truncate">{label}</span>
|
|
506
|
+
<Icon className="size-4 shrink-0 text-primary" />
|
|
507
|
+
<span className="flex-1 truncate text-primary">{label}</span>
|
|
397
508
|
{count !== undefined && count > 0 && (
|
|
398
509
|
<span
|
|
399
510
|
className={cn(
|
|
400
511
|
"shrink-0 tabular-nums text-[11px]",
|
|
401
|
-
|
|
512
|
+
"text-primary/80",
|
|
402
513
|
)}
|
|
403
514
|
>
|
|
404
515
|
{count}
|
|
@@ -424,12 +535,12 @@ export function LibraryLayout({
|
|
|
424
535
|
to={to}
|
|
425
536
|
aria-label={label}
|
|
426
537
|
className={cn(
|
|
427
|
-
"flex size-9 items-center justify-center rounded-md text-
|
|
538
|
+
"flex size-9 items-center justify-center rounded-md text-primary hover:bg-accent/60 hover:text-primary",
|
|
428
539
|
active &&
|
|
429
540
|
"bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary",
|
|
430
541
|
)}
|
|
431
542
|
>
|
|
432
|
-
<Icon className="size-4" />
|
|
543
|
+
<Icon className="size-4 text-primary" />
|
|
433
544
|
</NavLink>
|
|
434
545
|
</TooltipTrigger>
|
|
435
546
|
<TooltipContent side="right">{label}</TooltipContent>
|
|
@@ -437,6 +548,31 @@ export function LibraryLayout({
|
|
|
437
548
|
);
|
|
438
549
|
};
|
|
439
550
|
|
|
551
|
+
const renderExpandedNavGroup = (
|
|
552
|
+
item: (typeof navItems)[number],
|
|
553
|
+
group: SidebarGroupKey,
|
|
554
|
+
children: ReactNode,
|
|
555
|
+
) => (
|
|
556
|
+
<ExpandedSidebarNavGroup
|
|
557
|
+
key={item.to}
|
|
558
|
+
to={item.to}
|
|
559
|
+
label={item.label}
|
|
560
|
+
icon={item.icon}
|
|
561
|
+
active={isSidebarGroupActive(
|
|
562
|
+
location.pathname,
|
|
563
|
+
group,
|
|
564
|
+
item.match(location.pathname),
|
|
565
|
+
)}
|
|
566
|
+
count={item.count}
|
|
567
|
+
open={expandedSidebarGroups[group]}
|
|
568
|
+
onOpenChange={(open) =>
|
|
569
|
+
setExpandedSidebarGroups((groups) => ({ ...groups, [group]: open }))
|
|
570
|
+
}
|
|
571
|
+
>
|
|
572
|
+
{children}
|
|
573
|
+
</ExpandedSidebarNavGroup>
|
|
574
|
+
);
|
|
575
|
+
|
|
440
576
|
const pageContent = (
|
|
441
577
|
<div className="flex min-h-0 min-w-0 flex-1 flex-col">
|
|
442
578
|
<InvitationBanner />
|
|
@@ -489,16 +625,16 @@ export function LibraryLayout({
|
|
|
489
625
|
to="/library"
|
|
490
626
|
aria-label={t("navigation.brand")}
|
|
491
627
|
className={cn(
|
|
492
|
-
"flex min-w-0
|
|
628
|
+
"flex min-w-0 items-center gap-2 rounded text-start outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
493
629
|
showCollapsedSidebar ? "size-8 justify-center" : "shrink-0",
|
|
494
630
|
)}
|
|
495
631
|
>
|
|
496
632
|
<AgentNativeIcon
|
|
497
633
|
aria-hidden="true"
|
|
498
|
-
className="h-3.5 w-6 shrink-0 text-
|
|
634
|
+
className="h-3.5 w-6 shrink-0 text-primary"
|
|
499
635
|
/>
|
|
500
636
|
{!showCollapsedSidebar && (
|
|
501
|
-
<span className="truncate text-sm font-semibold text-
|
|
637
|
+
<span className="truncate text-sm font-semibold text-primary">
|
|
502
638
|
{t("navigation.brand")}
|
|
503
639
|
</span>
|
|
504
640
|
)}
|
|
@@ -515,143 +651,168 @@ export function LibraryLayout({
|
|
|
515
651
|
</nav>
|
|
516
652
|
) : (
|
|
517
653
|
<nav className="space-y-0.5 px-2 py-3">
|
|
518
|
-
{primaryNavItems.map((item) =>
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
654
|
+
{primaryNavItems.map((item) => {
|
|
655
|
+
if (item.to === "/library" && libFolderList.length > 0) {
|
|
656
|
+
return renderExpandedNavGroup(
|
|
657
|
+
item,
|
|
658
|
+
"library",
|
|
659
|
+
<FolderTree
|
|
660
|
+
compact
|
|
661
|
+
folders={libFolderList}
|
|
662
|
+
organizationId={currentOrganizationId}
|
|
663
|
+
spaceId={null}
|
|
664
|
+
buildPath={(id) => `/library/folder/${id}`}
|
|
665
|
+
activeFolderId={folderId ?? null}
|
|
666
|
+
/>,
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (
|
|
671
|
+
item.to === "/spaces" &&
|
|
672
|
+
(spaces?.spaces ?? []).length > 0
|
|
673
|
+
) {
|
|
674
|
+
return renderExpandedNavGroup(
|
|
675
|
+
item,
|
|
676
|
+
"spaces",
|
|
677
|
+
<ul className="space-y-0.5">
|
|
678
|
+
{(spaces?.spaces ?? []).map((s: any) => {
|
|
679
|
+
const active = spaceId === s.id;
|
|
680
|
+
const spaceFolders = spaceFolderLists.get(s.id) ?? [];
|
|
681
|
+
return (
|
|
682
|
+
<li key={s.id}>
|
|
683
|
+
<ContextMenu>
|
|
684
|
+
<ContextMenuTrigger asChild>
|
|
685
|
+
<div
|
|
686
|
+
className={cn(
|
|
687
|
+
"group flex items-center gap-2 rounded px-1.5 py-1 text-xs",
|
|
688
|
+
active
|
|
689
|
+
? "bg-primary/10 text-primary"
|
|
690
|
+
: "text-primary hover:bg-accent/60",
|
|
691
|
+
)}
|
|
692
|
+
>
|
|
693
|
+
<NavLink
|
|
694
|
+
to={`/spaces/${s.id}`}
|
|
695
|
+
className="flex min-w-0 flex-1 items-center gap-2 text-primary"
|
|
548
696
|
>
|
|
549
|
-
<
|
|
550
|
-
|
|
551
|
-
|
|
697
|
+
<div
|
|
698
|
+
className="flex size-4 shrink-0 items-center justify-center rounded text-[10px]"
|
|
699
|
+
style={{
|
|
700
|
+
background:
|
|
701
|
+
s.color ?? "hsl(var(--primary))",
|
|
702
|
+
color: "hsl(var(--primary-foreground))",
|
|
703
|
+
}}
|
|
552
704
|
>
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}}
|
|
561
|
-
>
|
|
562
|
-
{s.iconEmoji ??
|
|
563
|
-
s.name.slice(0, 1).toUpperCase()}
|
|
564
|
-
</div>
|
|
565
|
-
<span className="truncate">{s.name}</span>
|
|
566
|
-
</NavLink>
|
|
567
|
-
{canManageOrg && (
|
|
568
|
-
<DropdownMenu>
|
|
569
|
-
<DropdownMenuTrigger asChild>
|
|
570
|
-
<button
|
|
571
|
-
type="button"
|
|
572
|
-
aria-label={`${s.name}: ${t("root.commandActions")}`}
|
|
573
|
-
title={`${s.name}: ${t("root.commandActions")}`}
|
|
574
|
-
className="rounded p-0.5 text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 data-[state=open]:opacity-100"
|
|
575
|
-
>
|
|
576
|
-
<IconDots className="size-3.5" />
|
|
577
|
-
</button>
|
|
578
|
-
</DropdownMenuTrigger>
|
|
579
|
-
<DropdownMenuContent
|
|
580
|
-
align="start"
|
|
581
|
-
side="right"
|
|
582
|
-
>
|
|
583
|
-
<DropdownMenuItem
|
|
584
|
-
onSelect={() => {
|
|
585
|
-
setTimeout(() => {
|
|
586
|
-
setRenameSpaceValue(s.name);
|
|
587
|
-
setRenameSpaceId(s.id);
|
|
588
|
-
}, 0);
|
|
589
|
-
}}
|
|
590
|
-
>
|
|
591
|
-
<IconEdit className="me-2 size-3.5" />
|
|
592
|
-
{t("spaceDialog.renameSpace")}
|
|
593
|
-
</DropdownMenuItem>
|
|
594
|
-
<DropdownMenuItem
|
|
595
|
-
onSelect={() => {
|
|
596
|
-
setTimeout(() => {
|
|
597
|
-
setDeleteSpaceId(s.id);
|
|
598
|
-
setDeleteSpaceName(s.name);
|
|
599
|
-
}, 0);
|
|
600
|
-
}}
|
|
601
|
-
className="text-destructive"
|
|
602
|
-
>
|
|
603
|
-
<IconTrash className="me-2 size-3.5" />
|
|
604
|
-
{t("spaceDialog.deleteSpace")}
|
|
605
|
-
</DropdownMenuItem>
|
|
606
|
-
</DropdownMenuContent>
|
|
607
|
-
</DropdownMenu>
|
|
608
|
-
)}
|
|
609
|
-
</div>
|
|
610
|
-
</ContextMenuTrigger>
|
|
611
|
-
<ContextMenuContent>
|
|
612
|
-
<ContextMenuItem asChild>
|
|
613
|
-
<NavLink to={`/spaces/${s.id}`}>
|
|
614
|
-
<IconUsersGroup className="me-2 size-3.5" />
|
|
615
|
-
{t("clipsFinalRaw.view")}
|
|
616
|
-
</NavLink>
|
|
617
|
-
</ContextMenuItem>
|
|
705
|
+
{s.iconEmoji ??
|
|
706
|
+
s.name.slice(0, 1).toUpperCase()}
|
|
707
|
+
</div>
|
|
708
|
+
<span className="truncate text-primary">
|
|
709
|
+
{s.name}
|
|
710
|
+
</span>
|
|
711
|
+
</NavLink>
|
|
618
712
|
{canManageOrg && (
|
|
619
|
-
|
|
620
|
-
<
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
onSelect={() => {
|
|
634
|
-
setTimeout(() => {
|
|
635
|
-
setDeleteSpaceId(s.id);
|
|
636
|
-
setDeleteSpaceName(s.name);
|
|
637
|
-
}, 0);
|
|
638
|
-
}}
|
|
639
|
-
className="text-destructive focus:text-destructive"
|
|
713
|
+
<DropdownMenu>
|
|
714
|
+
<DropdownMenuTrigger asChild>
|
|
715
|
+
<button
|
|
716
|
+
type="button"
|
|
717
|
+
aria-label={`${s.name}: ${t("root.commandActions")}`}
|
|
718
|
+
title={`${s.name}: ${t("root.commandActions")}`}
|
|
719
|
+
className="rounded p-0.5 text-primary opacity-0 transition-opacity hover:bg-accent hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 data-[state=open]:opacity-100"
|
|
720
|
+
>
|
|
721
|
+
<IconDots className="size-3.5" />
|
|
722
|
+
</button>
|
|
723
|
+
</DropdownMenuTrigger>
|
|
724
|
+
<DropdownMenuContent
|
|
725
|
+
align="start"
|
|
726
|
+
side="right"
|
|
640
727
|
>
|
|
641
|
-
<
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
728
|
+
<DropdownMenuItem
|
|
729
|
+
onSelect={() => {
|
|
730
|
+
setTimeout(() => {
|
|
731
|
+
setRenameSpaceValue(s.name);
|
|
732
|
+
setRenameSpaceId(s.id);
|
|
733
|
+
}, 0);
|
|
734
|
+
}}
|
|
735
|
+
>
|
|
736
|
+
<IconEdit className="me-2 size-3.5" />
|
|
737
|
+
{t("spaceDialog.renameSpace")}
|
|
738
|
+
</DropdownMenuItem>
|
|
739
|
+
<DropdownMenuItem
|
|
740
|
+
onSelect={() => {
|
|
741
|
+
setTimeout(() => {
|
|
742
|
+
setDeleteSpaceId(s.id);
|
|
743
|
+
setDeleteSpaceName(s.name);
|
|
744
|
+
}, 0);
|
|
745
|
+
}}
|
|
746
|
+
className="text-destructive"
|
|
747
|
+
>
|
|
748
|
+
<IconTrash className="me-2 size-3.5" />
|
|
749
|
+
{t("spaceDialog.deleteSpace")}
|
|
750
|
+
</DropdownMenuItem>
|
|
751
|
+
</DropdownMenuContent>
|
|
752
|
+
</DropdownMenu>
|
|
645
753
|
)}
|
|
646
|
-
</
|
|
647
|
-
</
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
754
|
+
</div>
|
|
755
|
+
</ContextMenuTrigger>
|
|
756
|
+
<ContextMenuContent>
|
|
757
|
+
<ContextMenuItem asChild>
|
|
758
|
+
<NavLink to={`/spaces/${s.id}`}>
|
|
759
|
+
<IconUsersGroup className="me-2 size-3.5" />
|
|
760
|
+
{t("clipsFinalRaw.view")}
|
|
761
|
+
</NavLink>
|
|
762
|
+
</ContextMenuItem>
|
|
763
|
+
{canManageOrg && (
|
|
764
|
+
<>
|
|
765
|
+
<ContextMenuSeparator />
|
|
766
|
+
<ContextMenuItem
|
|
767
|
+
onSelect={() => {
|
|
768
|
+
setTimeout(() => {
|
|
769
|
+
setRenameSpaceValue(s.name);
|
|
770
|
+
setRenameSpaceId(s.id);
|
|
771
|
+
}, 0);
|
|
772
|
+
}}
|
|
773
|
+
>
|
|
774
|
+
<IconEdit className="me-2 size-3.5" />
|
|
775
|
+
{t("spaceDialog.renameSpace")}
|
|
776
|
+
</ContextMenuItem>
|
|
777
|
+
<ContextMenuItem
|
|
778
|
+
onSelect={() => {
|
|
779
|
+
setTimeout(() => {
|
|
780
|
+
setDeleteSpaceId(s.id);
|
|
781
|
+
setDeleteSpaceName(s.name);
|
|
782
|
+
}, 0);
|
|
783
|
+
}}
|
|
784
|
+
className="text-destructive focus:text-destructive"
|
|
785
|
+
>
|
|
786
|
+
<IconTrash className="me-2 size-3.5" />
|
|
787
|
+
{t("spaceDialog.deleteSpace")}
|
|
788
|
+
</ContextMenuItem>
|
|
789
|
+
</>
|
|
790
|
+
)}
|
|
791
|
+
</ContextMenuContent>
|
|
792
|
+
</ContextMenu>
|
|
793
|
+
{spaceFolders.length > 0 && (
|
|
794
|
+
<div className="ms-3 border-s border-border/70 ps-2">
|
|
795
|
+
<FolderTree
|
|
796
|
+
compact
|
|
797
|
+
folders={spaceFolders}
|
|
798
|
+
organizationId={currentOrganizationId}
|
|
799
|
+
spaceId={s.id}
|
|
800
|
+
buildPath={(id) =>
|
|
801
|
+
`/spaces/${s.id}/folder/${id}`
|
|
802
|
+
}
|
|
803
|
+
activeFolderId={folderId ?? null}
|
|
804
|
+
/>
|
|
805
|
+
</div>
|
|
806
|
+
)}
|
|
807
|
+
</li>
|
|
808
|
+
);
|
|
809
|
+
})}
|
|
810
|
+
</ul>,
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
return renderExpandedNavItem(item);
|
|
815
|
+
})}
|
|
655
816
|
|
|
656
817
|
<div className="mt-3 space-y-0.5 border-t border-border/70 pt-3">
|
|
657
818
|
{lifecycleNavItems.map(renderExpandedNavItem)}
|
|
@@ -662,23 +823,33 @@ export function LibraryLayout({
|
|
|
662
823
|
|
|
663
824
|
<div
|
|
664
825
|
className={cn(
|
|
665
|
-
"shrink-0 border-t border-border p-2
|
|
666
|
-
showCollapsedSidebar
|
|
667
|
-
? "flex flex-col items-center gap-1"
|
|
668
|
-
: "flex items-center gap-0.5",
|
|
826
|
+
"shrink-0 border-t border-border p-2",
|
|
827
|
+
showCollapsedSidebar ? "space-y-1" : "space-y-1.5",
|
|
669
828
|
)}
|
|
670
829
|
>
|
|
671
|
-
<
|
|
672
|
-
|
|
830
|
+
<SidebarFeedbackButton collapsed={showCollapsedSidebar} />
|
|
831
|
+
<div
|
|
832
|
+
data-sidebar-footer-utilities
|
|
673
833
|
className={cn(
|
|
674
|
-
|
|
675
|
-
|
|
834
|
+
showCollapsedSidebar
|
|
835
|
+
? "flex flex-col items-center gap-1"
|
|
836
|
+
: "flex items-center gap-0.5",
|
|
676
837
|
)}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
838
|
+
>
|
|
839
|
+
<OrgSwitcher
|
|
840
|
+
compact={showCollapsedSidebar}
|
|
841
|
+
className={cn(
|
|
842
|
+
"!bg-transparent !text-primary hover:!bg-accent/60 hover:!text-primary",
|
|
843
|
+
showCollapsedSidebar
|
|
844
|
+
? "!size-9 !p-0 [&>svg]:!size-4"
|
|
845
|
+
: "min-w-0 flex-1",
|
|
846
|
+
)}
|
|
847
|
+
settingsPath="/settings/organization"
|
|
848
|
+
currentAppId="clips"
|
|
849
|
+
utilityLinks={workspaceUtilityLinks}
|
|
850
|
+
/>
|
|
851
|
+
{collapseButton}
|
|
852
|
+
</div>
|
|
682
853
|
</div>
|
|
683
854
|
</aside>
|
|
684
855
|
|
|
@@ -700,34 +871,41 @@ export function LibraryLayout({
|
|
|
700
871
|
ref={setHeaderSlot}
|
|
701
872
|
className="flex min-w-0 flex-1 items-center gap-3 overflow-hidden"
|
|
702
873
|
/>
|
|
703
|
-
|
|
704
|
-
<
|
|
705
|
-
|
|
706
|
-
</div>
|
|
707
|
-
) : null}
|
|
874
|
+
<div className="ms-1 flex items-center border-s border-border ps-2">
|
|
875
|
+
<ClipsAgentToggleButton />
|
|
876
|
+
</div>
|
|
708
877
|
</header>
|
|
709
878
|
)}
|
|
710
|
-
<div className="flex min-h-0 flex-1 overflow-hidden [
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
t("navigation.
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
879
|
+
<div className="flex min-h-0 flex-1 overflow-hidden [--agent-native-viewport-height:100%]">
|
|
880
|
+
<AgentSidebar
|
|
881
|
+
position="right"
|
|
882
|
+
defaultOpen={false}
|
|
883
|
+
showCollapseButton={isMobile}
|
|
884
|
+
emptyStateText={
|
|
885
|
+
recordingScope
|
|
886
|
+
? t("recordingPage.askAboutClip")
|
|
887
|
+
: t("navigation.agentEmptyState")
|
|
888
|
+
}
|
|
889
|
+
suggestions={
|
|
890
|
+
recordingScope
|
|
891
|
+
? [
|
|
892
|
+
t("recordingPage.summarizeClip"),
|
|
893
|
+
t("recordingPage.findKeyMoments"),
|
|
894
|
+
t("recordingPage.listFollowUpActions"),
|
|
895
|
+
t("recordingPage.draftQuestions"),
|
|
896
|
+
]
|
|
897
|
+
: [
|
|
898
|
+
t("navigation.agentSuggestionSummary"),
|
|
899
|
+
t("navigation.agentSuggestionPricing"),
|
|
900
|
+
t("navigation.agentSuggestionFiller"),
|
|
901
|
+
]
|
|
902
|
+
}
|
|
903
|
+
agentPageHref="/settings/agent"
|
|
904
|
+
scope={recordingScope}
|
|
905
|
+
browserTabId={getBrowserTabId()}
|
|
906
|
+
>
|
|
907
|
+
{pageContent}
|
|
908
|
+
</AgentSidebar>
|
|
731
909
|
</div>
|
|
732
910
|
</div>
|
|
733
911
|
|