@agent-native/core 0.76.10 → 0.76.11
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/docs/content/locales/ar-SA/actions.md +7 -7
- package/corpus/core/docs/content/locales/ar-SA/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/de-DE/actions.md +9 -9
- package/corpus/core/docs/content/locales/de-DE/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/es-ES/actions.md +9 -9
- package/corpus/core/docs/content/locales/es-ES/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/fr-FR/actions.md +9 -9
- package/corpus/core/docs/content/locales/fr-FR/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/hi-IN/actions.md +9 -9
- package/corpus/core/docs/content/locales/hi-IN/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/ja-JP/actions.md +9 -9
- package/corpus/core/docs/content/locales/ja-JP/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/ko-KR/actions.md +9 -9
- package/corpus/core/docs/content/locales/ko-KR/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/pt-BR/actions.md +9 -9
- package/corpus/core/docs/content/locales/pt-BR/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/zh-CN/actions.md +9 -9
- package/corpus/core/docs/content/locales/zh-CN/template-plan.md +4 -4
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/ErrorBoundary.tsx +151 -10
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +51 -31
- package/corpus/templates/analytics/app/components/layout/DashboardHeader.tsx +26 -16
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -2
- package/corpus/templates/analytics/app/components/layout/HeaderActions.tsx +8 -1
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -5
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +172 -107
- package/corpus/templates/analytics/app/i18n-data.ts +1076 -5
- package/corpus/templates/analytics/app/pages/Settings.tsx +2 -2
- package/corpus/templates/analytics/changelog/2026-06-24-analytics-navigation-command-palette-and-settings-now-honor-.md +6 -0
- package/corpus/templates/assets/app/components/layout/Header.tsx +0 -2
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +0 -2
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -2
- package/corpus/templates/chat/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/clips/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/clips/app/hooks/use-library.ts +2 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +3 -1
- package/corpus/templates/clips/changelog/2026-06-24-archive-and-spaces-navigation-is-more-resilient-when-sidebar.md +6 -0
- package/corpus/templates/content/app/components/layout/Header.tsx +0 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/forms/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/macros/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/mail/app/components/email/CodeBlockLangPicker.tsx +4 -2
- package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +18 -12
- package/corpus/templates/mail/app/components/email/ComposeEditor.tsx +9 -5
- package/corpus/templates/mail/app/components/email/ComposeModal.tsx +36 -19
- package/corpus/templates/mail/app/components/email/EmailList.tsx +59 -55
- package/corpus/templates/mail/app/components/email/EmailListItem.tsx +7 -3
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +25 -16
- package/corpus/templates/mail/app/components/email/InlineReplyComposer.tsx +25 -19
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +32 -17
- package/corpus/templates/mail/app/components/email/RecipientInput.tsx +26 -10
- package/corpus/templates/mail/app/components/email/SendLaterButton.tsx +5 -3
- package/corpus/templates/mail/app/components/email/SnoozeModal.tsx +4 -2
- package/corpus/templates/mail/app/components/email/SnoozePopover.tsx +9 -5
- package/corpus/templates/mail/app/components/email/extensions/ComposeImageBlock.tsx +4 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +168 -86
- package/corpus/templates/mail/app/components/layout/SearchBar.tsx +4 -2
- package/corpus/templates/mail/app/i18n/ar-SA.ts +212 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +212 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +212 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +212 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +212 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +212 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +212 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +212 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +212 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +211 -0
- package/corpus/templates/mail/changelog/2026-06-24-interface-language-support-now-covers-more-mail-controls-and.md +6 -0
- package/corpus/templates/plan/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/slides/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/videos/app/components/layout/Header.tsx +1 -6
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +128 -7
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/docs/content/locales/ar-SA/actions.md +7 -7
- package/docs/content/locales/ar-SA/template-plan.md +6 -4
- package/docs/content/locales/de-DE/actions.md +9 -9
- package/docs/content/locales/de-DE/template-plan.md +6 -4
- package/docs/content/locales/es-ES/actions.md +9 -9
- package/docs/content/locales/es-ES/template-plan.md +6 -4
- package/docs/content/locales/fr-FR/actions.md +9 -9
- package/docs/content/locales/fr-FR/template-plan.md +6 -4
- package/docs/content/locales/hi-IN/actions.md +9 -9
- package/docs/content/locales/hi-IN/template-plan.md +4 -4
- package/docs/content/locales/ja-JP/actions.md +9 -9
- package/docs/content/locales/ja-JP/template-plan.md +4 -4
- package/docs/content/locales/ko-KR/actions.md +9 -9
- package/docs/content/locales/ko-KR/template-plan.md +4 -4
- package/docs/content/locales/pt-BR/actions.md +9 -9
- package/docs/content/locales/pt-BR/template-plan.md +6 -4
- package/docs/content/locales/zh-CN/actions.md +9 -9
- package/docs/content/locales/zh-CN/template-plan.md +4 -4
- package/package.json +1 -1
|
@@ -228,6 +228,8 @@ function SidebarSectionSettingsPopover({
|
|
|
228
228
|
showHidden?: boolean;
|
|
229
229
|
onShowHiddenChange?: (value: boolean) => void;
|
|
230
230
|
}) {
|
|
231
|
+
const t = useT();
|
|
232
|
+
const settingsLabel = t("sidebar.sectionSettings", { label });
|
|
231
233
|
return (
|
|
232
234
|
<Popover>
|
|
233
235
|
<Tooltip>
|
|
@@ -236,13 +238,13 @@ function SidebarSectionSettingsPopover({
|
|
|
236
238
|
<button
|
|
237
239
|
type="button"
|
|
238
240
|
className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/65 opacity-0 transition-all hover:bg-sidebar-accent hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring group-hover/section:opacity-100 data-[state=open]:opacity-100"
|
|
239
|
-
aria-label={
|
|
241
|
+
aria-label={settingsLabel}
|
|
240
242
|
>
|
|
241
243
|
<IconSettings className="h-3.5 w-3.5" />
|
|
242
244
|
</button>
|
|
243
245
|
</PopoverTrigger>
|
|
244
246
|
</TooltipTrigger>
|
|
245
|
-
<TooltipContent side="right">{
|
|
247
|
+
<TooltipContent side="right">{settingsLabel}</TooltipContent>
|
|
246
248
|
</Tooltip>
|
|
247
249
|
<PopoverContent side="right" align="start" className="w-60 p-2">
|
|
248
250
|
<div className="px-2 pb-2">
|
|
@@ -251,7 +253,7 @@ function SidebarSectionSettingsPopover({
|
|
|
251
253
|
<div className="grid gap-3">
|
|
252
254
|
<div className="grid gap-1.5">
|
|
253
255
|
<p className="px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
|
|
254
|
-
|
|
256
|
+
{t("sidebar.sortBy")}
|
|
255
257
|
</p>
|
|
256
258
|
<ToggleGroup
|
|
257
259
|
type="single"
|
|
@@ -269,24 +271,24 @@ function SidebarSectionSettingsPopover({
|
|
|
269
271
|
>
|
|
270
272
|
<ToggleGroupItem
|
|
271
273
|
value="most-used"
|
|
272
|
-
aria-label="
|
|
274
|
+
aria-label={t("sidebar.sortMostUsed")}
|
|
273
275
|
className="h-7 px-2 text-[11px]"
|
|
274
276
|
>
|
|
275
|
-
|
|
277
|
+
{t("sidebar.used")}
|
|
276
278
|
</ToggleGroupItem>
|
|
277
279
|
<ToggleGroupItem
|
|
278
280
|
value="alphabetical"
|
|
279
|
-
aria-label="
|
|
281
|
+
aria-label={t("sidebar.sortAlphabetically")}
|
|
280
282
|
className="h-7 px-2 text-[11px]"
|
|
281
283
|
>
|
|
282
|
-
|
|
284
|
+
{t("sidebar.alphabetical")}
|
|
283
285
|
</ToggleGroupItem>
|
|
284
286
|
<ToggleGroupItem
|
|
285
287
|
value="manual"
|
|
286
|
-
aria-label="
|
|
288
|
+
aria-label={t("sidebar.sortManually")}
|
|
287
289
|
className="h-7 px-2 text-[11px]"
|
|
288
290
|
>
|
|
289
|
-
|
|
291
|
+
{t("sidebar.manual")}
|
|
290
292
|
</ToggleGroupItem>
|
|
291
293
|
</ToggleGroup>
|
|
292
294
|
</div>
|
|
@@ -295,12 +297,14 @@ function SidebarSectionSettingsPopover({
|
|
|
295
297
|
htmlFor={`${label.toLowerCase()}-shared-filter`}
|
|
296
298
|
className="flex items-center justify-between gap-3 rounded-md px-2 py-1.5 text-xs text-foreground hover:bg-sidebar-accent/60"
|
|
297
299
|
>
|
|
298
|
-
<span className="min-w-0 truncate">
|
|
300
|
+
<span className="min-w-0 truncate">
|
|
301
|
+
{t("sidebar.orgSharedOnly")}
|
|
302
|
+
</span>
|
|
299
303
|
<Switch
|
|
300
304
|
id={`${label.toLowerCase()}-shared-filter`}
|
|
301
305
|
checked={sharedOnly}
|
|
302
306
|
onCheckedChange={onSharedOnlyChange}
|
|
303
|
-
aria-label={`${label}
|
|
307
|
+
aria-label={`${label} ${t("sidebar.orgSharedOnly")}`}
|
|
304
308
|
/>
|
|
305
309
|
</label>
|
|
306
310
|
{onShowHiddenChange && showHidden !== undefined && (
|
|
@@ -308,12 +312,14 @@ function SidebarSectionSettingsPopover({
|
|
|
308
312
|
htmlFor={`${label.toLowerCase()}-hidden-filter`}
|
|
309
313
|
className="flex items-center justify-between gap-3 rounded-md px-2 py-1.5 text-xs text-foreground hover:bg-sidebar-accent/60"
|
|
310
314
|
>
|
|
311
|
-
<span className="min-w-0 truncate">
|
|
315
|
+
<span className="min-w-0 truncate">
|
|
316
|
+
{t("sidebar.hiddenAnalyses")}
|
|
317
|
+
</span>
|
|
312
318
|
<Switch
|
|
313
319
|
id={`${label.toLowerCase()}-hidden-filter`}
|
|
314
320
|
checked={showHidden}
|
|
315
321
|
onCheckedChange={onShowHiddenChange}
|
|
316
|
-
aria-label={`${label}
|
|
322
|
+
aria-label={`${label} ${t("sidebar.hiddenAnalyses")}`}
|
|
317
323
|
/>
|
|
318
324
|
</label>
|
|
319
325
|
)}
|
|
@@ -370,6 +376,7 @@ function SortableRow({
|
|
|
370
376
|
onSetVisibility?: (visibility: Visibility) => Promise<void> | void;
|
|
371
377
|
children?: React.ReactNode;
|
|
372
378
|
}) {
|
|
379
|
+
const t = useT();
|
|
373
380
|
const {
|
|
374
381
|
attributes,
|
|
375
382
|
listeners,
|
|
@@ -407,11 +414,14 @@ function SortableRow({
|
|
|
407
414
|
setRenameValue(name);
|
|
408
415
|
toast.error(
|
|
409
416
|
e instanceof Error
|
|
410
|
-
?
|
|
411
|
-
|
|
417
|
+
? t("sidebar.renameFailedWithMessage", {
|
|
418
|
+
name,
|
|
419
|
+
message: e.message,
|
|
420
|
+
})
|
|
421
|
+
: t("sidebar.renameFailed", { name }),
|
|
412
422
|
);
|
|
413
423
|
}
|
|
414
|
-
}, [name, onRename, renameValue]);
|
|
424
|
+
}, [name, onRename, renameValue, t]);
|
|
415
425
|
|
|
416
426
|
const runDelete = useCallback(async () => {
|
|
417
427
|
setMenuOpen(false);
|
|
@@ -421,11 +431,14 @@ function SortableRow({
|
|
|
421
431
|
} catch (e) {
|
|
422
432
|
toast.error(
|
|
423
433
|
e instanceof Error
|
|
424
|
-
?
|
|
425
|
-
|
|
434
|
+
? t("sidebar.deleteFailedWithMessage", {
|
|
435
|
+
name,
|
|
436
|
+
message: e.message,
|
|
437
|
+
})
|
|
438
|
+
: t("sidebar.deleteFailed", { name }),
|
|
426
439
|
);
|
|
427
440
|
}
|
|
428
|
-
}, [name, onDelete]);
|
|
441
|
+
}, [name, onDelete, t]);
|
|
429
442
|
|
|
430
443
|
const runArchive = useCallback(async () => {
|
|
431
444
|
setMenuOpen(false);
|
|
@@ -435,11 +448,14 @@ function SortableRow({
|
|
|
435
448
|
} catch (e) {
|
|
436
449
|
toast.error(
|
|
437
450
|
e instanceof Error
|
|
438
|
-
?
|
|
439
|
-
|
|
451
|
+
? t("sidebar.archiveFailedWithMessage", {
|
|
452
|
+
name,
|
|
453
|
+
message: e.message,
|
|
454
|
+
})
|
|
455
|
+
: t("sidebar.archiveFailed", { name }),
|
|
440
456
|
);
|
|
441
457
|
}
|
|
442
|
-
}, [name, onArchive]);
|
|
458
|
+
}, [name, onArchive, t]);
|
|
443
459
|
|
|
444
460
|
const runHide = useCallback(async () => {
|
|
445
461
|
setMenuOpen(false);
|
|
@@ -449,11 +465,14 @@ function SortableRow({
|
|
|
449
465
|
} catch (e) {
|
|
450
466
|
toast.error(
|
|
451
467
|
e instanceof Error
|
|
452
|
-
?
|
|
453
|
-
|
|
468
|
+
? t("sidebar.hideFailedWithMessage", {
|
|
469
|
+
name,
|
|
470
|
+
message: e.message,
|
|
471
|
+
})
|
|
472
|
+
: t("sidebar.hideFailed", { name }),
|
|
454
473
|
);
|
|
455
474
|
}
|
|
456
|
-
}, [name, onHide]);
|
|
475
|
+
}, [name, onHide, t]);
|
|
457
476
|
|
|
458
477
|
const runUnhide = useCallback(async () => {
|
|
459
478
|
setMenuOpen(false);
|
|
@@ -463,11 +482,14 @@ function SortableRow({
|
|
|
463
482
|
} catch (e) {
|
|
464
483
|
toast.error(
|
|
465
484
|
e instanceof Error
|
|
466
|
-
?
|
|
467
|
-
|
|
485
|
+
? t("sidebar.unhideFailedWithMessage", {
|
|
486
|
+
name,
|
|
487
|
+
message: e.message,
|
|
488
|
+
})
|
|
489
|
+
: t("sidebar.unhideFailed", { name }),
|
|
468
490
|
);
|
|
469
491
|
}
|
|
470
|
-
}, [name, onUnhide]);
|
|
492
|
+
}, [name, onUnhide, t]);
|
|
471
493
|
|
|
472
494
|
const runSetVisibility = useCallback(
|
|
473
495
|
async (visibility: Visibility) => {
|
|
@@ -478,29 +500,31 @@ function SortableRow({
|
|
|
478
500
|
} catch (e) {
|
|
479
501
|
toast.error(
|
|
480
502
|
e instanceof Error
|
|
481
|
-
?
|
|
482
|
-
|
|
503
|
+
? t("sidebar.updateVisibilityFailedWithMessage", {
|
|
504
|
+
message: e.message,
|
|
505
|
+
})
|
|
506
|
+
: t("sidebar.updateVisibilityFailed"),
|
|
483
507
|
);
|
|
484
508
|
}
|
|
485
509
|
},
|
|
486
|
-
[onSetVisibility],
|
|
510
|
+
[onSetVisibility, t],
|
|
487
511
|
);
|
|
488
512
|
|
|
489
513
|
const copyLink = useCallback(() => {
|
|
490
514
|
const url = window.location.origin + href;
|
|
491
515
|
navigator.clipboard.writeText(url).then(
|
|
492
|
-
() => toast.success("
|
|
493
|
-
() => toast.error(
|
|
516
|
+
() => toast.success(t("sidebar.linkCopied")),
|
|
517
|
+
() => toast.error(t("sidebar.copyLinkFailed")),
|
|
494
518
|
);
|
|
495
519
|
setMenuOpen(false);
|
|
496
|
-
}, [href]);
|
|
520
|
+
}, [href, t]);
|
|
497
521
|
|
|
498
522
|
return (
|
|
499
523
|
<div ref={setNodeRef} style={style} className="group/item relative min-w-0">
|
|
500
524
|
<button
|
|
501
525
|
type="button"
|
|
502
526
|
className="absolute -start-4 top-1/2 z-10 -translate-y-1/2 cursor-grab rounded p-1 text-muted-foreground/30 opacity-0 transition-colors hover:text-muted-foreground/60 group-hover/item:opacity-100 active:cursor-grabbing"
|
|
503
|
-
aria-label={
|
|
527
|
+
aria-label={t("sidebar.dragItem", { name })}
|
|
504
528
|
{...attributes}
|
|
505
529
|
{...listeners}
|
|
506
530
|
>
|
|
@@ -557,13 +581,15 @@ function SortableRow({
|
|
|
557
581
|
? "text-yellow-500"
|
|
558
582
|
: "text-muted-foreground/50 hover:text-yellow-500",
|
|
559
583
|
)}
|
|
560
|
-
aria-label={
|
|
584
|
+
aria-label={
|
|
585
|
+
isFav ? t("sidebar.unfavorite") : t("sidebar.favorite")
|
|
586
|
+
}
|
|
561
587
|
>
|
|
562
588
|
<IconStar className={cn("h-3 w-3", isFav && "fill-current")} />
|
|
563
589
|
</button>
|
|
564
590
|
</TooltipTrigger>
|
|
565
591
|
<TooltipContent side="right">
|
|
566
|
-
{isFav ? "
|
|
592
|
+
{isFav ? t("sidebar.unfavorite") : t("sidebar.favorite")}
|
|
567
593
|
</TooltipContent>
|
|
568
594
|
</Tooltip>
|
|
569
595
|
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
|
|
@@ -573,13 +599,15 @@ function SortableRow({
|
|
|
573
599
|
<button
|
|
574
600
|
type="button"
|
|
575
601
|
className="pointer-events-auto rounded p-0.5 text-muted-foreground/50 transition-colors hover:text-foreground"
|
|
576
|
-
aria-label={
|
|
602
|
+
aria-label={t("sidebar.itemActions", { name })}
|
|
577
603
|
>
|
|
578
604
|
<IconDots className="h-3 w-3" />
|
|
579
605
|
</button>
|
|
580
606
|
</DropdownMenuTrigger>
|
|
581
607
|
</TooltipTrigger>
|
|
582
|
-
<TooltipContent side="right">
|
|
608
|
+
<TooltipContent side="right">
|
|
609
|
+
{t("sidebar.itemActions", { name })}
|
|
610
|
+
</TooltipContent>
|
|
583
611
|
</Tooltip>
|
|
584
612
|
<DropdownMenuContent side="right" align="start" className="w-44">
|
|
585
613
|
<DropdownMenuItem
|
|
@@ -589,7 +617,7 @@ function SortableRow({
|
|
|
589
617
|
}}
|
|
590
618
|
>
|
|
591
619
|
<IconPencil className="me-2 h-3.5 w-3.5" />
|
|
592
|
-
|
|
620
|
+
{t("sidebar.rename")}
|
|
593
621
|
</DropdownMenuItem>
|
|
594
622
|
{onSetVisibility && visibility !== undefined && (
|
|
595
623
|
<DropdownMenuItem
|
|
@@ -605,12 +633,14 @@ function SortableRow({
|
|
|
605
633
|
) : (
|
|
606
634
|
<IconLock className="me-2 h-3.5 w-3.5" />
|
|
607
635
|
)}
|
|
608
|
-
{visibility === "private"
|
|
636
|
+
{visibility === "private"
|
|
637
|
+
? t("sidebar.shareWithOrg")
|
|
638
|
+
: t("sidebar.makePrivate")}
|
|
609
639
|
</DropdownMenuItem>
|
|
610
640
|
)}
|
|
611
641
|
<DropdownMenuItem onSelect={copyLink}>
|
|
612
642
|
<IconLink className="me-2 h-3.5 w-3.5" />
|
|
613
|
-
|
|
643
|
+
{t("sidebar.copyLink")}
|
|
614
644
|
</DropdownMenuItem>
|
|
615
645
|
{onUnhide && hidden ? (
|
|
616
646
|
<DropdownMenuItem
|
|
@@ -620,7 +650,7 @@ function SortableRow({
|
|
|
620
650
|
}}
|
|
621
651
|
>
|
|
622
652
|
<IconEye className="me-2 h-3.5 w-3.5" />
|
|
623
|
-
|
|
653
|
+
{t("sidebar.unhide")}
|
|
624
654
|
</DropdownMenuItem>
|
|
625
655
|
) : onHide ? (
|
|
626
656
|
<DropdownMenuItem
|
|
@@ -630,7 +660,7 @@ function SortableRow({
|
|
|
630
660
|
}}
|
|
631
661
|
>
|
|
632
662
|
<IconEyeOff className="me-2 h-3.5 w-3.5" />
|
|
633
|
-
|
|
663
|
+
{t("sidebar.hide")}
|
|
634
664
|
</DropdownMenuItem>
|
|
635
665
|
) : null}
|
|
636
666
|
<DropdownMenuSeparator />
|
|
@@ -643,7 +673,7 @@ function SortableRow({
|
|
|
643
673
|
}}
|
|
644
674
|
>
|
|
645
675
|
<IconArchive className="me-2 h-3.5 w-3.5" />
|
|
646
|
-
|
|
676
|
+
{t("sidebar.archive")}
|
|
647
677
|
</DropdownMenuItem>
|
|
648
678
|
<DropdownMenuSeparator />
|
|
649
679
|
<DropdownMenuItem
|
|
@@ -655,7 +685,7 @@ function SortableRow({
|
|
|
655
685
|
className="text-destructive focus:text-destructive"
|
|
656
686
|
>
|
|
657
687
|
<IconTrash className="me-2 h-3.5 w-3.5" />
|
|
658
|
-
|
|
688
|
+
{t("sidebar.deletePermanently")}
|
|
659
689
|
</DropdownMenuItem>
|
|
660
690
|
</>
|
|
661
691
|
) : (
|
|
@@ -668,7 +698,7 @@ function SortableRow({
|
|
|
668
698
|
className="text-destructive focus:text-destructive"
|
|
669
699
|
>
|
|
670
700
|
<IconTrash className="me-2 h-3.5 w-3.5" />
|
|
671
|
-
|
|
701
|
+
{t("sidebar.delete")}
|
|
672
702
|
</DropdownMenuItem>
|
|
673
703
|
)}
|
|
674
704
|
</DropdownMenuContent>
|
|
@@ -679,22 +709,21 @@ function SortableRow({
|
|
|
679
709
|
<AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
|
|
680
710
|
<AlertDialogContent>
|
|
681
711
|
<AlertDialogHeader>
|
|
682
|
-
<AlertDialogTitle>
|
|
712
|
+
<AlertDialogTitle>
|
|
713
|
+
{t("sidebar.deletePermanentlyTitle")}
|
|
714
|
+
</AlertDialogTitle>
|
|
683
715
|
<AlertDialogDescription>
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
{onArchive
|
|
687
|
-
? " To keep it recoverable, choose Archive instead."
|
|
688
|
-
: ""}
|
|
716
|
+
{t("sidebar.deletePermanentlyDescription", { name })}
|
|
717
|
+
{onArchive ? t("sidebar.deletePermanentlyArchiveHint") : ""}
|
|
689
718
|
</AlertDialogDescription>
|
|
690
719
|
</AlertDialogHeader>
|
|
691
720
|
<AlertDialogFooter>
|
|
692
|
-
<AlertDialogCancel>
|
|
721
|
+
<AlertDialogCancel>{t("sidebar.cancel")}</AlertDialogCancel>
|
|
693
722
|
<AlertDialogAction
|
|
694
723
|
onClick={() => void runDelete()}
|
|
695
724
|
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
696
725
|
>
|
|
697
|
-
|
|
726
|
+
{t("sidebar.deletePermanently")}
|
|
698
727
|
</AlertDialogAction>
|
|
699
728
|
</AlertDialogFooter>
|
|
700
729
|
</AlertDialogContent>
|
|
@@ -734,6 +763,7 @@ function SortableDashboardItem({
|
|
|
734
763
|
) => Promise<void>;
|
|
735
764
|
}) {
|
|
736
765
|
const href = `/dashboards/${d.id}`;
|
|
766
|
+
const t = useT();
|
|
737
767
|
const { mutateAsync: deleteView } = useDeleteDashboardView();
|
|
738
768
|
const [deletingViewId, setDeletingViewId] = useState<string | null>(null);
|
|
739
769
|
|
|
@@ -845,8 +875,8 @@ function SortableDashboardItem({
|
|
|
845
875
|
</TooltipTrigger>
|
|
846
876
|
<TooltipContent side="right">
|
|
847
877
|
{favoriteIds.has(`view:${d.id}:${sv.id}`)
|
|
848
|
-
? "
|
|
849
|
-
: "
|
|
878
|
+
? t("sidebar.unfavorite")
|
|
879
|
+
: t("sidebar.favorite")}
|
|
850
880
|
</TooltipContent>
|
|
851
881
|
</Tooltip>
|
|
852
882
|
<Popover
|
|
@@ -863,7 +893,9 @@ function SortableDashboardItem({
|
|
|
863
893
|
</button>
|
|
864
894
|
</PopoverTrigger>
|
|
865
895
|
</TooltipTrigger>
|
|
866
|
-
<TooltipContent side="right">
|
|
896
|
+
<TooltipContent side="right">
|
|
897
|
+
{t("sidebar.deleteView", { name: sv.name })}
|
|
898
|
+
</TooltipContent>
|
|
867
899
|
</Tooltip>
|
|
868
900
|
<PopoverContent
|
|
869
901
|
className="w-56 p-3"
|
|
@@ -871,7 +903,7 @@ function SortableDashboardItem({
|
|
|
871
903
|
align="start"
|
|
872
904
|
>
|
|
873
905
|
<p className="text-sm mb-3">
|
|
874
|
-
|
|
906
|
+
{t("sidebar.deleteView", { name: sv.name })}
|
|
875
907
|
</p>
|
|
876
908
|
<div className="flex gap-2">
|
|
877
909
|
<button
|
|
@@ -888,8 +920,10 @@ function SortableDashboardItem({
|
|
|
888
920
|
setDeletingViewId(sv.id);
|
|
889
921
|
toast.error(
|
|
890
922
|
err instanceof Error
|
|
891
|
-
?
|
|
892
|
-
|
|
923
|
+
? t("sidebar.deleteViewFailedWithMessage", {
|
|
924
|
+
message: err.message,
|
|
925
|
+
})
|
|
926
|
+
: t("sidebar.deleteViewFailed"),
|
|
893
927
|
);
|
|
894
928
|
}
|
|
895
929
|
}}
|
|
@@ -898,14 +932,16 @@ function SortableDashboardItem({
|
|
|
898
932
|
{isDeleting && (
|
|
899
933
|
<IconLoader2 className="h-3 w-3 animate-spin" />
|
|
900
934
|
)}
|
|
901
|
-
{isDeleting
|
|
935
|
+
{isDeleting
|
|
936
|
+
? t("sidebar.deleting")
|
|
937
|
+
: t("sidebar.delete")}
|
|
902
938
|
</button>
|
|
903
939
|
<button
|
|
904
940
|
disabled={isDeleting}
|
|
905
941
|
onClick={() => setDeletingViewId(null)}
|
|
906
942
|
className="flex-1 rounded-md border border-border px-3 py-1.5 text-xs font-medium hover:bg-sidebar-accent/50 transition-colors disabled:opacity-60"
|
|
907
943
|
>
|
|
908
|
-
|
|
944
|
+
{t("sidebar.cancel")}
|
|
909
945
|
</button>
|
|
910
946
|
</div>
|
|
911
947
|
</PopoverContent>
|
|
@@ -990,7 +1026,9 @@ type SqlDashboardListItem = {
|
|
|
990
1026
|
visibility?: Visibility;
|
|
991
1027
|
};
|
|
992
1028
|
|
|
993
|
-
async function fetchSqlDashboards(
|
|
1029
|
+
async function fetchSqlDashboards(
|
|
1030
|
+
t: (key: string) => string,
|
|
1031
|
+
): Promise<SqlDashboardListItem[]> {
|
|
994
1032
|
try {
|
|
995
1033
|
const rows = await callAction("list-sql-dashboards", {}, { method: "GET" });
|
|
996
1034
|
return (Array.isArray(rows) ? rows : [])
|
|
@@ -1000,7 +1038,7 @@ async function fetchSqlDashboards(): Promise<SqlDashboardListItem[]> {
|
|
|
1000
1038
|
name:
|
|
1001
1039
|
typeof d.name === "string" && d.name.trim().length > 0
|
|
1002
1040
|
? d.name
|
|
1003
|
-
: "
|
|
1041
|
+
: t("sidebar.untitledDashboard"),
|
|
1004
1042
|
visibility:
|
|
1005
1043
|
d.visibility === "org" || d.visibility === "public"
|
|
1006
1044
|
? (d.visibility as Visibility)
|
|
@@ -1012,6 +1050,7 @@ async function fetchSqlDashboards(): Promise<SqlDashboardListItem[]> {
|
|
|
1012
1050
|
}
|
|
1013
1051
|
|
|
1014
1052
|
async function fetchSidebarAnalyses(
|
|
1053
|
+
t: (key: string) => string,
|
|
1015
1054
|
hidden: AnalysisHiddenFilter = "visible",
|
|
1016
1055
|
): Promise<
|
|
1017
1056
|
{
|
|
@@ -1036,7 +1075,7 @@ async function fetchSidebarAnalyses(
|
|
|
1036
1075
|
name:
|
|
1037
1076
|
typeof a.name === "string" && a.name.trim().length > 0
|
|
1038
1077
|
? a.name
|
|
1039
|
-
: "
|
|
1078
|
+
: t("sidebar.untitledAnalysis"),
|
|
1040
1079
|
visibility:
|
|
1041
1080
|
a.visibility === "org" || a.visibility === "public"
|
|
1042
1081
|
? a.visibility
|
|
@@ -1068,6 +1107,7 @@ type PrefetchedSqlDashboard = {
|
|
|
1068
1107
|
|
|
1069
1108
|
async function fetchSqlDashboardForPrefetch(
|
|
1070
1109
|
id: string,
|
|
1110
|
+
t: (key: string) => string,
|
|
1071
1111
|
): Promise<PrefetchedSqlDashboard | null> {
|
|
1072
1112
|
try {
|
|
1073
1113
|
const data: any = await callAction(
|
|
@@ -1082,7 +1122,7 @@ async function fetchSqlDashboardForPrefetch(
|
|
|
1082
1122
|
name:
|
|
1083
1123
|
typeof data.name === "string" && data.name.trim().length > 0
|
|
1084
1124
|
? data.name
|
|
1085
|
-
: "
|
|
1125
|
+
: t("sidebar.untitledDashboard"),
|
|
1086
1126
|
description: data.description,
|
|
1087
1127
|
filters: data.filters,
|
|
1088
1128
|
variables: data.variables,
|
|
@@ -1282,14 +1322,14 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1282
1322
|
const { data: sqlDashboards = [], isLoading: sqlDashboardsLoading } =
|
|
1283
1323
|
useQuery({
|
|
1284
1324
|
queryKey: ["sql-dashboards-sidebar", dashboardsSync],
|
|
1285
|
-
queryFn: fetchSqlDashboards,
|
|
1325
|
+
queryFn: () => fetchSqlDashboards(t),
|
|
1286
1326
|
staleTime: 30_000,
|
|
1287
1327
|
placeholderData: (prev) => prev,
|
|
1288
1328
|
});
|
|
1289
1329
|
|
|
1290
1330
|
const { data: analysesList = [], isLoading: analysesLoading } = useQuery({
|
|
1291
1331
|
queryKey: ["analyses-sidebar", analysesSync, analysisHiddenFilter],
|
|
1292
|
-
queryFn: () => fetchSidebarAnalyses(analysisHiddenFilter),
|
|
1332
|
+
queryFn: () => fetchSidebarAnalyses(t, analysisHiddenFilter),
|
|
1293
1333
|
staleTime: 30_000,
|
|
1294
1334
|
placeholderData: (prev) => prev,
|
|
1295
1335
|
});
|
|
@@ -1365,13 +1405,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1365
1405
|
void queryClient.prefetchQuery({
|
|
1366
1406
|
queryKey,
|
|
1367
1407
|
queryFn: async () => ({
|
|
1368
|
-
data: await fetchSqlDashboardForPrefetch(d.id),
|
|
1408
|
+
data: await fetchSqlDashboardForPrefetch(d.id, t),
|
|
1369
1409
|
syncVersion: dashboardsSync,
|
|
1370
1410
|
}),
|
|
1371
1411
|
staleTime: cached?.syncVersion === dashboardsSync ? 30_000 : 0,
|
|
1372
1412
|
});
|
|
1373
1413
|
},
|
|
1374
|
-
[dashboardsSync, queryClient],
|
|
1414
|
+
[dashboardsSync, queryClient, t],
|
|
1375
1415
|
);
|
|
1376
1416
|
|
|
1377
1417
|
const prefetchAnalysis = useCallback(
|
|
@@ -1504,13 +1544,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1504
1544
|
await archiveDashboardMut({ id: d.id, archived: true });
|
|
1505
1545
|
queryClient.removeQueries({ queryKey: sqlDashboardPrefetchKey(d.id) });
|
|
1506
1546
|
queryClient.invalidateQueries({ queryKey: activeKey });
|
|
1507
|
-
toast.success(
|
|
1547
|
+
toast.success(t("sidebar.archivedName", { name: d.name }));
|
|
1508
1548
|
} catch (err) {
|
|
1509
1549
|
restoreQuerySnapshots(queryClient, prevActive);
|
|
1510
1550
|
throw err;
|
|
1511
1551
|
}
|
|
1512
1552
|
},
|
|
1513
|
-
[queryClient, archiveDashboardMut],
|
|
1553
|
+
[queryClient, archiveDashboardMut, t],
|
|
1514
1554
|
);
|
|
1515
1555
|
|
|
1516
1556
|
const handleDashboardRename = useCallback(
|
|
@@ -1603,15 +1643,15 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1603
1643
|
queryClient.invalidateQueries({ queryKey });
|
|
1604
1644
|
toast.success(
|
|
1605
1645
|
visibility === "org"
|
|
1606
|
-
?
|
|
1607
|
-
:
|
|
1646
|
+
? t("sidebar.nameSharedWithOrg", { name: d.name })
|
|
1647
|
+
: t("sidebar.nameMadePrivate", { name: d.name }),
|
|
1608
1648
|
);
|
|
1609
1649
|
} catch (err) {
|
|
1610
1650
|
restoreQuerySnapshots(queryClient, prev);
|
|
1611
1651
|
throw err;
|
|
1612
1652
|
}
|
|
1613
1653
|
},
|
|
1614
|
-
[queryClient, setResourceVisibility],
|
|
1654
|
+
[queryClient, setResourceVisibility, t],
|
|
1615
1655
|
);
|
|
1616
1656
|
|
|
1617
1657
|
const handleAnalysisSetVisibility = useCallback(
|
|
@@ -1644,8 +1684,8 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1644
1684
|
queryClient.invalidateQueries({ queryKey: listKey });
|
|
1645
1685
|
toast.success(
|
|
1646
1686
|
visibility === "org"
|
|
1647
|
-
?
|
|
1648
|
-
:
|
|
1687
|
+
? t("sidebar.nameSharedWithOrg", { name: a.name })
|
|
1688
|
+
: t("sidebar.nameMadePrivate", { name: a.name }),
|
|
1649
1689
|
);
|
|
1650
1690
|
} catch (err) {
|
|
1651
1691
|
restoreQuerySnapshots(queryClient, prevSidebar);
|
|
@@ -1653,7 +1693,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1653
1693
|
throw err;
|
|
1654
1694
|
}
|
|
1655
1695
|
},
|
|
1656
|
-
[queryClient, setResourceVisibility],
|
|
1696
|
+
[queryClient, setResourceVisibility, t],
|
|
1657
1697
|
);
|
|
1658
1698
|
|
|
1659
1699
|
const handleAnalysisRename = useCallback(
|
|
@@ -1719,13 +1759,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1719
1759
|
await hideAnalysisMut({ id: a.id, hidden: true });
|
|
1720
1760
|
queryClient.invalidateQueries({ queryKey: sidebarKey });
|
|
1721
1761
|
queryClient.invalidateQueries({ queryKey: ["analyses-list"] });
|
|
1722
|
-
toast.success(
|
|
1762
|
+
toast.success(t("sidebar.nameHidden", { name: a.name }));
|
|
1723
1763
|
} catch (err) {
|
|
1724
1764
|
restoreQuerySnapshots(queryClient, prev);
|
|
1725
1765
|
throw err;
|
|
1726
1766
|
}
|
|
1727
1767
|
},
|
|
1728
|
-
[queryClient, hideAnalysisMut],
|
|
1768
|
+
[queryClient, hideAnalysisMut, t],
|
|
1729
1769
|
);
|
|
1730
1770
|
|
|
1731
1771
|
const handleAnalysisUnhide = useCallback(
|
|
@@ -1742,13 +1782,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1742
1782
|
await hideAnalysisMut({ id: a.id, hidden: false });
|
|
1743
1783
|
queryClient.invalidateQueries({ queryKey: sidebarKey });
|
|
1744
1784
|
queryClient.invalidateQueries({ queryKey: ["analyses-list"] });
|
|
1745
|
-
toast.success(
|
|
1785
|
+
toast.success(t("sidebar.nameUnhidden", { name: a.name }));
|
|
1746
1786
|
} catch (err) {
|
|
1747
1787
|
restoreQuerySnapshots(queryClient, prev);
|
|
1748
1788
|
throw err;
|
|
1749
1789
|
}
|
|
1750
1790
|
},
|
|
1751
|
-
[queryClient, hideAnalysisMut],
|
|
1791
|
+
[queryClient, hideAnalysisMut, t],
|
|
1752
1792
|
);
|
|
1753
1793
|
|
|
1754
1794
|
const sensors = useSensors(
|
|
@@ -1859,7 +1899,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1859
1899
|
aria-hidden="true"
|
|
1860
1900
|
className="hidden h-5 w-auto shrink-0 dark:block"
|
|
1861
1901
|
/>
|
|
1862
|
-
<span className="text-lg font-bold tracking-tight">
|
|
1902
|
+
<span className="text-lg font-bold tracking-tight">
|
|
1903
|
+
{t("navigation.brand")}
|
|
1904
|
+
</span>
|
|
1863
1905
|
</Link>
|
|
1864
1906
|
</div>
|
|
1865
1907
|
<div className="flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden py-2">
|
|
@@ -1887,7 +1929,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1887
1929
|
)}
|
|
1888
1930
|
>
|
|
1889
1931
|
<IconMessageCircle className="h-4 w-4" />
|
|
1890
|
-
|
|
1932
|
+
{t("navigation.ask")}
|
|
1891
1933
|
</Link>
|
|
1892
1934
|
|
|
1893
1935
|
{/* Overview link */}
|
|
@@ -1901,7 +1943,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1901
1943
|
)}
|
|
1902
1944
|
>
|
|
1903
1945
|
<IconHome className="h-4 w-4" />
|
|
1904
|
-
|
|
1946
|
+
{t("navigation.overview")}
|
|
1905
1947
|
</Link>
|
|
1906
1948
|
|
|
1907
1949
|
{/* Data Sources link */}
|
|
@@ -1915,7 +1957,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1915
1957
|
)}
|
|
1916
1958
|
>
|
|
1917
1959
|
<IconDatabase className="h-4 w-4" />
|
|
1918
|
-
|
|
1960
|
+
{t("navigation.dataSources")}
|
|
1919
1961
|
</Link>
|
|
1920
1962
|
|
|
1921
1963
|
{/* Data Dictionary link */}
|
|
@@ -1929,7 +1971,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1929
1971
|
)}
|
|
1930
1972
|
>
|
|
1931
1973
|
<IconBook2 className="h-4 w-4" />
|
|
1932
|
-
|
|
1974
|
+
{t("navigation.dataDictionary")}
|
|
1933
1975
|
</Link>
|
|
1934
1976
|
|
|
1935
1977
|
{/* Catalog link */}
|
|
@@ -1943,7 +1985,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1943
1985
|
)}
|
|
1944
1986
|
>
|
|
1945
1987
|
<IconTemplate className="h-4 w-4" />
|
|
1946
|
-
|
|
1988
|
+
{t("navigation.templateCatalog")}
|
|
1947
1989
|
</Link>
|
|
1948
1990
|
|
|
1949
1991
|
{/* Dashboards section */}
|
|
@@ -1963,10 +2005,12 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1963
2005
|
aria-expanded={dashOpen}
|
|
1964
2006
|
>
|
|
1965
2007
|
<IconChartBar className="h-4 w-4 shrink-0" />
|
|
1966
|
-
<span className="min-w-0 flex-1 truncate">
|
|
2008
|
+
<span className="min-w-0 flex-1 truncate">
|
|
2009
|
+
{t("navigation.dashboards")}
|
|
2010
|
+
</span>
|
|
1967
2011
|
</button>
|
|
1968
2012
|
<SidebarSectionSettingsPopover
|
|
1969
|
-
label="
|
|
2013
|
+
label={t("navigation.dashboards")}
|
|
1970
2014
|
sortMode={dashboardSortMode}
|
|
1971
2015
|
onSortModeChange={setDashboardSortMode}
|
|
1972
2016
|
sharedOnly={dashFilter === "org"}
|
|
@@ -1979,7 +2023,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1979
2023
|
onClick={toggleDashOpen}
|
|
1980
2024
|
className="me-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
|
|
1981
2025
|
aria-label={
|
|
1982
|
-
dashOpen
|
|
2026
|
+
dashOpen
|
|
2027
|
+
? t("sidebar.collapseDashboards")
|
|
2028
|
+
: t("sidebar.expandDashboards")
|
|
1983
2029
|
}
|
|
1984
2030
|
>
|
|
1985
2031
|
<IconChevronDown
|
|
@@ -2024,8 +2070,12 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2024
2070
|
className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
|
|
2025
2071
|
>
|
|
2026
2072
|
{dashShowAll
|
|
2027
|
-
? "
|
|
2028
|
-
:
|
|
2073
|
+
? t("sidebar.showLess")
|
|
2074
|
+
: t("sidebar.showMore", {
|
|
2075
|
+
count:
|
|
2076
|
+
filteredDashboards.length -
|
|
2077
|
+
SIDEBAR_PREVIEW_COUNT,
|
|
2078
|
+
})}
|
|
2029
2079
|
</button>
|
|
2030
2080
|
)}
|
|
2031
2081
|
{sqlDashboardsLoading &&
|
|
@@ -2066,10 +2116,12 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2066
2116
|
aria-expanded={analysesOpen}
|
|
2067
2117
|
>
|
|
2068
2118
|
<IconReportAnalytics className="h-4 w-4 shrink-0" />
|
|
2069
|
-
<span className="min-w-0 flex-1 truncate">
|
|
2119
|
+
<span className="min-w-0 flex-1 truncate">
|
|
2120
|
+
{t("navigation.analyses")}
|
|
2121
|
+
</span>
|
|
2070
2122
|
</button>
|
|
2071
2123
|
<SidebarSectionSettingsPopover
|
|
2072
|
-
label="
|
|
2124
|
+
label={t("navigation.analyses")}
|
|
2073
2125
|
sortMode={analysisSortMode}
|
|
2074
2126
|
onSortModeChange={setAnalysisSortMode}
|
|
2075
2127
|
sharedOnly={analysisFilter === "org"}
|
|
@@ -2086,7 +2138,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2086
2138
|
onClick={toggleAnalysesOpen}
|
|
2087
2139
|
className="me-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
|
|
2088
2140
|
aria-label={
|
|
2089
|
-
analysesOpen
|
|
2141
|
+
analysesOpen
|
|
2142
|
+
? t("sidebar.collapseAnalyses")
|
|
2143
|
+
: t("sidebar.expandAnalyses")
|
|
2090
2144
|
}
|
|
2091
2145
|
>
|
|
2092
2146
|
<IconChevronDown
|
|
@@ -2145,8 +2199,11 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2145
2199
|
className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
|
|
2146
2200
|
>
|
|
2147
2201
|
{analysesShowAll
|
|
2148
|
-
? "
|
|
2149
|
-
:
|
|
2202
|
+
? t("sidebar.showLess")
|
|
2203
|
+
: t("sidebar.showMore", {
|
|
2204
|
+
count:
|
|
2205
|
+
filteredAnalyses.length - SIDEBAR_PREVIEW_COUNT,
|
|
2206
|
+
})}
|
|
2150
2207
|
</button>
|
|
2151
2208
|
)}
|
|
2152
2209
|
{analysesLoading &&
|
|
@@ -2165,7 +2222,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2165
2222
|
))}
|
|
2166
2223
|
{!analysesLoading && sortedAnalyses.length === 0 && (
|
|
2167
2224
|
<p className="px-3 py-1 text-[11px] text-muted-foreground/60">
|
|
2168
|
-
|
|
2225
|
+
{t("sidebar.noAnalysesYet")}
|
|
2169
2226
|
</p>
|
|
2170
2227
|
)}
|
|
2171
2228
|
<NewAnalysisDialog />
|
|
@@ -2218,14 +2275,18 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2218
2275
|
new CustomEvent("analytics:open-command-palette"),
|
|
2219
2276
|
)
|
|
2220
2277
|
}
|
|
2221
|
-
aria-label="
|
|
2278
|
+
aria-label={t("sidebar.search")}
|
|
2222
2279
|
className="flex items-center justify-center rounded-lg p-2 text-muted-foreground transition-all hover:text-primary cursor-pointer hover:bg-sidebar-accent/50"
|
|
2223
2280
|
>
|
|
2224
2281
|
<IconSearch className="h-4 w-4" />
|
|
2225
2282
|
</button>
|
|
2226
2283
|
</TooltipTrigger>
|
|
2227
2284
|
<TooltipContent side="top">
|
|
2228
|
-
<p>
|
|
2285
|
+
<p>
|
|
2286
|
+
{t("sidebar.searchShortcut", {
|
|
2287
|
+
shortcut: `${shortcutModifierLabel()}+K`,
|
|
2288
|
+
})}
|
|
2289
|
+
</p>
|
|
2229
2290
|
</TooltipContent>
|
|
2230
2291
|
</Tooltip>
|
|
2231
2292
|
<Popover open={logoutOpen} onOpenChange={setLogoutOpen}>
|
|
@@ -2238,7 +2299,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2238
2299
|
</PopoverTrigger>
|
|
2239
2300
|
</TooltipTrigger>
|
|
2240
2301
|
<TooltipContent side="top">
|
|
2241
|
-
<p>
|
|
2302
|
+
<p>{t("sidebar.signOut")}</p>
|
|
2242
2303
|
</TooltipContent>
|
|
2243
2304
|
</Tooltip>
|
|
2244
2305
|
<PopoverContent
|
|
@@ -2246,7 +2307,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2246
2307
|
side="top"
|
|
2247
2308
|
align="start"
|
|
2248
2309
|
>
|
|
2249
|
-
<p className="text-sm mb-3">
|
|
2310
|
+
<p className="text-sm mb-3">
|
|
2311
|
+
{t("sidebar.signOutTitle")}
|
|
2312
|
+
</p>
|
|
2250
2313
|
<div className="flex gap-2">
|
|
2251
2314
|
<button
|
|
2252
2315
|
onClick={() => {
|
|
@@ -2255,13 +2318,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2255
2318
|
}}
|
|
2256
2319
|
className="flex-1 rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground hover:bg-destructive/90 transition-colors"
|
|
2257
2320
|
>
|
|
2258
|
-
|
|
2321
|
+
{t("sidebar.yes")}
|
|
2259
2322
|
</button>
|
|
2260
2323
|
<button
|
|
2261
2324
|
onClick={() => setLogoutOpen(false)}
|
|
2262
2325
|
className="flex-1 rounded-md border border-border px-3 py-1.5 text-xs font-medium hover:bg-sidebar-accent/50 transition-colors"
|
|
2263
2326
|
>
|
|
2264
|
-
|
|
2327
|
+
{t("sidebar.cancel")}
|
|
2265
2328
|
</button>
|
|
2266
2329
|
</div>
|
|
2267
2330
|
</PopoverContent>
|
|
@@ -2284,7 +2347,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2284
2347
|
</button>
|
|
2285
2348
|
</TooltipTrigger>
|
|
2286
2349
|
<TooltipContent side="top">
|
|
2287
|
-
<p>
|
|
2350
|
+
<p>
|
|
2351
|
+
{light ? t("sidebar.darkMode") : t("sidebar.lightMode")}
|
|
2352
|
+
</p>
|
|
2288
2353
|
</TooltipContent>
|
|
2289
2354
|
</Tooltip>
|
|
2290
2355
|
</div>
|