diff --git a/components/email/email-composer.tsx b/components/email/email-composer.tsx index 1dbefb2a0..b062d9892 100644 --- a/components/email/email-composer.tsx +++ b/components/email/email-composer.tsx @@ -1561,7 +1561,9 @@ export function EmailComposer({ [composingAccountId], ); // The admin may leave users only organisation and team templates. - const personalTemplatesHidden = useTemplateSources(composingAccountId).personalHidden; + const composingTemplates = useTemplateSources(composingAccountId); + const personalTemplatesHidden = composingTemplates.personalHidden; + const composingPersonalTemplates = composingTemplates.sources.find((source) => source.kind === 'personal')?.templates; // Sign/encrypt is provided by crypto plugins (S/MIME, PGP) via the // composer-toolbar slot + the onComposeSend hook — the host stays // crypto-agnostic. @@ -4873,6 +4875,7 @@ export function EmailComposer({ >

{t('save_as_template')}

{ expect(screen.getByText('Mine')).toBeInTheDocument(); expect(screen.queryByText("Dave's own")).toBeNull(); }); + + it('shows who a template addresses before it is inserted', () => { + useTemplateStore.setState({ templates: [own('mine', 'Mine', { defaultRecipients: { to: ['a@x.test', 'b@x.test'], cc: ['c@x.test'], bcc: ['hidden@x.test'] } })] }); + render( {}} onSelect={() => {}} />); + const line = screen.getByTestId('template-recipients'); + expect(line).toHaveTextContent('preview_to'); + expect(line).toHaveTextContent('preview_cc'); + }); }); diff --git a/components/templates/template-form.tsx b/components/templates/template-form.tsx index fad3eaa65..c268ec349 100644 --- a/components/templates/template-form.tsx +++ b/components/templates/template-form.tsx @@ -31,15 +31,18 @@ interface TemplateFormProps { shared?: boolean; /** A save is under way: the save button waits. */ busy?: boolean; + /** The templates whose categories the category field suggests; the browser's list when left out. */ + categorySource?: EmailTemplate[]; } -export function TemplateForm({ template, initialData, onSave, onCancel, shared = false, busy = false }: TemplateFormProps) { +export function TemplateForm({ template, initialData, onSave, onCancel, shared = false, busy = false, categorySource }: TemplateFormProps) { const t = useTranslations('templates'); const tSettings = useTranslations('settings.templates'); const tComposer = useTranslations('email_composer'); const { identities } = useAuthStore(); - const templates = useTemplateStore((s) => s.templates); + const browserList = useTemplateStore((s) => s.templates); + const templates = categorySource ?? browserList; const [name, setName] = useState(template?.name || ''); const [category, setCategory] = useState(template?.category || ''); diff --git a/components/templates/template-picker.tsx b/components/templates/template-picker.tsx index dd1cb2291..8c2fdff41 100644 --- a/components/templates/template-picker.tsx +++ b/components/templates/template-picker.tsx @@ -113,6 +113,15 @@ export function TemplatePicker({ isOpen, onClose, onSelect, accountId }: Templat {template.subject}

)} + {/* Who the template addresses, before it is put into the message. */} + {(template.defaultRecipients?.to?.length || template.defaultRecipients?.cc?.length) ? ( +

+ {[ + template.defaultRecipients?.to?.length ? tOrg('preview_to', { list: template.defaultRecipients.to.join(', ') }) : null, + template.defaultRecipients?.cc?.length ? tOrg('preview_cc', { list: template.defaultRecipients.cc.join(', ') }) : null, + ].filter(Boolean).join(' · ')} +

+ ) : null} ); diff --git a/locales/de/common.json b/locales/de/common.json index 3880ae779..16d1fb485 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -2925,7 +2925,10 @@ "local_only_no_room": "Nur in diesem Browser: In Ihrem Konto ist kein Platz für weitere Vorlagen.", "personal_in_account": "Ihre Vorlagen werden in Ihrem Konto gespeichert, Sie haben sie also auf jedem Gerät, auf dem Sie sich anmelden. Alle, für die Sie Ihren Posteingang freigeben, können sie lesen.", "team_note": "Alle Mitglieder von {name} sehen diese Vorlagen und können sie ändern.", - "team_read_only": "Sie können diese Vorlagen verwenden, aber nicht ändern." + "team_read_only": "Sie können diese Vorlagen verwenden, aber nicht ändern.", + "save_failed_conflict": "Von jemand anderem geändert. Laden Sie neu und versuchen Sie es erneut.", + "preview_to": "An: {list}", + "preview_cc": "Cc: {list}" }, "contacts": { "directory": { diff --git a/locales/en/common.json b/locales/en/common.json index 53a06b2ad..d71930a35 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -2925,7 +2925,10 @@ "local_only_no_room": "Only in this browser: your account has no room for more templates.", "personal_in_account": "Your templates are kept in your account, so you have them on every device you sign in on. Anyone you share your Inbox with can read them.", "team_note": "Everyone in {name} sees these templates and can change them.", - "team_read_only": "You can use these templates but not change them." + "team_read_only": "You can use these templates but not change them.", + "save_failed_conflict": "Changed by someone else. Reload and try again.", + "preview_to": "To: {list}", + "preview_cc": "Cc: {list}" }, "contacts": { "directory": {