@agent-native/core 0.76.9 → 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 +39 -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/scripts/generate-og-font-data.mjs +9 -5
- package/corpus/core/src/client/AgentPanel.tsx +70 -1
- package/corpus/core/src/client/AssistantChat.tsx +1 -3
- package/corpus/core/src/client/ErrorBoundary.tsx +151 -10
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +0 -62
- package/corpus/core/src/client/composer/TiptapComposer.tsx +6 -13
- package/corpus/core/src/server/og-fonts-data.ts +7 -4
- package/corpus/core/src/server/og-fonts.ts +10 -3
- package/corpus/core/src/server/social-og-image.ts +45 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +199 -19
- 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/app/pages/adhoc/AdhocRouter.tsx +1 -21
- package/corpus/templates/analytics/app/pages/adhoc/DashboardSkeleton.tsx +35 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +3 -26
- package/corpus/templates/analytics/changelog/2026-06-24-analytics-navigation-command-palette-and-settings-now-honor-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-daily-dashboard-charts-now-use-local-day-buckets-and-show-th.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-dashboard-loading-placeholders-now-span-the-available-page-w.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-first-party-dashboard-dates-now-align-to-pacific-time-for-da.md +6 -0
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +19 -7
- 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/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +23 -4
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +1 -3
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- 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/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -17
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +4 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +5 -9
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/server/og-fonts-data.d.ts +1 -0
- package/dist/server/og-fonts-data.d.ts.map +1 -1
- package/dist/server/og-fonts-data.js +5 -4
- package/dist/server/og-fonts-data.js.map +1 -1
- package/dist/server/og-fonts.d.ts +1 -0
- package/dist/server/og-fonts.d.ts.map +1 -1
- package/dist/server/og-fonts.js +10 -4
- package/dist/server/og-fonts.js.map +1 -1
- package/dist/server/social-og-image.d.ts.map +1 -1
- package/dist/server/social-og-image.js +33 -6
- package/dist/server/social-og-image.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
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
} from "@/hooks/use-emails";
|
|
37
37
|
import { useAliases } from "@/hooks/use-aliases";
|
|
38
38
|
import { expandAliasTokens } from "@/lib/alias-utils";
|
|
39
|
-
import { useAgentChatGenerating } from "@agent-native/core/client";
|
|
39
|
+
import { useAgentChatGenerating, useT } from "@agent-native/core/client";
|
|
40
40
|
import { toast } from "sonner";
|
|
41
41
|
import type { ComposeState, EmailMessage } from "@shared/types";
|
|
42
42
|
import {
|
|
@@ -89,6 +89,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
89
89
|
},
|
|
90
90
|
ref,
|
|
91
91
|
) {
|
|
92
|
+
const t = useT();
|
|
92
93
|
const [showQuoted, setShowQuoted] = useState(false);
|
|
93
94
|
const [generateOpen, setGenerateOpen] = useState(false);
|
|
94
95
|
const [generatePrompt, setGeneratePrompt] = useState("");
|
|
@@ -452,7 +453,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
452
453
|
<>
|
|
453
454
|
<div className="flex items-center justify-between px-4 pt-3 pb-1">
|
|
454
455
|
<span className="text-[13px] font-semibold text-green-400">
|
|
455
|
-
|
|
456
|
+
{t("mail.compose.forward")}
|
|
456
457
|
</span>
|
|
457
458
|
<Tooltip>
|
|
458
459
|
<TooltipTrigger asChild>
|
|
@@ -463,7 +464,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
463
464
|
<IconExternalLink className="h-3.5 w-3.5" />
|
|
464
465
|
</button>
|
|
465
466
|
</TooltipTrigger>
|
|
466
|
-
<TooltipContent>
|
|
467
|
+
<TooltipContent>{t("mail.compose.popOut")}</TooltipContent>
|
|
467
468
|
</Tooltip>
|
|
468
469
|
</div>
|
|
469
470
|
{recipientFields}
|
|
@@ -473,10 +474,10 @@ export const InlineReplyComposer = forwardRef<
|
|
|
473
474
|
<div className="flex items-center justify-between px-4 pt-3 pb-1">
|
|
474
475
|
<div className="flex items-center gap-1.5 min-w-0">
|
|
475
476
|
<span className="text-[13px] font-semibold text-green-400">
|
|
476
|
-
|
|
477
|
+
{t("mail.compose.reply")}
|
|
477
478
|
</span>
|
|
478
479
|
<span className="text-[13px] text-muted-foreground/70 truncate">
|
|
479
|
-
|
|
480
|
+
{t("mail.compose.replyTo", { recipient: recipientDisplay })}
|
|
480
481
|
</span>
|
|
481
482
|
</div>
|
|
482
483
|
<Tooltip>
|
|
@@ -488,7 +489,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
488
489
|
<IconExternalLink className="h-3.5 w-3.5" />
|
|
489
490
|
</button>
|
|
490
491
|
</TooltipTrigger>
|
|
491
|
-
<TooltipContent>
|
|
492
|
+
<TooltipContent>{t("mail.compose.popOut")}</TooltipContent>
|
|
492
493
|
</Tooltip>
|
|
493
494
|
</div>
|
|
494
495
|
{recipientFields}
|
|
@@ -540,7 +541,11 @@ export const InlineReplyComposer = forwardRef<
|
|
|
540
541
|
<>
|
|
541
542
|
<button
|
|
542
543
|
type="button"
|
|
543
|
-
aria-label={
|
|
544
|
+
aria-label={
|
|
545
|
+
showQuoted
|
|
546
|
+
? t("mail.thread.hideQuotedText")
|
|
547
|
+
: t("mail.thread.showQuotedText")
|
|
548
|
+
}
|
|
544
549
|
onClick={() => setShowQuoted(!showQuoted)}
|
|
545
550
|
className="mt-1 inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground/50 transition-colors hover:bg-accent hover:text-muted-foreground"
|
|
546
551
|
>
|
|
@@ -577,7 +582,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
577
582
|
<IconBold className="h-3.5 w-3.5" />
|
|
578
583
|
</Button>
|
|
579
584
|
</TooltipTrigger>
|
|
580
|
-
<TooltipContent>
|
|
585
|
+
<TooltipContent>{t("mail.compose.bold")}</TooltipContent>
|
|
581
586
|
</Tooltip>
|
|
582
587
|
<Tooltip>
|
|
583
588
|
<TooltipTrigger asChild>
|
|
@@ -590,7 +595,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
590
595
|
<IconItalic className="h-3.5 w-3.5" />
|
|
591
596
|
</Button>
|
|
592
597
|
</TooltipTrigger>
|
|
593
|
-
<TooltipContent>
|
|
598
|
+
<TooltipContent>{t("mail.compose.italic")}</TooltipContent>
|
|
594
599
|
</Tooltip>
|
|
595
600
|
<Tooltip>
|
|
596
601
|
<TooltipTrigger asChild>
|
|
@@ -603,7 +608,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
603
608
|
<IconLink className="h-3.5 w-3.5" />
|
|
604
609
|
</Button>
|
|
605
610
|
</TooltipTrigger>
|
|
606
|
-
<TooltipContent>
|
|
611
|
+
<TooltipContent>{t("mail.compose.insertLink")}</TooltipContent>
|
|
607
612
|
</Tooltip>
|
|
608
613
|
<Tooltip>
|
|
609
614
|
<TooltipTrigger asChild>
|
|
@@ -616,7 +621,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
616
621
|
<IconPaperclip className="h-3.5 w-3.5" />
|
|
617
622
|
</Button>
|
|
618
623
|
</TooltipTrigger>
|
|
619
|
-
<TooltipContent>
|
|
624
|
+
<TooltipContent>{t("mail.compose.attachFile")}</TooltipContent>
|
|
620
625
|
</Tooltip>
|
|
621
626
|
|
|
622
627
|
<div className="mx-1 h-4 w-px bg-border" />
|
|
@@ -624,7 +629,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
624
629
|
{isGenerating ? (
|
|
625
630
|
<div className="flex items-center gap-1.5 px-2 text-xs text-muted-foreground">
|
|
626
631
|
<IconLoader2 className="h-3.5 w-3.5 animate-spin" />
|
|
627
|
-
<span>
|
|
632
|
+
<span>{t("mail.compose.generating")}</span>
|
|
628
633
|
</div>
|
|
629
634
|
) : (
|
|
630
635
|
<Popover open={generateOpen} onOpenChange={setGenerateOpen}>
|
|
@@ -634,13 +639,13 @@ export const InlineReplyComposer = forwardRef<
|
|
|
634
639
|
size="sm"
|
|
635
640
|
className="h-7 gap-1.5 px-2 text-xs"
|
|
636
641
|
>
|
|
637
|
-
|
|
642
|
+
{t("mail.compose.generate")}
|
|
638
643
|
</Button>
|
|
639
644
|
</PopoverTrigger>
|
|
640
645
|
<PopoverContent side="top" align="start" className="w-80 p-3">
|
|
641
646
|
<div className="flex flex-col gap-2">
|
|
642
647
|
<label className="text-xs font-medium text-muted-foreground">
|
|
643
|
-
|
|
648
|
+
{t("mail.compose.agentPromptLabel")}
|
|
644
649
|
</label>
|
|
645
650
|
<textarea
|
|
646
651
|
value={generatePrompt}
|
|
@@ -655,13 +660,14 @@ export const InlineReplyComposer = forwardRef<
|
|
|
655
660
|
setGenerateOpen(false);
|
|
656
661
|
}
|
|
657
662
|
}}
|
|
658
|
-
placeholder="
|
|
663
|
+
placeholder={t("mail.compose.agentPromptPlaceholder")}
|
|
659
664
|
className="min-h-[60px] w-full resize-none rounded-md border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground focus:ring-1 focus:ring-ring"
|
|
660
665
|
autoFocus
|
|
661
666
|
/>
|
|
662
667
|
<div className="flex items-center justify-between">
|
|
663
668
|
<span className="text-[10px] text-muted-foreground">
|
|
664
|
-
<kbd className="kbd-hint">↵</kbd>
|
|
669
|
+
<kbd className="kbd-hint">↵</kbd>{" "}
|
|
670
|
+
{t("mail.compose.toSubmit")}
|
|
665
671
|
</span>
|
|
666
672
|
<Button
|
|
667
673
|
size="sm"
|
|
@@ -669,7 +675,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
669
675
|
disabled={!generatePrompt.trim()}
|
|
670
676
|
className="h-7 gap-1.5 px-3 text-xs"
|
|
671
677
|
>
|
|
672
|
-
|
|
678
|
+
{t("mail.compose.generate")}
|
|
673
679
|
</Button>
|
|
674
680
|
</div>
|
|
675
681
|
</div>
|
|
@@ -690,7 +696,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
690
696
|
<IconTrash className="h-3.5 w-3.5" />
|
|
691
697
|
</Button>
|
|
692
698
|
</TooltipTrigger>
|
|
693
|
-
<TooltipContent>
|
|
699
|
+
<TooltipContent>{t("mail.compose.discardDraft")}</TooltipContent>
|
|
694
700
|
</Tooltip>
|
|
695
701
|
<Button
|
|
696
702
|
size="sm"
|
|
@@ -699,7 +705,7 @@ export const InlineReplyComposer = forwardRef<
|
|
|
699
705
|
className="gap-1.5"
|
|
700
706
|
>
|
|
701
707
|
<IconSend className="h-3.5 w-3.5" />
|
|
702
|
-
|
|
708
|
+
{t("mail.compose.send")}
|
|
703
709
|
</Button>
|
|
704
710
|
</div>
|
|
705
711
|
</div>
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
DropdownMenuContent,
|
|
20
20
|
DropdownMenuItem,
|
|
21
21
|
} from "@/components/ui/dropdown-menu";
|
|
22
|
-
import { useSendToAgentChat } from "@agent-native/core/client";
|
|
22
|
+
import { useSendToAgentChat, useT } from "@agent-native/core/client";
|
|
23
23
|
import { ExtensionSlot } from "@agent-native/core/client/extensions";
|
|
24
24
|
import {
|
|
25
25
|
useIntegration,
|
|
@@ -330,6 +330,7 @@ function IntegrationSetup() {
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
function AddIntegrationButton() {
|
|
333
|
+
const t = useT();
|
|
333
334
|
const [open, setOpen] = useState(false);
|
|
334
335
|
const [value, setValue] = useState("");
|
|
335
336
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
@@ -365,7 +366,7 @@ function AddIntegrationButton() {
|
|
|
365
366
|
<div className="h-7 w-7 rounded-md border border-dashed border-border/40 flex items-center justify-center shrink-0">
|
|
366
367
|
<IconPlus className="h-3 w-3" />
|
|
367
368
|
</div>
|
|
368
|
-
<span>
|
|
369
|
+
<span>{t("mail.integrations.addIntegration")}</span>
|
|
369
370
|
</button>
|
|
370
371
|
</PopoverTrigger>
|
|
371
372
|
<PopoverContent
|
|
@@ -377,7 +378,7 @@ function AddIntegrationButton() {
|
|
|
377
378
|
>
|
|
378
379
|
<div className="px-3.5 pt-3 pb-1.5">
|
|
379
380
|
<span className="text-[12px] font-medium text-foreground/80">
|
|
380
|
-
|
|
381
|
+
{t("mail.integrations.newIntegration")}
|
|
381
382
|
</span>
|
|
382
383
|
</div>
|
|
383
384
|
|
|
@@ -397,7 +398,7 @@ function AddIntegrationButton() {
|
|
|
397
398
|
handleSubmit();
|
|
398
399
|
}
|
|
399
400
|
}}
|
|
400
|
-
placeholder="
|
|
401
|
+
placeholder={t("mail.integrations.newIntegrationPlaceholder")}
|
|
401
402
|
className="w-full bg-transparent text-[12px] text-foreground/90 placeholder:text-muted-foreground/30 outline-none resize-none"
|
|
402
403
|
rows={3}
|
|
403
404
|
style={{ maxHeight: "200px" }}
|
|
@@ -407,7 +408,7 @@ function AddIntegrationButton() {
|
|
|
407
408
|
<div className="px-3.5 py-2 flex items-center justify-end gap-2 border-t border-border/30">
|
|
408
409
|
<span className="text-[11px] text-muted-foreground/60">
|
|
409
410
|
{/Mac|iPhone|iPad/.test(navigator.userAgent) ? "⌘" : "Ctrl"}
|
|
410
|
-
+Enter
|
|
411
|
+
+Enter {t("mail.compose.toSubmit")}
|
|
411
412
|
</span>
|
|
412
413
|
<Tooltip>
|
|
413
414
|
<TooltipTrigger asChild>
|
|
@@ -420,12 +421,16 @@ function AddIntegrationButton() {
|
|
|
420
421
|
? "bg-primary hover:bg-primary/90 text-primary-foreground"
|
|
421
422
|
: "bg-muted/50 text-muted-foreground/30 cursor-not-allowed",
|
|
422
423
|
)}
|
|
423
|
-
aria-label="
|
|
424
|
+
aria-label={t("mail.integrations.submit")}
|
|
424
425
|
>
|
|
425
426
|
<IconArrowUp className="w-4 h-4" />
|
|
426
427
|
</button>
|
|
427
428
|
</TooltipTrigger>
|
|
428
|
-
<TooltipContent>
|
|
429
|
+
<TooltipContent>
|
|
430
|
+
{t("mail.integrations.submitShortcut", {
|
|
431
|
+
shortcut: `${/Mac|iPhone|iPad/.test(navigator.userAgent) ? "⌘" : "Ctrl"}+Enter`,
|
|
432
|
+
})}
|
|
433
|
+
</TooltipContent>
|
|
429
434
|
</Tooltip>
|
|
430
435
|
</div>
|
|
431
436
|
</PopoverContent>
|
|
@@ -443,6 +448,7 @@ function IntegrationRow({
|
|
|
443
448
|
connected: boolean;
|
|
444
449
|
onConfigure: () => void;
|
|
445
450
|
}) {
|
|
451
|
+
const t = useT();
|
|
446
452
|
const { disconnect } = useIntegration(def.id);
|
|
447
453
|
|
|
448
454
|
return (
|
|
@@ -470,20 +476,20 @@ function IntegrationRow({
|
|
|
470
476
|
</button>
|
|
471
477
|
</DropdownMenuTrigger>
|
|
472
478
|
</TooltipTrigger>
|
|
473
|
-
<TooltipContent>
|
|
479
|
+
<TooltipContent>{t("mail.toolbar.settings")}</TooltipContent>
|
|
474
480
|
</Tooltip>
|
|
475
481
|
<DropdownMenuContent align="end" className="w-36">
|
|
476
482
|
<DropdownMenuItem
|
|
477
483
|
onClick={() => onConfigure()}
|
|
478
484
|
className="text-[12px] text-foreground/70"
|
|
479
485
|
>
|
|
480
|
-
|
|
486
|
+
{t("mail.integrations.updateKey")}
|
|
481
487
|
</DropdownMenuItem>
|
|
482
488
|
<DropdownMenuItem
|
|
483
489
|
onClick={() => disconnect.mutate()}
|
|
484
490
|
className="text-[12px] text-red-400/80"
|
|
485
491
|
>
|
|
486
|
-
|
|
492
|
+
{t("mail.integrations.disconnect")}
|
|
487
493
|
</DropdownMenuItem>
|
|
488
494
|
</DropdownMenuContent>
|
|
489
495
|
</DropdownMenu>
|
|
@@ -493,7 +499,7 @@ function IntegrationRow({
|
|
|
493
499
|
onClick={onConfigure}
|
|
494
500
|
className="shrink-0 text-[11px] text-primary hover:text-primary/90 font-medium transition-colors"
|
|
495
501
|
>
|
|
496
|
-
|
|
502
|
+
{t("mail.integrations.connect")}
|
|
497
503
|
</button>
|
|
498
504
|
)}
|
|
499
505
|
</div>
|
|
@@ -507,6 +513,7 @@ function IntegrationKeyEntry({
|
|
|
507
513
|
def: IntegrationDef;
|
|
508
514
|
onBack: () => void;
|
|
509
515
|
}) {
|
|
516
|
+
const t = useT();
|
|
510
517
|
const [apiKey, setApiKey] = useState("");
|
|
511
518
|
const { connect } = useIntegration(def.id);
|
|
512
519
|
const errorMessage =
|
|
@@ -550,7 +557,9 @@ function IntegrationKeyEntry({
|
|
|
550
557
|
disabled={!apiKey.trim() || connect.isPending}
|
|
551
558
|
className="shrink-0 rounded-md bg-primary px-2.5 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors"
|
|
552
559
|
>
|
|
553
|
-
{connect.isPending
|
|
560
|
+
{connect.isPending
|
|
561
|
+
? t("mail.integrations.checking")
|
|
562
|
+
: t("mail.integrations.save")}
|
|
554
563
|
</button>
|
|
555
564
|
</div>
|
|
556
565
|
|
|
@@ -561,7 +570,7 @@ function IntegrationKeyEntry({
|
|
|
561
570
|
{/* Instructions always visible */}
|
|
562
571
|
<div className="rounded-md bg-accent/30 px-2.5 py-2">
|
|
563
572
|
<p className="text-[11px] text-muted-foreground/70 mb-1.5">
|
|
564
|
-
|
|
573
|
+
{t("mail.integrations.getApiKey")}
|
|
565
574
|
</p>
|
|
566
575
|
<ol className="text-[11px] text-muted-foreground/50 space-y-0.5 list-decimal ps-3 mb-1.5">
|
|
567
576
|
{def.helpSteps.map((step, i) => (
|
|
@@ -574,7 +583,10 @@ function IntegrationKeyEntry({
|
|
|
574
583
|
rel="noopener noreferrer"
|
|
575
584
|
className="text-[11px] text-primary/80 hover:text-primary hover:underline transition-colors"
|
|
576
585
|
>
|
|
577
|
-
|
|
586
|
+
{t("mail.integrations.openProviderSettings", {
|
|
587
|
+
provider: def.name,
|
|
588
|
+
})}{" "}
|
|
589
|
+
→
|
|
578
590
|
</a>
|
|
579
591
|
</div>
|
|
580
592
|
</div>
|
|
@@ -817,7 +829,7 @@ function ApolloSection({ email }: { email: string }) {
|
|
|
817
829
|
rel="noopener noreferrer"
|
|
818
830
|
className="text-[11px] text-muted-foreground/60 hover:text-foreground transition-colors"
|
|
819
831
|
>
|
|
820
|
-
LinkedIn
|
|
832
|
+
LinkedIn{/* i18n-ignore */}
|
|
821
833
|
</a>
|
|
822
834
|
)}
|
|
823
835
|
{safeExternalHref(person.twitter_url) && (
|
|
@@ -837,7 +849,7 @@ function ApolloSection({ email }: { email: string }) {
|
|
|
837
849
|
rel="noopener noreferrer"
|
|
838
850
|
className="text-[11px] text-muted-foreground/60 hover:text-foreground transition-colors"
|
|
839
851
|
>
|
|
840
|
-
GitHub
|
|
852
|
+
GitHub{/* i18n-ignore */}
|
|
841
853
|
</a>
|
|
842
854
|
)}
|
|
843
855
|
{safeExternalHref(person.organization?.website_url) && (
|
|
@@ -932,7 +944,10 @@ function HubSpotSection({ email }: { email: string }) {
|
|
|
932
944
|
<>
|
|
933
945
|
<div className="h-px bg-border/30 mx-4" />
|
|
934
946
|
<div className="px-4 py-3">
|
|
935
|
-
<SectionHeader
|
|
947
|
+
<SectionHeader
|
|
948
|
+
logo={INTEGRATIONS[1].logo}
|
|
949
|
+
label={"HubSpot" /* i18n-ignore */}
|
|
950
|
+
/>
|
|
936
951
|
|
|
937
952
|
{name && (
|
|
938
953
|
<p className="text-[12px] text-foreground/80 font-medium">{name}</p>
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
TooltipContent,
|
|
38
38
|
TooltipTrigger,
|
|
39
39
|
} from "@/components/ui/tooltip";
|
|
40
|
+
import { useT } from "@agent-native/core/client";
|
|
40
41
|
|
|
41
42
|
/** Which header field a RecipientInput represents — used for cross-field drag. */
|
|
42
43
|
export type RecipientField = "to" | "cc" | "bcc";
|
|
@@ -144,6 +145,7 @@ function AliasPopover({
|
|
|
144
145
|
onClose,
|
|
145
146
|
onExpand,
|
|
146
147
|
}: AliasPopoverProps) {
|
|
148
|
+
const t = useT();
|
|
147
149
|
const navigate = useNavigate();
|
|
148
150
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
149
151
|
const [pos, setPos] = useState({ top: 0, left: 0 });
|
|
@@ -194,7 +196,9 @@ function AliasPopover({
|
|
|
194
196
|
{alias.name}
|
|
195
197
|
</span>
|
|
196
198
|
<span className="rounded-full bg-indigo-500/15 px-2 py-0.5 text-[11px] font-medium text-indigo-300">
|
|
197
|
-
{
|
|
199
|
+
{t("mail.recipients.recipientCount", {
|
|
200
|
+
count: alias.emails.length,
|
|
201
|
+
})}
|
|
198
202
|
</span>
|
|
199
203
|
<Tooltip>
|
|
200
204
|
<TooltipTrigger asChild>
|
|
@@ -206,7 +210,7 @@ function AliasPopover({
|
|
|
206
210
|
<IconPencil className="size-3.5" />
|
|
207
211
|
</button>
|
|
208
212
|
</TooltipTrigger>
|
|
209
|
-
<TooltipContent>
|
|
213
|
+
<TooltipContent>{t("mail.recipients.editAlias")}</TooltipContent>
|
|
210
214
|
</Tooltip>
|
|
211
215
|
<Tooltip>
|
|
212
216
|
<TooltipTrigger asChild>
|
|
@@ -218,7 +222,9 @@ function AliasPopover({
|
|
|
218
222
|
<IconArrowsDiagonal className="size-3.5" />
|
|
219
223
|
</button>
|
|
220
224
|
</TooltipTrigger>
|
|
221
|
-
<TooltipContent>
|
|
225
|
+
<TooltipContent>
|
|
226
|
+
{t("mail.recipients.expandToIndividualEmails")}
|
|
227
|
+
</TooltipContent>
|
|
222
228
|
</Tooltip>
|
|
223
229
|
</div>
|
|
224
230
|
{/* Email list */}
|
|
@@ -250,6 +256,7 @@ interface SaveAliasModalProps {
|
|
|
250
256
|
}
|
|
251
257
|
|
|
252
258
|
function SaveAliasModal({ emails, onClose }: SaveAliasModalProps) {
|
|
259
|
+
const t = useT();
|
|
253
260
|
const [name, setName] = useState("");
|
|
254
261
|
const createAlias = useCreateAlias();
|
|
255
262
|
|
|
@@ -263,9 +270,13 @@ function SaveAliasModal({ emails, onClose }: SaveAliasModalProps) {
|
|
|
263
270
|
<Dialog open onOpenChange={(open) => !open && onClose()}>
|
|
264
271
|
<DialogContent className="max-w-sm">
|
|
265
272
|
<DialogHeader>
|
|
266
|
-
<DialogTitle className="text-[14px]">
|
|
273
|
+
<DialogTitle className="text-[14px]">
|
|
274
|
+
{t("mail.recipients.saveAsAlias")}
|
|
275
|
+
</DialogTitle>
|
|
267
276
|
<DialogDescription className="text-[12px]">
|
|
268
|
-
|
|
277
|
+
{t("mail.recipients.createReusableGroup", {
|
|
278
|
+
count: emails.length,
|
|
279
|
+
})}
|
|
269
280
|
</DialogDescription>
|
|
270
281
|
</DialogHeader>
|
|
271
282
|
<Input
|
|
@@ -277,7 +288,7 @@ function SaveAliasModal({ emails, onClose }: SaveAliasModalProps) {
|
|
|
277
288
|
if (e.key === "Enter") handleSave();
|
|
278
289
|
e.stopPropagation();
|
|
279
290
|
}}
|
|
280
|
-
placeholder="
|
|
291
|
+
placeholder={t("mail.recipients.aliasName")}
|
|
281
292
|
/>
|
|
282
293
|
<DialogFooter>
|
|
283
294
|
<button
|
|
@@ -285,7 +296,7 @@ function SaveAliasModal({ emails, onClose }: SaveAliasModalProps) {
|
|
|
285
296
|
onClick={onClose}
|
|
286
297
|
className="rounded-lg px-3 py-1.5 text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
287
298
|
>
|
|
288
|
-
|
|
299
|
+
{t("mail.compose.cancel")}
|
|
289
300
|
</button>
|
|
290
301
|
<button
|
|
291
302
|
type="button"
|
|
@@ -293,7 +304,9 @@ function SaveAliasModal({ emails, onClose }: SaveAliasModalProps) {
|
|
|
293
304
|
disabled={!name.trim() || createAlias.isPending}
|
|
294
305
|
className="rounded-lg bg-indigo-600 px-3 py-1.5 text-[13px] font-medium text-white hover:opacity-90 disabled:opacity-40"
|
|
295
306
|
>
|
|
296
|
-
{createAlias.isPending
|
|
307
|
+
{createAlias.isPending
|
|
308
|
+
? t("mail.recipients.saving")
|
|
309
|
+
: t("mail.integrations.save")}
|
|
297
310
|
</button>
|
|
298
311
|
</DialogFooter>
|
|
299
312
|
</DialogContent>
|
|
@@ -311,6 +324,7 @@ export function RecipientInput({
|
|
|
311
324
|
field,
|
|
312
325
|
onMoveRecipient,
|
|
313
326
|
}: RecipientInputProps) {
|
|
327
|
+
const t = useT();
|
|
314
328
|
const [inputValue, setInputValue] = useState("");
|
|
315
329
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
316
330
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -611,7 +625,9 @@ export function RecipientInput({
|
|
|
611
625
|
{alias.name}
|
|
612
626
|
</span>
|
|
613
627
|
<span className="shrink-0 text-[11px] text-indigo-400/70">
|
|
614
|
-
{
|
|
628
|
+
{t("mail.recipients.peopleCount", {
|
|
629
|
+
count: alias.emails.length,
|
|
630
|
+
})}
|
|
615
631
|
</span>
|
|
616
632
|
</button>
|
|
617
633
|
))}
|
|
@@ -765,7 +781,7 @@ export function RecipientInput({
|
|
|
765
781
|
className="flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] text-muted-foreground/35 transition-colors hover:text-muted-foreground/60"
|
|
766
782
|
>
|
|
767
783
|
<IconPlus className="size-3" />
|
|
768
|
-
|
|
784
|
+
{t("mail.recipients.saveAsAlias")}
|
|
769
785
|
</button>
|
|
770
786
|
)}
|
|
771
787
|
</div>
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "@/components/ui/popover";
|
|
7
7
|
import { Button } from "@/components/ui/button";
|
|
8
8
|
import { IconSend, IconChevronDown, IconCalendar } from "@tabler/icons-react";
|
|
9
|
+
import { useT } from "@agent-native/core/client";
|
|
9
10
|
|
|
10
11
|
interface SendLaterButtonProps {
|
|
11
12
|
onSend: () => void;
|
|
@@ -54,6 +55,7 @@ export function SendLaterButton({
|
|
|
54
55
|
disabled,
|
|
55
56
|
isSending,
|
|
56
57
|
}: SendLaterButtonProps) {
|
|
58
|
+
const t = useT();
|
|
57
59
|
const [open, setOpen] = useState(false);
|
|
58
60
|
const presets = getPresets();
|
|
59
61
|
const dateInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -73,7 +75,7 @@ export function SendLaterButton({
|
|
|
73
75
|
onClick={onSend}
|
|
74
76
|
>
|
|
75
77
|
<IconSend className="h-3.5 w-3.5 mr-1.5" />
|
|
76
|
-
{isSending ? "
|
|
78
|
+
{isSending ? t("mail.compose.sending") : t("mail.compose.send")}
|
|
77
79
|
</Button>
|
|
78
80
|
<Popover open={open} onOpenChange={setOpen}>
|
|
79
81
|
<PopoverTrigger asChild>
|
|
@@ -89,7 +91,7 @@ export function SendLaterButton({
|
|
|
89
91
|
<PopoverContent className="w-64 p-3" align="end" side="top">
|
|
90
92
|
<div className="space-y-2">
|
|
91
93
|
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
92
|
-
|
|
94
|
+
{t("mail.sendLater.scheduleSend")}
|
|
93
95
|
</div>
|
|
94
96
|
<div className="space-y-1">
|
|
95
97
|
{presets.map((preset) => (
|
|
@@ -112,7 +114,7 @@ export function SendLaterButton({
|
|
|
112
114
|
className="w-full flex items-center gap-2 px-2.5 py-2 rounded-md hover:bg-accent hover:text-accent-foreground transition-colors text-sm text-muted-foreground"
|
|
113
115
|
>
|
|
114
116
|
<IconCalendar className="h-4 w-4" />
|
|
115
|
-
|
|
117
|
+
{t("mail.sendLater.pickDateTime")}
|
|
116
118
|
</button>
|
|
117
119
|
<input
|
|
118
120
|
ref={dateInputRef}
|
|
@@ -5,6 +5,7 @@ import { useParseDate, useSnoozeEmail } from "@/hooks/use-scheduled-jobs";
|
|
|
5
5
|
import { toast } from "sonner";
|
|
6
6
|
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
|
7
7
|
import { Input } from "@/components/ui/input";
|
|
8
|
+
import { useT } from "@agent-native/core/client";
|
|
8
9
|
|
|
9
10
|
interface SnoozeModalProps {
|
|
10
11
|
open: boolean;
|
|
@@ -103,6 +104,7 @@ export function SnoozeModal({
|
|
|
103
104
|
onClose,
|
|
104
105
|
onSnoozed,
|
|
105
106
|
}: SnoozeModalProps) {
|
|
107
|
+
const t = useT();
|
|
106
108
|
const [nlInput, setNlInput] = useState("");
|
|
107
109
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
108
110
|
const [parsedDate, setParsedDate] = useState<Date | null>(null);
|
|
@@ -274,7 +276,7 @@ export function SnoozeModal({
|
|
|
274
276
|
type="text"
|
|
275
277
|
value={nlInput}
|
|
276
278
|
onChange={(e) => setNlInput(e.target.value)}
|
|
277
|
-
placeholder="
|
|
279
|
+
placeholder={t("mail.snooze.modalPlaceholder")}
|
|
278
280
|
className="h-11 border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
279
281
|
/>
|
|
280
282
|
{nlTyping && (nlParsed || parseDate.isPending) && (
|
|
@@ -287,7 +289,7 @@ export function SnoozeModal({
|
|
|
287
289
|
{/* Options list */}
|
|
288
290
|
<div className="max-h-[300px] overflow-y-auto overflow-x-hidden p-1">
|
|
289
291
|
<div className="px-2 py-1.5 text-xs font-medium text-muted-foreground">
|
|
290
|
-
|
|
292
|
+
{t("mail.snooze.snoozeUntil")}
|
|
291
293
|
</div>
|
|
292
294
|
{options.map((opt, i) => {
|
|
293
295
|
const active = i === selectedIndex;
|
|
@@ -9,6 +9,7 @@ import { cn } from "@/lib/utils";
|
|
|
9
9
|
import { useParseDate, useSnoozeEmail } from "@/hooks/use-scheduled-jobs";
|
|
10
10
|
import { IconAlarm } from "@tabler/icons-react";
|
|
11
11
|
import { toast } from "sonner";
|
|
12
|
+
import { useT } from "@agent-native/core/client";
|
|
12
13
|
|
|
13
14
|
interface SnoozePopoverProps {
|
|
14
15
|
emailId: string;
|
|
@@ -68,6 +69,7 @@ export function SnoozePopover({
|
|
|
68
69
|
onArchive,
|
|
69
70
|
children,
|
|
70
71
|
}: SnoozePopoverProps) {
|
|
72
|
+
const t = useT();
|
|
71
73
|
const [open, setOpen] = useState(false);
|
|
72
74
|
const [nlInput, setNlInput] = useState("");
|
|
73
75
|
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
|
|
@@ -140,7 +142,7 @@ export function SnoozePopover({
|
|
|
140
142
|
<PopoverContent className="w-72 p-3" align="end">
|
|
141
143
|
<div className="space-y-3">
|
|
142
144
|
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
143
|
-
|
|
145
|
+
{t("mail.snooze.snoozeUntil")}
|
|
144
146
|
</div>
|
|
145
147
|
|
|
146
148
|
{/* Preset chips */}
|
|
@@ -171,17 +173,17 @@ export function SnoozePopover({
|
|
|
171
173
|
type="text"
|
|
172
174
|
value={nlInput}
|
|
173
175
|
onChange={(e) => setNlInput(e.target.value)}
|
|
174
|
-
placeholder="
|
|
176
|
+
placeholder={t("mail.snooze.tryPlaceholder")}
|
|
175
177
|
className="w-full text-xs px-2.5 py-1.5 rounded-md border border-input bg-background placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring/30"
|
|
176
178
|
/>
|
|
177
179
|
{nlInput && displayDate && (
|
|
178
180
|
<div className="text-[11px] px-1 text-muted-foreground">
|
|
179
|
-
|
|
181
|
+
{t("mail.snooze.snoozeUntilDate", { date: displayDate })}
|
|
180
182
|
</div>
|
|
181
183
|
)}
|
|
182
184
|
{nlInput && !displayDate && parseDate.isPending && (
|
|
183
185
|
<div className="text-[11px] px-1 text-muted-foreground">
|
|
184
|
-
|
|
186
|
+
{t("mail.snooze.parsing")}
|
|
185
187
|
</div>
|
|
186
188
|
)}
|
|
187
189
|
</div>
|
|
@@ -194,7 +196,9 @@ export function SnoozePopover({
|
|
|
194
196
|
onClick={handleSnooze}
|
|
195
197
|
>
|
|
196
198
|
<IconAlarm className="h-3.5 w-3.5 mr-1.5" />
|
|
197
|
-
{snoozeEmail.isPending
|
|
199
|
+
{snoozeEmail.isPending
|
|
200
|
+
? t("mail.snooze.snoozing")
|
|
201
|
+
: t("mail.snooze.snooze")}
|
|
198
202
|
{displayDate && !snoozeEmail.isPending && (
|
|
199
203
|
<span className="ml-1 opacity-60 truncate max-w-[120px]">
|
|
200
204
|
· {displayDate}
|
|
@@ -2,6 +2,7 @@ import { NodeViewWrapper, type NodeViewProps } from "@tiptap/react";
|
|
|
2
2
|
import { useState, useCallback } from "react";
|
|
3
3
|
import { IconPhoto, IconLoader2, IconX } from "@tabler/icons-react";
|
|
4
4
|
import { openFilePicker, uploadFile } from "@/lib/upload";
|
|
5
|
+
import { useT } from "@agent-native/core/client";
|
|
5
6
|
|
|
6
7
|
export function ComposeImageBlock({
|
|
7
8
|
node,
|
|
@@ -9,6 +10,7 @@ export function ComposeImageBlock({
|
|
|
9
10
|
deleteNode,
|
|
10
11
|
selected,
|
|
11
12
|
}: NodeViewProps) {
|
|
13
|
+
const t = useT();
|
|
12
14
|
const [isUploading, setIsUploading] = useState(false);
|
|
13
15
|
const [isHovered, setIsHovered] = useState(false);
|
|
14
16
|
const src = node.attrs.src as string;
|
|
@@ -40,12 +42,12 @@ export function ComposeImageBlock({
|
|
|
40
42
|
{isUploading ? (
|
|
41
43
|
<>
|
|
42
44
|
<IconLoader2 size={20} className="animate-spin" />
|
|
43
|
-
<span>
|
|
45
|
+
<span>{t("mail.compose.uploading")}</span>
|
|
44
46
|
</>
|
|
45
47
|
) : (
|
|
46
48
|
<>
|
|
47
49
|
<IconPhoto size={20} />
|
|
48
|
-
<span>
|
|
50
|
+
<span>{t("mail.compose.addImage")}</span>
|
|
49
51
|
</>
|
|
50
52
|
)}
|
|
51
53
|
</div>
|