Skip to content

Commit 03a52f0

Browse files
committed
✨(template) add view and modal to manage message template for a mailbox
1 parent 607ea16 commit 03a52f0

File tree

20 files changed

+608
-13
lines changed

20 files changed

+608
-13
lines changed

src/backend/core/api/openapi.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2387,7 +2387,7 @@
23872387
"/api/v1.0/mailboxes/{mailbox_id}/message-templates/": {
23882388
"get": {
23892389
"operationId": "mailboxes_message_templates_list",
2390-
"description": "ViewSet for retrieving and rendering message templates for a mailbox.",
2390+
"description": "List message templates for a mailbox.",
23912391
"parameters": [
23922392
{
23932393
"in": "path",
@@ -2397,6 +2397,20 @@
23972397
"format": "uuid"
23982398
},
23992399
"required": true
2400+
},
2401+
{
2402+
"in": "query",
2403+
"name": "type",
2404+
"schema": {
2405+
"type": "array",
2406+
"items": {
2407+
"type": "string",
2408+
"enum": [
2409+
"message",
2410+
"signature"
2411+
]
2412+
}
2413+
}
24002414
}
24012415
],
24022416
"tags": [

src/backend/core/api/viewsets/message_template.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ def render_template(self, request, mailbox_id, pk=None): # pylint: disable=unus
103103
status=status.HTTP_400_BAD_REQUEST,
104104
)
105105

106+
@extend_schema(
107+
responses=MessageTemplateSerializer(many=True),
108+
description="List message templates for a mailbox.",
109+
parameters=[
110+
OpenApiParameter(
111+
name="type",
112+
type=OpenApiTypes.STR,
113+
location=OpenApiParameter.QUERY,
114+
enum=[c[1] for c in MessageTemplateTypeChoices.choices],
115+
many=True,
116+
),
117+
],
118+
)
119+
def list(self, request, *args, **kwargs):
120+
"""List message templates for a mailbox."""
121+
return super().list(request, *args, **kwargs)
122+
106123

107124
class AvailableMailboxMessageTemplateViewSet(
108125
mixins.ListModelMixin, viewsets.GenericViewSet

src/backend/core/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
)
9898

9999
# Router for /mailboxes/{mailbox_id}/message-templates/available/
100-
# allow to insert the template into editor (new message, reply, signature)
100+
# allow to insert the template into editor (message, signature)
101101
mailbox_message_template_nested_router = DefaultRouter()
102102
mailbox_message_template_nested_router.register(
103103
r"message-templates/available",

src/backend/locale/fr_FR/LC_MESSAGES/django.po

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -743,10 +743,8 @@ msgstr ""
743743
"{html: str, text: str, raw: any}"
744744

745745
#: core/models.py:1687
746-
#, fuzzy
747-
#| msgid "Type of template (reply, new_message, signature)"
748746
msgid "Type of template (message, signature)"
749-
msgstr "Type de modèle (réponse, nouveau message, signature)"
747+
msgstr "Type de modèle (message, signature)"
750748

751749
#: core/models.py:1693
752750
msgid "Whether this template is available for use"

src/frontend/public/locales/common/en-US.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"Are you sure you want to delete this label? This action is irreversible!": "Are you sure you want to delete this label? This action is irreversible!",
4949
"Are you sure you want to delete this mailbox? This action is irreversible!": "Are you sure you want to delete this mailbox? This action is irreversible!",
5050
"Are you sure you want to delete this signature? This action is irreversible!": "Are you sure you want to delete this signature? This action is irreversible!",
51+
"Are you sure you want to delete this template? This action is irreversible!": "Are you sure you want to delete this template? This action is irreversible!",
5152
"Are you sure you want to reset the password?": "Are you sure you want to reset the password?",
5253
"At least one recipient is required.": "At least one recipient is required.",
5354
"Attachments must be less than {{size}}.": "Attachments must be less than {{size}}.",
@@ -83,6 +84,7 @@
8384
"Create a new personal mailbox": "Create a new personal mailbox",
8485
"Create a new shared mailbox": "Create a new shared mailbox",
8586
"Create a new signature for {{domain}}": "Create a new signature for {{domain}}",
87+
"Create a new template": "Create a new template",
8688
"Create a simple redirect (Coming soon)": "Create a simple redirect (Coming soon)",
8789
"Create the label \"{{label}}\"": "Create the label \"{{label}}\"",
8890
"create_mailbox_modal.success.credential_text": "Your Messages credentials are:\n- Email: {{id}}\n- Password: {{password}}\n\nIt will be asked to change your password at your first login.",
@@ -96,6 +98,7 @@
9698
"Delete label \"{{label}}\"": "Delete label \"{{label}}\"",
9799
"Delete mailbox {{mailbox}}": "Delete mailbox {{mailbox}}",
98100
"Delete signature \"{{signature}}\"": "Delete signature \"{{signature}}\"",
101+
"Delete template \"{{template}}\"": "Delete template \"{{template}}\"",
99102
"Description": "Description",
100103
"Description must be less than 255 characters.": "Description must be less than 255 characters.",
101104
"Did you forget an attachment?": "Did you forget an attachment?",
@@ -115,15 +118,19 @@
115118
"Drop your attachments here": "Drop your attachments here",
116119
"Edit": "Edit",
117120
"Edit {{mailbox}} address": "Edit {{mailbox}} address",
121+
"Edit template \"{{template}}\"": "Edit template \"{{template}}\"",
118122
"Email address": "Email address",
119123
"EML or MBOX": "EML or MBOX",
120124
"Enter the email addresses of the recipients separated by commas": "Enter the email addresses of the recipients separated by commas",
121125
"Error while checking DNS records": "Error while checking DNS records",
122126
"Error while loading addresses": "Error while loading addresses",
123127
"Error while loading signatures": "Error while loading signatures",
128+
"Error while loading templates": "Error while loading templates",
124129
"Expand": "Expand",
125130
"Expand all": "Expand all",
131+
"Failed to delete template.": "Failed to delete template.",
126132
"Failed to refresh summary.": "Failed to refresh summary.",
133+
"Failed to save template. Please try again.": "Failed to save template. Please try again.",
127134
"Feedback?": "Feedback?",
128135
"First name": "First name",
129136
"First name is required.": "First name is required.",
@@ -171,6 +178,7 @@
171178
"Loading labels...": "Loading labels...",
172179
"Loading next threads...": "Loading next threads...",
173180
"Loading signatures...": "Loading signatures...",
181+
"Loading templates...": "Loading templates...",
174182
"Loading variables...": "Loading variables...",
175183
"Logout": "Logout",
176184
"Mailbox {{mailbox}} has been deleted successfully.": "Mailbox {{mailbox}} has been deleted successfully.",
@@ -184,6 +192,7 @@
184192
"Mark as unread": "Mark as unread",
185193
"Mark as unread from here": "Mark as unread from here",
186194
"Message sent successfully": "Message sent successfully",
195+
"Message templates": "Message templates",
187196
"Messaging": "Messaging",
188197
"Missing": "Missing",
189198
"Modify": "Modify",
@@ -198,6 +207,7 @@
198207
"New domain": "New domain",
199208
"New message": "New message",
200209
"New signature": "New signature",
210+
"New template": "New template",
201211
"No accesses": "No accesses",
202212
"No attachments": "No attachments",
203213
"No DNS records found": "No DNS records found",
@@ -206,6 +216,7 @@
206216
"No signatures found": "No signatures found",
207217
"No subject": "No subject",
208218
"No summary available.": "No summary available.",
219+
"No template found": "No template found",
209220
"No threads.": "No threads.",
210221
"Open filters": "Open filters",
211222
"Open the menu": "Open the menu",
@@ -267,6 +278,9 @@
267278
"Synchronize mailboxes with an identity provider": "Synchronize mailboxes with an identity provider",
268279
"Target": "Target",
269280
"Target email": "Target email",
281+
"Template created!": "Template created!",
282+
"Template deleted!": "Template deleted!",
283+
"Template updated!": "Template updated!",
270284
"Temporary password": "Temporary password",
271285
"Thank you for your feedback!": "Thank you for your feedback!",
272286
"The address has been updated!": "The address has been updated!",

src/frontend/public/locales/common/fr-FR.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"Are you sure you want to delete this label? This action is irreversible!": "Êtes-vous sûr de vouloir supprimer ce libellé ? Cette action est irréversible !",
4949
"Are you sure you want to delete this mailbox? This action is irreversible!": "Êtes-vous sûr de vouloir supprimer cette boîte aux lettres ? Cette action est irréversible !",
5050
"Are you sure you want to delete this signature? This action is irreversible!": "Êtes-vous sûr de vouloir supprimer cette signature ? Cette action est irréversible !",
51+
"Are you sure you want to delete this template? This action is irreversible!": "Êtes-vous sûr de vouloir supprimer ce modèle ? Cette action est irréversible !",
5152
"Are you sure you want to reset the password?": "Êtes-vous sûr de vouloir réinitialiser le mot de passe ?",
5253
"At least one recipient is required.": "Il faut au moins un destinataire.",
5354
"Attachments must be less than {{size}}.": "Les pièces jointes ne peuvent pas excéder {{size}}.",
@@ -83,6 +84,7 @@
8384
"Create a new personal mailbox": "Créer une nouvelle boîte personnelle",
8485
"Create a new shared mailbox": "Créer une nouvelle boîte partagée",
8586
"Create a new signature for {{domain}}": "Création d'une nouvelle signature pour {{domain}}",
87+
"Create a new template": "Créer un nouveau modèle",
8688
"Create a simple redirect (Coming soon)": "Créer une simple redirection (Bientôt disponible)",
8789
"Create the label \"{{label}}\"": "Créer le libellé \"{{label}}\"",
8890
"create_mailbox_modal.success.credential_text": "Vos identifiants Messages sont : \n- Courriel : {{id}}\n- Mot de passe : {{password}}\n\nIl vous sera demandé de changer votre mot de passe lors de votre première connexion.",
@@ -96,6 +98,7 @@
9698
"Delete label \"{{label}}\"": "Supprimer le libellé \"{{label}}\"",
9799
"Delete mailbox {{mailbox}}": "Supprimer la boîte aux lettres {{mailbox}}",
98100
"Delete signature \"{{signature}}\"": "Supprimer la signature \"{{signature}}\"",
101+
"Delete template \"{{template}}\"": "Supprimer le modèle \"{{template}}\"",
99102
"Description": "Description",
100103
"Description must be less than 255 characters.": "La description ne peut pas excéder 255 caractères.",
101104
"Did you forget an attachment?": "N'avez-vous pas oublié une pièce jointe ?",
@@ -115,15 +118,19 @@
115118
"Drop your attachments here": "Déposez vos pièces jointes ici",
116119
"Edit": "Modifier",
117120
"Edit {{mailbox}} address": "Modifier l'adresse {{mailbox}}",
121+
"Edit template \"{{template}}\"": "Modifier le modèle \"{{template}}\"",
118122
"Email address": "Adresse mail",
119123
"EML or MBOX": "EML ou MBOX",
120124
"Enter the email addresses of the recipients separated by commas": "Entrez les adresses e-mail des destinataires séparés par des virgules",
121125
"Error while checking DNS records": "Erreur lors de la vérification des enregistrements DNS",
122126
"Error while loading addresses": "Erreur lors du chargement des adresses",
123127
"Error while loading signatures": "Erreur lors du chargement des signatures",
128+
"Error while loading templates": "Erreur lors du chargement des modèles",
124129
"Expand": "Développer",
125130
"Expand all": "Tout développer",
131+
"Failed to delete template.": "Erreur lors de la suppression du modèle.",
126132
"Failed to refresh summary.": "Erreur lors de la mise à jour du résumé.",
133+
"Failed to save template. Please try again.": "Erreur lors de la sauvegarde du modèle. Veuillez réessayer.",
127134
"Feedback?": "Faire un retour",
128135
"First name": "Prénom",
129136
"First name is required.": "Le prénom est requis.",
@@ -171,6 +178,7 @@
171178
"Loading labels...": "Chargement des libellés...",
172179
"Loading next threads...": "Chargement des conversations suivantes...",
173180
"Loading signatures...": "Chargement des signatures...",
181+
"Loading templates...": "Chargement des modèles...",
174182
"Loading variables...": "Chargement des variables...",
175183
"Logout": "Déconnexion",
176184
"Mailbox {{mailbox}} has been deleted successfully.": "La boîte aux lettres {{mailbox}} a été supprimée avec succès.",
@@ -184,6 +192,7 @@
184192
"Mark as unread": "Marquer comme non lu",
185193
"Mark as unread from here": "Marquer comme non lu à partir d'ici",
186194
"Message sent successfully": "Message envoyé avec succès",
195+
"Message templates": "Modèles de message",
187196
"Messaging": "Messages",
188197
"Missing": "Manquant",
189198
"Modify": "Modifier",
@@ -198,6 +207,7 @@
198207
"New domain": "Nouveau domaine",
199208
"New message": "Nouveau message",
200209
"New signature": "Nouvelle signature",
210+
"New template": "Nouveau modèle",
201211
"No accesses": "Aucun accès",
202212
"No attachments": "Aucune pièce jointe",
203213
"No DNS records found": "Aucun enregistrement DNS trouvé",
@@ -206,6 +216,7 @@
206216
"No signatures found": "Aucune signature trouvée",
207217
"No subject": "Aucun objet",
208218
"No summary available.": "Aucun résumé disponible.",
219+
"No template found": "Aucun modèle trouvé",
209220
"No threads.": "Aucune conversation.",
210221
"Open filters": "Ouvrir les filtres",
211222
"Open the menu": "Ouvrir le menu",
@@ -267,6 +278,9 @@
267278
"Synchronize mailboxes with an identity provider": "Synchroniser les boîtes aux lettres avec un fournisseur d'identité",
268279
"Target": "Cible",
269280
"Target email": "Adresse de destination",
281+
"Template created!": "Modèle créé !",
282+
"Template deleted!": "Modèle supprimé !",
283+
"Template updated!": "Modèle mis à jour !",
270284
"Temporary password": "Mot de passe temporaire",
271285
"Thank you for your feedback!": "Merci pour votre message !",
272286
"The address has been updated!": "L'adresse a été mise à jour !",

src/frontend/src/features/api/gen/mailboxes/mailboxes.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type {
2525
Mailbox,
2626
MailboxLight,
2727
MailboxesMessageTemplatesAvailableListParams,
28+
MailboxesMessageTemplatesListParams,
2829
MailboxesMessageTemplatesRenderRetrieve200,
2930
MailboxesSearchListParams,
3031
MessageTemplate,
@@ -183,7 +184,7 @@ export function useMailboxesList<
183184
}
184185

185186
/**
186-
* ViewSet for retrieving and rendering message templates for a mailbox.
187+
* List message templates for a mailbox.
187188
*/
188189
export type mailboxesMessageTemplatesListResponse200 = {
189190
data: MessageTemplate[];
@@ -198,32 +199,55 @@ export type mailboxesMessageTemplatesListResponse =
198199
headers: Headers;
199200
};
200201

201-
export const getMailboxesMessageTemplatesListUrl = (mailboxId: string) => {
202-
return `/api/v1.0/mailboxes/${mailboxId}/message-templates/`;
202+
export const getMailboxesMessageTemplatesListUrl = (
203+
mailboxId: string,
204+
params?: MailboxesMessageTemplatesListParams,
205+
) => {
206+
const normalizedParams = new URLSearchParams();
207+
208+
Object.entries(params || {}).forEach(([key, value]) => {
209+
if (value !== undefined) {
210+
normalizedParams.append(key, value === null ? "null" : value.toString());
211+
}
212+
});
213+
214+
const stringifiedParams = normalizedParams.toString();
215+
216+
return stringifiedParams.length > 0
217+
? `/api/v1.0/mailboxes/${mailboxId}/message-templates/?${stringifiedParams}`
218+
: `/api/v1.0/mailboxes/${mailboxId}/message-templates/`;
203219
};
204220

205221
export const mailboxesMessageTemplatesList = async (
206222
mailboxId: string,
223+
params?: MailboxesMessageTemplatesListParams,
207224
options?: RequestInit,
208225
): Promise<mailboxesMessageTemplatesListResponse> => {
209226
return fetchAPI<mailboxesMessageTemplatesListResponse>(
210-
getMailboxesMessageTemplatesListUrl(mailboxId),
227+
getMailboxesMessageTemplatesListUrl(mailboxId, params),
211228
{
212229
...options,
213230
method: "GET",
214231
},
215232
);
216233
};
217234

218-
export const getMailboxesMessageTemplatesListQueryKey = (mailboxId: string) => {
219-
return [`/api/v1.0/mailboxes/${mailboxId}/message-templates/`] as const;
235+
export const getMailboxesMessageTemplatesListQueryKey = (
236+
mailboxId: string,
237+
params?: MailboxesMessageTemplatesListParams,
238+
) => {
239+
return [
240+
`/api/v1.0/mailboxes/${mailboxId}/message-templates/`,
241+
...(params ? [params] : []),
242+
] as const;
220243
};
221244

222245
export const getMailboxesMessageTemplatesListQueryOptions = <
223246
TData = Awaited<ReturnType<typeof mailboxesMessageTemplatesList>>,
224247
TError = unknown,
225248
>(
226249
mailboxId: string,
250+
params?: MailboxesMessageTemplatesListParams,
227251
options?: {
228252
query?: Partial<
229253
UseQueryOptions<
@@ -239,12 +263,15 @@ export const getMailboxesMessageTemplatesListQueryOptions = <
239263

240264
const queryKey =
241265
queryOptions?.queryKey ??
242-
getMailboxesMessageTemplatesListQueryKey(mailboxId);
266+
getMailboxesMessageTemplatesListQueryKey(mailboxId, params);
243267

244268
const queryFn: QueryFunction<
245269
Awaited<ReturnType<typeof mailboxesMessageTemplatesList>>
246270
> = ({ signal }) =>
247-
mailboxesMessageTemplatesList(mailboxId, { signal, ...requestOptions });
271+
mailboxesMessageTemplatesList(mailboxId, params, {
272+
signal,
273+
...requestOptions,
274+
});
248275

249276
return {
250277
queryKey,
@@ -268,6 +295,7 @@ export function useMailboxesMessageTemplatesList<
268295
TError = unknown,
269296
>(
270297
mailboxId: string,
298+
params: undefined | MailboxesMessageTemplatesListParams,
271299
options: {
272300
query: Partial<
273301
UseQueryOptions<
@@ -295,6 +323,7 @@ export function useMailboxesMessageTemplatesList<
295323
TError = unknown,
296324
>(
297325
mailboxId: string,
326+
params?: MailboxesMessageTemplatesListParams,
298327
options?: {
299328
query?: Partial<
300329
UseQueryOptions<
@@ -322,6 +351,7 @@ export function useMailboxesMessageTemplatesList<
322351
TError = unknown,
323352
>(
324353
mailboxId: string,
354+
params?: MailboxesMessageTemplatesListParams,
325355
options?: {
326356
query?: Partial<
327357
UseQueryOptions<
@@ -342,6 +372,7 @@ export function useMailboxesMessageTemplatesList<
342372
TError = unknown,
343373
>(
344374
mailboxId: string,
375+
params?: MailboxesMessageTemplatesListParams,
345376
options?: {
346377
query?: Partial<
347378
UseQueryOptions<
@@ -358,6 +389,7 @@ export function useMailboxesMessageTemplatesList<
358389
} {
359390
const queryOptions = getMailboxesMessageTemplatesListQueryOptions(
360391
mailboxId,
392+
params,
361393
options,
362394
);
363395

src/frontend/src/features/api/gen/models/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export * from "./mailbox_role_choices";
6767
export * from "./mailboxes_accesses_list_params";
6868
export * from "./mailboxes_message_templates_available_list_params";
6969
export * from "./mailboxes_message_templates_available_list_type";
70+
export * from "./mailboxes_message_templates_list_params";
71+
export * from "./mailboxes_message_templates_list_type_item";
7072
export * from "./mailboxes_message_templates_render_retrieve200";
7173
export * from "./mailboxes_search_list_params";
7274
export * from "./maildomain_access_read";

0 commit comments

Comments
 (0)