@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import { IconVideoPlus } from "@tabler/icons-react";
|
|
3
|
+
import { NavLink } from "react-router";
|
|
4
|
+
|
|
5
|
+
import { ImportMenu } from "@/components/import-menu";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
buildLibraryActionHrefs,
|
|
9
|
+
type LibraryActionScope,
|
|
10
|
+
} from "./library-action-hrefs";
|
|
11
|
+
import { PageHeaderActionGroup, PageHeaderPrimaryAction } from "./page-header";
|
|
12
|
+
|
|
13
|
+
type LibraryPrimaryActionsProps = LibraryActionScope;
|
|
14
|
+
|
|
15
|
+
export function LibraryPrimaryActions({
|
|
16
|
+
folderId,
|
|
17
|
+
spaceId,
|
|
18
|
+
}: LibraryPrimaryActionsProps) {
|
|
19
|
+
const t = useT();
|
|
20
|
+
const { recordHref, uploadHref, importLoomHref } = buildLibraryActionHrefs({
|
|
21
|
+
folderId,
|
|
22
|
+
spaceId,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<PageHeaderActionGroup>
|
|
27
|
+
<PageHeaderPrimaryAction asChild>
|
|
28
|
+
<NavLink to={recordHref} aria-label={t("navigation.newRecording")}>
|
|
29
|
+
<IconVideoPlus />
|
|
30
|
+
<span className="hidden sm:inline">
|
|
31
|
+
{t("navigation.newRecording")}
|
|
32
|
+
</span>
|
|
33
|
+
</NavLink>
|
|
34
|
+
</PageHeaderPrimaryAction>
|
|
35
|
+
<ImportMenu
|
|
36
|
+
uploadHref={uploadHref}
|
|
37
|
+
importLoomHref={importLoomHref}
|
|
38
|
+
iconOnly
|
|
39
|
+
triggerIcon="chevron"
|
|
40
|
+
size="sm"
|
|
41
|
+
variant="default"
|
|
42
|
+
className="w-8 self-stretch border-s border-primary-foreground/20 px-0 shadow-none"
|
|
43
|
+
menuSide="bottom"
|
|
44
|
+
menuAlign="end"
|
|
45
|
+
/>
|
|
46
|
+
</PageHeaderActionGroup>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -2,18 +2,22 @@ import {
|
|
|
2
2
|
type ComponentProps,
|
|
3
3
|
createContext,
|
|
4
4
|
forwardRef,
|
|
5
|
+
Fragment,
|
|
5
6
|
ReactNode,
|
|
6
7
|
useContext,
|
|
7
8
|
useEffect,
|
|
8
9
|
useState,
|
|
9
10
|
} from "react";
|
|
10
11
|
import { createPortal } from "react-dom";
|
|
12
|
+
import { NavLink } from "react-router";
|
|
11
13
|
|
|
12
14
|
import {
|
|
13
15
|
Breadcrumb,
|
|
14
16
|
BreadcrumbItem,
|
|
17
|
+
BreadcrumbLink,
|
|
15
18
|
BreadcrumbList,
|
|
16
19
|
BreadcrumbPage,
|
|
20
|
+
BreadcrumbSeparator,
|
|
17
21
|
} from "@/components/ui/breadcrumb";
|
|
18
22
|
import { Button, type ButtonProps } from "@/components/ui/button";
|
|
19
23
|
import { ButtonGroup } from "@/components/ui/button-group";
|
|
@@ -76,22 +80,58 @@ export const PageHeaderActionGroup = forwardRef<
|
|
|
76
80
|
return (
|
|
77
81
|
<ButtonGroup
|
|
78
82
|
ref={ref}
|
|
79
|
-
className={cn(
|
|
83
|
+
className={cn(
|
|
84
|
+
"shrink-0 [&>*]:h-9 has-[>input[data-button-group-ignore]]:[&>*:nth-last-child(2)]:!rounded-r-md",
|
|
85
|
+
className,
|
|
86
|
+
)}
|
|
80
87
|
{...props}
|
|
81
88
|
/>
|
|
82
89
|
);
|
|
83
90
|
});
|
|
84
91
|
PageHeaderActionGroup.displayName = "PageHeaderActionGroup";
|
|
85
92
|
|
|
86
|
-
export
|
|
93
|
+
export interface PageBreadcrumbItem {
|
|
94
|
+
label: string;
|
|
95
|
+
to?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function PageBreadcrumb({
|
|
99
|
+
items,
|
|
100
|
+
}: {
|
|
101
|
+
items: readonly PageBreadcrumbItem[];
|
|
102
|
+
}) {
|
|
103
|
+
if (items.length === 0) return null;
|
|
104
|
+
|
|
87
105
|
return (
|
|
88
|
-
<Breadcrumb
|
|
106
|
+
<Breadcrumb
|
|
107
|
+
aria-label={items.map((item) => item.label).join(" / ")}
|
|
108
|
+
className="min-w-0"
|
|
109
|
+
>
|
|
89
110
|
<BreadcrumbList className="flex-nowrap overflow-hidden">
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
111
|
+
{items.map((item, index) => {
|
|
112
|
+
const current = index === items.length - 1;
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Fragment key={`${item.to ?? "current"}:${item.label}:${index}`}>
|
|
116
|
+
{index > 0 ? <BreadcrumbSeparator className="shrink-0" /> : null}
|
|
117
|
+
<BreadcrumbItem className={current ? "min-w-0" : "shrink-0"}>
|
|
118
|
+
{current ? (
|
|
119
|
+
<BreadcrumbPage className="truncate font-medium">
|
|
120
|
+
{item.label}
|
|
121
|
+
</BreadcrumbPage>
|
|
122
|
+
) : item.to ? (
|
|
123
|
+
<BreadcrumbLink asChild>
|
|
124
|
+
<NavLink to={item.to} className="block max-w-48 truncate">
|
|
125
|
+
{item.label}
|
|
126
|
+
</NavLink>
|
|
127
|
+
</BreadcrumbLink>
|
|
128
|
+
) : (
|
|
129
|
+
<span className="block max-w-48 truncate">{item.label}</span>
|
|
130
|
+
)}
|
|
131
|
+
</BreadcrumbItem>
|
|
132
|
+
</Fragment>
|
|
133
|
+
);
|
|
134
|
+
})}
|
|
95
135
|
</BreadcrumbList>
|
|
96
136
|
</Breadcrumb>
|
|
97
137
|
);
|
|
@@ -461,7 +461,7 @@ export function RecordingCard({
|
|
|
461
461
|
|
|
462
462
|
{/* Body */}
|
|
463
463
|
<div className="relative z-10 flex flex-1 flex-col gap-2 p-4 pointer-events-none">
|
|
464
|
-
<div className="flex items-
|
|
464
|
+
<div className="flex items-center gap-3">
|
|
465
465
|
<div className="min-w-0 flex-1">
|
|
466
466
|
{hasDefaultTitle ? (
|
|
467
467
|
<Skeleton
|
|
@@ -473,60 +473,6 @@ export function RecordingCard({
|
|
|
473
473
|
{displayTitle}
|
|
474
474
|
</div>
|
|
475
475
|
)}
|
|
476
|
-
<div className="mt-1.5 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground">
|
|
477
|
-
<span className="inline-flex min-w-0 items-center gap-1.5">
|
|
478
|
-
<ClipsAvatar
|
|
479
|
-
email={recording.ownerEmail}
|
|
480
|
-
alt={displayOwnerName}
|
|
481
|
-
fallback={ownerInitials}
|
|
482
|
-
className="h-4 w-4 shrink-0"
|
|
483
|
-
fallbackClassName="bg-primary/15 text-[8px] text-primary"
|
|
484
|
-
/>
|
|
485
|
-
<span className="min-w-0 truncate">{displayOwnerName}</span>
|
|
486
|
-
</span>
|
|
487
|
-
<span aria-hidden className="text-muted-foreground/60">
|
|
488
|
-
•
|
|
489
|
-
</span>
|
|
490
|
-
<time dateTime={recording.createdAt} className="shrink-0">
|
|
491
|
-
{relative}
|
|
492
|
-
</time>
|
|
493
|
-
</div>
|
|
494
|
-
<div className="mt-1 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground">
|
|
495
|
-
<span className="inline-flex items-center gap-1.5">
|
|
496
|
-
<PrivacyIcon
|
|
497
|
-
visibility={recording.visibility}
|
|
498
|
-
className="shrink-0"
|
|
499
|
-
/>
|
|
500
|
-
<span>{visibilityLabel}</span>
|
|
501
|
-
</span>
|
|
502
|
-
<span aria-hidden className="text-muted-foreground/60">
|
|
503
|
-
•
|
|
504
|
-
</span>
|
|
505
|
-
{recording.viewCount > 0 && !readOnly ? (
|
|
506
|
-
<ViewedByPopover
|
|
507
|
-
recordingId={recording.id}
|
|
508
|
-
className="pointer-events-auto underline-offset-2 hover:underline hover:text-foreground"
|
|
509
|
-
>
|
|
510
|
-
{t("clipsFinalRaw.viewsCount", {
|
|
511
|
-
count: recording.viewCount,
|
|
512
|
-
})}
|
|
513
|
-
</ViewedByPopover>
|
|
514
|
-
) : (
|
|
515
|
-
<span>
|
|
516
|
-
{t("clipsFinalRaw.viewsCount", {
|
|
517
|
-
count: recording.viewCount,
|
|
518
|
-
})}
|
|
519
|
-
</span>
|
|
520
|
-
)}
|
|
521
|
-
{recording.agentViewCount > 0 ? (
|
|
522
|
-
<AgentViewCount
|
|
523
|
-
count={recording.agentViewCount}
|
|
524
|
-
label={t("recordingInsights.agentViewsCount", {
|
|
525
|
-
count: recording.agentViewCount,
|
|
526
|
-
})}
|
|
527
|
-
/>
|
|
528
|
-
) : null}
|
|
529
|
-
</div>
|
|
530
476
|
</div>
|
|
531
477
|
|
|
532
478
|
{showActions && (
|
|
@@ -630,6 +576,63 @@ export function RecordingCard({
|
|
|
630
576
|
)}
|
|
631
577
|
</div>
|
|
632
578
|
|
|
579
|
+
<div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-4 gap-y-1.5 text-xs text-muted-foreground">
|
|
580
|
+
<div className="flex min-w-0 items-center gap-1.5">
|
|
581
|
+
<ClipsAvatar
|
|
582
|
+
email={recording.ownerEmail}
|
|
583
|
+
alt={displayOwnerName}
|
|
584
|
+
fallback={ownerInitials}
|
|
585
|
+
className="h-4 w-4 shrink-0"
|
|
586
|
+
fallbackClassName="bg-primary/15 text-[8px] text-primary"
|
|
587
|
+
/>
|
|
588
|
+
<span className="min-w-0 truncate">{displayOwnerName}</span>
|
|
589
|
+
</div>
|
|
590
|
+
|
|
591
|
+
<div className="flex items-center justify-self-end gap-x-2 whitespace-nowrap">
|
|
592
|
+
{recording.viewCount > 0 && !readOnly ? (
|
|
593
|
+
<ViewedByPopover
|
|
594
|
+
recordingId={recording.id}
|
|
595
|
+
className="pointer-events-auto underline-offset-2 hover:text-foreground hover:underline"
|
|
596
|
+
>
|
|
597
|
+
{t("clipsFinalRaw.viewsCount", {
|
|
598
|
+
count: recording.viewCount,
|
|
599
|
+
})}
|
|
600
|
+
</ViewedByPopover>
|
|
601
|
+
) : (
|
|
602
|
+
<span>
|
|
603
|
+
{t("clipsFinalRaw.viewsCount", {
|
|
604
|
+
count: recording.viewCount,
|
|
605
|
+
})}
|
|
606
|
+
</span>
|
|
607
|
+
)}
|
|
608
|
+
{recording.agentViewCount > 0 ? (
|
|
609
|
+
<AgentViewCount
|
|
610
|
+
count={recording.agentViewCount}
|
|
611
|
+
label={t("recordingInsights.agentViewsCount", {
|
|
612
|
+
count: recording.agentViewCount,
|
|
613
|
+
})}
|
|
614
|
+
/>
|
|
615
|
+
) : null}
|
|
616
|
+
</div>
|
|
617
|
+
|
|
618
|
+
<time
|
|
619
|
+
dateTime={recording.createdAt}
|
|
620
|
+
className="whitespace-nowrap"
|
|
621
|
+
>
|
|
622
|
+
{relative}
|
|
623
|
+
</time>
|
|
624
|
+
|
|
625
|
+
<div className="flex items-center justify-self-end gap-1.5 whitespace-nowrap">
|
|
626
|
+
<span className="inline-flex items-center gap-1.5">
|
|
627
|
+
<PrivacyIcon
|
|
628
|
+
visibility={recording.visibility}
|
|
629
|
+
className="shrink-0"
|
|
630
|
+
/>
|
|
631
|
+
<span>{visibilityLabel}</span>
|
|
632
|
+
</span>
|
|
633
|
+
</div>
|
|
634
|
+
</div>
|
|
635
|
+
|
|
633
636
|
{recording.tags.length > 0 && (
|
|
634
637
|
<div className="flex items-center gap-1 truncate">
|
|
635
638
|
{recording.tags.slice(0, 2).map((t) => (
|
|
@@ -108,29 +108,15 @@ export function SearchBar({ className, side = "right" }: SearchBarProps) {
|
|
|
108
108
|
return () => cancelAnimationFrame(frame);
|
|
109
109
|
}, [focusSearchInput, routeRequestsFocus, setSearchParams]);
|
|
110
110
|
|
|
111
|
-
// "/" is the inline search shortcut. Cmd+K belongs to the app command menu.
|
|
112
111
|
useEffect(() => {
|
|
113
112
|
const onKey = (e: KeyboardEvent) => {
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
!e.ctrlKey &&
|
|
118
|
-
!e.altKey &&
|
|
119
|
-
(e.target as HTMLElement)?.tagName?.toLowerCase() !== "input" &&
|
|
120
|
-
(e.target as HTMLElement)?.tagName?.toLowerCase() !== "textarea" &&
|
|
121
|
-
!(e.target as HTMLElement)?.isContentEditable
|
|
122
|
-
) {
|
|
123
|
-
e.preventDefault();
|
|
124
|
-
focusSearchInput();
|
|
125
|
-
}
|
|
126
|
-
if (e.key === "Escape") {
|
|
127
|
-
setOpen(false);
|
|
128
|
-
inputRef.current?.blur();
|
|
129
|
-
}
|
|
113
|
+
if (e.key !== "Escape") return;
|
|
114
|
+
setOpen(false);
|
|
115
|
+
inputRef.current?.blur();
|
|
130
116
|
};
|
|
131
117
|
window.addEventListener("keydown", onKey);
|
|
132
118
|
return () => window.removeEventListener("keydown", onKey);
|
|
133
|
-
}, [
|
|
119
|
+
}, []);
|
|
134
120
|
|
|
135
121
|
function pickResult(hit: SearchHit) {
|
|
136
122
|
setOpen(false);
|
|
@@ -184,7 +170,7 @@ export function SearchBar({ className, side = "right" }: SearchBarProps) {
|
|
|
184
170
|
aria-hidden="true"
|
|
185
171
|
className="absolute end-1.5 top-1/2 h-5 -translate-y-1/2 px-1 font-mono text-[10px]"
|
|
186
172
|
>
|
|
187
|
-
{shortcutLabel("
|
|
173
|
+
{shortcutLabel("cmd+k")}
|
|
188
174
|
</Kbd>
|
|
189
175
|
)}
|
|
190
176
|
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import { IconMessageCircle } from "@tabler/icons-react";
|
|
3
|
+
|
|
4
|
+
import { Button } from "@/components/ui/button";
|
|
5
|
+
import {
|
|
6
|
+
Tooltip,
|
|
7
|
+
TooltipContent,
|
|
8
|
+
TooltipTrigger,
|
|
9
|
+
} from "@/components/ui/tooltip";
|
|
10
|
+
import { openBugReportDialog } from "@/lib/command-events";
|
|
11
|
+
|
|
12
|
+
interface SidebarFeedbackButtonProps {
|
|
13
|
+
collapsed: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function SidebarFeedbackButton({
|
|
17
|
+
collapsed,
|
|
18
|
+
}: SidebarFeedbackButtonProps) {
|
|
19
|
+
const t = useT();
|
|
20
|
+
const label = t("bugReportRoute.sidebarCta");
|
|
21
|
+
|
|
22
|
+
const button = (
|
|
23
|
+
<Button
|
|
24
|
+
type="button"
|
|
25
|
+
size={collapsed ? "icon" : "sm"}
|
|
26
|
+
variant="ghost"
|
|
27
|
+
aria-label={collapsed ? label : undefined}
|
|
28
|
+
onClick={openBugReportDialog}
|
|
29
|
+
className={
|
|
30
|
+
collapsed
|
|
31
|
+
? "size-9 bg-transparent text-primary hover:bg-accent/60 hover:text-primary"
|
|
32
|
+
: "h-auto w-full justify-start gap-2 bg-transparent px-2 py-1.5 text-xs font-normal text-primary hover:bg-accent/60 hover:text-primary"
|
|
33
|
+
}
|
|
34
|
+
>
|
|
35
|
+
<IconMessageCircle className="size-4 shrink-0 text-primary" />
|
|
36
|
+
{!collapsed && <span>{label}</span>}
|
|
37
|
+
</Button>
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (!collapsed) return button;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Tooltip>
|
|
44
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
45
|
+
<TooltipContent side="right">{label}</TooltipContent>
|
|
46
|
+
</Tooltip>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -506,7 +506,7 @@ export function CommentsPanel(props: CommentsPanelProps) {
|
|
|
506
506
|
)}
|
|
507
507
|
>
|
|
508
508
|
{isInlinePresentation && enableComments ? (
|
|
509
|
-
<div className="mb-
|
|
509
|
+
<div className="mb-3 shrink-0">{composer}</div>
|
|
510
510
|
) : null}
|
|
511
511
|
<div
|
|
512
512
|
className={cn(
|
|
@@ -524,7 +524,7 @@ export function CommentsPanel(props: CommentsPanelProps) {
|
|
|
524
524
|
isInlinePresentation={isInlinePresentation}
|
|
525
525
|
/>
|
|
526
526
|
) : (
|
|
527
|
-
<ul className="space-y-
|
|
527
|
+
<ul className="space-y-3">
|
|
528
528
|
{sortedThreads.map((thread) => {
|
|
529
529
|
const root = thread[0];
|
|
530
530
|
const replies = thread.slice(1);
|