diff --git a/packages/manager/apps/zimbra/.gitignore b/packages/manager/apps/zimbra/.gitignore new file mode 100644 index 000000000000..4ebc8aea50e0 --- /dev/null +++ b/packages/manager/apps/zimbra/.gitignore @@ -0,0 +1 @@ +coverage diff --git a/packages/manager/apps/zimbra/package.json b/packages/manager/apps/zimbra/package.json index becd81b02352..624946f32834 100644 --- a/packages/manager/apps/zimbra/package.json +++ b/packages/manager/apps/zimbra/package.json @@ -56,10 +56,10 @@ "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.6.0", + "@vitest/coverage-v8": "^2.1.2", "typescript": "^4.3.2", "vite": "^5.2.13", - "vitest": "^2.0.5" + "vitest": "^2.1.2" }, "regions": [ "CA", diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_de_DE.json index 3db328aca574..e93c15043127 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_de_DE.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_de_DE.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "Ihre Anfrage zur Erstellung einer Account-E-Mail-Adresse ist fehlgeschlagen. {{ error }}", "zimbra_account_edit_success_message": "Ihre Anfrage zur Änderung eines E-Mail Accounts wurde registriert. Sie wird in Kürze bearbeitet.", "zimbra_account_edit_error_message": "Ihre Anfrage zur Änderung der Account-E-Mail-Adresse ist fehlgeschlagen. {{ error }}", - "zimbra_account_add_input_displayName_tooltip": "Name, der im Verzeichnis verwendet und den E-Mail-Empfänger:innen angezeigt wird" + "zimbra_account_add_input_displayName_tooltip": "Name, der im Verzeichnis verwendet und den E-Mail-Empfänger:innen angezeigt wird", + "zimbra_account_edit_tabs_settings": "Kontoeinstellungen", + "zimbra_account_edit_tabs_redirections": "Weiterleitungen", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_en_GB.json index 9d6e6c056762..b3ae9efe87e3 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_en_GB.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_en_GB.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "Unable to submit your email account creation request. {{ error }}", "zimbra_account_edit_success_message": "Your request to edit your email account has been submitted. It will be processed in a few moments.", "zimbra_account_edit_error_message": "Unable to submit the request to edit your email account. {{ error }}", - "zimbra_account_add_input_displayName_tooltip": "Name displayed in the directory and to email recipients." + "zimbra_account_add_input_displayName_tooltip": "Name displayed in the directory and to email recipients.", + "zimbra_account_edit_tabs_settings": "Account settings", + "zimbra_account_edit_tabs_redirections": "Redirections", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_es_ES.json index 0e094c35e7db..c4a3ece81a01 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_es_ES.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_es_ES.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "Se ha producido un error al enviar la solicitud de creación de cuenta de correo: {{ error }}", "zimbra_account_edit_success_message": "La solicitud de modificación de la cuenta de correo se ha enviado. Será tratada en unos instantes.", "zimbra_account_edit_error_message": "Se ha producido un error al enviar la solicitud de modificación de cuenta de correo: {{ error }}", - "zimbra_account_add_input_displayName_tooltip": "Nombre utilizado en el directorio y mostrado a los destinatarios de los emails" + "zimbra_account_add_input_displayName_tooltip": "Nombre utilizado en el directorio y mostrado a los destinatarios de los emails", + "zimbra_account_edit_tabs_settings": "Configuración de la cuenta", + "zimbra_account_edit_tabs_redirections": "Redirecciones", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_CA.json index b1a6b10892f9..52b7615a758e 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_CA.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_CA.json @@ -2,6 +2,9 @@ "zimbra_account_add_cta_back": "Retour vers mes comptes emails", "zimbra_account_add_title": "Créer un compte email", "zimbra_account_edit_title": "Modifier le compte {{ account }}", + "zimbra_account_edit_tabs_settings": "Paramètres du compte", + "zimbra_account_edit_tabs_redirections": "Redirections", + "zimbra_account_edit_tabs_alias": "Alias", "zimbra_account_add_input_email_label": "Compte email", "zimbra_account_add_input_email_placeholder": "Nom du compte", "zimbra_account_add_input_email_helper": "La partie locale de votre adresse mail (le texte précédant le « @ ») doit suivre les lignes directrices suivantes :", diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_FR.json index b1a6b10892f9..52b7615a758e 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_fr_FR.json @@ -2,6 +2,9 @@ "zimbra_account_add_cta_back": "Retour vers mes comptes emails", "zimbra_account_add_title": "Créer un compte email", "zimbra_account_edit_title": "Modifier le compte {{ account }}", + "zimbra_account_edit_tabs_settings": "Paramètres du compte", + "zimbra_account_edit_tabs_redirections": "Redirections", + "zimbra_account_edit_tabs_alias": "Alias", "zimbra_account_add_input_email_label": "Compte email", "zimbra_account_add_input_email_placeholder": "Nom du compte", "zimbra_account_add_input_email_helper": "La partie locale de votre adresse mail (le texte précédant le « @ ») doit suivre les lignes directrices suivantes :", diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_it_IT.json index 8870b126e20d..3a6e5660731f 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_it_IT.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_it_IT.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "La tua richiesta di creazione dell'account email non è andata a buon fine: {{ error }}", "zimbra_account_edit_success_message": "La tua richiesta di modifica dell'account email è stata presa in carico. Sarà elaborata entro pochi minuti.", "zimbra_account_edit_error_message": "La tua richiesta di modifica dell'account email non è andata a buon fine: {{ error }}", - "zimbra_account_add_input_displayName_tooltip": "Nome utilizzato nell'elenco e visualizzato dai destinatari delle email" + "zimbra_account_add_input_displayName_tooltip": "Nome utilizzato nell'elenco e visualizzato dai destinatari delle email", + "zimbra_account_edit_tabs_settings": "Impostazioni account", + "zimbra_account_edit_tabs_redirections": "Reindirizzamenti", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pl_PL.json index 32709514d375..32f56afc0a3c 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pl_PL.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pl_PL.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "Utworzenie konta e-mail nie powiodło się. {{error}}", "zimbra_account_edit_success_message": "Dyspozycja modyfikacji konta e-mail została przyjęta. Zostanie przetworzona w ciągu kilku minut.", "zimbra_account_edit_error_message": "Modyfikacja konta e-mail nie powiodła się. {{error}}", - "zimbra_account_add_input_displayName_tooltip": "Nazwa używana w książce adresowej i wyświetlana odbiorcom wiadomości e-mail" + "zimbra_account_add_input_displayName_tooltip": "Nazwa używana w książce adresowej i wyświetlana odbiorcom wiadomości e-mail", + "zimbra_account_edit_tabs_settings": "Parametry konta", + "zimbra_account_edit_tabs_redirections": "Przekierowania", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pt_PT.json index 507494255d56..2ed6240b4feb 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pt_PT.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/addAndEdit/Messages_pt_PT.json @@ -33,5 +33,8 @@ "zimbra_account_add_error_message": "O seu pedido de criação de uma conta de e-mail não foi bem-sucedido. {{ error }}", "zimbra_account_edit_success_message": "O seu pedido de alteração de uma conta de e-mail foi registado. Será tratado dentro de alguns instantes.", "zimbra_account_edit_error_message": "O seu pedido de alteração de uma conta de e-mail não foi bem-sucedido. {{ error }}", - "zimbra_account_add_input_displayName_tooltip": "Nome utilizado no diretório e apresentado aos destinatários dos e-mails" + "zimbra_account_add_input_displayName_tooltip": "Nome utilizado no diretório e apresentado aos destinatários dos e-mails", + "zimbra_account_edit_tabs_settings": "Parâmetros da conta", + "zimbra_account_edit_tabs_redirections": "Reencaminhamentos", + "zimbra_account_edit_tabs_alias": "Alias" } diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_de_DE.json new file mode 100644 index 000000000000..34b8cfc88122 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_de_DE.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Verwaltung der Alias", + "zimbra_account_alias_cta": "Alias hinzufügen", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Status", + "zimbra_account_alias_datagrid_tooltip_delete": "Löschen" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_en_GB.json new file mode 100644 index 000000000000..a7afa1c6db72 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_en_GB.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Alias management", + "zimbra_account_alias_cta": "Add an alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Status", + "zimbra_account_alias_datagrid_tooltip_delete": "Delete" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_es_ES.json new file mode 100644 index 000000000000..01806a6c1a9a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_es_ES.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Gestión de los alias", + "zimbra_account_alias_cta": "Añadir un alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Estado", + "zimbra_account_alias_datagrid_tooltip_delete": "Eliminar" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_CA.json new file mode 100644 index 000000000000..748101bc3ce9 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_CA.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Gestion des alias", + "zimbra_account_alias_cta": "Ajouter un alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Statut", + "zimbra_account_alias_datagrid_tooltip_delete": "Supprimer" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_FR.json new file mode 100644 index 000000000000..748101bc3ce9 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_fr_FR.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Gestion des alias", + "zimbra_account_alias_cta": "Ajouter un alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Statut", + "zimbra_account_alias_datagrid_tooltip_delete": "Supprimer" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_it_IT.json new file mode 100644 index 000000000000..e00404dd7ab5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_it_IT.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Gestione degli alias", + "zimbra_account_alias_cta": "Aggiungi un alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Status", + "zimbra_account_alias_datagrid_tooltip_delete": "Eliminare" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pl_PL.json new file mode 100644 index 000000000000..91c1faa36469 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pl_PL.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Zarządzanie aliasami", + "zimbra_account_alias_cta": "Dodaj alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Status", + "zimbra_account_alias_datagrid_tooltip_delete": "Usuń" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pt_PT.json new file mode 100644 index 000000000000..ec7b3abaa4e2 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/Messages_pt_PT.json @@ -0,0 +1,7 @@ +{ + "zimbra_account_alias_title": "Gestão dos alias", + "zimbra_account_alias_cta": "Adicionar um alias", + "zimbra_account_alias_datagrid_alias_label": "Alias", + "zimbra_account_alias_datagrid_status_label": "Estado", + "zimbra_account_alias_datagrid_tooltip_delete": "Suprimir" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_de_DE.json new file mode 100644 index 000000000000..20dbf6ffdd3f --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_de_DE.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Alias erstellen", + "zimbra_account_alias_add_description": "Alias für den Account {{ account }} erstellen", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "Der lokale Teil Ihres Alias (der Text vor dem „@“) muss den folgenden Richtlinien folgen:", + "zimbra_account_alias_add_input_email_helper_rule_1": "Sie muss mit einem Buchstaben oder einer Nummer enden", + "zimbra_account_alias_add_input_email_helper_rule_2": "Zulässige Sonderzeichen sind “.“, „+“, „-“ und „_“", + "zimbra_account_alias_add_input_email_helper_rule_3": "Sonderzeichen können nicht nebeneinander platziert werden", + "zimbra_account_alias_add_select_domain_placeholder": "Einen Domainnamen auswählen", + "zimbra_account_alias_add_btn_confirm": "Bestätigen", + "zimbra_account_alias_add_success_message": "Ihre Anfrage zur Erstellung eines Alias wurde registriert. Sie wird in einigen Augenblicken behandelt.", + "zimbra_account_alias_add_error_message": "Ihre Anfrage zur Erstellung eines Alias konnte nicht abgeschlossen werden. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_en_GB.json new file mode 100644 index 000000000000..e7883448a57a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_en_GB.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Create an alias", + "zimbra_account_alias_add_description": "Create an alias for the {{ account }} account", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "The local part of your alias (the text preceding the '@') must follow the following guidelines:", + "zimbra_account_alias_add_input_email_helper_rule_1": "It must end with a letter or number", + "zimbra_account_alias_add_input_email_helper_rule_2": "Allowed special characters are \".\", \"+\", \"-\" and \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Special characters cannot be placed side by side", + "zimbra_account_alias_add_select_domain_placeholder": "Select a domain name", + "zimbra_account_alias_add_btn_confirm": "Confirm", + "zimbra_account_alias_add_success_message": "Your request to create an alias has been processed. It will be processed in a few moments.", + "zimbra_account_alias_add_error_message": "Your request to create an alias could not be completed. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_es_ES.json new file mode 100644 index 000000000000..661dfe3ee6d4 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_es_ES.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Crear un alias", + "zimbra_account_alias_add_description": "Crear un alias para la cuenta {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "La parte local del alias (el texto que precede al «@») debe seguir las siguientes directrices:", + "zimbra_account_alias_add_input_email_helper_rule_1": "Debe terminar con una letra o un número", + "zimbra_account_alias_add_input_email_helper_rule_2": "Los caracteres especiales permitidos son \".\", \"+\", \"-\" y \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Los caracteres especiales no se pueden colocar juntos", + "zimbra_account_alias_add_select_domain_placeholder": "Seleccionar un dominio", + "zimbra_account_alias_add_btn_confirm": "Confirmar", + "zimbra_account_alias_add_success_message": "La solicitud de creación de alias se ha enviado. Será tratada en unos instantes.", + "zimbra_account_alias_add_error_message": "No se ha podido completar la solicitud de creación de alias. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_CA.json new file mode 100644 index 000000000000..8212ea263c1c --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_CA.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Créer un alias", + "zimbra_account_alias_add_description": "Créer un alias pour le compte {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "La partie locale de votre alias (le texte précédant le « @ ») doit suivre les lignes directrices suivantes :", + "zimbra_account_alias_add_input_email_helper_rule_1": "Elle doit se terminer par une lettre ou un numéro", + "zimbra_account_alias_add_input_email_helper_rule_2": "Les caractères spéciaux autorisés sont \".\", \"+\", \"-\" et \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Les caractères spéciaux ne peuvent pas être placés côte à côte", + "zimbra_account_alias_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_account_alias_add_btn_confirm": "Confirmer", + "zimbra_account_alias_add_success_message": "Votre demande de création d'alias a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_account_alias_add_error_message": "Votre demande de création d'alias n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json new file mode 100644 index 000000000000..8212ea263c1c --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Créer un alias", + "zimbra_account_alias_add_description": "Créer un alias pour le compte {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "La partie locale de votre alias (le texte précédant le « @ ») doit suivre les lignes directrices suivantes :", + "zimbra_account_alias_add_input_email_helper_rule_1": "Elle doit se terminer par une lettre ou un numéro", + "zimbra_account_alias_add_input_email_helper_rule_2": "Les caractères spéciaux autorisés sont \".\", \"+\", \"-\" et \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Les caractères spéciaux ne peuvent pas être placés côte à côte", + "zimbra_account_alias_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_account_alias_add_btn_confirm": "Confirmer", + "zimbra_account_alias_add_success_message": "Votre demande de création d'alias a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_account_alias_add_error_message": "Votre demande de création d'alias n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_it_IT.json new file mode 100644 index 000000000000..94a386ddc43e --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_it_IT.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Crea un alias", + "zimbra_account_alias_add_description": "Crea un alias per l’account {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "La parte locale dell’alias (il testo che precede \"@\") deve seguire queste linee guida:", + "zimbra_account_alias_add_input_email_helper_rule_1": "Deve terminare con una lettera o un numero", + "zimbra_account_alias_add_input_email_helper_rule_2": "I caratteri speciali autorizzati sono \".\", \"+\", \"-\" e \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Impossibile posizionare i caratteri speciali affiancati", + "zimbra_account_alias_add_select_domain_placeholder": "Seleziona un dominio", + "zimbra_account_alias_add_btn_confirm": "Conferma", + "zimbra_account_alias_add_success_message": "La richiesta di creazione dell'alias è stata presa in carico. Sarà elaborata entro pochi minuti.", + "zimbra_account_alias_add_error_message": "Impossibile completare la richiesta di creazione dell'alias. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pl_PL.json new file mode 100644 index 000000000000..97ba555b8ec5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pl_PL.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Utwórz alias", + "zimbra_account_alias_add_description": "Utwórz alias dla konta {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "Pierwsza część aliasu (tekst przed \"@\") musi być utworzona zgodnie z następującymi wytycznymi:", + "zimbra_account_alias_add_input_email_helper_rule_1": "Musi kończyć się literą lub numerem", + "zimbra_account_alias_add_input_email_helper_rule_2": "Dozwolone są następujące znaki specjalne: \".\", \"+\", \"-\" i \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Znaków specjalnych nie można umieścić obok siebie", + "zimbra_account_alias_add_select_domain_placeholder": "Wybierz nazwę domeny", + "zimbra_account_alias_add_btn_confirm": "Zatwierdź", + "zimbra_account_alias_add_success_message": "Zlecenie utworzenia aliasu zostało przyjęte. Zostanie ona przetworzona za kilka minut.", + "zimbra_account_alias_add_error_message": "Zlecenie utworzenia aliasu nie powiodło się. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pt_PT.json new file mode 100644 index 000000000000..24062baa5b5e --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_pt_PT.json @@ -0,0 +1,13 @@ +{ + "zimbra_account_alias_add_modal_title": "Criar um alias", + "zimbra_account_alias_add_description": "Criar um alias para a conta {{ account }}", + "zimbra_account_alias_add_input_email_placeholder": "Alias", + "zimbra_account_alias_add_input_email_helper": "A parte local do seu alias (o texto que precede o « @ ») deve seguir as seguintes diretrizes:", + "zimbra_account_alias_add_input_email_helper_rule_1": "Deve terminar por uma letra ou um número", + "zimbra_account_alias_add_input_email_helper_rule_2": "Os caracteres especiais permitidos são \".\", \"+\", \"-\" e \"_\"", + "zimbra_account_alias_add_input_email_helper_rule_3": "Os caracteres especiais não podem ser colocados lado a lado", + "zimbra_account_alias_add_select_domain_placeholder": "Selecionar um domínio", + "zimbra_account_alias_add_btn_confirm": "Confirmar", + "zimbra_account_alias_add_success_message": "O seu pedido de criação de alias foi corretamente tomado em conta. Será tratada dentro de alguns instantes.", + "zimbra_account_alias_add_error_message": "O seu pedido de criação de alias não foi bem-sucedido. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_de_DE.json new file mode 100644 index 000000000000..5702dda1a605 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_de_DE.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Alias löschen", + "zimbra_account_alias_delete_modal_description": "Sind Sie sicher, dass Sie es löschen möchten?", + "zimbra_account_alias_delete_modal_cancel_btn": "Abbrechen", + "zimbra_account_alias_delete_modal_delete_btn": "Löschen", + "zimbra_account_alias_delete_success_message": "Ihre Anfrage zur Löschung wurde registriert. Sie wird in einigen Augenblicken ausgeführt.", + "zimbra_account_alias_delete_error_message": "Ihre Anfrage zum Löschen konnte nicht abgeschlossen werden. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_en_GB.json new file mode 100644 index 000000000000..505af99ccd21 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_en_GB.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Delete alias", + "zimbra_account_alias_delete_modal_description": "Are you sure you want to delete it?", + "zimbra_account_alias_delete_modal_cancel_btn": "Cancel", + "zimbra_account_alias_delete_modal_delete_btn": "Delete", + "zimbra_account_alias_delete_success_message": "Your deletion request has been processed. It will be executed in a few moments.", + "zimbra_account_alias_delete_error_message": "Your deletion request could not be completed. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_es_ES.json new file mode 100644 index 000000000000..81c4a0eff3eb --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_es_ES.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Eliminar el alias", + "zimbra_account_alias_delete_modal_description": "¿Seguro que quiere eliminarlo?", + "zimbra_account_alias_delete_modal_cancel_btn": "Cancelar", + "zimbra_account_alias_delete_modal_delete_btn": "Eliminar", + "zimbra_account_alias_delete_success_message": "La solicitud de eliminación se ha enviado. Va a ejecutarse.", + "zimbra_account_alias_delete_error_message": "No se ha podido completar la solicitud de eliminación. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_CA.json new file mode 100644 index 000000000000..4a25818cbd69 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_CA.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Supprimer l'alias", + "zimbra_account_alias_delete_modal_description": "Êtes-vous sûr de vouloir le supprimer ?", + "zimbra_account_alias_delete_modal_cancel_btn": "Annuler", + "zimbra_account_alias_delete_modal_delete_btn": "Supprimer", + "zimbra_account_alias_delete_success_message": "Votre demande de suppression a bien été prise en compte. Elle sera exécutée d'ici quelques instants.", + "zimbra_account_alias_delete_error_message": "Votre demande de suppression n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_FR.json new file mode 100644 index 000000000000..4a25818cbd69 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_fr_FR.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Supprimer l'alias", + "zimbra_account_alias_delete_modal_description": "Êtes-vous sûr de vouloir le supprimer ?", + "zimbra_account_alias_delete_modal_cancel_btn": "Annuler", + "zimbra_account_alias_delete_modal_delete_btn": "Supprimer", + "zimbra_account_alias_delete_success_message": "Votre demande de suppression a bien été prise en compte. Elle sera exécutée d'ici quelques instants.", + "zimbra_account_alias_delete_error_message": "Votre demande de suppression n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_it_IT.json new file mode 100644 index 000000000000..659560c507bf --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_it_IT.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Elimina l'alias", + "zimbra_account_alias_delete_modal_description": "Vuoi davvero eliminarlo?", + "zimbra_account_alias_delete_modal_cancel_btn": "Annulla", + "zimbra_account_alias_delete_modal_delete_btn": "Eliminare", + "zimbra_account_alias_delete_success_message": "La richiesta di eliminazione è stata presa in carico. Sarà eseguita entro pochi minuti.", + "zimbra_account_alias_delete_error_message": "Impossibile completare la richiesta di eliminazione. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pl_PL.json new file mode 100644 index 000000000000..e9f816911436 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pl_PL.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Usuń alias", + "zimbra_account_alias_delete_modal_description": "Czy chcesz go usunąć?", + "zimbra_account_alias_delete_modal_cancel_btn": "Anuluj", + "zimbra_account_alias_delete_modal_delete_btn": "Usuń", + "zimbra_account_alias_delete_success_message": "Zlecenie usunięcia zostało przyjęte. Zostanie ona wykonana w ciągu kilku minut.", + "zimbra_account_alias_delete_error_message": "Zlecenie usunięcia nie powiodło się. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pt_PT.json new file mode 100644 index 000000000000..2f1a1be51eb3 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/delete/Messages_pt_PT.json @@ -0,0 +1,8 @@ +{ + "zimbra_account_alias_delete_modal_title": "Eliminar o alias", + "zimbra_account_alias_delete_modal_description": "Tem a certeza de que pretende eliminar este ficheiro?", + "zimbra_account_alias_delete_modal_cancel_btn": "Anular", + "zimbra_account_alias_delete_modal_delete_btn": "Suprimir", + "zimbra_account_alias_delete_success_message": "O seu pedido de eliminação foi corretamente tomado em conta. Será executada dentro de alguns instantes.", + "zimbra_account_alias_delete_error_message": "O seu pedido de eliminação não foi bem-sucedido. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_de_DE.json new file mode 100644 index 000000000000..6f1f1c4a4db5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_de_DE.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Name", + "zimbra_auto_replies_from": "Von", + "zimbra_auto_replies_until": "bis zum", + "zimbra_auto_replies_copyTo": "Kopieren nach" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_en_GB.json new file mode 100644 index 000000000000..ef882bc199db --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_en_GB.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Name", + "zimbra_auto_replies_from": "From the \n", + "zimbra_auto_replies_until": "Until", + "zimbra_auto_replies_copyTo": "Copy to" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_es_ES.json new file mode 100644 index 000000000000..b704337cd24d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_es_ES.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Nombre", + "zimbra_auto_replies_from": "Del", + "zimbra_auto_replies_until": "Hasta el", + "zimbra_auto_replies_copyTo": "Copiar en" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_CA.json new file mode 100644 index 000000000000..2fcff96db483 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_CA.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Nom", + "zimbra_auto_replies_from": "Du", + "zimbra_auto_replies_until": "Jusqu'au", + "zimbra_auto_replies_copyTo": "Copier vers" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_FR.json new file mode 100644 index 000000000000..2fcff96db483 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_fr_FR.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Nom", + "zimbra_auto_replies_from": "Du", + "zimbra_auto_replies_until": "Jusqu'au", + "zimbra_auto_replies_copyTo": "Copier vers" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_it_IT.json new file mode 100644 index 000000000000..4f7a2f97fdf0 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_it_IT.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Cognome", + "zimbra_auto_replies_from": "Dal", + "zimbra_auto_replies_until": "Fino al", + "zimbra_auto_replies_copyTo": "Copia in" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pl_PL.json new file mode 100644 index 000000000000..980bfb9548d4 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pl_PL.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Nazwisko", + "zimbra_auto_replies_from": "Od", + "zimbra_auto_replies_until": "Do", + "zimbra_auto_replies_copyTo": "Kopiuj do" +} diff --git a/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pt_PT.json new file mode 100644 index 000000000000..99d3650e11ae --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/autoReplies/Messages_pt_PT.json @@ -0,0 +1,6 @@ +{ + "zimbra_auto_replies_name": "Nome", + "zimbra_auto_replies_from": "De", + "zimbra_auto_replies_until": "Até", + "zimbra_auto_replies_copyTo": "Copiar para" +} diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_de_DE.json index 4cf7a36c438d..2ec70075dc1f 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_de_DE.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_de_DE.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statistiken", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Account pro Angebot", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Sie haben derzeit keine Postfächer.", - "zimbra_dashboard_tile_usefulLinks_title": "Nützliche Links" + "zimbra_dashboard_tile_usefulLinks_title": "Nützliche Links", + "zimbra_dashboard_domains_edit": "Konfiguration der Domain", + "zimbra_dashboard_domains_diagnostic": "Diagnose", + "zimbra_dashboard_email_accounts_settings": "Kontoeinstellungen", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Alias erstellen", + "zimbra_dashboard_email_accounts_alias_delete": "Alias löschen", + "zimbra_dashboard_email_accounts_redirections": "Weiterleitungen", + "zimbra_dashboard_email_accounts_redirections_add": "Weiterleitung erstellen", + "zimbra_dashboard_email_accounts_redirections_edit": "Weiterleitung bearbeiten", + "zimbra_dashboard_email_accounts_redirections_delete": "Eine Weiterleitung löschen", + "zimbra_dashboard_mailing_lists_add": "Mailingliste erstellen", + "zimbra_dashboard_mailing_lists_settings": "Mailingliste bearbeiten", + "zimbra_dashboard_mailing_lists": "Mailinglisten", + "zimbra_dashboard_redirections": "Weiterleitungen", + "zimbra_dashboard_redirections_edit": "Weiterleitung bearbeiten", + "zimbra_dashboard_redirections_delete": "Weiterleitung löschen", + "zimbra_dashboard_auto_replies": "Beantworter" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_en_GB.json index 844b6228d52f..8cdf4f976457 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_en_GB.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_en_GB.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statistics", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Account per solution", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "You currently do not have any mailboxes.", - "zimbra_dashboard_tile_usefulLinks_title": "Useful links" + "zimbra_dashboard_tile_usefulLinks_title": "Useful links", + "zimbra_dashboard_domains_edit": "Domain configuration", + "zimbra_dashboard_domains_diagnostic": "Diagnostic", + "zimbra_dashboard_email_accounts_settings": "Account settings", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Create an alias", + "zimbra_dashboard_email_accounts_alias_delete": "Delete an alias", + "zimbra_dashboard_email_accounts_redirections": "Redirections", + "zimbra_dashboard_email_accounts_redirections_add": "Create a redirection", + "zimbra_dashboard_email_accounts_redirections_edit": "Modify a redirection", + "zimbra_dashboard_email_accounts_redirections_delete": "Delete a redirection", + "zimbra_dashboard_mailing_lists_add": "Create mailing list", + "zimbra_dashboard_mailing_lists_settings": "Edit mailing list", + "zimbra_dashboard_mailing_lists": "Mailing lists", + "zimbra_dashboard_redirections": "Redirections", + "zimbra_dashboard_redirections_edit": "Modify the redirection", + "zimbra_dashboard_redirections_delete": "Delete redirection", + "zimbra_dashboard_auto_replies": "Auto-replies" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_es_ES.json index f763de8b3b96..41dc2af50593 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_es_ES.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_es_ES.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Estadísticas", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Cuenta por servicio", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Actualmente no tiene ninguna cuenta de correo.", - "zimbra_dashboard_tile_usefulLinks_title": "Enlaces útiles" + "zimbra_dashboard_tile_usefulLinks_title": "Enlaces útiles", + "zimbra_dashboard_domains_edit": "Configuración del dominio", + "zimbra_dashboard_domains_diagnostic": "Diagnóstico", + "zimbra_dashboard_email_accounts_settings": "Configuración de la cuenta", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Crear un alias", + "zimbra_dashboard_email_accounts_alias_delete": "Eliminar un alias", + "zimbra_dashboard_email_accounts_redirections": "Redirecciones", + "zimbra_dashboard_email_accounts_redirections_add": "Crear una redirección", + "zimbra_dashboard_email_accounts_redirections_edit": "Modificar una redirección", + "zimbra_dashboard_email_accounts_redirections_delete": "Eliminar una redirección", + "zimbra_dashboard_mailing_lists_add": "Crear una lista de difusión", + "zimbra_dashboard_mailing_lists_settings": "Editar lista de difusión", + "zimbra_dashboard_mailing_lists": "Listas de difusión", + "zimbra_dashboard_redirections": "Redirecciones", + "zimbra_dashboard_redirections_edit": "Modificar la redirección", + "zimbra_dashboard_redirections_delete": "Eliminar la redirección", + "zimbra_dashboard_auto_replies": "Respuesta automática" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_CA.json index 5b4e4ab37a43..e52b1af6a220 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_CA.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_CA.json @@ -2,18 +2,34 @@ "zimbra_dashboard_administrator_guide": "Guide administrateur", "zimbra_dashboard_domains": "Domaine", "zimbra_dashboard_domains_add": "Ajouter un domaine", + "zimbra_dashboard_domains_edit": "Configuration du domaine", "zimbra_dashboard_domains_delete": "Supprimer un domaine", + "zimbra_dashboard_domains_diagnostic": "Diagnostique", "zimbra_dashboard_email_accounts": "Comptes email", "zimbra_dashboard_email_accounts_add": "Créer un compte email", "zimbra_dashboard_email_accounts_edit": "Modifier le compte", + "zimbra_dashboard_email_accounts_settings": "Paramètres du compte", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Créer un alias", + "zimbra_dashboard_email_accounts_alias_delete": "Supprimer un alias", "zimbra_dashboard_email_accounts_delete": "Supprimer la boite mail", + "zimbra_dashboard_email_accounts_redirections": "Redirections", + "zimbra_dashboard_email_accounts_redirections_add": "Créer une redirection", + "zimbra_dashboard_email_accounts_redirections_edit": "Modifier une redirection", + "zimbra_dashboard_email_accounts_redirections_delete": "Supprimer une redirection", + "zimbra_dashboard_mailing_lists_add": "Créer une liste de diffusion", + "zimbra_dashboard_mailing_lists_settings": "Modifier la liste de diffusion", "zimbra_dashboard_error_service": "No services info", + "zimbra_dashboard_mailing_lists": "Listes de diffusion", "zimbra_dashboard_general_informations": "Informations générales", "zimbra_dashboard_header_guides": "Guides", "zimbra_dashboard_organizations": "Organisation", "zimbra_dashboard_organizations_add": "Ajouter une organisation", "zimbra_dashboard_organizations_edit": "Modifier l'organisation", "zimbra_dashboard_organizations_delete": "Supprimer l'organisation", + "zimbra_dashboard_redirections": "Redirections", + "zimbra_dashboard_redirections_edit": "Modifier la redirection", + "zimbra_dashboard_redirections_delete": "Supprimer la redirection", "zimbra_dashboard_title": "Zimbra", "zimbra_dashboard_usefull_links": "Liens utiles", "zimbra_dashboard_user_guides": "Guide d'utilisateur", @@ -26,5 +42,6 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statistiques", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Compte par offre", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Vous ne possedez actuellement aucune boite email.", - "zimbra_dashboard_tile_usefulLinks_title": "Liens utiles" + "zimbra_dashboard_tile_usefulLinks_title": "Liens utiles", + "zimbra_dashboard_auto_replies": "Répondeurs" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_FR.json index 5b4e4ab37a43..e52b1af6a220 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_fr_FR.json @@ -2,18 +2,34 @@ "zimbra_dashboard_administrator_guide": "Guide administrateur", "zimbra_dashboard_domains": "Domaine", "zimbra_dashboard_domains_add": "Ajouter un domaine", + "zimbra_dashboard_domains_edit": "Configuration du domaine", "zimbra_dashboard_domains_delete": "Supprimer un domaine", + "zimbra_dashboard_domains_diagnostic": "Diagnostique", "zimbra_dashboard_email_accounts": "Comptes email", "zimbra_dashboard_email_accounts_add": "Créer un compte email", "zimbra_dashboard_email_accounts_edit": "Modifier le compte", + "zimbra_dashboard_email_accounts_settings": "Paramètres du compte", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Créer un alias", + "zimbra_dashboard_email_accounts_alias_delete": "Supprimer un alias", "zimbra_dashboard_email_accounts_delete": "Supprimer la boite mail", + "zimbra_dashboard_email_accounts_redirections": "Redirections", + "zimbra_dashboard_email_accounts_redirections_add": "Créer une redirection", + "zimbra_dashboard_email_accounts_redirections_edit": "Modifier une redirection", + "zimbra_dashboard_email_accounts_redirections_delete": "Supprimer une redirection", + "zimbra_dashboard_mailing_lists_add": "Créer une liste de diffusion", + "zimbra_dashboard_mailing_lists_settings": "Modifier la liste de diffusion", "zimbra_dashboard_error_service": "No services info", + "zimbra_dashboard_mailing_lists": "Listes de diffusion", "zimbra_dashboard_general_informations": "Informations générales", "zimbra_dashboard_header_guides": "Guides", "zimbra_dashboard_organizations": "Organisation", "zimbra_dashboard_organizations_add": "Ajouter une organisation", "zimbra_dashboard_organizations_edit": "Modifier l'organisation", "zimbra_dashboard_organizations_delete": "Supprimer l'organisation", + "zimbra_dashboard_redirections": "Redirections", + "zimbra_dashboard_redirections_edit": "Modifier la redirection", + "zimbra_dashboard_redirections_delete": "Supprimer la redirection", "zimbra_dashboard_title": "Zimbra", "zimbra_dashboard_usefull_links": "Liens utiles", "zimbra_dashboard_user_guides": "Guide d'utilisateur", @@ -26,5 +42,6 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statistiques", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Compte par offre", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Vous ne possedez actuellement aucune boite email.", - "zimbra_dashboard_tile_usefulLinks_title": "Liens utiles" + "zimbra_dashboard_tile_usefulLinks_title": "Liens utiles", + "zimbra_dashboard_auto_replies": "Répondeurs" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_it_IT.json index 0d1b8d109c16..7abea445944e 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_it_IT.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_it_IT.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statistiche", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Account per servizio", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Al momento non disponi di nessuna casella email.", - "zimbra_dashboard_tile_usefulLinks_title": "Link utili" + "zimbra_dashboard_tile_usefulLinks_title": "Link utili", + "zimbra_dashboard_domains_edit": "Configurazione del dominio", + "zimbra_dashboard_domains_diagnostic": "Diagnostica", + "zimbra_dashboard_email_accounts_settings": "Impostazioni account", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Crea un alias", + "zimbra_dashboard_email_accounts_alias_delete": "Elimina un alias", + "zimbra_dashboard_email_accounts_redirections": "Reindirizzamenti", + "zimbra_dashboard_email_accounts_redirections_add": "Crea un reindirizzamento", + "zimbra_dashboard_email_accounts_redirections_edit": "Modifica un reindirizzamento", + "zimbra_dashboard_email_accounts_redirections_delete": "Elimina un reindirizzamento", + "zimbra_dashboard_mailing_lists_add": "Creare una mailing list", + "zimbra_dashboard_mailing_lists_settings": "Modifica lista di distribuzione", + "zimbra_dashboard_mailing_lists": "Mailing list", + "zimbra_dashboard_redirections": "Reindirizzamenti", + "zimbra_dashboard_redirections_edit": "Modifica il reindirizzamento", + "zimbra_dashboard_redirections_delete": "Elimina il reindirizzamento", + "zimbra_dashboard_auto_replies": "Risposte automatiche" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pl_PL.json index 3cdadcc220a8..22f1bd3b8257 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pl_PL.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pl_PL.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Statystyki", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Konto wg oferty", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Aktualnie nie posiadasz żadnej skrzynki e-mail.", - "zimbra_dashboard_tile_usefulLinks_title": "Przydatne linki" + "zimbra_dashboard_tile_usefulLinks_title": "Przydatne linki", + "zimbra_dashboard_domains_edit": "Konfiguracja domeny", + "zimbra_dashboard_domains_diagnostic": "Diagnostyka", + "zimbra_dashboard_email_accounts_settings": "Parametry konta", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Utwórz alias", + "zimbra_dashboard_email_accounts_alias_delete": "Usuń alias", + "zimbra_dashboard_email_accounts_redirections": "Przekierowania", + "zimbra_dashboard_email_accounts_redirections_add": "Utwórz przekierowanie", + "zimbra_dashboard_email_accounts_redirections_edit": "Edytuj przekierowanie", + "zimbra_dashboard_email_accounts_redirections_delete": "Usuń przekierowanie", + "zimbra_dashboard_mailing_lists_add": "Utwórz listę mailingową", + "zimbra_dashboard_mailing_lists_settings": "Edytuj listę mailingową", + "zimbra_dashboard_mailing_lists": "Listy mailingowe", + "zimbra_dashboard_redirections": "Przekierowania", + "zimbra_dashboard_redirections_edit": "Edytuj przekierowanie", + "zimbra_dashboard_redirections_delete": "Usuń przekierowanie", + "zimbra_dashboard_auto_replies": "Autorespondery" } diff --git a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pt_PT.json index e165ef2d7122..3aaa6a94c359 100644 --- a/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pt_PT.json +++ b/packages/manager/apps/zimbra/public/translations/dashboard/Messages_pt_PT.json @@ -34,5 +34,22 @@ "zimbra_dashboard_tile_serviceConsumption_title": "Estatísticas", "zimbra_dashboard_tile_serviceConsumption_accountOffer": "Conta por oferta", "zimbra_dashboard_tile_serviceConsumption_noAccountOffer": "Atualmente não dispõe de nenhuma caixa de e-mail.", - "zimbra_dashboard_tile_usefulLinks_title": "Ligações úteis" + "zimbra_dashboard_tile_usefulLinks_title": "Ligações úteis", + "zimbra_dashboard_domains_edit": "Configuração do domínio", + "zimbra_dashboard_domains_diagnostic": "Diagnóstico", + "zimbra_dashboard_email_accounts_settings": "Parâmetros da conta", + "zimbra_dashboard_email_accounts_alias": "Alias", + "zimbra_dashboard_email_accounts_alias_add": "Criar um alias", + "zimbra_dashboard_email_accounts_alias_delete": "Eliminar um alias", + "zimbra_dashboard_email_accounts_redirections": "Reencaminhamentos", + "zimbra_dashboard_email_accounts_redirections_add": "Criar um reencaminhamento", + "zimbra_dashboard_email_accounts_redirections_edit": "Modificar um reencaminhamento", + "zimbra_dashboard_email_accounts_redirections_delete": "Eliminar um reencaminhamento", + "zimbra_dashboard_mailing_lists_add": "Criar uma lista de difusão", + "zimbra_dashboard_mailing_lists_settings": "Modificar a lista de difusão", + "zimbra_dashboard_mailing_lists": "Listas de difusão", + "zimbra_dashboard_redirections": "Reencaminhamentos", + "zimbra_dashboard_redirections_edit": "Modificar o reencaminhamento", + "zimbra_dashboard_redirections_delete": "Eliminar o reencaminhamento", + "zimbra_dashboard_auto_replies": "Resposta automática" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_de_DE.json index 4c3012c84e88..848a5a8c5c0f 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_de_DE.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_de_DE.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organisation", "zimbra_domains_datagrid_account_number": "Anzahl der Accounts", "zimbra_domains_tooltip_delete": "Löschen", - "zimbra_domains_tooltip_need_organization": "Konfigurieren Sie zuerst eine Organisation." + "zimbra_domains_tooltip_need_organization": "Konfigurieren Sie zuerst eine Organisation.", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Einstellungen OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnose {{ diagType }}", + "zimbra_domains_tooltip_configure": "Konfigurieren" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_en_GB.json index f9ef7866b90d..b171af54e7aa 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_en_GB.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_en_GB.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organisation", "zimbra_domains_datagrid_account_number": "Number of accounts", "zimbra_domains_tooltip_delete": "Delete", - "zimbra_domains_tooltip_need_organization": "Please set up an organisation first" + "zimbra_domains_tooltip_need_organization": "Please set up an organisation first", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configuration OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnostic {{ diagType }}", + "zimbra_domains_tooltip_configure": "Configure" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_es_ES.json index ff75a8e349b7..065f1b93f4a1 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_es_ES.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_es_ES.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organización", "zimbra_domains_datagrid_account_number": "Número de cuentas", "zimbra_domains_tooltip_delete": "Eliminar", - "zimbra_domains_tooltip_need_organization": "En primer lugar, debe configurar una organización" + "zimbra_domains_tooltip_need_organization": "En primer lugar, debe configurar una organización", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configuración OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnóstico {{ diagType }}", + "zimbra_domains_tooltip_configure": "Configurar" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_CA.json index 7acbaa558485..912f98d04464 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_CA.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_CA.json @@ -2,9 +2,12 @@ "zimbra_domains_add_domain_title": "Ajouter un domaine", "zimbra_domains_datagrid_account_label": "Nombre de comptes", "zimbra_domains_datagrid_diagnostic_label": "Diagnostique", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configuration OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnostic {{ diagType }}", "zimbra_domains_datagrid_domain_label": "Domaine", "zimbra_domains_datagrid_organization_label": "Organisation", "zimbra_domains_datagrid_account_number": "Nombre de comptes", + "zimbra_domains_tooltip_configure": "Configurer", "zimbra_domains_tooltip_delete": "Supprimer", "zimbra_domains_tooltip_need_organization": "Veuillez d'abord configurer une organisation" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_FR.json index 7acbaa558485..912f98d04464 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_fr_FR.json @@ -2,9 +2,12 @@ "zimbra_domains_add_domain_title": "Ajouter un domaine", "zimbra_domains_datagrid_account_label": "Nombre de comptes", "zimbra_domains_datagrid_diagnostic_label": "Diagnostique", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configuration OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnostic {{ diagType }}", "zimbra_domains_datagrid_domain_label": "Domaine", "zimbra_domains_datagrid_organization_label": "Organisation", "zimbra_domains_datagrid_account_number": "Nombre de comptes", + "zimbra_domains_tooltip_configure": "Configurer", "zimbra_domains_tooltip_delete": "Supprimer", "zimbra_domains_tooltip_need_organization": "Veuillez d'abord configurer une organisation" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_it_IT.json index 88f8b4320a18..b39a80c409c1 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_it_IT.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_it_IT.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organizzazione", "zimbra_domains_datagrid_account_number": "Numero di account", "zimbra_domains_tooltip_delete": "Eliminare", - "zimbra_domains_tooltip_need_organization": "Configura prima un'organizzazione" + "zimbra_domains_tooltip_need_organization": "Configura prima un'organizzazione", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configurazione OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnostica {{ diagType }}", + "zimbra_domains_tooltip_configure": "Configura" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_pl_PL.json index 571671373550..f38dce31d9c9 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_pl_PL.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_pl_PL.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organizacja", "zimbra_domains_datagrid_account_number": "Liczba kont", "zimbra_domains_tooltip_delete": "Usuń", - "zimbra_domains_tooltip_need_organization": "Najpierw skonfiguruj organizację" + "zimbra_domains_tooltip_need_organization": "Najpierw skonfiguruj organizację", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Konfiguracja OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnostyka {{ diagType }}", + "zimbra_domains_tooltip_configure": "Skonfiguruj" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/domains/Messages_pt_PT.json index 02aeba12f44e..412da98b6577 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/Messages_pt_PT.json +++ b/packages/manager/apps/zimbra/public/translations/domains/Messages_pt_PT.json @@ -6,5 +6,8 @@ "zimbra_domains_datagrid_organization_label": "Organização", "zimbra_domains_datagrid_account_number": "Número de contas", "zimbra_domains_tooltip_delete": "Eliminar", - "zimbra_domains_tooltip_need_organization": "Comece por configurar uma organização" + "zimbra_domains_tooltip_need_organization": "Comece por configurar uma organização", + "zimbra_domains_datagrid_diagnostic_configuration_ok": "Configuração OK", + "zimbra_domains_datagrid_diagnostic_tooltip_title": "Diagnóstico {{ diagType }}", + "zimbra_domains_tooltip_configure": "Configurar" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_de_DE.json index 7a3407ba4c6c..9117fe70582d 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_de_DE.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_de_DE.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Eine Organisation auswählen", "zimbra_domains_add_domain_configuration_title": "Konfiguration", "zimbra_domains_add_domain_success_message": "Ihre Anfrage zum Hinzufügen wurde registriert. Sie wird in Kürze ausgeführt.", - "zimbra_domains_add_domain_error_message": "Ihre Anfrage zum Hinzufügen ist fehlgeschlagen. {{ error }}" + "zimbra_domains_add_domain_error_message": "Ihre Anfrage zum Hinzufügen ist fehlgeschlagen. {{ error }}", + "zimbra_domains_add_domain_cta_access_domains": "Zu meinen Domainnamen", + "zimbra_domains_add_domain_configuration_description": "Wie möchten Sie Ihre DNS-Zone konfigurieren?", + "zimbra_domains_add_domain_configuration_choice_standard": "Empfohlene Konfiguration", + "zimbra_domains_add_domain_configuration_choice_standard_info": "Wir richten Ihre Dienstleistung so ein, dass ein Höchstmaß an Sicherheit gewährleistet ist.", + "zimbra_domains_add_domain_configuration_choice_expert": "Benutzerdefinierte Konfiguration", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Sie können die Konfiguration personalisieren und auswählen, wann Ihre E-Mails auf diesen Dienst umgestellt werden sollen.", + "zimbra_domains_add_domain_configuration_expert_title": "Ihre Domain {{domain}} wird im autoritativen Modus konfiguriert.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "SRV-Eintrag automatisch konfigurieren (Autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "MX-Eintrag automatisch konfigurieren (E-Mails empfangen)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "SPF-Eintrag automatisch konfigurieren", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "DKIM-Eintrag automatisch konfigurieren", + "zimbra_domains_add_domain_configuration_cname_title": "Validierung Ihrer Domain", + "zimbra_domains_add_domain_configuration_cname_description": "Um zu bestätigen, dass Sie der Inhaber dieser Domain sind, fügen Sie bitte diesen Eintrag hinzu.", + "zimbra_domains_add_domain_configuration_info": "Sie haben 48 Stunden Zeit, um diese Validierung durchzuführen. Sie finden diese Informationen später in der Tabelle Domains.", + "zimbra_domains_add_domain_configuration_part_1": "Nach der Validierung Ihrer Domain müssen Sie die MX- und SRV-Einträge in Ihrer DNS-Zone manuell ändern.", + "zimbra_domains_add_domain_configuration_part_2": "Sie finden die erforderlichen Informationen im Bereich der dazugehörigen Domain.", + "zimbra_domains_add_domain_configuration_guides_referee": "Lesen Sie unsere Anleitung", + "zimbra_domains_add_domain_warning_modification_domain": "Stellen Sie sicher, dass die DNS-Zone der gewählten Domain vom Administrator geändert werden kann." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_en_GB.json index f94bacb96814..0f8ab73e4a6e 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_en_GB.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_en_GB.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Select an organisation", "zimbra_domains_add_domain_configuration_title": "Configuration", "zimbra_domains_add_domain_success_message": "Your add-in request has been submitted. It will be executed in a few moments.", - "zimbra_domains_add_domain_error_message": "Unable to submit your add-in request. {{ error }}" + "zimbra_domains_add_domain_error_message": "Unable to submit your add-in request. {{ error }}", + "zimbra_domains_add_domain_cta_access_domains": "Access my domain names", + "zimbra_domains_add_domain_configuration_description": "How do you want to configure your DNS zone?", + "zimbra_domains_add_domain_configuration_choice_standard": "Recommended configuration", + "zimbra_domains_add_domain_configuration_choice_standard_info": "We configure your service to ensure the best level of security.", + "zimbra_domains_add_domain_configuration_choice_expert": "Custom configuration", + "zimbra_domains_add_domain_configuration_choice_expert_info": "You can customize the configuration and choose when to switch your emails to this service.", + "zimbra_domains_add_domain_configuration_expert_title": "Your {{domain}} domain will be configured in authoritative mode.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configure the SRV record automatically (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configure MX record automatically (receive emails)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configure SPF record automatically", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configure DKIM record automatically", + "zimbra_domains_add_domain_configuration_cname_title": "Validation of your domain", + "zimbra_domains_add_domain_configuration_cname_description": "To confirm that you are the owner of this domain, please add this record.", + "zimbra_domains_add_domain_configuration_info": "You have 48 hours to complete this validation. You can find this information later in the domain table.", + "zimbra_domains_add_domain_configuration_part_1": "Once your domain has been validated, you will need to modify the MX and SRV records in your DNS zone manually.", + "zimbra_domains_add_domain_configuration_part_2": "You can find the information required in the section for the associated domain.", + "zimbra_domains_add_domain_configuration_guides_referee": "Please refer to our guide", + "zimbra_domains_add_domain_warning_modification_domain": "You must ensure that the DNS zone of the chosen domain can be modified by its administrator." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_es_ES.json index 8199db68ec3f..a9c1c110a22d 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_es_ES.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_es_ES.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Seleccionar una organización", "zimbra_domains_add_domain_configuration_title": "Configuración", "zimbra_domains_add_domain_success_message": "La solicitud de adición se ha enviado. Se ejecutará en unos instantes.", - "zimbra_domains_add_domain_error_message": "Se ha producido un error al enviar la solicitud de adición: {{ error }}" + "zimbra_domains_add_domain_error_message": "Se ha producido un error al enviar la solicitud de adición: {{ error }}", + "zimbra_domains_add_domain_cta_access_domains": "Acceder a mis dominios", + "zimbra_domains_add_domain_configuration_description": "¿Cómo quiere configurar la zona DNS?", + "zimbra_domains_add_domain_configuration_choice_standard": "Configuración recomendada", + "zimbra_domains_add_domain_configuration_choice_standard_info": "Estamos configurando su servicio para garantizar el mejor nivel de seguridad.", + "zimbra_domains_add_domain_configuration_choice_expert": "Configuración personalizada", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Puede personalizar la configuración y elegir cuándo migrar su correo a este servicio.", + "zimbra_domains_add_domain_configuration_expert_title": "El dominio {{domain}} se configurará en modo autoritario.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configurar el registro SRV automáticamente (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configurar el registro MX automáticamente (recepción de correo)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configurar el registro SPF automáticamente", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configurar el registro DKIM automáticamente", + "zimbra_domains_add_domain_configuration_cname_title": "Validación de su dominio", + "zimbra_domains_add_domain_configuration_cname_description": "Para validar que es el propietario de este dominio, agregue este registro.", + "zimbra_domains_add_domain_configuration_info": "Dispone de 48 horas para realizar esta validación. Puede consultar esta información más adelante en la tabla dominio.", + "zimbra_domains_add_domain_configuration_part_1": "Una vez validado el dominio, deberá editar manualmente los registros MX y SRV en la zona DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Puede encontrar la información necesaria en la sección del dominio asociado.", + "zimbra_domains_add_domain_configuration_guides_referee": "Por favor, consulte nuestra guía", + "zimbra_domains_add_domain_warning_modification_domain": "Debe asegurarse de que el administrador del dominio puede modificar la zona DNS del dominio elegido." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_CA.json index 6321341206f4..6911c8c29928 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_CA.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_CA.json @@ -1,6 +1,7 @@ { "zimbra_domains_add_domain_cta_back": "Retour vers les noms de domaine", "zimbra_domains_add_domain_cta_confirm": "Confirmer", + "zimbra_domains_add_domain_cta_access_domains": "Accéder à mes noms de domaine", "zimbra_domains_add_domain_cta_next": "Suivant", "zimbra_domains_add_domain_title": "Nom de domaine", "zimbra_domains_add_domain_title_select": "Ajouter un domaine", @@ -11,6 +12,23 @@ "zimbra_domains_add_domain_organization": "Organisation", "zimbra_domains_add_domain_organization_select": "Sélectionner une organisation", "zimbra_domains_add_domain_configuration_title": "Configuration", + "zimbra_domains_add_domain_configuration_description": "Comment voulez-vous configurer votre zone DNS ?", + "zimbra_domains_add_domain_configuration_choice_standard": "Configuration recommandée", + "zimbra_domains_add_domain_configuration_choice_standard_info": "Nous configurons votre service pour assurer le meilleur niveau de sécurité.", + "zimbra_domains_add_domain_configuration_choice_expert": "Configuration personnalisée", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Vous pouvez personnaliser la configuration et choisir quand basculer vos emails vers ce service.", + "zimbra_domains_add_domain_configuration_expert_title": "Votre domaine {{domain}} sera configuré en mode autoritatif.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configurer l'enregistrement SRV automatiquement (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configurer l'enregistrement MX automatiquement (réception des emails)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configurer l'enregistrement SPF automatiquement", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configurer l'enregistrement DKIM automatiquement", + "zimbra_domains_add_domain_configuration_cname_title": "Validation de votre domaine", + "zimbra_domains_add_domain_configuration_cname_description": "Pour valider que vous êtes propriétaire de ce domaine, veuillez ajouter cet enregistrement.", + "zimbra_domains_add_domain_configuration_info": "Vous avez 48 heures pour effectuer cette validation. Vous pourrez retrouver ces informations à posteriori dans la table domaine.", + "zimbra_domains_add_domain_configuration_part_1": "Suite à la validation de votre domaine, vous devrez modifier manuellement les enregistrements MX et SRV dans votre zone DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Vous pourrez trouver les informations requises dans la section du domaine associée.", + "zimbra_domains_add_domain_configuration_guides_referee": "Veuillez vous référer à notre guide", + "zimbra_domains_add_domain_warning_modification_domain": "Vous devez vous assurer que la zone DNS du domaine choisi peut être modifiée par son administrateur.", "zimbra_domains_add_domain_success_message": "Votre demande d'ajout a bien été prise en compte. Elle sera exécutée d'ici quelques instants.", "zimbra_domains_add_domain_error_message": "Votre demande d'ajout n'a pas pu aboutir. {{ error }}" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_FR.json index 6321341206f4..6911c8c29928 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_fr_FR.json @@ -1,6 +1,7 @@ { "zimbra_domains_add_domain_cta_back": "Retour vers les noms de domaine", "zimbra_domains_add_domain_cta_confirm": "Confirmer", + "zimbra_domains_add_domain_cta_access_domains": "Accéder à mes noms de domaine", "zimbra_domains_add_domain_cta_next": "Suivant", "zimbra_domains_add_domain_title": "Nom de domaine", "zimbra_domains_add_domain_title_select": "Ajouter un domaine", @@ -11,6 +12,23 @@ "zimbra_domains_add_domain_organization": "Organisation", "zimbra_domains_add_domain_organization_select": "Sélectionner une organisation", "zimbra_domains_add_domain_configuration_title": "Configuration", + "zimbra_domains_add_domain_configuration_description": "Comment voulez-vous configurer votre zone DNS ?", + "zimbra_domains_add_domain_configuration_choice_standard": "Configuration recommandée", + "zimbra_domains_add_domain_configuration_choice_standard_info": "Nous configurons votre service pour assurer le meilleur niveau de sécurité.", + "zimbra_domains_add_domain_configuration_choice_expert": "Configuration personnalisée", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Vous pouvez personnaliser la configuration et choisir quand basculer vos emails vers ce service.", + "zimbra_domains_add_domain_configuration_expert_title": "Votre domaine {{domain}} sera configuré en mode autoritatif.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configurer l'enregistrement SRV automatiquement (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configurer l'enregistrement MX automatiquement (réception des emails)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configurer l'enregistrement SPF automatiquement", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configurer l'enregistrement DKIM automatiquement", + "zimbra_domains_add_domain_configuration_cname_title": "Validation de votre domaine", + "zimbra_domains_add_domain_configuration_cname_description": "Pour valider que vous êtes propriétaire de ce domaine, veuillez ajouter cet enregistrement.", + "zimbra_domains_add_domain_configuration_info": "Vous avez 48 heures pour effectuer cette validation. Vous pourrez retrouver ces informations à posteriori dans la table domaine.", + "zimbra_domains_add_domain_configuration_part_1": "Suite à la validation de votre domaine, vous devrez modifier manuellement les enregistrements MX et SRV dans votre zone DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Vous pourrez trouver les informations requises dans la section du domaine associée.", + "zimbra_domains_add_domain_configuration_guides_referee": "Veuillez vous référer à notre guide", + "zimbra_domains_add_domain_warning_modification_domain": "Vous devez vous assurer que la zone DNS du domaine choisi peut être modifiée par son administrateur.", "zimbra_domains_add_domain_success_message": "Votre demande d'ajout a bien été prise en compte. Elle sera exécutée d'ici quelques instants.", "zimbra_domains_add_domain_error_message": "Votre demande d'ajout n'a pas pu aboutir. {{ error }}" } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_it_IT.json index efda8df4850e..1fa12f52c39a 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_it_IT.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_it_IT.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Selezionare un'organizzazione", "zimbra_domains_add_domain_configuration_title": "Configurazione", "zimbra_domains_add_domain_success_message": "La tua richiesta di aggiunta è stata presa in carico. Sarà eseguita entro pochi minuti.", - "zimbra_domains_add_domain_error_message": "La tua richiesta di aggiunta non è andata a buon fine: {{ error }}" + "zimbra_domains_add_domain_error_message": "La tua richiesta di aggiunta non è andata a buon fine: {{ error }}", + "zimbra_domains_add_domain_cta_access_domains": "Accedi ai tuoi domini", + "zimbra_domains_add_domain_configuration_description": "Come configurare la zona DNS?", + "zimbra_domains_add_domain_configuration_choice_standard": "Configurazione consigliata", + "zimbra_domains_add_domain_configuration_choice_standard_info": "OVHcloud configura il servizio per garantire il massimo livello di sicurezza.", + "zimbra_domains_add_domain_configuration_choice_expert": "Configurazione personalizzata", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Puoi personalizzare la configurazione e scegliere quando trasferire le tue email verso questo servizio.", + "zimbra_domains_add_domain_configuration_expert_title": "Il dominio {{domain}} verrà configurato in modalità autoritativa.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configura il record SRV automaticamente (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configura il record MX automaticamente (ricezione email)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configura il record SPF automaticamente", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configura record DKIM automaticamente", + "zimbra_domains_add_domain_configuration_cname_title": "Conferma del tuo dominio", + "zimbra_domains_add_domain_configuration_cname_description": "Per confermare di essere proprietario di questo dominio, è necessario aggiungere questo record.", + "zimbra_domains_add_domain_configuration_info": "Hai 48 ore per effettuare questa convalida. Queste informazioni sono disponibili a posteriori nella tabella dominio.", + "zimbra_domains_add_domain_configuration_part_1": "Una volta confermata la registrazione del dominio, è necessario modificare manualmente i record MX e SRV della zona DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Le informazioni richieste sono disponibili nella sezione del dominio associata.", + "zimbra_domains_add_domain_configuration_guides_referee": "Consulta la nostra guida", + "zimbra_domains_add_domain_warning_modification_domain": "Assicurati che la zona DNS del dominio scelto possa essere modificata dall'amministratore." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pl_PL.json index 709ac808a2e6..caf8a1cd6341 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pl_PL.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pl_PL.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Wybierz organizację", "zimbra_domains_add_domain_configuration_title": "Konfiguracja", "zimbra_domains_add_domain_success_message": "Dyspozycja dodania została przyjęta. Zostanie wykonana w ciągu kilku minut.", - "zimbra_domains_add_domain_error_message": "Dodanie nie powiodło się. {{error}}" + "zimbra_domains_add_domain_error_message": "Dodanie nie powiodło się. {{error}}", + "zimbra_domains_add_domain_cta_access_domains": "Dostęp do domen", + "zimbra_domains_add_domain_configuration_description": "W jaki sposób chcesz skonfigurować Twoją strefę DNS?", + "zimbra_domains_add_domain_configuration_choice_standard": "Rekomendowana konfiguracja:", + "zimbra_domains_add_domain_configuration_choice_standard_info": "Konfigurujemy Twoją usługę, aby zapewnić najwyższy poziom bezpieczeństwa.", + "zimbra_domains_add_domain_configuration_choice_expert": "Konfiguracja niestandardowa", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Możesz spersonalizować konfigurację i wybrać, kiedy przełączyć e-maile do tej usługi.", + "zimbra_domains_add_domain_configuration_expert_title": "Twoja domena {{domain}} zostanie skonfigurowana w trybie autorytatywnym.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Skonfiguruj automatycznie rekord SRV (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Skonfiguruj automatycznie rekord MX (otrzymywanie e-maili)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Automatycznie konfiguruj rekord SPF", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Skonfiguruj automatycznie rekord DKIM", + "zimbra_domains_add_domain_configuration_cname_title": "Potwierdzenie domeny", + "zimbra_domains_add_domain_configuration_cname_description": "Aby potwierdzić, że jesteś właścicielem tej domeny, dodaj ten rekord.", + "zimbra_domains_add_domain_configuration_info": "Zatwierdzenie operacji należy wykonać w ciągu 48 godzin. Informacje te odnajdziesz później w tabeli Domeny.", + "zimbra_domains_add_domain_configuration_part_1": "Po zatwierdzeniu domeny będziesz musiał ręcznie zmienić wpisy MX i SRV w strefie DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Wymagane informacje są dostępne w sekcji przypisanej domeny.", + "zimbra_domains_add_domain_configuration_guides_referee": "Sprawdź przewodnik", + "zimbra_domains_add_domain_warning_modification_domain": "Upewnij się, że ustawienia w strefie DNS wybranej domeny będą mogły zostać zmienione przez jej administratora." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pt_PT.json index 79a68a3c6432..af9f803c357f 100644 --- a/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pt_PT.json +++ b/packages/manager/apps/zimbra/public/translations/domains/addDomain/Messages_pt_PT.json @@ -12,5 +12,23 @@ "zimbra_domains_add_domain_organization_select": "Escolher uma organização", "zimbra_domains_add_domain_configuration_title": "Configuração", "zimbra_domains_add_domain_success_message": "O seu pedido de adição foi registado. Será executado dentro de alguns instantes.", - "zimbra_domains_add_domain_error_message": "O seu pedido de adição não foi bem-sucedido. {{ error }}" + "zimbra_domains_add_domain_error_message": "O seu pedido de adição não foi bem-sucedido. {{ error }}", + "zimbra_domains_add_domain_cta_access_domains": "Aceder aos meus nomes de domínio", + "zimbra_domains_add_domain_configuration_description": "Como pretende configurar a sua zona DNS?", + "zimbra_domains_add_domain_configuration_choice_standard": "Configuração recomendada", + "zimbra_domains_add_domain_configuration_choice_standard_info": "A OVHcloud configura o seu serviço para assegurar o melhor nível de segurança.", + "zimbra_domains_add_domain_configuration_choice_expert": "Definições personalizadas", + "zimbra_domains_add_domain_configuration_choice_expert_info": "Pode personalizar a configuração e escolher quando migrar os seus emails para este serviço.", + "zimbra_domains_add_domain_configuration_expert_title": "O seu domínio {{domain}} será configurado em modo autoritário.", + "zimbra_domains_add_domain_configuration_expert_configure_srv": "Configurar o registo SRV automaticamente (autodiscover)", + "zimbra_domains_add_domain_configuration_expert_configure_mx": "Configurar o registo MX automaticamente (receção dos e-mails)", + "zimbra_domains_add_domain_configuration_expert_configure_spf": "Configurar o registo SPF automaticamente", + "zimbra_domains_add_domain_configuration_expert_configure_dkim": "Configurar o registo DKIM automaticamente", + "zimbra_domains_add_domain_configuration_cname_title": "Validação do seu domínio", + "zimbra_domains_add_domain_configuration_cname_description": "Para validar que é proprietário deste domínio, queira adicionar este registo.", + "zimbra_domains_add_domain_configuration_info": "Terá 48 horas para efetuar esta validação. Poderá consultar essas informações a posteriori na tabela domínio.", + "zimbra_domains_add_domain_configuration_part_1": "Após a validação do seu domínio, deverá modificar manualmente os registos MX e SRV na sua zona DNS.", + "zimbra_domains_add_domain_configuration_part_2": "Poderá encontrar as informações necessárias na secção do domínio associado.", + "zimbra_domains_add_domain_configuration_guides_referee": "Consulte o nosso manual", + "zimbra_domains_add_domain_warning_modification_domain": "Deve assegurar-se de que a zona DNS do domínio pode ser alterada pelo seu administrador." } diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_de_DE.json new file mode 100644 index 000000000000..dbcc4c21959f --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_de_DE.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "Hilfe.", + "zimbra_domain_modal_diagnostic_srv_title": "SRV-Diagnose", + "zimbra_domain_modal_diagnostic_srv_content_header": "Um die Konfiguration der Mailboxen auf Ihren Geräten zu vereinfachen, fügen Sie bitte diese Konfiguration zu Ihrem DNS hinzu (siehe )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "Die SRV Konfiguration erlaubt die automatische Konfiguration Ihrer E-Mail Accounts auf Ihren E-Mail Clients.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Ihre Domain ist bei OVHcloud gehostet, wir werden Ihren SRV-Eintrag konfigurieren.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domain", + "zimbra_domain_modal_diagnostic_fields": "Felder", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Bestätigen", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Abbrechen", + "zimbra_domain_modal_diagnostic_srv_action_close": "Schliessen", + "zimbra_domain_modal_diagnostic_field_subdomain": "Subdomain:", + "zimbra_domain_modal_diagnostic_field_priority": "Priorität", + "zimbra_domain_modal_diagnostic_field_weight": "Gewicht", + "zimbra_domain_modal_diagnostic_field_port": "Port:", + "zimbra_domain_modal_diagnostic_field_target": "Ziel", + "zimbra_domain_modal_diagnostic_mx_title": "MX Diagnose", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "Die Konfiguration des MX Eintrags erlaubt den Empfang Ihrer E-Mails in Ihren E-Mail Accounts.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Da Ihre Domain nicht von OVHcloud verwaltet wird, muss diese Aktion manuell durchgeführt werden.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Bitte erstellen Sie die MX-Einträge für diese Domain mit den gleichen Informationen wie unten angegeben.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "Die Konfiguration des MX Eintrags erlaubt den Empfang Ihrer E-Mails in Ihren E-Mail Accounts.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Da Ihre Domain bei OVHcloud gehostet wird, werden wir die Konfiguration für Sie vornehmen.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Möchten Sie mit dem Empfang von E-Mails der Domain {{domain}} für diesen Dienst beginnen?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "Bei Problemen lesen Sie bitte die Dokumentation Ihres Domain-Anbieters.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Bestätigen", + "zimbra_domain_modal_diagnostic_mx_action_test": "Testen", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Abbrechen", + "zimbra_domain_modal_diagnostic_mx_action_close": "Schliessen", + "zimbra_domain_modal_diagnostic_spf_title": "SPF-Diagnose", + "zimbra_domain_modal_diagnostic_spf_content_header": "Wenn die Domain nicht über dieselbe Kundenkennung wie Exchange verwaltet oder nicht bei OVHcloud gehostet wird, ist die automatische Konfiguration nicht möglich. Bitte erstellen Sie den SPF-Eintrag für diese Domain manuell mit den gleichen Informationen wie unten angegeben.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "Mit SPF können Sie bestätigen, dass OVHcloud ein legitimer E-Mail-Absender mit Ihrem Domainnamen ist.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Da Ihre Domain bei OVHcloud gehostet wird, können wir die automatische Konfiguration durchführen.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Möchten Sie die Konfiguration durchführen?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Abbrechen", + "zimbra_domain_modal_diagnostic_spf_action_close": "Schliessen", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_en_GB.json new file mode 100644 index 000000000000..fa5768999e86 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_en_GB.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "Guide.", + "zimbra_domain_modal_diagnostic_srv_title": "SRV diagnostic", + "zimbra_domain_modal_diagnostic_srv_content_header": "To make it easier to configure mailboxes on your devices, please add this configuration to your DNS (see our )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "The SRV configuration allows automatic configuration of your mailboxes on your email clients.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Your domain is hosted with OVH Cloud. We will configure your SRV record.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domain", + "zimbra_domain_modal_diagnostic_fields": "Fields", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Confirm", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Cancel", + "zimbra_domain_modal_diagnostic_srv_action_close": "Close", + "zimbra_domain_modal_diagnostic_field_subdomain": "Sub-domain:", + "zimbra_domain_modal_diagnostic_field_priority": "Priority:", + "zimbra_domain_modal_diagnostic_field_weight": "Weight:", + "zimbra_domain_modal_diagnostic_field_port": "Port:", + "zimbra_domain_modal_diagnostic_field_target": "Target:", + "zimbra_domain_modal_diagnostic_mx_title": "MX Diagnostic", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "The MX record configuration allows you to receive your emails in your mailboxes.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Since your domain is not managed by OVHcloud, you will need to do this manually.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Please create the MX records for this domain using the same information as below.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "The MX record configuration allows you to receive your emails in your mailboxes.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Since your domain is hosted by OVHcloud, we will configure it for you.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Do you want to start receiving emails from the {{domain}} domain on this service?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "If you encounter any issues, please consult your domain provider’s documentation.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Confirm", + "zimbra_domain_modal_diagnostic_mx_action_test": "Test", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Cancel", + "zimbra_domain_modal_diagnostic_mx_action_close": "Close", + "zimbra_domain_modal_diagnostic_spf_title": "SPF diagnostic", + "zimbra_domain_modal_diagnostic_spf_content_header": "If the domain is not managed by the same NIC handle as the Exchange service, or if your domain is not hosted with OVHcloud, automatic configuration is not possible. Please create the SPF record on this domain manually, giving the same information as below.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "SPF allows you to confirm that OVHcloud is a legitimate email sender with your domain name.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Since your domain is hosted with OVHcloud, we can proceed with automatic configuration.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Do you want to configure it?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Cancel", + "zimbra_domain_modal_diagnostic_spf_action_close": "Close", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_es_ES.json new file mode 100644 index 000000000000..101a7cfa848a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_es_ES.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "guía", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnóstico SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Para facilitar la configuración de las cuentas de correo en sus terminales, añada esta configuración a su DNS (consulte nuestra )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "La configuración SRV permite la configuración automática de las cuentas de correo en los clientes de correo.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Su dominio está alojado en OVH Cloud. Vamos a proceder a la configuración de su registro SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Dominio", + "zimbra_domain_modal_diagnostic_fields": "Campos", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Aceptar", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Cancelar", + "zimbra_domain_modal_diagnostic_srv_action_close": "Cerrar", + "zimbra_domain_modal_diagnostic_field_subdomain": "Subdominio:", + "zimbra_domain_modal_diagnostic_field_priority": "Prioridad:", + "zimbra_domain_modal_diagnostic_field_weight": "Peso:", + "zimbra_domain_modal_diagnostic_field_port": "Puerto:", + "zimbra_domain_modal_diagnostic_field_target": "Destino:", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnóstico MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "La configuración del registro MX permite recibir mensajes de correo en sus cuentas de correo.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Su dominio no está gestionado por OVH Cloud, por lo que esta acción debe realizarse manualmente.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Por favor, cree los registros MX en este dominio introduciendo la misma información que se indica a continuación.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "La configuración del registro MX permite recibir mensajes de correo en sus cuentas de correo.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Como su dominio está alojado en OVH Cloud, vamos a realizar la configuración por usted.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "¿Quiere empezar a recibir los emails del dominio {{domain}} en este servicio?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "Si tiene problemas, consulte la documentación de su proveedor de dominio.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Confirmar", + "zimbra_domain_modal_diagnostic_mx_action_test": "Probar", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Cancelar", + "zimbra_domain_modal_diagnostic_mx_action_close": "Cerrar", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnóstico SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Si el dominio no es gestionado por el mismo ID de cliente que el servicio Exchange, o si el dominio no está alojado en OVHcloud, no es posible realizar la configuración automática. Por favor, cree el registro SPF en este dominio manualmente introduciendo la misma información que se indica a continuación.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "SPF permite validar que OVHcloud es un emisor legítimo de emails con su dominio.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Como su dominio está alojado en OVHcloud, podemos proceder a la configuración automática.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "¿Quiere realizar la configuración?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Cancelar", + "zimbra_domain_modal_diagnostic_spf_action_close": "Cerrar", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Aceptar" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_CA.json new file mode 100644 index 000000000000..ded8a920ff98 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_CA.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "guide", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnostique SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Pour faciliter la configuration des boites mails sur vos terminaux, veuillez ajouter cette configuration à votre DNS (consulter notre )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "La configuration SRV permet la configuration automatique de vos boites mails sur vos clients de messagerie.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Votre domaine est hébergé chez OVH Cloud, nous allons procéder à la configuration de votre champ SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domaine", + "zimbra_domain_modal_diagnostic_fields": "Champs", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Valider", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_srv_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_field_subdomain": "Sous domaine :", + "zimbra_domain_modal_diagnostic_field_priority": "Priorité :", + "zimbra_domain_modal_diagnostic_field_weight": "Poids :", + "zimbra_domain_modal_diagnostic_field_port": "Port :", + "zimbra_domain_modal_diagnostic_field_target": "Cible :", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnostique MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "La configuration de l'enregistrement MX permet de recevoir vos emails dans vos boites mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Votre domaine n'étant pas géré par OVH Cloud, cette action doit être effectuée manuellement.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Veuillez créer les champs MX sur ce domaine en donnant les mêmes informations que ci-dessous.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "La configuration de l'enregistrement MX permet de recevoir vos emails dans vos boites mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Votre domaine étant hébergé chez OVH Cloud, nous allons effectuer la configuration pour vous.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Souhaitez-vous commencer à recevoir les mails du domaine {{domain}} sur ce service ?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "En cas de problème, consultez la documentation de votre fournisseur de domaine.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Confirmer", + "zimbra_domain_modal_diagnostic_mx_action_test": "Tester", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_mx_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnostique SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Si le domaine n'est pas géré par le même identifiant client que le service Exchange ou si votre domaine n'est pas hébergé chez OVHcloud, la configuration automatique n'est pas possible. Veuillez créer le champ SPF sur ce domaine manuellement en donnant les mêmes informations que ci-dessous.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "SPF permet de valider qu'OVHCloud est un émetteur légitime de mails avec votre nom de domaine.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Votre domaine étant hébergé chez OVHCloud, nous pouvons procéder à la configuration automatique.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Souhaitez-vous effectuer la configuration ?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_spf_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_FR.json new file mode 100644 index 000000000000..ded8a920ff98 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_fr_FR.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "guide", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnostique SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Pour faciliter la configuration des boites mails sur vos terminaux, veuillez ajouter cette configuration à votre DNS (consulter notre )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "La configuration SRV permet la configuration automatique de vos boites mails sur vos clients de messagerie.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Votre domaine est hébergé chez OVH Cloud, nous allons procéder à la configuration de votre champ SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domaine", + "zimbra_domain_modal_diagnostic_fields": "Champs", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Valider", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_srv_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_field_subdomain": "Sous domaine :", + "zimbra_domain_modal_diagnostic_field_priority": "Priorité :", + "zimbra_domain_modal_diagnostic_field_weight": "Poids :", + "zimbra_domain_modal_diagnostic_field_port": "Port :", + "zimbra_domain_modal_diagnostic_field_target": "Cible :", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnostique MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "La configuration de l'enregistrement MX permet de recevoir vos emails dans vos boites mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Votre domaine n'étant pas géré par OVH Cloud, cette action doit être effectuée manuellement.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Veuillez créer les champs MX sur ce domaine en donnant les mêmes informations que ci-dessous.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "La configuration de l'enregistrement MX permet de recevoir vos emails dans vos boites mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Votre domaine étant hébergé chez OVH Cloud, nous allons effectuer la configuration pour vous.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Souhaitez-vous commencer à recevoir les mails du domaine {{domain}} sur ce service ?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "En cas de problème, consultez la documentation de votre fournisseur de domaine.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Confirmer", + "zimbra_domain_modal_diagnostic_mx_action_test": "Tester", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_mx_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnostique SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Si le domaine n'est pas géré par le même identifiant client que le service Exchange ou si votre domaine n'est pas hébergé chez OVHcloud, la configuration automatique n'est pas possible. Veuillez créer le champ SPF sur ce domaine manuellement en donnant les mêmes informations que ci-dessous.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "SPF permet de valider qu'OVHCloud est un émetteur légitime de mails avec votre nom de domaine.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Votre domaine étant hébergé chez OVHCloud, nous pouvons procéder à la configuration automatique.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Souhaitez-vous effectuer la configuration ?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Annuler", + "zimbra_domain_modal_diagnostic_spf_action_close": "Fermer", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_it_IT.json new file mode 100644 index 000000000000..6f00ae37eda5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_it_IT.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "guida.", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnostica SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Per facilitare la configurazione delle caselle di posta sui tuoi terminali, aggiungi questa configurazione al tuo DNS (consulta la nostra )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "La configurazione SRV permette la configurazione automatica delle caselle di posta sui client di posta.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Il tuo dominio è ospitato in OVH Cloud. Procederemo alla configurazione del tuo record SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Dominio", + "zimbra_domain_modal_diagnostic_fields": "Campi", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Conferma", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Annulla", + "zimbra_domain_modal_diagnostic_srv_action_close": "Chiudere", + "zimbra_domain_modal_diagnostic_field_subdomain": "Sottodominio:", + "zimbra_domain_modal_diagnostic_field_priority": "Priorità:", + "zimbra_domain_modal_diagnostic_field_weight": "Peso:", + "zimbra_domain_modal_diagnostic_field_port": "Porta:", + "zimbra_domain_modal_diagnostic_field_target": "Destinazione:", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnostica MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "La configurazione del record MX permette di ricevere le tue email nelle caselle mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Il dominio non è gestito da OVH Cloud ed è quindi necessario eseguirlo manualmente.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Creare i record MX su questo dominio fornendo le stesse informazioni indicate qui sotto.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "La configurazione del record MX permette di ricevere le tue email nelle caselle mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Se il tuo dominio è ospitato in OVH Cloud, effettueremo la configurazione per te.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Vuoi iniziare a ricevere le email del dominio {{domain}} su questo servizio?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "In caso di problemi, consulta la documentazione del tuo provider di dominio.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Conferma", + "zimbra_domain_modal_diagnostic_mx_action_test": "Testare", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Annulla", + "zimbra_domain_modal_diagnostic_mx_action_close": "Chiudere", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnostica SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Se il dominio non è gestito dallo stesso identificativo cliente della tua piattaforma Exchange o non è registrato in OVHcloud, non è possibile eseguire la configurazione automatica. Crea manualmente il record SPF su questo dominio fornendo le stesse informazioni indicate qui sotto.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "Il record SPF permette di confermare che OVHcloud è un mittente legittimo di email con il tuo dominio.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Se il tuo dominio è ospitato in OVHcloud, possiamo procedere alla configurazione automatica.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Vuoi effettuare la configurazione?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Annulla", + "zimbra_domain_modal_diagnostic_spf_action_close": "Chiudere", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pl_PL.json new file mode 100644 index 000000000000..bf654a07efbd --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pl_PL.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "przewodniku", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnostyka SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Aby ułatwić konfigurację kont e-mail na Twoich urządzeniach końcowych, dodaj tę konfigurację do Twojego DNS (sprawdź naszą )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "Konfiguracja SRV pozwala na automatyczną konfigurację skrzynek e-mail na klientach poczty.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "Twoja domena jest zainstalowana w OVH Cloud. Przystąpimy do konfiguracji Twojego pola SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domena", + "zimbra_domain_modal_diagnostic_fields": "Pola", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Potwierdź", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Anuluj", + "zimbra_domain_modal_diagnostic_srv_action_close": "Zamknij", + "zimbra_domain_modal_diagnostic_field_subdomain": "Subdomena:", + "zimbra_domain_modal_diagnostic_field_priority": "Priorytet:", + "zimbra_domain_modal_diagnostic_field_weight": "Waga:", + "zimbra_domain_modal_diagnostic_field_port": "Port:", + "zimbra_domain_modal_diagnostic_field_target": "Adres docelowy:", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnostyka MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "Konfiguracja rekordu MX pozwala na otrzymywanie e-maili na skrzynki e-mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "Ponieważ Twoja domena nie jest zarządzana przez OVHcloud, operację tę należy przeprowadzić ręcznie.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Utwórz pola MX dla tej domeny, wprowadzając te same informacje, co poniżej.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "Konfiguracja rekordu MX pozwala na otrzymywanie e-maili na skrzynki e-mail.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "Ponieważ Twoja domena jest zainstalowana w OVHcloud, przeprowadzimy konfigurację za Ciebie.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Czy chcesz rozpocząć odbiór e-maili domeny {{domain}} dla tej usługi?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "W przypadku problemów należy zapoznać się z dokumentacją dostawcy domeny.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Zatwierdź", + "zimbra_domain_modal_diagnostic_mx_action_test": "Testuj", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Anuluj", + "zimbra_domain_modal_diagnostic_mx_action_close": "Zamknij", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnostyka SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Jeśli domena nie jest zarządzana przez ten sam identyfikator klienta, który zarządza usługą Exchange lub jeśli domena nie jest obsługiwana w OVHcloud, automatyczna konfiguracja nie będzie możliwa. Utwórz ręcznie pole SPF dla tej domeny, wprowadzając te same informacje, co poniżej.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "SPF pozwala na potwierdzenie, że OVHCloud jest uprawnionym nadawcą e-maili dla Twojej domeny.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Ponieważ Twoja domena jest zainstalowana w OVHCloud, możemy przeprowadzić automatyczną konfigurację.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Czy chcesz przeprowadzić konfigurację?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Anuluj", + "zimbra_domain_modal_diagnostic_spf_action_close": "Zamknij", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pt_PT.json new file mode 100644 index 000000000000..e9772c1379cd --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/diagnostic/Messages_pt_PT.json @@ -0,0 +1,37 @@ +{ + "zimbra_domain_modal_diagnostic_guide": "guia", + "zimbra_domain_modal_diagnostic_srv_title": "Diagnóstico SRV", + "zimbra_domain_modal_diagnostic_srv_content_header": "Para facilitar a configuração das caixas de e-mail nos seus terminais, adicione esta configuração ao seu DNS (consulte a nossa )", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1": "A configuração SRV permite a configuração automática das suas caixas de email nos seus clientes de email.", + "zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2": "O seu domínio está alojado na OVH Cloud. Vamos proceder à configuração do seu campo SRV.", + "zimbra_domain_modal_diagnostic_srv_domain": "Domínio", + "zimbra_domain_modal_diagnostic_fields": "Campos", + "zimbra_domain_modal_diagnostic_srv_action_validate": "Validar", + "zimbra_domain_modal_diagnostic_srv_action_cancel": "Anular", + "zimbra_domain_modal_diagnostic_srv_action_close": "Fechar", + "zimbra_domain_modal_diagnostic_field_subdomain": "Subdomínio:", + "zimbra_domain_modal_diagnostic_field_priority": "Prioridade:", + "zimbra_domain_modal_diagnostic_field_weight": "Peso:", + "zimbra_domain_modal_diagnostic_field_port": "Porta:", + "zimbra_domain_modal_diagnostic_field_target": "Destino:", + "zimbra_domain_modal_diagnostic_mx_title": "Diagnóstico MX", + "zimbra_domain_modal_diagnostic_mx_content_header_part1": "A configuração do registo MX permite receber os seus e-mails nas suas caixas email.", + "zimbra_domain_modal_diagnostic_mx_content_header_part2": "O seu domínio não é gerido pela OVH Cloud, pelo que esta ação deve ser realizada manualmente.", + "zimbra_domain_modal_diagnostic_mx_content_header_part3": "Crie os campos MX neste domínio ao fornecer as mesmas informações que se seguem.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1": "A configuração do registo MX permite receber os seus e-mails nas suas caixas email.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2": "O seu domínio está alojado na OVH Cloud. A configuração será efetuada por si.", + "zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3": "Deseja começar a receber os e-mails do domínio {{domain}} para este serviço?", + "zimbra_domain_modal_diagnostic_mx_content_footer": "Em caso de problema, consulte a documentação do fornecedor do domínio.", + "zimbra_domain_modal_diagnostic_mx_action_validate": "Confirmar", + "zimbra_domain_modal_diagnostic_mx_action_test": "Testar", + "zimbra_domain_modal_diagnostic_mx_action_cancel": "Anular", + "zimbra_domain_modal_diagnostic_mx_action_close": "Fechar", + "zimbra_domain_modal_diagnostic_spf_title": "Diagnóstico SPF", + "zimbra_domain_modal_diagnostic_spf_content_header": "Se o domínio não for gerido pelo mesmo identificador de cliente que o serviço Exchange, ou se o seu domínio não estiver alojado na OVHcloud, a configuração automática não é possível. Crie manualmente o registo SPF para este domínio ao fornecer as mesmas informações que se seguem.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1": "O SPF permite validar que a OVHcloud é um emissor legítimo de e-mails com o seu nome de domínio.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2": "Como o seu domínio está alojado na OVHcloud, podemos proceder à configuração automática.", + "zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3": "Deseja efetuar a configuração?", + "zimbra_domain_modal_diagnostic_spf_action_cancel": "Anular", + "zimbra_domain_modal_diagnostic_spf_action_close": "Fechar", + "zimbra_domain_modal_diagnostic_spf_action_validate": "Ok" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_de_DE.json new file mode 100644 index 000000000000..94cabea16862 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_de_DE.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Konfiguration der Domain", + "zimbra_domain_edit_modal_content": "Sind Sie sicher, dass Sie die Domain vom Zimbra Server löschen möchten?", + "zimbra_domain_edit_modal_message_disabled": "Ihre Domain wird verwendet. Diese Domäne kann nicht gelöscht werden, solange sie vorhanden ist.", + "zimbra_domain_edit_success_message": "Die Konfiguration Ihrer Domain wurde erfolgreich durchgeführt. Sie wird in einigen Augenblicken aktiv sein.", + "zimbra_domain_edit_error_message": "Die Konfiguration Ihrer Domain konnte nicht abgeschlossen werden. {{ error }}", + "zimbra_domain_edit_domain_label": "Domain", + "zimbra_domain_edit_organization_label": "Organisation", + "zimbra_domain_edit_confirm": "Bestätigen", + "zimbra_domain_edit_cancel": "Abbrechen" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_en_GB.json new file mode 100644 index 000000000000..33ef20383b53 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_en_GB.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Domain configuration", + "zimbra_domain_edit_modal_content": "Are you sure you want to delete the domain from the Zimbra server?", + "zimbra_domain_edit_modal_message_disabled": "Your domain is in use. You cannot delete this domain while it is in this case.", + "zimbra_domain_edit_success_message": "Your domain configuration has been processed. It will be active in a few moments.", + "zimbra_domain_edit_error_message": "Your domain configuration could not be completed. {{ error }}", + "zimbra_domain_edit_domain_label": "Domain", + "zimbra_domain_edit_organization_label": "Organisation ", + "zimbra_domain_edit_confirm": "Confirm", + "zimbra_domain_edit_cancel": "Cancel" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_es_ES.json new file mode 100644 index 000000000000..661e5c67811d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_es_ES.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Configuración del dominio", + "zimbra_domain_edit_modal_content": "¿Seguro que quiere eliminar el dominio del servidor Zimbra?", + "zimbra_domain_edit_modal_message_disabled": "Su dominio está en uso. No puede eliminar este dominio mientras se encuentre en este caso.", + "zimbra_domain_edit_success_message": "La configuración del dominio se ha registrado correctamente. Se activará en unos instantes.", + "zimbra_domain_edit_error_message": "No se ha podido configurar el dominio. {{ error }}", + "zimbra_domain_edit_domain_label": "Dominio", + "zimbra_domain_edit_organization_label": "Organización", + "zimbra_domain_edit_confirm": "Confirmar", + "zimbra_domain_edit_cancel": "Cancelar" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_CA.json new file mode 100644 index 000000000000..d12e66eca4de --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_CA.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Configuration du domaine", + "zimbra_domain_edit_modal_content": "Êtes-vous sûr(e) de vouloir supprimer le domaine du serveur Zimbra ?", + "zimbra_domain_edit_modal_message_disabled": "Votre domaine est en cours d'utilisation. Vous ne pouvez pas supprimer ce domaine tant qu'il est dans ce cas.", + "zimbra_domain_edit_success_message": "La configuration de votre domaine a bien été prise en compte. Elle sera active d'ici quelques instants.", + "zimbra_domain_edit_error_message": "La configuration de votre domaine n'a pas pu aboutir. {{ error }}", + "zimbra_domain_edit_domain_label": "Domaine", + "zimbra_domain_edit_organization_label": "Organisation", + "zimbra_domain_edit_confirm": "Confirmer", + "zimbra_domain_edit_cancel": "Annuler" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_FR.json new file mode 100644 index 000000000000..d12e66eca4de --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_fr_FR.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Configuration du domaine", + "zimbra_domain_edit_modal_content": "Êtes-vous sûr(e) de vouloir supprimer le domaine du serveur Zimbra ?", + "zimbra_domain_edit_modal_message_disabled": "Votre domaine est en cours d'utilisation. Vous ne pouvez pas supprimer ce domaine tant qu'il est dans ce cas.", + "zimbra_domain_edit_success_message": "La configuration de votre domaine a bien été prise en compte. Elle sera active d'ici quelques instants.", + "zimbra_domain_edit_error_message": "La configuration de votre domaine n'a pas pu aboutir. {{ error }}", + "zimbra_domain_edit_domain_label": "Domaine", + "zimbra_domain_edit_organization_label": "Organisation", + "zimbra_domain_edit_confirm": "Confirmer", + "zimbra_domain_edit_cancel": "Annuler" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_it_IT.json new file mode 100644 index 000000000000..f30d8adffc9b --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_it_IT.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Configurazione del dominio", + "zimbra_domain_edit_modal_content": "Vuoi davvero eliminare il dominio dal server Zimbra?", + "zimbra_domain_edit_modal_message_disabled": "Il tuo dominio è in uso. Non è possibile eliminare questo dominio finché non compare.", + "zimbra_domain_edit_success_message": "La configurazione del dominio è stata presa in carico. Sarà attiva tra pochi minuti.", + "zimbra_domain_edit_error_message": "La configurazione del dominio non è andata a buon fine. {{ error }}", + "zimbra_domain_edit_domain_label": "Dominio", + "zimbra_domain_edit_organization_label": "Denominazione", + "zimbra_domain_edit_confirm": "Conferma", + "zimbra_domain_edit_cancel": "Annulla" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pl_PL.json new file mode 100644 index 000000000000..4ceafabbbf6e --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pl_PL.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Konfiguracja domeny", + "zimbra_domain_edit_modal_content": "Czy jesteś pewny(a), że chcesz usunąć domenę z serwera Zimbra?", + "zimbra_domain_edit_modal_message_disabled": "Twoja domena jest aktualnie używana. Nie możesz usunąć tej domeny, dopóki jest ona aktywna.", + "zimbra_domain_edit_success_message": "Konfiguracja Twojej domeny została zapisana. Zostanie włączona za kilka minut.", + "zimbra_domain_edit_error_message": "Konfiguracja Twojej domeny nie powiodła się. {{ error }}", + "zimbra_domain_edit_domain_label": "Domena", + "zimbra_domain_edit_organization_label": "Firma", + "zimbra_domain_edit_confirm": "Zatwierdź", + "zimbra_domain_edit_cancel": "Anuluj" +} diff --git a/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pt_PT.json new file mode 100644 index 000000000000..5faa020e2672 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/domains/edit/Messages_pt_PT.json @@ -0,0 +1,11 @@ +{ + "zimbra_domain_edit_modal_title": "Configuração do domínio", + "zimbra_domain_edit_modal_content": "Tem a certeza de que deseja eliminar o domínio do servidor Zimbra?", + "zimbra_domain_edit_modal_message_disabled": "O seu domínio está a ser utilizado. Não é possível eliminar o domínio enquanto este existir.", + "zimbra_domain_edit_success_message": "A configuração do seu domínio foi corretamente tomada em conta. Ela estará ativa dentro de alguns instantes.", + "zimbra_domain_edit_error_message": "A configuração do seu domínio não foi bem-sucedida. {{ error }}", + "zimbra_domain_edit_domain_label": "Domínio", + "zimbra_domain_edit_organization_label": "Organização", + "zimbra_domain_edit_confirm": "Confirmar", + "zimbra_domain_edit_cancel": "Anular" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_de_DE.json new file mode 100644 index 000000000000..193a6cef7443 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_de_DE.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Name", + "zimbra_mailinglists_datagrid_organization_label": "Organisation", + "zimbra_mailinglists_datagrid_owner_label": "Inhaber", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderatoren", + "zimbra_mailinglists_datagrid_subscribers_label": "Abonnenten", + "zimbra_mailinglists_datagrid_action_edit": "Mailingliste konfigurieren", + "zimbra_mailinglists_datagrid_action_define_members": "Mitglieder definieren", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Delegierung konfigurieren", + "zimbra_mailinglists_datagrid_action_delete": "Mailingliste löschen", + "zimbra_mailinglists_datagrid_cta": "Mailingliste erstellen", + "zimbra_mailinglists_quota_label": "Mailinglistenkontingent" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_en_GB.json new file mode 100644 index 000000000000..328673ee107d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_en_GB.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Name", + "zimbra_mailinglists_datagrid_organization_label": "Organisation ", + "zimbra_mailinglists_datagrid_owner_label": "Owner", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderators", + "zimbra_mailinglists_datagrid_subscribers_label": "Subscribers", + "zimbra_mailinglists_datagrid_action_edit": "Configure mailing list", + "zimbra_mailinglists_datagrid_action_define_members": "Define Members", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configure delegation", + "zimbra_mailinglists_datagrid_action_delete": "Delete mailing list", + "zimbra_mailinglists_datagrid_cta": "Create mailing list", + "zimbra_mailinglists_quota_label": "Mailing list quota" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_es_ES.json new file mode 100644 index 000000000000..ae3722831a0d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_es_ES.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Nombre", + "zimbra_mailinglists_datagrid_organization_label": "Organización", + "zimbra_mailinglists_datagrid_owner_label": "Propietario", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderadores", + "zimbra_mailinglists_datagrid_subscribers_label": "Abonados", + "zimbra_mailinglists_datagrid_action_edit": "Configurar lista de difusión", + "zimbra_mailinglists_datagrid_action_define_members": "Definir miembros", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configurar delegación", + "zimbra_mailinglists_datagrid_action_delete": "Eliminar la lista de difusión", + "zimbra_mailinglists_datagrid_cta": "Crear una lista de difusión", + "zimbra_mailinglists_quota_label": "Cuota de lista de difusión" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_CA.json new file mode 100644 index 000000000000..ee1211c064b5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_CA.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Nom", + "zimbra_mailinglists_datagrid_organization_label": "Organisation", + "zimbra_mailinglists_datagrid_owner_label": "Propriétaire", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Modérateurs", + "zimbra_mailinglists_datagrid_subscribers_label": "Abonnés", + "zimbra_mailinglists_datagrid_action_edit": "Configurer la liste de diffusion", + "zimbra_mailinglists_datagrid_action_define_members": "Définir les membres", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configurer la délégation", + "zimbra_mailinglists_datagrid_action_delete": "Supprimer la liste de diffusion", + "zimbra_mailinglists_datagrid_cta": "Créer une liste de diffusion", + "zimbra_mailinglists_quota_label": "Quota de liste de diffusion" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_FR.json new file mode 100644 index 000000000000..ee1211c064b5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_fr_FR.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Nom", + "zimbra_mailinglists_datagrid_organization_label": "Organisation", + "zimbra_mailinglists_datagrid_owner_label": "Propriétaire", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Modérateurs", + "zimbra_mailinglists_datagrid_subscribers_label": "Abonnés", + "zimbra_mailinglists_datagrid_action_edit": "Configurer la liste de diffusion", + "zimbra_mailinglists_datagrid_action_define_members": "Définir les membres", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configurer la délégation", + "zimbra_mailinglists_datagrid_action_delete": "Supprimer la liste de diffusion", + "zimbra_mailinglists_datagrid_cta": "Créer une liste de diffusion", + "zimbra_mailinglists_quota_label": "Quota de liste de diffusion" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_it_IT.json new file mode 100644 index 000000000000..d2ab9153ead5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_it_IT.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Cognome", + "zimbra_mailinglists_datagrid_organization_label": "Denominazione", + "zimbra_mailinglists_datagrid_owner_label": "Proprietario", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderatori", + "zimbra_mailinglists_datagrid_subscribers_label": "Iscritti", + "zimbra_mailinglists_datagrid_action_edit": "Configura lista di distribuzione", + "zimbra_mailinglists_datagrid_action_define_members": "Definisci i membri", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configura la delega", + "zimbra_mailinglists_datagrid_action_delete": "Elimina mailing list", + "zimbra_mailinglists_datagrid_cta": "Creare una mailing list", + "zimbra_mailinglists_quota_label": "Quota di mailing list" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pl_PL.json new file mode 100644 index 000000000000..4f357e6e3473 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pl_PL.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Nazwisko", + "zimbra_mailinglists_datagrid_organization_label": "Firma", + "zimbra_mailinglists_datagrid_owner_label": "Właściciel", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderatorzy", + "zimbra_mailinglists_datagrid_subscribers_label": "Abonenci", + "zimbra_mailinglists_datagrid_action_edit": "Skonfiguruj listę mailingową", + "zimbra_mailinglists_datagrid_action_define_members": "Zdefiniuj członków", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Delegowanie uprawnień", + "zimbra_mailinglists_datagrid_action_delete": "Usuń listę mailingową", + "zimbra_mailinglists_datagrid_cta": "Utwórz listę mailingową", + "zimbra_mailinglists_quota_label": "Limit listy mailingowej" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pt_PT.json new file mode 100644 index 000000000000..f7913043fb99 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/Messages_pt_PT.json @@ -0,0 +1,14 @@ +{ + "zimbra_mailinglists_datagrid_name_label": "Nome", + "zimbra_mailinglists_datagrid_organization_label": "Organização", + "zimbra_mailinglists_datagrid_owner_label": "Titular", + "zimbra_mailinglists_datagrid_aliases_label": "Alias", + "zimbra_mailinglists_datagrid_moderators_label": "Moderadores", + "zimbra_mailinglists_datagrid_subscribers_label": "Subscritores", + "zimbra_mailinglists_datagrid_action_edit": "Configurar a lista de difusão", + "zimbra_mailinglists_datagrid_action_define_members": "Definir membros", + "zimbra_mailinglists_datagrid_action_configure_delegation": "Configurar a delegação", + "zimbra_mailinglists_datagrid_action_delete": "Eliminar lista de difusão", + "zimbra_mailinglists_datagrid_cta": "Criar uma lista de difusão", + "zimbra_mailinglists_quota_label": "Quota da lista de difusão" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_de_DE.json new file mode 100644 index 000000000000..1bcd543d075a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_de_DE.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Mailingliste erstellen", + "zimbra_mailinglist_edit_title": "Mailingliste konfigurieren", + "zimbra_mailinglist_add_cta_back": "Zurück zu den Mailinglisten", + "zimbra_mailinglist_add_reply_to_list": "Zur Liste", + "zimbra_mailinglist_add_reply_to_sender": "An den Absender der E-Mail", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Auf einer anderen Mailbox", + "zimbra_mailinglist_add_moderation_choice_all": "Alle Nachrichten moderieren", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Nur Abonnenten können posten", + "zimbra_mailinglist_add_moderation_choice_none": "Jeder kann posten (keine Moderation)", + "zimbra_mailinglist_add_success_message": "Ihre Anfrage zur Erstellung einer Mailingliste wurde registriert. Sie wird in einigen Augenblicken behandelt.", + "zimbra_mailinglist_add_error_message": "Ihre Anfrage zur Erstellung der Mailingliste konnte nicht abgeschlossen werden. Bitte versuchen Sie es in einigen Augenblicken erneut.", + "zimbra_mailinglist_edit_success_message": "Ihre Anfrage zur Änderung der Mailingliste wurde registriert. Sie wird in einigen Augenblicken behandelt", + "zimbra_mailinglist_edit_error_message": "Ihre Anfrage zur Änderung der Mailingliste konnte nicht ausgeführt werden. Bitte versuchen Sie es in einigen Augenblicken noch einmal", + "zimbra_mailinglist_add_header": "Sie sind im Begriff, eine Mailingliste zu erstellen. Bitte geben Sie die folgenden Informationen ein.", + "zimbra_mailinglist_edit_header": "Sie sind im Begriff, eine Mailingliste zu bearbeiten. Bitte geben Sie die folgenden Informationen ein.", + "zimbra_mailinglist_mandatory_fields": "Die mit einem Sternchen* gekennzeichneten Felder sind Pflichtangaben.", + "zimbra_mailinglist_add_input_email_label": "Name", + "zimbra_mailinglist_add_input_email_placeholder": "Name", + "zimbra_mailinglist_add_select_domain_placeholder": "Einen Domainnamen auswählen", + "zimbra_mailinglist_add_message_organization": "Diese Mailingliste wird der Organisation {{organization}} hinzugefügt.", + "zimbra_mailinglist_add_input_owner_label": "Inhaber", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Sprache", + "zimbra_mailinglist_add_select_language_placeholder": "Sprache auswählen", + "zimbra_mailinglist_add_moderation_choice_label": "Nachrichtenmoderation", + "zimbra_mailinglist_add_subscriber_moderation": "Moderation der Abonnenten", + "zimbra_mailinglist_add_subscriber_moderation_info": "Maximale Anzahl von Abonnenten für die Mailingliste: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Bestätigen", + "zimbra_mailinglist_add_button_cancel": "Abbrechen" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_en_GB.json new file mode 100644 index 000000000000..a897121fe456 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_en_GB.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Create mailing list", + "zimbra_mailinglist_edit_title": "Configure mailing list", + "zimbra_mailinglist_add_cta_back": "Back to mailing lists", + "zimbra_mailinglist_add_reply_to_list": "To the list", + "zimbra_mailinglist_add_reply_to_sender": "To the sender of the email", + "zimbra_mailinglist_add_reply_to_another_mailbox": "On another mailbox", + "zimbra_mailinglist_add_moderation_choice_all": "Moderate all messages", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Only subscribers can post", + "zimbra_mailinglist_add_moderation_choice_none": "Everyone can post (no moderation)", + "zimbra_mailinglist_add_success_message": "Your request to create a mailing list has been processed. It will be dealt with in a few moments.", + "zimbra_mailinglist_add_error_message": "Your request to create a mailing list could not be completed. Please try again in a few moments.", + "zimbra_mailinglist_edit_success_message": "Your request to modify the mailing list has been processed. It will be processed in a few moments", + "zimbra_mailinglist_edit_error_message": "Your request to change the mailing list could not be completed. Please try again in a few moments", + "zimbra_mailinglist_add_header": "You are about to create a mailing list, please enter the following information.", + "zimbra_mailinglist_edit_header": "You are about to edit a mailing list, please enter the following information.", + "zimbra_mailinglist_mandatory_fields": "Fields marked with an asterisk* are mandatory.", + "zimbra_mailinglist_add_input_email_label": "Name", + "zimbra_mailinglist_add_input_email_placeholder": "name", + "zimbra_mailinglist_add_select_domain_placeholder": "Select a domain name", + "zimbra_mailinglist_add_message_organization": "This mailing list will be added to the {{organization}} organization.", + "zimbra_mailinglist_add_input_owner_label": "Owner", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Language", + "zimbra_mailinglist_add_select_language_placeholder": "Select a language", + "zimbra_mailinglist_add_moderation_choice_label": "Message moderation", + "zimbra_mailinglist_add_subscriber_moderation": "Subscriber Moderation", + "zimbra_mailinglist_add_subscriber_moderation_info": "Maximum number of mailing list subscribers: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Confirm", + "zimbra_mailinglist_add_button_cancel": "Cancel" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_es_ES.json new file mode 100644 index 000000000000..4969b921763c --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_es_ES.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Crear una lista de difusión", + "zimbra_mailinglist_edit_title": "Configurar lista de difusión", + "zimbra_mailinglist_add_cta_back": "Volver a las listas de difusión", + "zimbra_mailinglist_add_reply_to_list": "A la lista", + "zimbra_mailinglist_add_reply_to_sender": "Al remitente del email", + "zimbra_mailinglist_add_reply_to_another_mailbox": "En otra cuenta de correo", + "zimbra_mailinglist_add_moderation_choice_all": "Moderar todos los mensajes", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Solo los abonados pueden publicar", + "zimbra_mailinglist_add_moderation_choice_none": "Todo el mundo puede publicar (sin moderación)", + "zimbra_mailinglist_add_success_message": "La solicitud de creación de lista de difusión se ha enviado. Será tratada en unos momentos.", + "zimbra_mailinglist_add_error_message": "No se pudo completar la solicitud de creación de la lista de correo. Por favor, vuelva a intentarlo en unos instantes.", + "zimbra_mailinglist_edit_success_message": "La solicitud de modificación de la lista de difusión se ha enviado. Será tratado en unos instantes", + "zimbra_mailinglist_edit_error_message": "No se pudo completar la solicitud de modificación de la lista de distribución de correo. Por favor, vuelva a intentarlo en unos instantes", + "zimbra_mailinglist_add_header": "Está a punto de crear una lista de difusión, introduzca la siguiente información.", + "zimbra_mailinglist_edit_header": "Está a punto de editar una lista de difusión. Introduzca la siguiente información.", + "zimbra_mailinglist_mandatory_fields": "Los campos marcados con un asterisco* son obligatorios.", + "zimbra_mailinglist_add_input_email_label": "Nombre", + "zimbra_mailinglist_add_input_email_placeholder": "nombre", + "zimbra_mailinglist_add_select_domain_placeholder": "Seleccionar un dominio", + "zimbra_mailinglist_add_message_organization": "Esta lista de difusión se agregará a la organización {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Propietario", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Lenguaje", + "zimbra_mailinglist_add_select_language_placeholder": "Seleccionar un lenguaje", + "zimbra_mailinglist_add_moderation_choice_label": "Moderación de mensajes", + "zimbra_mailinglist_add_subscriber_moderation": "Moderación de los abonados", + "zimbra_mailinglist_add_subscriber_moderation_info": "Número máximo de suscriptores a la lista de difusión: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Confirmar", + "zimbra_mailinglist_add_button_cancel": "Cancelar" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_CA.json new file mode 100644 index 000000000000..ad7a6953007b --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_CA.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Créer une liste de diffusion", + "zimbra_mailinglist_edit_title": "Configurer la liste de diffusion", + "zimbra_mailinglist_add_cta_back": "Retour aux listes de diffusion", + "zimbra_mailinglist_add_reply_to_list": "À la liste", + "zimbra_mailinglist_add_reply_to_sender": "À l'expéditeur de l'email", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Sur une autre boîte mail", + "zimbra_mailinglist_add_moderation_choice_all": "Modérer tous les messages", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Seuls les abonnés peuvent poster", + "zimbra_mailinglist_add_moderation_choice_none": "Tout le monde peut poster (pas de modération)", + "zimbra_mailinglist_add_success_message": "Votre demande de création de liste de diffusion a bien été prise en compte. Elle sera traité d'ici quelques instants.", + "zimbra_mailinglist_add_error_message": "Votre demande de création de liste de diffusion n'a pas pu aboutir. Merci de réessayer dans quelques instants.", + "zimbra_mailinglist_edit_success_message": "Votre demande de modification de la liste de diffusion a bien été prise en compte. Elle sera traité d'ici quelques instants", + "zimbra_mailinglist_edit_error_message": "Votre demande de modification de la liste de diffusion n'a pas pu aboutir. Merci de réessayer dans quelques instants", + "zimbra_mailinglist_add_header": "Vous êtes sur le point de créer une liste de diffusion, veuillez saisir les informations suivantes.", + "zimbra_mailinglist_edit_header": "Vous êtes sur le point de modifier une liste de diffusion, veuillez saisir les informations suivantes.", + "zimbra_mailinglist_mandatory_fields": "Les champs mentionnés avec un astérisque* sont obligatoires.", + "zimbra_mailinglist_add_input_email_label": "Nom", + "zimbra_mailinglist_add_input_email_placeholder": "nom", + "zimbra_mailinglist_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_mailinglist_add_message_organization": "Cette liste de diffusion sera ajoutée à l'organisation {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Propriétaire", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Langage", + "zimbra_mailinglist_add_select_language_placeholder": "Sélectionner un langage", + "zimbra_mailinglist_add_moderation_choice_label": "Modération de message", + "zimbra_mailinglist_add_subscriber_moderation": "Modération des abonnés", + "zimbra_mailinglist_add_subscriber_moderation_info": "Nombre maximal d'abonnés à la liste de diffusion : {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Confirmer", + "zimbra_mailinglist_add_button_cancel": "Annuler" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_FR.json new file mode 100644 index 000000000000..ad7a6953007b --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_fr_FR.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Créer une liste de diffusion", + "zimbra_mailinglist_edit_title": "Configurer la liste de diffusion", + "zimbra_mailinglist_add_cta_back": "Retour aux listes de diffusion", + "zimbra_mailinglist_add_reply_to_list": "À la liste", + "zimbra_mailinglist_add_reply_to_sender": "À l'expéditeur de l'email", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Sur une autre boîte mail", + "zimbra_mailinglist_add_moderation_choice_all": "Modérer tous les messages", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Seuls les abonnés peuvent poster", + "zimbra_mailinglist_add_moderation_choice_none": "Tout le monde peut poster (pas de modération)", + "zimbra_mailinglist_add_success_message": "Votre demande de création de liste de diffusion a bien été prise en compte. Elle sera traité d'ici quelques instants.", + "zimbra_mailinglist_add_error_message": "Votre demande de création de liste de diffusion n'a pas pu aboutir. Merci de réessayer dans quelques instants.", + "zimbra_mailinglist_edit_success_message": "Votre demande de modification de la liste de diffusion a bien été prise en compte. Elle sera traité d'ici quelques instants", + "zimbra_mailinglist_edit_error_message": "Votre demande de modification de la liste de diffusion n'a pas pu aboutir. Merci de réessayer dans quelques instants", + "zimbra_mailinglist_add_header": "Vous êtes sur le point de créer une liste de diffusion, veuillez saisir les informations suivantes.", + "zimbra_mailinglist_edit_header": "Vous êtes sur le point de modifier une liste de diffusion, veuillez saisir les informations suivantes.", + "zimbra_mailinglist_mandatory_fields": "Les champs mentionnés avec un astérisque* sont obligatoires.", + "zimbra_mailinglist_add_input_email_label": "Nom", + "zimbra_mailinglist_add_input_email_placeholder": "nom", + "zimbra_mailinglist_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_mailinglist_add_message_organization": "Cette liste de diffusion sera ajoutée à l'organisation {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Propriétaire", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Langage", + "zimbra_mailinglist_add_select_language_placeholder": "Sélectionner un langage", + "zimbra_mailinglist_add_moderation_choice_label": "Modération de message", + "zimbra_mailinglist_add_subscriber_moderation": "Modération des abonnés", + "zimbra_mailinglist_add_subscriber_moderation_info": "Nombre maximal d'abonnés à la liste de diffusion : {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Confirmer", + "zimbra_mailinglist_add_button_cancel": "Annuler" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_it_IT.json new file mode 100644 index 000000000000..b4b8c095b81a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_it_IT.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Creare una mailing list", + "zimbra_mailinglist_edit_title": "Configura lista di distribuzione", + "zimbra_mailinglist_add_cta_back": "Ritorna alle mailing list", + "zimbra_mailinglist_add_reply_to_list": "Alla lista", + "zimbra_mailinglist_add_reply_to_sender": "Al mittente dell'email", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Su un'altra casella email", + "zimbra_mailinglist_add_moderation_choice_all": "Moderazione di tutti i messaggi", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Solo gli iscritti possono inviare messaggi", + "zimbra_mailinglist_add_moderation_choice_none": "Chiunque può inviare messaggi (nessuna moderazione)", + "zimbra_mailinglist_add_success_message": "La richiesta di creazione della mailing list è stata presa in carico. Sarà elaborata tra pochi minuti.", + "zimbra_mailinglist_add_error_message": "Impossibile completare la richiesta di creazione della mailing list. Ti preghiamo di riprovare più tardi.", + "zimbra_mailinglist_edit_success_message": "La richiesta di modifica della mailing list è stata presa in carico. Sarà elaborata tra pochi minuti", + "zimbra_mailinglist_edit_error_message": "Impossibile completare la richiesta di modifica della mailing list. Ti preghiamo di riprovare", + "zimbra_mailinglist_add_header": "Se si sta per creare una mailing list, immettere le seguenti informazioni.", + "zimbra_mailinglist_edit_header": "Se si sta per modificare una mailing list, immettere le informazioni seguenti.", + "zimbra_mailinglist_mandatory_fields": "I campi contrassegnati con un asterisco* sono obbligatori.", + "zimbra_mailinglist_add_input_email_label": "Cognome", + "zimbra_mailinglist_add_input_email_placeholder": "nome", + "zimbra_mailinglist_add_select_domain_placeholder": "Seleziona un dominio", + "zimbra_mailinglist_add_message_organization": "Questa mailing list verrà aggiunta all'organizzazione {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Proprietario", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Linguaggio", + "zimbra_mailinglist_add_select_language_placeholder": "Seleziona un linguaggio", + "zimbra_mailinglist_add_moderation_choice_label": "Moderazione dei messaggi", + "zimbra_mailinglist_add_subscriber_moderation": "Moderazione degli iscritti", + "zimbra_mailinglist_add_subscriber_moderation_info": "Numero massimo di iscritti alla mailing list: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Conferma", + "zimbra_mailinglist_add_button_cancel": "Annulla" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pl_PL.json new file mode 100644 index 000000000000..b4624ffbe5b5 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pl_PL.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Utwórz listę mailingową", + "zimbra_mailinglist_edit_title": "Skonfiguruj listę mailingową", + "zimbra_mailinglist_add_cta_back": "Powrót do list mailingowych", + "zimbra_mailinglist_add_reply_to_list": "Na listę", + "zimbra_mailinglist_add_reply_to_sender": "Nadawca e-maila", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Na inną skrzynkę e-mail", + "zimbra_mailinglist_add_moderation_choice_all": "Moderuj wszystkie wiadomości", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Tylko abonenci mogą wysyłać wiadomości", + "zimbra_mailinglist_add_moderation_choice_none": "Każdy może przesłać wiadomość (bez moderowania)", + "zimbra_mailinglist_add_success_message": "Zlecenie utworzenia listy mailingowej zostało zarejestrowane. Zostanie przetworzone w ciągu kilku minut.", + "zimbra_mailinglist_add_error_message": "Zlecenie utworzenia listy mailingowej nie powiodło się. Spróbuj ponownie za kilka minut.", + "zimbra_mailinglist_edit_success_message": "Twoje zlecenie zmiany listy mailingowej zostało przyjęte. Zostanie przetworzone w ciągu kilku minut", + "zimbra_mailinglist_edit_error_message": "Żądanie zmiany listy mailingowej nie powiodło się. Spróbuj ponownie za kilka minut", + "zimbra_mailinglist_add_header": "Chcesz utworzyć listę mailingową. Podaj następujące informacje.", + "zimbra_mailinglist_edit_header": "Chcesz zmodyfikować listę mailingową. Podaj następujące informacje.", + "zimbra_mailinglist_mandatory_fields": "Pola oznaczone gwiazdką* są obowiązkowe.", + "zimbra_mailinglist_add_input_email_label": "Nazwisko", + "zimbra_mailinglist_add_input_email_placeholder": "Nazwa", + "zimbra_mailinglist_add_select_domain_placeholder": "Wybierz nazwę domeny", + "zimbra_mailinglist_add_message_organization": "Ta lista mailingowa zostanie dodana do organizacji {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Właściciel", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: zdefiniuj ten placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Język", + "zimbra_mailinglist_add_select_language_placeholder": "Wybierz język", + "zimbra_mailinglist_add_moderation_choice_label": "Moderowanie wiadomości", + "zimbra_mailinglist_add_subscriber_moderation": "Moderowanie abonentów", + "zimbra_mailinglist_add_subscriber_moderation_info": "Maksymalna liczba subskrybentów listy mailingowej: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: Określ zawartość tego narzędzia", + "zimbra_mailinglist_add_button_confirm": "Zatwierdź", + "zimbra_mailinglist_add_button_cancel": "Anuluj" +} diff --git a/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pt_PT.json new file mode 100644 index 000000000000..0856b2fb3ffa --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/mailinglists/addAndEdit/Messages_pt_PT.json @@ -0,0 +1,33 @@ +{ + "zimbra_mailinglist_add_title": "Criar uma lista de difusão", + "zimbra_mailinglist_edit_title": "Configurar a lista de difusão", + "zimbra_mailinglist_add_cta_back": "Voltar às mailing lists", + "zimbra_mailinglist_add_reply_to_list": "À lista", + "zimbra_mailinglist_add_reply_to_sender": "Ao remetente do e-mail", + "zimbra_mailinglist_add_reply_to_another_mailbox": "Numa outra caixa de e-mail", + "zimbra_mailinglist_add_moderation_choice_all": "Moderar todas as mensagens", + "zimbra_mailinglist_add_moderation_choice_subs_only": "Apenas os subscritores podem publicar", + "zimbra_mailinglist_add_moderation_choice_none": "Todo mundo pode publicar (sem moderação)", + "zimbra_mailinglist_add_success_message": "O seu pedido de criação de lista de difusão foi corretamente tomado em conta. Será tratado dentro de alguns instantes.", + "zimbra_mailinglist_add_error_message": "A criação da lista de difusão não foi bem-sucedida. Tente novamente mais tarde.", + "zimbra_mailinglist_edit_success_message": "O seu pedido de alteração da lista de difusão foi corretamente tomado em conta. Será tratado dentro de alguns instantes", + "zimbra_mailinglist_edit_error_message": "Não foi possível executar o seu pedido para alterar a lista de correio. Tente novamente mais tarde", + "zimbra_mailinglist_add_header": "Está prestes a criar uma lista de difusão, queira introduzir as seguintes informações.", + "zimbra_mailinglist_edit_header": "Está prestes a modificar uma lista de difusão, introduza as seguintes informações.", + "zimbra_mailinglist_mandatory_fields": "Os campos marcados com asterisco* são de preenchimento obrigatório.", + "zimbra_mailinglist_add_input_email_label": "Nome", + "zimbra_mailinglist_add_input_email_placeholder": "apelido", + "zimbra_mailinglist_add_select_domain_placeholder": "Selecionar um domínio", + "zimbra_mailinglist_add_message_organization": "Esta lista de difusão será adicionada à organização {{organization}}.", + "zimbra_mailinglist_add_input_owner_label": "Titular", + "zimbra_mailinglist_add_input_owner_placeholder": "TODO: define this placeholder", + "zimbra_mailinglist_add_reply_to_label": "Reply to", + "zimbra_mailinglist_add_language_label": "Linguagem", + "zimbra_mailinglist_add_select_language_placeholder": "Selecionar uma linguagem", + "zimbra_mailinglist_add_moderation_choice_label": "Moderação da mensagem", + "zimbra_mailinglist_add_subscriber_moderation": "Moderação dos subscritores", + "zimbra_mailinglist_add_subscriber_moderation_info": "Número máximo de subscritores da lista de difusão: {{max}}", + "zimbra_mailinglist_add_subscriber_moderation_tooltip": "TODO: define this tooltip content", + "zimbra_mailinglist_add_button_confirm": "Confirmar", + "zimbra_mailinglist_add_button_cancel": "Anular" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_de_DE.json new file mode 100644 index 000000000000..91d747336a40 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_de_DE.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Weiterleitung erstellen", + "zimbra_redirections_from": "von", + "zimbra_redirections_to": "Ab", + "zimbra_redirections_organization": "Organisation", + "zimbra_redirections_datagrid_tooltip_modification": "Ändern", + "zimbra_redirections_datagrid_tooltip_delete": "Löschen", + "zimbra_redirections_account_title": "Verwaltung der Weiterleitungen" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_en_GB.json new file mode 100644 index 000000000000..c7b41fe3ca00 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_en_GB.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Create a redirection", + "zimbra_redirections_from": "From", + "zimbra_redirections_to": "Coming", + "zimbra_redirections_organization": "Organisation ", + "zimbra_redirections_datagrid_tooltip_modification": "Modify", + "zimbra_redirections_datagrid_tooltip_delete": "Delete", + "zimbra_redirections_account_title": "Manage redirections" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_es_ES.json new file mode 100644 index 000000000000..ab4350dd3856 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_es_ES.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Crear una redirección", + "zimbra_redirections_from": "De", + "zimbra_redirections_to": "A", + "zimbra_redirections_organization": "Organización", + "zimbra_redirections_datagrid_tooltip_modification": "Modificar", + "zimbra_redirections_datagrid_tooltip_delete": "Eliminar", + "zimbra_redirections_account_title": "Gestión de las redirecciones" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_CA.json new file mode 100644 index 000000000000..89a3a0835276 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_CA.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Créer une redirection", + "zimbra_redirections_from": "De", + "zimbra_redirections_to": "À", + "zimbra_redirections_organization": "Organisation", + "zimbra_redirections_datagrid_tooltip_modification": "Modifier", + "zimbra_redirections_datagrid_tooltip_delete": "Supprimer", + "zimbra_redirections_account_title": "Gestion des redirections" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_FR.json new file mode 100644 index 000000000000..89a3a0835276 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_fr_FR.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Créer une redirection", + "zimbra_redirections_from": "De", + "zimbra_redirections_to": "À", + "zimbra_redirections_organization": "Organisation", + "zimbra_redirections_datagrid_tooltip_modification": "Modifier", + "zimbra_redirections_datagrid_tooltip_delete": "Supprimer", + "zimbra_redirections_account_title": "Gestion des redirections" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_it_IT.json new file mode 100644 index 000000000000..de30e133673d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_it_IT.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Crea un reindirizzamento", + "zimbra_redirections_from": "Da", + "zimbra_redirections_to": "In", + "zimbra_redirections_organization": "Denominazione", + "zimbra_redirections_datagrid_tooltip_modification": "Modifica", + "zimbra_redirections_datagrid_tooltip_delete": "Eliminare", + "zimbra_redirections_account_title": "Gestione dei reindirizzamenti" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_pl_PL.json new file mode 100644 index 000000000000..9b010564450e --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_pl_PL.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Utwórz przekierowanie", + "zimbra_redirections_from": "Od", + "zimbra_redirections_to": "Wkrótce", + "zimbra_redirections_organization": "Firma", + "zimbra_redirections_datagrid_tooltip_modification": "Zmień", + "zimbra_redirections_datagrid_tooltip_delete": "Usuń", + "zimbra_redirections_account_title": "Zarządzanie przekierowaniami" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/redirections/Messages_pt_PT.json new file mode 100644 index 000000000000..f704a5087e3c --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/Messages_pt_PT.json @@ -0,0 +1,9 @@ +{ + "zimbra_redirections_cta": "Criar um reencaminhamento", + "zimbra_redirections_from": "De", + "zimbra_redirections_to": "A", + "zimbra_redirections_organization": "Organização", + "zimbra_redirections_datagrid_tooltip_modification": "Modificar", + "zimbra_redirections_datagrid_tooltip_delete": "Suprimir", + "zimbra_redirections_account_title": "Gestão dos reencaminhamentos" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_de_DE.json new file mode 100644 index 000000000000..92a7163dd856 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_de_DE.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Bitte geben Sie die Informationen für die Weiterleitung an.", + "zimbra_redirections_edit_2": "Die mit * gekennzeichneten Felder sind Pflichtangaben.", + "zimbra_redirections_title_add": "Weiterleitung erstellen", + "zimbra_redirections_title_edit": "Weiterleitung bearbeiten", + "zimbra_redirections_add_form_input_name_title_from": "Von Adresse", + "zimbra_redirections_add_form_input_name_title_to": "Zur Adresse", + "zimbra_redirections_add_form_input_checkbox": "Eine Kopie der E-Mail bei OVHcloud aufbewahren", + "zimbra_redirections_add_input_email_placeholder": "Name des Accounts", + "zimbra_redirections_add_select_domain_placeholder": "Einen Domainnamen auswählen", + "zimbra_redirections_add_btn_cancel": "Abbrechen", + "zimbra_redirections_add_btn_confirm": "Bestätigen", + "zimbra_redirections_add_success": "Ihre Anfrage zur Erstellung der Weiterleitung wurde registriert. Sie wird in einigen Augenblicken behandelt.", + "zimbra_redirections_edit_success": "Ihre Anfrage zur Änderung der Weiterleitung wurde registriert. Sie wird in einigen Augenblicken behandelt.", + "zimbra_redirections_add_error": "Ihre Anfrage zur Erstellung der Weiterleitung konnte nicht abgeschlossen werden. {{ error }}", + "zimbra_redirections_edit_error": "Ihre Anfrage zur Änderung der Weiterleitung konnte nicht abgeschlossen werden. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_en_GB.json new file mode 100644 index 000000000000..ba6122b7a38e --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_en_GB.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Please fill in the information for the redirection.", + "zimbra_redirections_edit_2": "Fields marked with an asterisk * are mandatory.", + "zimbra_redirections_title_add": "Create a redirection", + "zimbra_redirections_title_edit": "Modify the redirection", + "zimbra_redirections_add_form_input_name_title_from": "From the address", + "zimbra_redirections_add_form_input_name_title_to": "To address", + "zimbra_redirections_add_form_input_checkbox": "Keep a copy of the email with OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Account name", + "zimbra_redirections_add_select_domain_placeholder": "Select a domain name", + "zimbra_redirections_add_btn_cancel": "Cancel", + "zimbra_redirections_add_btn_confirm": "Confirm", + "zimbra_redirections_add_success": "Your redirection creation request has been processed. It will be processed in a few moments.", + "zimbra_redirections_edit_success": "Your redirection modification request has been processed. It will be processed in a few moments.", + "zimbra_redirections_add_error": "Your request to create a redirection could not be completed. {{ error }}", + "zimbra_redirections_edit_error": "Your redirection modification request could not be completed. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_es_ES.json new file mode 100644 index 000000000000..5d46fd5e8533 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_es_ES.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Por favor, complete los datos para la redirección.", + "zimbra_redirections_edit_2": "Los campos marcados con * son obligatorios.", + "zimbra_redirections_title_add": "Crear una redirección", + "zimbra_redirections_title_edit": "Modificar la redirección", + "zimbra_redirections_add_form_input_name_title_from": "De la dirección", + "zimbra_redirections_add_form_input_name_title_to": "A la dirección", + "zimbra_redirections_add_form_input_checkbox": "Conservar una copia del correo en OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nombre de la cuenta", + "zimbra_redirections_add_select_domain_placeholder": "Seleccionar un dominio", + "zimbra_redirections_add_btn_cancel": "Cancelar", + "zimbra_redirections_add_btn_confirm": "Confirmar", + "zimbra_redirections_add_success": "La solicitud de creación de redirecciones se ha enviado. Será tratada en unos instantes.", + "zimbra_redirections_edit_success": "La solicitud de modificación de la redirección se ha enviado. Será tratada en unos instantes.", + "zimbra_redirections_add_error": "No se ha podido completar la solicitud de creación de redirecciones. {{ error }}", + "zimbra_redirections_edit_error": "No se ha podido completar la solicitud de cambio de redirección. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_CA.json new file mode 100644 index 000000000000..65c5d8ce3eee --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_CA.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Merci de compléter les informations pour la redirection.", + "zimbra_redirections_edit_2": "Les champs mentionnés avec un astérisque * sont obligatoires.", + "zimbra_redirections_title_add": "Créer une redirection", + "zimbra_redirections_title_edit": "Modifier la redirection", + "zimbra_redirections_add_form_input_name_title_from": "De l'adresse", + "zimbra_redirections_add_form_input_name_title_to": "Vers l'adresse", + "zimbra_redirections_add_form_input_checkbox": "Conserver une copie de l'email chez OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nom du compte", + "zimbra_redirections_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_redirections_add_btn_cancel": "Annuler", + "zimbra_redirections_add_btn_confirm": "Confirmer", + "zimbra_redirections_add_success": "Votre demande de création de redirection a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_redirections_edit_success": "Votre demande de modification de redirection a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_redirections_add_error": "Votre demande de création de redirection n'a pas pu aboutir. {{ error }}", + "zimbra_redirections_edit_error": "Votre demande de modification de redirection n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_FR.json new file mode 100644 index 000000000000..65c5d8ce3eee --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_fr_FR.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Merci de compléter les informations pour la redirection.", + "zimbra_redirections_edit_2": "Les champs mentionnés avec un astérisque * sont obligatoires.", + "zimbra_redirections_title_add": "Créer une redirection", + "zimbra_redirections_title_edit": "Modifier la redirection", + "zimbra_redirections_add_form_input_name_title_from": "De l'adresse", + "zimbra_redirections_add_form_input_name_title_to": "Vers l'adresse", + "zimbra_redirections_add_form_input_checkbox": "Conserver une copie de l'email chez OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nom du compte", + "zimbra_redirections_add_select_domain_placeholder": "Sélectionner un nom de domaine", + "zimbra_redirections_add_btn_cancel": "Annuler", + "zimbra_redirections_add_btn_confirm": "Confirmer", + "zimbra_redirections_add_success": "Votre demande de création de redirection a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_redirections_edit_success": "Votre demande de modification de redirection a bien été prise en compte. Elle sera traitée d'ici quelques instants.", + "zimbra_redirections_add_error": "Votre demande de création de redirection n'a pas pu aboutir. {{ error }}", + "zimbra_redirections_edit_error": "Votre demande de modification de redirection n'a pas pu aboutir. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_it_IT.json new file mode 100644 index 000000000000..b1e976d82b0f --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_it_IT.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Inserisci le informazioni relative al reindirizzamento.", + "zimbra_redirections_edit_2": "I campi contrassegnati con un asterisco * sono obbligatori.", + "zimbra_redirections_title_add": "Crea un reindirizzamento", + "zimbra_redirections_title_edit": "Modifica il reindirizzamento", + "zimbra_redirections_add_form_input_name_title_from": "Dall'indirizzo", + "zimbra_redirections_add_form_input_name_title_to": "All'indirizzo", + "zimbra_redirections_add_form_input_checkbox": "Conserva una copia dell'email in OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nome dell'account", + "zimbra_redirections_add_select_domain_placeholder": "Seleziona un dominio", + "zimbra_redirections_add_btn_cancel": "Annulla", + "zimbra_redirections_add_btn_confirm": "Conferma", + "zimbra_redirections_add_success": "La richiesta di creazione del reindirizzamento è stata presa in carico. Sarà elaborata entro pochi minuti.", + "zimbra_redirections_edit_success": "La richiesta di modifica del reindirizzamento è stata presa in carico. Sarà elaborata entro pochi minuti.", + "zimbra_redirections_add_error": "La richiesta di creazione del reindirizzamento non è andata a buon fine. {{ error }}", + "zimbra_redirections_edit_error": "La richiesta di modifica del reindirizzamento non è andata a buon fine. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pl_PL.json new file mode 100644 index 000000000000..40b065c38c18 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pl_PL.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Uzupełnij informacje dotyczące przekierowania.", + "zimbra_redirections_edit_2": "Pola oznaczone gwiazdką * są obowiązkowe.", + "zimbra_redirections_title_add": "Utwórz przekierowanie", + "zimbra_redirections_title_edit": "Edytuj przekierowanie", + "zimbra_redirections_add_form_input_name_title_from": "Z adresu", + "zimbra_redirections_add_form_input_name_title_to": "Na adres", + "zimbra_redirections_add_form_input_checkbox": "Zachowaj kopię e-maila w OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nazwa konta", + "zimbra_redirections_add_select_domain_placeholder": "Wybierz nazwę domeny", + "zimbra_redirections_add_btn_cancel": "Anuluj", + "zimbra_redirections_add_btn_confirm": "Zatwierdź", + "zimbra_redirections_add_success": "Zlecenie utworzenia przekierowania zostało zarejestrowane. Zostanie ona przetworzona za kilka minut.", + "zimbra_redirections_edit_success": "Zlecenie modyfikacji przekierowania zostało przyjęte. Zostanie ona przetworzona za kilka minut.", + "zimbra_redirections_add_error": "Zlecenie utworzenia przekierowania nie powiodło się. {{ error }}", + "zimbra_redirections_edit_error": "Zlecenie zmiany przekierowania nie mogło zostać zrealizowane. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pt_PT.json new file mode 100644 index 000000000000..2e4ca512208d --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/addAndEdit/Messages_pt_PT.json @@ -0,0 +1,17 @@ +{ + "zimbra_redirections_edit_1": "Preencha as informações para o reencaminhamento.", + "zimbra_redirections_edit_2": "Os campos marcados com * são obrigatórios.", + "zimbra_redirections_title_add": "Criar um reencaminhamento", + "zimbra_redirections_title_edit": "Modificar o reencaminhamento", + "zimbra_redirections_add_form_input_name_title_from": "Do endereço", + "zimbra_redirections_add_form_input_name_title_to": "Para o endereço", + "zimbra_redirections_add_form_input_checkbox": "Conservar uma cópia do e-mail na OVHcloud", + "zimbra_redirections_add_input_email_placeholder": "Nome da conta", + "zimbra_redirections_add_select_domain_placeholder": "Selecionar um domínio", + "zimbra_redirections_add_btn_cancel": "Anular", + "zimbra_redirections_add_btn_confirm": "Confirmar", + "zimbra_redirections_add_success": "O seu pedido de criação do reencaminhamento foi corretamente tomado em conta. Será tratada dentro de alguns instantes.", + "zimbra_redirections_edit_success": "O seu pedido de alteração do reencaminhamento foi corretamente tomado em conta. Será tratada dentro de alguns instantes.", + "zimbra_redirections_add_error": "O seu pedido de criação do reencaminhamento não foi bem-sucedido. {{ error }}", + "zimbra_redirections_edit_error": "O seu pedido de alteração do reencaminhamento não foi bem-sucedido. {{ error }}" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_de_DE.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_de_DE.json new file mode 100644 index 000000000000..ea75c7552281 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_de_DE.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Weiterleitung löschen", + "zimbra_redirections_delete_modal_content": "Möchten Sie die Weiterleitung löschen?", + "zimbra_redirections_delete_button_delete": "Löschen", + "zimbra_redirections_delete_button_cancel": "Abbrechen", + "zimbra_redirections_delete_modal_from": "Von", + "zimbra_redirections_delete_modal_to": "Zu" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_en_GB.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_en_GB.json new file mode 100644 index 000000000000..dc76edc266e8 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_en_GB.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Delete redirection", + "zimbra_redirections_delete_modal_content": "Do you want to delete the redirection?", + "zimbra_redirections_delete_button_delete": "Delete", + "zimbra_redirections_delete_button_cancel": "Cancel", + "zimbra_redirections_delete_modal_from": "From:", + "zimbra_redirections_delete_modal_to": "To:" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_es_ES.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_es_ES.json new file mode 100644 index 000000000000..d8d794c80aa9 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_es_ES.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Eliminar la redirección", + "zimbra_redirections_delete_modal_content": "¿Quiere eliminar la redirección?", + "zimbra_redirections_delete_button_delete": "Eliminar", + "zimbra_redirections_delete_button_cancel": "Cancelar", + "zimbra_redirections_delete_modal_from": "De:", + "zimbra_redirections_delete_modal_to": "A:" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_CA.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_CA.json new file mode 100644 index 000000000000..2fa0b7d045ab --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_CA.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Supprimer la redirection", + "zimbra_redirections_delete_modal_content": "Souhaitez-vous supprimer la redirection ?", + "zimbra_redirections_delete_button_delete": "Supprimer", + "zimbra_redirections_delete_button_cancel": "Annuler", + "zimbra_redirections_delete_modal_from": "De :", + "zimbra_redirections_delete_modal_to": "Vers :" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_FR.json new file mode 100644 index 000000000000..2fa0b7d045ab --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_fr_FR.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Supprimer la redirection", + "zimbra_redirections_delete_modal_content": "Souhaitez-vous supprimer la redirection ?", + "zimbra_redirections_delete_button_delete": "Supprimer", + "zimbra_redirections_delete_button_cancel": "Annuler", + "zimbra_redirections_delete_modal_from": "De :", + "zimbra_redirections_delete_modal_to": "Vers :" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_it_IT.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_it_IT.json new file mode 100644 index 000000000000..8bd31e645c14 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_it_IT.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Elimina il reindirizzamento", + "zimbra_redirections_delete_modal_content": "Vuoi eliminare il reindirizzamento?", + "zimbra_redirections_delete_button_delete": "Eliminare", + "zimbra_redirections_delete_button_cancel": "Annulla", + "zimbra_redirections_delete_modal_from": "Da:", + "zimbra_redirections_delete_modal_to": "Verso:" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pl_PL.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pl_PL.json new file mode 100644 index 000000000000..0f86f512058a --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pl_PL.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Usuń przekierowanie", + "zimbra_redirections_delete_modal_content": "Czy chcesz usunąć przekierowanie?", + "zimbra_redirections_delete_button_delete": "Usuń", + "zimbra_redirections_delete_button_cancel": "Anuluj", + "zimbra_redirections_delete_modal_from": "Od:", + "zimbra_redirections_delete_modal_to": "Na:" +} diff --git a/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pt_PT.json b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pt_PT.json new file mode 100644 index 000000000000..620e6a265de7 --- /dev/null +++ b/packages/manager/apps/zimbra/public/translations/redirections/delete/Messages_pt_PT.json @@ -0,0 +1,8 @@ +{ + "zimbra_redirections_delete_modal_title": "Eliminar o reencaminhamento", + "zimbra_redirections_delete_modal_content": "Deseja eliminar o reencaminhamento?", + "zimbra_redirections_delete_button_delete": "Suprimir", + "zimbra_redirections_delete_button_cancel": "Anular", + "zimbra_redirections_delete_modal_from": "De:", + "zimbra_redirections_delete_modal_to": "Para:" +} diff --git a/packages/manager/apps/zimbra/src/api/_mock_/account.ts b/packages/manager/apps/zimbra/src/api/_mock_/account.ts index 02cf6613e70a..c561f24e6cf1 100644 --- a/packages/manager/apps/zimbra/src/api/_mock_/account.ts +++ b/packages/manager/apps/zimbra/src/api/_mock_/account.ts @@ -1,82 +1,94 @@ import { AccountType } from '@/api/account'; import { ResourceStatus } from '@/api/api.type'; -export const accountMock: AccountType[] = [ - { - checksum: 'string', - currentState: { - contactInformation: { - city: 'string', - company: 'string', - country: 'string', - faxNumber: 'string', - mobileNumber: 'string', - office: 'string', - phoneNumber: 'string', - postcode: 'string', - profession: 'string', - service: 'string', - street: 'string', - }, - createdAt: '2024-07-09T13:27:12.775Z', - description: 'string', - detailedStatus: [ - { - details: 'string', - link: 'string', - status: 'BLOCKEDFORSPAM', - }, - ], - displayName: 'string', - domainId: '19097ad4-2870-4000-8bb0-470f414b0301', - email: 'string', - firstName: 'string', - hideInGal: false, - lastConnectionAt: '2024-07-09T13:27:12.775Z', - lastName: 'string', - offer: 'BUSINESS', - organizationId: '19097ad4-2870-4000-82b3-b71a147bc580', - organizationLabel: 'string', - quota: { - available: 0, - used: 0, - }, - updatedAt: '2024-07-09T13:27:12.775Z', +export const accountDetailMock: AccountType = { + checksum: 'string', + currentState: { + contactInformation: { + city: 'string', + company: 'string', + country: 'string', + faxNumber: 'string', + mobileNumber: 'string', + office: 'string', + phoneNumber: 'string', + postcode: 'string', + profession: 'string', + service: 'string', + street: 'string', }, - currentTasks: [ + createdAt: '2024-07-09T13:27:12.775Z', + description: 'string', + detailedStatus: [ { - id: '19097ad4-2870-4000-8bed-ecab3a061780', + details: 'string', link: 'string', - status: 'ERROR', - type: 'string', + status: 'BLOCKEDFORSPAM', }, ], - id: '19097ad4-2880-4000-8b03-9d110f0b8f80', - resourceStatus: ResourceStatus.CREATING, - targetSpec: { - contactInformation: { - city: 'string', - company: 'string', - country: 'string', - faxNumber: 'string', - mobileNumber: 'string', - office: 'string', - phoneNumber: 'string', - postcode: 'string', - profession: 'string', - service: 'string', - street: 'string', - }, - description: 'string', - displayName: 'string', - email: 'string', - firstName: 'string', - hideInGal: false, - lastName: 'string', - quota: { - available: 0, - used: 0, - }, + displayName: 'string', + domainId: '19097ad4-2870-4000-8bb0-470f414b0301', + email: 'string', + firstName: 'string', + hideInGal: false, + lastConnectionAt: '2024-07-09T13:27:12.775Z', + lastName: 'string', + offer: 'BUSINESS', + organizationId: '19097ad4-2870-4000-82b3-b71a147bc580', + organizationLabel: 'string', + quota: { + available: 0, + used: 0, + }, + updatedAt: '2024-07-09T13:27:12.775Z', + }, + currentTasks: [ + { + id: '19097ad4-2870-4000-8bed-ecab3a061780', + link: 'string', + status: 'ERROR', + type: 'string', }, + ], + id: '19097ad4-2880-4000-8b03-9d110f0b8f80', + resourceStatus: ResourceStatus.READY, + targetSpec: { + contactInformation: { + city: 'string', + company: 'string', + country: 'string', + faxNumber: 'string', + mobileNumber: 'string', + office: 'string', + phoneNumber: 'string', + postcode: 'string', + profession: 'string', + service: 'string', + street: 'string', + }, + description: 'string', + displayName: 'string', + email: 'string', + firstName: 'string', + hideInGal: false, + lastName: 'string', + quota: { + available: 0, + used: 0, + }, + }, +}; + +export const accountsMock: AccountType[] = [ + accountDetailMock, + { + ...accountDetailMock, + id: '19097ad4-2880-4444-8b03-9d110f0b8f80', + resourceStatus: ResourceStatus.CREATING, + }, + { + ...accountDetailMock, + id: '19097ad4-2880-5555-8b03-9d110f0b8f80', + resourceStatus: ResourceStatus.ERROR, }, ]; diff --git a/packages/manager/apps/zimbra/src/api/_mock_/alias.ts b/packages/manager/apps/zimbra/src/api/_mock_/alias.ts new file mode 100644 index 000000000000..3fc540e42fb5 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/_mock_/alias.ts @@ -0,0 +1,23 @@ +import { AliasType } from '@/api/alias'; +import { ResourceStatus } from '../api.type'; + +export const aliasMock: AliasType[] = [ + { + id: 'bf333af7-585d-4fb3-b81c-06be10df4828', + resourceStatus: ResourceStatus.READY, + checksum: '', + targetSpec: { + aliasTarget: '1bb958c9-cc20-465b-bf35-04b7f0d91276', + alias: '', + organizationId: 'ec66ce51-3561-4a29-a81d-4e1ddab2063d', + organizationLabel: '', + }, + currentState: { + aliasTarget: '7896d921-bb28-4555-98e6-932aae80b6ba', + alias: '', + organizationId: '75f1ed74-c3b2-4bba-8b8a-307aa80afa02', + organizationLabel: '', + }, + currentTasks: [], + }, +]; diff --git a/packages/manager/apps/zimbra/src/api/_mock_/domain.ts b/packages/manager/apps/zimbra/src/api/_mock_/domain.ts index a939666d31f3..23feb81d5869 100644 --- a/packages/manager/apps/zimbra/src/api/_mock_/domain.ts +++ b/packages/manager/apps/zimbra/src/api/_mock_/domain.ts @@ -1,38 +1,46 @@ import { DomainType } from '@/api/domain'; import { ResourceStatus } from '@/api/api.type'; -export const domainMock: DomainType[] = [ - { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - resourceStatus: ResourceStatus.READY, - checksum: 'string', - targetSpec: { - organizationId: '00000000-0000-0000-0000-000000000000', - }, - currentState: { - organizationId: '00000000-0000-0000-0000-000000000000', - name: 'NormalDomain', - status: 'READY', - createdAt: '2024-04-12T12:27:47.213Z', - updatedAt: '2024-04-12T12:27:47.213Z', - organizationLabel: 'ToyStory', - cnameToCheck: '', - accountsStatistics: [ - { - offer: 'STARTER', - configuredAccountsCount: 0, - availableAccountsCount: 4, - }, - ], - }, - currentTasks: [ +export const domainDetailMock: DomainType = { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + resourceStatus: ResourceStatus.READY, + checksum: 'string', + targetSpec: { + organizationId: '00000000-0000-0000-0000-000000000000', + }, + currentState: { + organizationId: '00000000-0000-0000-0000-000000000000', + name: 'NormalDomain', + status: 'READY', + createdAt: '2024-04-12T12:27:47.213Z', + updatedAt: '2024-04-12T12:27:47.213Z', + organizationLabel: 'ToyStory', + cnameToCheck: '', + accountsStatistics: [ { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - type: 'string', - link: 'string', + offer: 'STARTER', + configuredAccountsCount: 0, + availableAccountsCount: 4, }, ], + expectedDNSConfig: { + mx: [], + ownership: { + cname: null, + }, + }, }, + currentTasks: [ + { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + type: 'string', + link: 'string', + }, + ], +}; + +export const domainsMock: DomainType[] = [ + domainDetailMock, { id: '3fa91f64-0000-4562-b3fc-000000000000', resourceStatus: ResourceStatus.READY, @@ -55,6 +63,12 @@ export const domainMock: DomainType[] = [ availableAccountsCount: 4, }, ], + expectedDNSConfig: { + mx: [], + ownership: { + cname: null, + }, + }, }, currentTasks: [ { @@ -86,6 +100,12 @@ export const domainMock: DomainType[] = [ availableAccountsCount: 4, }, ], + expectedDNSConfig: { + mx: [], + ownership: { + cname: 'mycname', + }, + }, }, currentTasks: [ { @@ -96,3 +116,5 @@ export const domainMock: DomainType[] = [ ], }, ]; + +export const domainZone: string[] = ['test.fr', 'mydomain.fr', 'domain.fr']; diff --git a/packages/manager/apps/zimbra/src/api/_mock_/index.ts b/packages/manager/apps/zimbra/src/api/_mock_/index.ts index e2e0b17eda9e..39c0455f42f9 100644 --- a/packages/manager/apps/zimbra/src/api/_mock_/index.ts +++ b/packages/manager/apps/zimbra/src/api/_mock_/index.ts @@ -1,4 +1,7 @@ export * from './platform'; +export * from './mailinglist'; export * from './organization'; export * from './domain'; export * from './account'; +export * from './alias'; +export * from './task'; diff --git a/packages/manager/apps/zimbra/src/api/_mock_/mailinglist.ts b/packages/manager/apps/zimbra/src/api/_mock_/mailinglist.ts new file mode 100644 index 000000000000..b931fe5a848f --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/_mock_/mailinglist.ts @@ -0,0 +1,110 @@ +import { ResourceStatus } from '@/api/api.type'; +import { + MailingListType, + ModerationChoices, + ReplyToChoices, +} from '../mailinglist'; + +export const mailingListDetailMock: MailingListType = { + checksum: 'string', + currentState: { + defaultReplyTo: ReplyToChoices.LIST, + email: 'test@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-86f4-ce92e7b45e80'], + moderationOption: ModerationChoices.ALL, + organizationId: '191fa41e-46c0-4000-8a42-82cf2c709380', + organizationLabel: 'testOrg', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, + currentTasks: [ + { + id: '191fa41e-46c0-4000-8cdd-2fa1f5a6df01', + link: 'string', + status: 'ERROR', + type: 'string', + }, + ], + id: '191fa41e-46c0-4000-8904-72ce6e738f80', + resourceStatus: ResourceStatus.CREATING, + targetSpec: { + defaultReplyTo: ReplyToChoices.LIST, + email: 'test@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-8d25-fca4a684e601'], + moderationOption: ModerationChoices.ALL, + organizationId: '191fa41e-46c0-4000-8ae1-ce5ad8165601', + organizationLabel: 'testOrg', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, +}; + +export const mailingListsMock: MailingListType[] = [ + mailingListDetailMock, + { + checksum: 'string', + currentState: { + defaultReplyTo: ReplyToChoices.SENDER, + email: 'test2@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-86f4-ce92e7b45e80'], + moderationOption: ModerationChoices.SUBSONLY, + organizationId: '191fa41e-46c0-4000-8a42-82cf2c709380', + organizationLabel: 'testOrg2', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, + currentTasks: [ + { + id: '191fa41e-46c0-4000-8cdd-2fa1f5a6df01', + link: 'string', + status: 'ERROR', + type: 'string', + }, + ], + id: '191fa41e-46c0-4000-8904-72ce6e738f80', + resourceStatus: ResourceStatus.CREATING, + targetSpec: { + defaultReplyTo: ReplyToChoices.SENDER, + email: 'test2@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-8d25-fca4a684e601'], + moderationOption: ModerationChoices.SUBSONLY, + organizationId: '191fa41e-46c0-4000-8ae1-ce5ad8165601', + organizationLabel: 'testOrg2', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, + }, + { + checksum: 'string', + currentState: { + defaultReplyTo: ReplyToChoices.MAILBOX, + email: 'test3@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-86f4-ce92e7b45e80'], + moderationOption: ModerationChoices.NONE, + organizationId: '191fa41e-46c0-4000-8a42-82cf2c709380', + organizationLabel: 'testOrg3', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, + currentTasks: [ + { + id: '191fa41e-46c0-4000-8cdd-2fa1f5a6df01', + link: 'string', + status: 'ERROR', + type: 'string', + }, + ], + id: '191fa41e-46c0-4000-8904-72ce6e738f80', + resourceStatus: ResourceStatus.CREATING, + targetSpec: { + defaultReplyTo: ReplyToChoices.MAILBOX, + email: 'test3@mailinglist.com', + language: 'FR', + members: ['191fa41e-46c0-4000-8d25-fca4a684e601'], + moderationOption: ModerationChoices.NONE, + organizationId: '191fa41e-46c0-4000-8ae1-ce5ad8165601', + organizationLabel: 'testOrg3', + owner: '191fa41e-46c0-4000-8a42-82cf2c709370', + }, + }, +]; diff --git a/packages/manager/apps/zimbra/src/api/_mock_/task.ts b/packages/manager/apps/zimbra/src/api/_mock_/task.ts new file mode 100644 index 000000000000..28dc4b356d9d --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/_mock_/task.ts @@ -0,0 +1,21 @@ +export const taskDetailMock = { + createdAt: 'string', + errors: [{ message: 'string' }], + finishedAt: 'string', + id: '1', + link: 'string', + message: 'string', + progress: [{ name: 'string', status: 'string' }], + startedAt: 'string', + status: 'string', + type: 'string', + updatedAt: 'string', +}; + +export const taskMocks = [ + taskDetailMock, + { ...taskDetailMock, id: '2' }, + { ...taskDetailMock, id: '3' }, + { ...taskDetailMock, id: '4' }, + { ...taskDetailMock, id: '5' }, +]; diff --git a/packages/manager/apps/zimbra/src/api/alias/api.ts b/packages/manager/apps/zimbra/src/api/alias/api.ts new file mode 100644 index 000000000000..3194fc73e3b0 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/alias/api.ts @@ -0,0 +1,42 @@ +import { v2 } from '@ovh-ux/manager-core-api'; +import { AliasBodyParamsType, AliasType } from './type'; +import { getApiPath } from '../utils/apiPath'; + +// GET + +export const getZimbraPlatformAlias = async (platformId: string) => { + const { data } = await v2.get(`${getApiPath(platformId)}alias`); + return data; +}; + +export const getZimbraPlatformAliasDetail = async ( + platformId: string, + aliasId: string, +) => { + const { data } = await v2.get( + `${getApiPath(platformId)}alias/${aliasId}`, + ); + return data; +}; + +// POST + +export const postZimbraPlatformAlias = async ( + platformId: string, + params: AliasBodyParamsType, +) => { + const { data } = await v2.post(`${getApiPath(platformId)}alias`, { + targetSpec: params, + }); + return data; +}; + +// DELETE + +export const deleteZimbraPlatformAlias = async ( + platformId: string, + aliasId: string, +) => { + const { data } = await v2.delete(`${getApiPath(platformId)}alias/${aliasId}`); + return data; +}; diff --git a/packages/manager/apps/zimbra/src/api/alias/index.ts b/packages/manager/apps/zimbra/src/api/alias/index.ts new file mode 100644 index 000000000000..8eb7e0eb2cca --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/alias/index.ts @@ -0,0 +1,3 @@ +export * from './api'; +export * from './key'; +export * from './type'; diff --git a/packages/manager/apps/zimbra/src/api/alias/key.ts b/packages/manager/apps/zimbra/src/api/alias/key.ts new file mode 100644 index 000000000000..f114559ed381 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/alias/key.ts @@ -0,0 +1,8 @@ +export const getZimbraPlatformAliasQueryKey = (platformId: string) => { + return [`get/zimbra/platform/${platformId}/alias`]; +}; + +export const getZimbraPlatformAliasDetailQueryKey = ( + platformId: string, + aliasId?: string, +) => [`get/zimbra/platform/${platformId}/alias/${aliasId}`]; diff --git a/packages/manager/apps/zimbra/src/api/alias/type.ts b/packages/manager/apps/zimbra/src/api/alias/type.ts new file mode 100644 index 000000000000..826fa198b9e0 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/alias/type.ts @@ -0,0 +1,31 @@ +import { ResourceStatus } from '../api.type'; + +export type AliasType = { + checksum: string; + currentState: { + alias: string; + aliasTarget: string; + organizationId: string; + organizationLabel: string; + }; + currentTasks: { + id: string; + link: string; + status: string; + type: string; + }[]; + id: string; + resourceStatus: ResourceStatus; + targetSpec: { + alias: string; + aliasTarget: string; + organizationId: string; + organizationLabel: string; + }; +}; + +export type AliasBodyParamsType = { + organizationId?: string; + aliasTarget?: string; + alias?: string; +}; diff --git a/packages/manager/apps/zimbra/src/api/domain/api.ts b/packages/manager/apps/zimbra/src/api/domain/api.ts index 1de693827b76..79503126a691 100644 --- a/packages/manager/apps/zimbra/src/api/domain/api.ts +++ b/packages/manager/apps/zimbra/src/api/domain/api.ts @@ -26,6 +26,16 @@ export const getDomainsZoneList = async () => { return data; }; +export const getZimbraPlatformDomainDetail = async ( + platformId: string, + domainId: string, +) => { + const { data } = await v2.get( + `${getApiPath(platformId)}domain/${domainId}`, + ); + return data; +}; + // POST export const postZimbraDomain = async ( @@ -38,6 +48,19 @@ export const postZimbraDomain = async ( return data; }; +// PUT + +export const putZimbraDomain = async ( + platformId: string, + domainId: string, + params: DomainBodyParamsType, +) => { + const { data } = await v2.put(`${getApiPath(platformId)}domain/${domainId}`, { + targetSpec: params, + }); + return data; +}; + // DELETE export const deleteZimbraPlatformDomain = async ( diff --git a/packages/manager/apps/zimbra/src/api/domain/key.ts b/packages/manager/apps/zimbra/src/api/domain/key.ts index d042350933ef..71a1bb986312 100644 --- a/packages/manager/apps/zimbra/src/api/domain/key.ts +++ b/packages/manager/apps/zimbra/src/api/domain/key.ts @@ -5,4 +5,9 @@ export const getZimbraPlatformDomainsQueryKey = ( `get/zimbra/platform/${platformId}/domain?organizationId=${organizationId}`, ]; +export const getZimbraPlatformDomainQueryKey = ( + platformId: string, + domainId: string, +) => [`get/zimbra/platform/${platformId}/domain/${domainId}`]; + export const getDomainsZoneListQueryKey = ['get/domain/zone']; diff --git a/packages/manager/apps/zimbra/src/api/domain/type.ts b/packages/manager/apps/zimbra/src/api/domain/type.ts index a7cbb314ee25..00fa7ea16a16 100644 --- a/packages/manager/apps/zimbra/src/api/domain/type.ts +++ b/packages/manager/apps/zimbra/src/api/domain/type.ts @@ -16,6 +16,15 @@ export type DomainType = { status: string; updatedAt: string; accountsStatistics: AccountStatistics[]; + expectedDNSConfig: { + mx: Array<{ + priority: number; + target: string; + }>; + ownership: { + cname: string | null; + }; + }; }; currentTasks: Array<{ id: string; diff --git a/packages/manager/apps/zimbra/src/api/mailinglist/api.ts b/packages/manager/apps/zimbra/src/api/mailinglist/api.ts new file mode 100644 index 000000000000..29dd74dbf235 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/mailinglist/api.ts @@ -0,0 +1,60 @@ +import { v2 } from '@ovh-ux/manager-core-api'; +import { MailingListType, MailingListBodyParamsType } from './type'; +import { getApiPath } from '../utils/apiPath'; + +// GET + +export const getZimbraPlatformMailingLists = async ( + platformId: string, + queryParameters?: { + organizationId?: string; + organizationLabel?: string; + }, +) => { + const params = new URLSearchParams(queryParameters).toString(); + const queryString = params ? `?${params}` : ''; + const { data } = await v2.get( + `${getApiPath(platformId)}mailingList${queryString}`, + ); + return data; +}; + +export const getZimbraPlatformMailingListDetails = async ( + platformId: string, + mailingListId: string, +) => { + const { data } = await v2.get( + `${getApiPath(platformId)}mailingList/${mailingListId}`, + ); + return data; +}; + +// POST + +export const postZimbraPlatformMailingList = async ( + platformId: string, + params: MailingListBodyParamsType, +) => { + const { data } = await v2.post(`${getApiPath(platformId)}mailingList`, { + targetSpec: params, + }); + return data; +}; + +// PUT + +export const putZimbraPlatformMailingList = async ( + platformId: string, + mailingListId: string, + params: MailingListBodyParamsType, +) => { + const { data } = await v2.put( + `${getApiPath(platformId)}mailingList/${mailingListId}`, + { + targetSpec: params, + }, + ); + return data; +}; + +// DELETE diff --git a/packages/manager/apps/zimbra/src/api/mailinglist/index.ts b/packages/manager/apps/zimbra/src/api/mailinglist/index.ts new file mode 100644 index 000000000000..8eb7e0eb2cca --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/mailinglist/index.ts @@ -0,0 +1,3 @@ +export * from './api'; +export * from './key'; +export * from './type'; diff --git a/packages/manager/apps/zimbra/src/api/mailinglist/key.ts b/packages/manager/apps/zimbra/src/api/mailinglist/key.ts new file mode 100644 index 000000000000..94b43846bf11 --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/mailinglist/key.ts @@ -0,0 +1,16 @@ +export const getZimbraPlatformMailingListsQueryKey = ( + platformId: string, + queryParameters?: { + organizationId?: string; + organizationLabel?: string; + }, +) => { + const params = new URLSearchParams(queryParameters).toString(); + const queryString = params ? `?${params}` : ''; + return [`get/zimbra/platform/${platformId}/mailingList${queryString}`]; +}; + +export const getZimbraPlatformMailingListDetailsQueryKey = ( + platformId: string, + mailingListId: string, +) => [`get/zimbra/platform/${platformId}/mailingList/${mailingListId}`]; diff --git a/packages/manager/apps/zimbra/src/api/mailinglist/type.ts b/packages/manager/apps/zimbra/src/api/mailinglist/type.ts new file mode 100644 index 000000000000..a8200e29464b --- /dev/null +++ b/packages/manager/apps/zimbra/src/api/mailinglist/type.ts @@ -0,0 +1,55 @@ +import { ResourceStatus } from '../api.type'; + +export enum ReplyToChoices { + LIST = 'list', + SENDER = 'sender', + MAILBOX = 'another_mailbox', +} + +export enum ModerationChoices { + ALL = 'all', + SUBSONLY = 'subs_only', + NONE = 'none', +} + +export type MailingListType = { + id: string; + resourceStatus: ResourceStatus; + checksum: string; + targetSpec: { + defaultReplyTo: ReplyToChoices; + email: string; + language: string; + members: string[]; + moderationOption: ModerationChoices; + organizationId: string; + organizationLabel: string; + owner: string; + }; + currentState: { + defaultReplyTo: ReplyToChoices; + email: string; + language: string; + members: string[]; + moderationOption: ModerationChoices; + organizationId: string; + organizationLabel: string; + owner: string; + }; + currentTasks: Array<{ + id: string; + link: string; + status: string; + type: string; + }>; +}; + +export type MailingListBodyParamsType = { + defaultReplyTo?: ReplyToChoices; + email?: string; + language?: string; + members?: string[]; + moderationOption?: ModerationChoices; + organizationId?: string; + owner?: string; +}; diff --git a/packages/manager/apps/zimbra/src/api/platform/type.ts b/packages/manager/apps/zimbra/src/api/platform/type.ts index 2db0a95d9273..715f9deee2d8 100644 --- a/packages/manager/apps/zimbra/src/api/platform/type.ts +++ b/packages/manager/apps/zimbra/src/api/platform/type.ts @@ -1,8 +1,8 @@ -import { AccountStatistics } from '../api.type'; +import { AccountStatistics, ResourceStatus } from '../api.type'; export type ZimbraPlatformType = { id: string; - resourceStatus: string; + resourceStatus: ResourceStatus; checksum: string; targetSpec: { name: string; diff --git a/packages/manager/apps/zimbra/src/components/Breadcrumb/Breadcrumb.tsx b/packages/manager/apps/zimbra/src/components/Breadcrumb/Breadcrumb.tsx index e4a6074561dd..86735b42281c 100644 --- a/packages/manager/apps/zimbra/src/components/Breadcrumb/Breadcrumb.tsx +++ b/packages/manager/apps/zimbra/src/components/Breadcrumb/Breadcrumb.tsx @@ -55,7 +55,13 @@ export const Breadcrumb: React.FC = ({ ...items, ].filter(Boolean); - return ; + return ( + + ); }; export default Breadcrumb; diff --git a/packages/manager/apps/zimbra/src/components/Breadcrumb/__test__/Breadcrumb.spec.tsx b/packages/manager/apps/zimbra/src/components/Breadcrumb/__test__/Breadcrumb.spec.tsx new file mode 100644 index 000000000000..ff3cf061bafd --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/Breadcrumb/__test__/Breadcrumb.spec.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import { render } from '@/utils/test.provider'; +import Breadcrumb from '../Breadcrumb'; + +describe('Breadcrumb component', () => { + it('should render', async () => { + const { getByTestId } = render(); + const cmp = getByTestId('breadcrumb'); + expect(cmp).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/components/ButtonTooltip/ButtonTooltip.tsx b/packages/manager/apps/zimbra/src/components/ButtonTooltip/ButtonTooltip.tsx index 6a1ba4cff121..8d990ec00662 100644 --- a/packages/manager/apps/zimbra/src/components/ButtonTooltip/ButtonTooltip.tsx +++ b/packages/manager/apps/zimbra/src/components/ButtonTooltip/ButtonTooltip.tsx @@ -52,6 +52,7 @@ const ButtonTooltip: React.FC = (props) => { variant={ODS_BUTTON_VARIANT.stroked} color={ODS_THEME_COLOR_INTENT.primary} onClick={(event) => handleTooltipToggle(event)} + data-testid="button-tooltip" circle > { + it('should render', async () => { + const { getByTestId } = render( + , + ); + const cmp = getByTestId('button-tooltip'); + expect(cmp).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/components/DiagnosticBadge.tsx b/packages/manager/apps/zimbra/src/components/DiagnosticBadge.tsx new file mode 100644 index 000000000000..ef444a8ef14f --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/DiagnosticBadge.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { + OsdsChip, + OsdsText, + OsdsTooltip, + OsdsTooltipContent, +} from '@ovhcloud/ods-components/react'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; +import { DnsRecordType } from '@/utils'; +import { useGenerateUrl } from '@/hooks'; + +type StatusProps = 'error' | 'success' | 'warning'; +type DiagnosticBadgeProps = { + diagType: DnsRecordType; + status?: StatusProps; + domainId?: string; +}; + +export const DiagnosticBadge: React.FC = ({ + diagType, + status, + domainId, +}) => { + const { t } = useTranslation('domains'); + const chipColor = status as ODS_THEME_COLOR_INTENT; + const navigate = useNavigate(); + const hasAction = !!( + status === 'error' && + [DnsRecordType.MX, DnsRecordType.SPF, DnsRecordType.SRV].some( + (diag) => diag === diagType, + ) && + domainId + ); + + const href = useGenerateUrl('./diagnostic', 'path', { + domainId, + dnsRecordType: diagType, + // remove when we get it from api + isOvhDomain: 'false', + }); + + const handleChipClick = () => { + navigate(href); + }; + + return ( + + {status === 'success' ? ( + <> + {diagType} + + + {t('zimbra_domains_datagrid_diagnostic_tooltip_title', { + diagType, + })} + + + {t('zimbra_domains_datagrid_diagnostic_configuration_ok')} + + + + ) : ( + + {diagType} + + )} + + ); +}; diff --git a/packages/manager/apps/zimbra/src/components/Error/__test__/Error.spec.tsx b/packages/manager/apps/zimbra/src/components/Error/__test__/Error.spec.tsx new file mode 100644 index 000000000000..e78859751e50 --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/Error/__test__/Error.spec.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { describe, expect, vi } from 'vitest'; +import { render } from '@/utils/test.provider'; +import ErrorBanner from '../Error'; + +vi.mock('@ovh-ux/manager-react-core-application', async (importActual) => { + return { + ...(await importActual< + typeof import('@ovh-ux/manager-react-core-application') + >()), + useShell: vi.fn(() => ({ + tracking: { + trackPage: vi.fn(), + }, + environment: { + getEnvironment: vi.fn(() => Promise.resolve({})), + }, + })), + }; +}); + +describe('Error component', () => { + it('should render', async () => { + const { getByText } = render( + , + ); + expect(getByText('test')).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/components/GuideLink.tsx b/packages/manager/apps/zimbra/src/components/GuideLink.tsx new file mode 100644 index 000000000000..26dd2c86ec82 --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/GuideLink.tsx @@ -0,0 +1,28 @@ +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; +import React, { useContext } from 'react'; +import { Links, LinkType } from '@ovh-ux/manager-react-components'; +import { Guide } from '@/guides.constants'; + +interface GuideLinkProps { + label: string; + guide: Guide; +} + +export default function GuideLink({ label, guide }: Readonly) { + const context = useContext(ShellContext); + const { ovhSubsidiary } = context.environment.getUser(); + + return ( + + ); +} diff --git a/packages/manager/apps/zimbra/src/components/Loading/Loading.tsx b/packages/manager/apps/zimbra/src/components/Loading/Loading.tsx index c7ed75ea9de6..303bc4571e2e 100644 --- a/packages/manager/apps/zimbra/src/components/Loading/Loading.tsx +++ b/packages/manager/apps/zimbra/src/components/Loading/Loading.tsx @@ -8,7 +8,7 @@ export default function Loading({ size = ODS_SPINNER_SIZE.md, }) { return ( -
+
); diff --git a/packages/manager/apps/zimbra/src/components/Modals/Modal.tsx b/packages/manager/apps/zimbra/src/components/Modals/Modal.tsx index fdef3a13af31..5d00408bb36b 100644 --- a/packages/manager/apps/zimbra/src/components/Modals/Modal.tsx +++ b/packages/manager/apps/zimbra/src/components/Modals/Modal.tsx @@ -1,11 +1,8 @@ import React from 'react'; -import { - OsdsButton, - OsdsModal, - OsdsSpinner, -} from '@ovhcloud/ods-components/react'; +import { OsdsButton, OsdsModal } from '@ovhcloud/ods-components/react'; import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import { ODS_BUTTON_VARIANT, ODS_SPINNER_MODE } from '@ovhcloud/ods-components'; +import { ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; +import Loading from '@/components/Loading/Loading'; export interface ButtonType { testid?: string; @@ -47,14 +44,7 @@ const Modal: React.FC = ({ onOdsModalClose={onDismissible} > {!isLoading &&
{children}
} - {isLoading && ( -
- -
- )} + {isLoading && } {secondaryButton && ( > = ({ label, + testid, children, }) => ( -
+
{ const { platformId } = useParams(); @@ -68,7 +69,12 @@ export const Dashboard: React.FC = () => { name: 'domains', title: t('zimbra_dashboard_domains'), to: `${basePath}/domains`, - pathMatchers: computePathMatchers([urls.domains]), + pathMatchers: computePathMatchers([ + urls.domains, + urls.domainsEdit, + urls.domainsDelete, + urls.domains_diagnostic, + ]), }, { name: 'email_accounts', @@ -76,18 +82,47 @@ export const Dashboard: React.FC = () => { to: `${basePath}/email_accounts`, pathMatchers: computePathMatchers([urls.email_accounts]), }, + { + name: 'mailing_lists', + title: t('zimbra_dashboard_mailing_lists'), + to: `${basePath}/mailing_lists`, + pathMatchers: computePathMatchers([ + urls.mailing_lists, + urls.mailing_lists_delete, + ]), + hidden: !FEATURE_FLAGS.MAILINGLISTS, + }, + { + name: 'redirections', + title: t('zimbra_dashboard_redirections'), + to: `${basePath}/redirections`, + pathMatchers: computePathMatchers([ + urls.redirections, + urls.redirections_delete, + urls.redirections_edit, + ]), + hidden: !FEATURE_FLAGS.REDIRECTIONS, + }, + { + name: 'auto_replies', + title: t('zimbra_dashboard_auto_replies'), + to: `${basePath}/auto_replies`, + pathMatchers: computePathMatchers([urls.auto_replies]), + hidden: !FEATURE_FLAGS.AUTOREPLIES, + }, ]; return ( - } header={{ title: 'Zimbra', headerButton: , }} tabs={} - content={} - /> + > + + ); }; diff --git a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/Dashboard.spec.tsx b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/Dashboard.spec.tsx new file mode 100644 index 000000000000..241d71acb14e --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/Dashboard.spec.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import { render } from '@/utils/test.provider'; +import Dashboard from '../Dashboard'; + +describe('Dashboard component', () => { + it('should display correctly', async () => { + const { getByTestId } = render(); + const cmp = getByTestId('breadcrumb'); + expect(cmp).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/TabsPanel.spec.tsx b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/TabsPanel.spec.tsx new file mode 100644 index 000000000000..ee5b6d2d6ce4 --- /dev/null +++ b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/__test__/TabsPanel.spec.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { describe, expect, vi } from 'vitest'; +import { useLocation } from 'react-router-dom'; +import { render, waitFor } from '@/utils/test.provider'; +import TabsPanel from '../TabsPanel'; + +const tabs = [ + { + name: '1', + title: '1', + to: '/1', + pathMatchers: [/1/], + }, + { + name: '2', + title: '2', + to: '/2', + pathMatchers: [/2/], + }, +]; + +describe('TabsPanel component', () => { + it('should render correctly with first tab active', async () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/1', + search: '', + hash: '', + key: '', + state: '', + }); + + const { getByText, container } = render(); + + expect(container).toBeVisible(); + + const link1 = getByText('1'); + const link2 = getByText('2'); + + await waitFor(async () => { + expect(link1).toHaveAttribute('active', ''); + }); + + expect(link2).not.toHaveAttribute('active', ''); + }); + + it('should render correctly with second tab active', async () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/2', + search: '', + hash: '', + key: '', + state: '', + }); + + const { getByText, container } = render(); + + expect(container).toBeVisible(); + + const link1 = getByText('1'); + const link2 = getByText('2'); + + await waitFor(async () => { + expect(link2).toHaveAttribute('active', ''); + }); + + expect(link1).not.toHaveAttribute('active', ''); + }); +}); diff --git a/packages/manager/apps/zimbra/src/guides.constants.ts b/packages/manager/apps/zimbra/src/guides.constants.ts index e84c74c25130..6febabce4aa5 100644 --- a/packages/manager/apps/zimbra/src/guides.constants.ts +++ b/packages/manager/apps/zimbra/src/guides.constants.ts @@ -1,4 +1,4 @@ -interface GuideLinks { +export interface GuideLinks { [key: string]: string | undefined; FR?: string; GB: string; @@ -15,6 +15,12 @@ interface GuideLinks { IN?: string; } +export interface Guide { + key: string; + url: GuideLinks | string; + tracking: string; +} + const helpRoot = 'https://help.ovhcloud.com/csm/'; const WEBMAIL = 'https://webmail.mail.ovh.net/'; @@ -33,6 +39,21 @@ export const ZIMBRA_USER_GUIDE: GuideLinks = { SN: `${helpRoot}fr-mx-plan-zimbra-faq?id=kb_article_view&sysparm_article=KB0061410`, }; +export const ZIMBRA_CNAME_GUIDE: GuideLinks = { + FR: `${helpRoot}fr-email-cname-record?id=kb_article_view&sysparm_article=KB0053252`, + GB: `${helpRoot}en-gb-email-cname-record?id=kb_article_view&sysparm_article=KB0053251`, + DE: `${helpRoot}de-email-cname-record?id=kb_article_view&sysparm_article=KB0041310`, + ES: `${helpRoot}es-es-email-cname-record?id=kb_article_view&sysparm_article=KB0053242`, + IT: `${helpRoot}it-email-cname-record?id=kb_article_view&sysparm_article=KB0053256`, + PL: `${helpRoot}pl-email-cname-record?id=kb_article_view&sysparm_article=KB0053259`, + PT: `${helpRoot}pt-email-cname-record?id=kb_article_view&sysparm_article=KB0053255`, + IE: `${helpRoot}en-ie-email-cname-record?id=kb_article_view&sysparm_article=KB0053245`, + DEFAULT: `${helpRoot}fr-email-cname-record?id=kb_article_view&sysparm_article=KB0053252`, + MA: `${helpRoot}en-gb-email-cname-record?id=kb_article_view&sysparm_article=KB0053251`, + TN: `${helpRoot}fr-email-cname-record?id=kb_article_view&sysparm_article=KB0053252`, + SN: `${helpRoot}fr-email-cname-record?id=kb_article_view&sysparm_article=KB0053252`, +}; + export const ZIMBRA_ADMINISTRATOR_GUIDE: GuideLinks = { FR: `${helpRoot}fr-zimbra-getting-started?id=kb_article_view&sysparm_article=KB0064591`, GB: `${helpRoot}en-gb-zimbra-getting-started?id=kb_article_view&sysparm_article=KB0064594`, @@ -48,6 +69,21 @@ export const ZIMBRA_ADMINISTRATOR_GUIDE: GuideLinks = { SN: `${helpRoot}fr-zimbra-getting-started?id=kb_article_view&sysparm_article=KB0064591`, }; +export const ZIMBRA_DNS_CONFIGURATION_GUIDE: GuideLinks = { + FR: `${helpRoot}`, + GB: `${helpRoot}`, + DE: `${helpRoot}`, + ES: `${helpRoot}`, + IT: `${helpRoot}`, + PL: `${helpRoot}`, + PT: `${helpRoot}`, + IE: `${helpRoot}`, + DEFAULT: `${helpRoot}`, + MA: `${helpRoot}`, + TN: `${helpRoot}`, + SN: `${helpRoot}`, +}; + export const GUIDES_LIST = { webmail: { key: 'zimbra_dashboard_webmail', @@ -64,6 +100,16 @@ export const GUIDES_LIST = { url: ZIMBRA_USER_GUIDE, tracking: '::to define', }, + cname_guide: { + key: 'zimbra_cname_guide', + url: ZIMBRA_CNAME_GUIDE, + tracking: '::to define', + }, + dns_configuration_guide: { + key: 'zimbra_dns_configuration_guide', + url: ZIMBRA_DNS_CONFIGURATION_GUIDE, + tracking: '::to define', + }, }; export default { diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useAccount.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useAccount.spec.tsx index d6dc916ddfa7..b1a3e80dcea1 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useAccount.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useAccount.spec.tsx @@ -1,47 +1,23 @@ -import { describe, expect, vi } from 'vitest'; -import React from 'react'; +import { describe, expect } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { platformMock, accountMock } from '@/api/_mock_'; -import { useAccount } from '../useAccount'; - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - }; -}); - -vi.mock('@/api/account/api', () => { - const apiZimbraPlatformAccountDetail = vi.fn(() => - Promise.resolve(accountMock[0]), - ); - return { - getZimbraPlatformAccountDetail: apiZimbraPlatformAccountDetail, - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: { children: React.ReactNode }) => ( - {children} -); +import { accountDetailMock } from '@/api/_mock_'; +import { useAccount } from '@/hooks'; +import { wrapper } from '@/utils/test.provider'; describe('useAccount', () => { it('should return the detail of an account', async () => { const { result } = renderHook( - () => useAccount({ accountId: accountMock[0].id }), + () => useAccount({ accountId: accountDetailMock.id }), { wrapper, }, ); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); - expect(result.current.data).toEqual(accountMock[0]); + expect(result.current.data).toEqual(accountDetailMock); }); }); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useAccountList.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useAccountList.spec.tsx index 2ce3b36ac9e1..62dae1ef4e4b 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useAccountList.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useAccountList.spec.tsx @@ -1,48 +1,18 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; -import { platformMock, accountMock } from '@/api/_mock_'; -import { useAccountList } from '../useAccountList'; +import { accountsMock } from '@/api/_mock_'; +import { useAccountList } from '@/hooks'; +import { wrapper } from '@/utils/test.provider'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - }; -}); - -vi.mock('@/api/account/api', () => { - const apiZimbraPlatformAccount = vi.fn(() => - Promise.resolve({ data: accountMock }), - ); - return { - getZimbraPlatformAccounts: apiZimbraPlatformAccount, - }; -}); - -vi.mock('react-router-dom', () => { - return { - useSearchParams: vi.fn(() => [new URLSearchParams()]), - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('Account list', () => { - it('Return list of account', async () => { +describe('useAccountList', () => { + it('should return a list of accounts', async () => { const { result } = renderHook(() => useAccountList(), { wrapper }); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); - expect(result.current.data).toEqual(accountMock); + expect(result.current.data).toEqual(accountsMock); }); }); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useDomain.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useDomain.spec.tsx new file mode 100644 index 000000000000..38eaa0171ba9 --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useDomain.spec.tsx @@ -0,0 +1,20 @@ +import { describe, expect } from 'vitest'; +import '@testing-library/jest-dom'; +import { renderHook, waitFor } from '@testing-library/react'; +import { domainDetailMock } from '@/api/_mock_'; +import { useDomain } from '../useDomain'; +import { wrapper } from '@/utils/test.provider'; + +describe('useDomain', () => { + it('should return the detail of a domain', async () => { + const { result } = renderHook(() => useDomain(domainDetailMock.id), { + wrapper, + }); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toEqual(domainDetailMock); + }); +}); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useDomains.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useDomains.spec.tsx index 5e42fd847dc6..ca3909535cb8 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useDomains.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useDomains.spec.tsx @@ -1,43 +1,18 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; -import { platformMock, organizationDetailMock, domainMock } from '@/api/_mock_'; +import { domainsMock } from '@/api/_mock_'; import { useDomains } from '../useDomains'; +import { wrapper } from '@/utils/test.provider'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useOrganization: vi.fn(() => ({ - data: organizationDetailMock, - })), - }; -}); - -vi.mock('@/api/domain/api', () => { - const apiGetDomains = vi.fn(() => Promise.resolve({ data: domainMock })); - return { - getZimbraPlatformDomains: apiGetDomains, - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('Domains', () => { - it('Return domain list', async () => { +describe('useDomains', () => { + it('should return a domain list', async () => { const { result } = renderHook(() => useDomains(), { wrapper }); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); - expect(result.current.data).toEqual(domainMock); + expect(result.current.data).toEqual(domainsMock); }); }); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useGenerateUrl.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useGenerateUrl.spec.tsx index 60733a30ed5b..91037092772f 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useGenerateUrl.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useGenerateUrl.spec.tsx @@ -1,20 +1,12 @@ import { describe, expect, vi } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; import { useGenerateUrl } from '../useGenerateUrl'; - -vi.mock('@/hooks', () => { - return { - useOrganization: vi.fn(() => ({ data: undefined })), - }; -}); +import { wrapper } from '@/utils/test.provider'; vi.mock('react-router-dom', async (importOriginal) => { - const actual: any = await importOriginal(); return { - ...actual, + ...(await importOriginal()), useHref: vi.fn( (text) => `#/00000000-0000-0000-0000-000000000001/organizations/${text.slice(2)}`, @@ -22,14 +14,8 @@ vi.mock('react-router-dom', async (importOriginal) => { }; }); -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('href', () => { - it('Return url href', async () => { +describe('useGenerateUrl', () => { + it('should return url href', async () => { const { result } = renderHook(() => useGenerateUrl('./add', 'href'), { wrapper, }); @@ -38,7 +24,7 @@ describe('href', () => { ); }); - it('Return url href with params', async () => { + it('should return url href with params', async () => { const { result } = renderHook( () => useGenerateUrl('./delete', 'href', { @@ -53,14 +39,14 @@ describe('href', () => { ); }); - it('Return url path', async () => { + it('should return url path', async () => { const { result } = renderHook(() => useGenerateUrl('./add', 'path'), { wrapper, }); expect(result.current).toBe('./add?'); }); - it('Return url path with params', async () => { + it('should return url path with params', async () => { const { result } = renderHook( () => useGenerateUrl('./delete', 'path', { diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useMailingList.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useMailingList.spec.tsx new file mode 100644 index 000000000000..6db2172b95bd --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useMailingList.spec.tsx @@ -0,0 +1,23 @@ +import { describe, expect } from 'vitest'; +import '@testing-library/jest-dom'; +import { renderHook, waitFor } from '@testing-library/react'; +import { mailingListDetailMock } from '@/api/_mock_'; +import { useMailingList } from '@/hooks'; +import { wrapper } from '@/utils/test.provider'; + +describe('useMailingList', () => { + it('should return a mailinglist detail', async () => { + const { result } = renderHook( + () => useMailingList({ mailingListId: mailingListDetailMock.id }), + { + wrapper, + }, + ); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toEqual(mailingListDetailMock); + }); +}); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useMailingLists.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useMailingLists.spec.tsx new file mode 100644 index 000000000000..137bc4a4b4bc --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useMailingLists.spec.tsx @@ -0,0 +1,18 @@ +import { describe, expect } from 'vitest'; +import '@testing-library/jest-dom'; +import { renderHook, waitFor } from '@testing-library/react'; +import { mailingListsMock } from '@/api/_mock_'; +import { useMailingLists } from '@/hooks'; +import { wrapper } from '@/utils/test.provider'; + +describe('useMailingLists', () => { + it('should return mailing lists', async () => { + const { result } = renderHook(() => useMailingLists(), { wrapper }); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toEqual(mailingListsMock); + }); +}); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useOrganization.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useOrganization.spec.tsx index 121d64002fe1..84f54edcb124 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useOrganization.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useOrganization.spec.tsx @@ -1,62 +1,24 @@ import { describe, expect, vi } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; -import { platformMock, organizationDetailMock } from '@/api/_mock_'; +import { useSearchParams } from 'react-router-dom'; +import { organizationDetailMock } from '@/api/_mock_'; import { useOrganization } from '../useOrganization'; +import { wrapper } from '@/utils/test.provider'; -const useLocationMock: { - pathname: string; - search: string; - hash: string; - state: string | null; - key: string; -} = { - pathname: '/00000000-0000-0000-0000-000000000001', - search: '?organizationId=1903b491-4d10-4000-8b70-f474d1abe601', - hash: '', - state: null, - key: 'naq3ecco', -}; +describe('useOrganization', () => { + it('should return detail of organization in params url', async () => { + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + organizationId: organizationDetailMock.id, + }), + vi.fn(), + ]); -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - }; -}); - -vi.mock('@/api/organization/api', () => { - const apiOrganizationDetail = vi.fn(() => - Promise.resolve(organizationDetailMock), - ); - return { - getZimbraPlatformOrganizationDetails: apiOrganizationDetail, - }; -}); - -vi.mock('react-router-dom', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - useLocation: () => useLocationMock, - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('Organization', () => { - it('Return detail of organization in params url', async () => { const { result } = renderHook(() => useOrganization(), { wrapper }); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); expect(result.current.data).toEqual(organizationDetailMock); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useOrganizationsList.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useOrganizationsList.spec.tsx index cfafe541274e..27f0ad9865b0 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/useOrganizationsList.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useOrganizationsList.spec.tsx @@ -1,40 +1,16 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; -import { platformMock, organizationListMock } from '@/api/_mock_'; +import { organizationListMock } from '@/api/_mock_'; import { useOrganizationList } from '../useOrganizationsList'; +import { wrapper } from '@/utils/test.provider'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - }; -}); - -vi.mock('@/api/organization/api', () => { - const apiOrganization = vi.fn(() => - Promise.resolve({ data: organizationListMock }), - ); - return { - getZimbraPlatformOrganization: apiOrganization, - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('OrganizationList', () => { - it('Return list of organization', async () => { +describe('useOrganizationsList', () => { + it('should return a list of organization', async () => { const { result } = renderHook(() => useOrganizationList(), { wrapper }); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); expect(result.current.data).toEqual(organizationListMock); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useOverridePage.spec.ts b/packages/manager/apps/zimbra/src/hooks/__test__/useOverridePage.spec.ts new file mode 100644 index 000000000000..5224a5c59f6a --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useOverridePage.spec.ts @@ -0,0 +1,25 @@ +import { describe, expect, vi } from 'vitest'; +import { useMatches } from 'react-router-dom'; +import { useOverridePage } from '../useOverridePage'; +import '@testing-library/jest-dom'; + +describe('useOverridePage', () => { + it('should return false', async () => { + vi.mocked(useMatches).mockReturnValue([]); + expect(useOverridePage()).toBeFalsy(); + }); + + it('should return false', async () => { + vi.mocked(useMatches).mockReturnValue([ + { handle: { isOverridePage: false } }, + ] as never); + expect(useOverridePage()).toBeFalsy(); + }); + + it('should return false', async () => { + vi.mocked(useMatches).mockReturnValue([ + { handle: { isOverridePage: true } }, + ] as never); + expect(useOverridePage()).toBeTruthy(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/usePlatform.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/usePlatform.spec.tsx index 5757b5d6d00e..3da9f64c20e0 100644 --- a/packages/manager/apps/zimbra/src/hooks/__test__/usePlatform.spec.tsx +++ b/packages/manager/apps/zimbra/src/hooks/__test__/usePlatform.spec.tsx @@ -1,30 +1,16 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect } from 'vitest'; import '@testing-library/jest-dom'; import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import React from 'react'; import { usePlatform } from '../usePlatform'; import { platformMock } from '@/api/_mock_'; +import { wrapper } from '@/utils/test.provider'; -vi.mock('@/api/platform/api', () => { - const mock = vi.fn(() => Promise.resolve(platformMock)); - return { - getZimbraPlatformList: mock, - }; -}); - -const queryClient = new QueryClient(); - -const wrapper = ({ children }: any) => ( - {children} -); - -describe('Platform', () => { - it('We have to return the firt element', async () => { +describe('usePlatform', () => { + it('should return the first element of the platform list', async () => { const { result } = renderHook(() => usePlatform(), { wrapper }); await waitFor(() => { - expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(true); }); expect(result.current.data).toEqual(platformMock[0]); diff --git a/packages/manager/apps/zimbra/src/hooks/__test__/useTasks.spec.tsx b/packages/manager/apps/zimbra/src/hooks/__test__/useTasks.spec.tsx new file mode 100644 index 000000000000..83aa4405c0be --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/__test__/useTasks.spec.tsx @@ -0,0 +1,18 @@ +import { describe, expect } from 'vitest'; +import '@testing-library/jest-dom'; +import { renderHook, waitFor } from '@testing-library/react'; +import { taskMocks } from '@/api/_mock_'; +import { useTasks } from '../useTasks'; +import { wrapper } from '@/utils/test.provider'; + +describe('useTasks', () => { + it('should return a list of tasks', async () => { + const { result } = renderHook(() => useTasks(), { wrapper }); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toEqual(taskMocks); + }); +}); diff --git a/packages/manager/apps/zimbra/src/hooks/index.ts b/packages/manager/apps/zimbra/src/hooks/index.ts index 88f8ee11df4b..f42c7fc916e6 100644 --- a/packages/manager/apps/zimbra/src/hooks/index.ts +++ b/packages/manager/apps/zimbra/src/hooks/index.ts @@ -1,9 +1,14 @@ export * from './useAccount'; export * from './useAccountList'; export * from './useDomains'; +export * from './useDomain'; export * from './useGenerateUrl'; +export * from './useMailingList'; +export * from './useMailingLists'; export * from './useOrganization'; export * from './useOrganizationsList'; export * from './useOverridePage'; export * from './usePlatform'; +export * from './useAccount'; +export * from './useTasks'; export * from './types'; diff --git a/packages/manager/apps/zimbra/src/hooks/useAccount.ts b/packages/manager/apps/zimbra/src/hooks/useAccount.ts index 15fecf469ce9..ccfdefca4d19 100644 --- a/packages/manager/apps/zimbra/src/hooks/useAccount.ts +++ b/packages/manager/apps/zimbra/src/hooks/useAccount.ts @@ -15,20 +15,20 @@ type UseAccountParams = Omit< 'queryKey' | 'queryFn' | 'gcTime' > & { accountId?: string; - noCache?: boolean; }; export const useAccount = (props: UseAccountParams) => { - const { accountId, noCache, ...options } = props; + const { accountId, ...options } = props; const { platformId } = usePlatform(); return useQuery({ ...options, queryKey: getZimbraPlatformAccountDetailQueryKey(platformId, accountId), queryFn: () => getZimbraPlatformAccountDetail(platformId, accountId), - enabled: - (typeof options.enabled !== 'undefined' ? options.enabled : true) && + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && !!platformId && !!accountId, - gcTime: noCache ? 0 : 5000, }) as UseQueryResult; }; diff --git a/packages/manager/apps/zimbra/src/hooks/useAccountList.ts b/packages/manager/apps/zimbra/src/hooks/useAccountList.ts index 5a81b548ffa4..67d9f48abd3e 100644 --- a/packages/manager/apps/zimbra/src/hooks/useAccountList.ts +++ b/packages/manager/apps/zimbra/src/hooks/useAccountList.ts @@ -43,8 +43,10 @@ export const useAccountList = (props: UseAccountListParams = {}) => { queryParameters, pageParam, }), - enabled: - (typeof options.enabled !== 'undefined' ? options.enabled : true) && + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && !!platformId, getNextPageParam: (lastPage: { cursorNext?: string }) => lastPage.cursorNext, diff --git a/packages/manager/apps/zimbra/src/hooks/useDomain.ts b/packages/manager/apps/zimbra/src/hooks/useDomain.ts new file mode 100644 index 000000000000..b94ffe06f7b5 --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/useDomain.ts @@ -0,0 +1,18 @@ +import { useQuery } from '@tanstack/react-query'; +import { usePlatform } from '@/hooks'; + +import { + getZimbraPlatformDomainDetail, + getZimbraPlatformDomainQueryKey, +} from '@/api/domain'; + +export const useDomain = (domainId: string, noCache?: boolean) => { + const { platformId } = usePlatform(); + + return useQuery({ + queryKey: getZimbraPlatformDomainQueryKey(platformId, domainId), + queryFn: () => getZimbraPlatformDomainDetail(platformId, domainId), + enabled: !!platformId && !!domainId, + gcTime: noCache ? 0 : 5000, + }); +}; diff --git a/packages/manager/apps/zimbra/src/hooks/useDomains.ts b/packages/manager/apps/zimbra/src/hooks/useDomains.ts index 9a93c93f3227..19c1baeae08c 100644 --- a/packages/manager/apps/zimbra/src/hooks/useDomains.ts +++ b/packages/manager/apps/zimbra/src/hooks/useDomains.ts @@ -37,10 +37,11 @@ export const useDomains = (props: UseDomainsParams = {}) => { organizationId: organizationId || selectedOrganizationId, pageParam, }), - enabled: - (typeof options.enabled !== 'undefined' ? options.enabled : true) && + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && !!platformId, - staleTime: Infinity, getNextPageParam: (lastPage: { cursorNext?: string }) => lastPage.cursorNext, select: (data) => diff --git a/packages/manager/apps/zimbra/src/hooks/useGenerateUrl.ts b/packages/manager/apps/zimbra/src/hooks/useGenerateUrl.ts index 59f39906a0f3..74835d3644f0 100644 --- a/packages/manager/apps/zimbra/src/hooks/useGenerateUrl.ts +++ b/packages/manager/apps/zimbra/src/hooks/useGenerateUrl.ts @@ -4,7 +4,7 @@ import { useOrganization } from '@/hooks'; export const useGenerateUrl = ( baseURL: string, type: 'path' | 'href' = 'path', - params?: Record, + params?: Record, ) => { const { data: organization } = useOrganization(); diff --git a/packages/manager/apps/zimbra/src/hooks/useMailingList.ts b/packages/manager/apps/zimbra/src/hooks/useMailingList.ts new file mode 100644 index 000000000000..fbf40fa1e5b5 --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/useMailingList.ts @@ -0,0 +1,38 @@ +import { + useQuery, + UseQueryOptions, + UseQueryResult, +} from '@tanstack/react-query'; +import { usePlatform } from '@/hooks'; +import { + getZimbraPlatformMailingListDetails, + getZimbraPlatformMailingListDetailsQueryKey, + MailingListType, +} from '@/api/mailinglist'; + +type UseMailingListParams = Omit< + UseQueryOptions, + 'queryKey' | 'queryFn' | 'select' +> & { + mailingListId?: string; +}; + +export const useMailingList = (props: UseMailingListParams = {}) => { + const { platformId } = usePlatform(); + const { mailingListId, ...options } = props; + return useQuery({ + ...options, + queryKey: getZimbraPlatformMailingListDetailsQueryKey( + platformId, + mailingListId, + ), + queryFn: () => + getZimbraPlatformMailingListDetails(platformId, mailingListId), + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && + !!mailingListId && + !!platformId, + }) as UseQueryResult; +}; diff --git a/packages/manager/apps/zimbra/src/hooks/useMailingLists.ts b/packages/manager/apps/zimbra/src/hooks/useMailingLists.ts new file mode 100644 index 000000000000..fa400784765e --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/useMailingLists.ts @@ -0,0 +1,51 @@ +import { + useQuery, + UseQueryOptions, + UseQueryResult, +} from '@tanstack/react-query'; +import { useSearchParams } from 'react-router-dom'; +import { usePlatform } from '@/hooks'; +import { + getZimbraPlatformMailingLists, + getZimbraPlatformMailingListsQueryKey, + MailingListType, +} from '@/api/mailinglist'; + +type UseMailingListsParams = Omit< + UseQueryOptions, + 'queryKey' | 'queryFn' | 'select' +> & { + organizationId?: string; + organizationLabel?: string; +}; + +export const useMailingLists = (props: UseMailingListsParams = {}) => { + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const { organizationId, organizationLabel, ...options } = props; + const selectedOrganizationId = + organizationId ?? searchParams.get('organizationId'); + const selectedOrganizationLabel = + organizationLabel ?? searchParams.get('organizationLabel'); + + const queryParameters = { + ...(selectedOrganizationId && { organizationId: selectedOrganizationId }), + ...(selectedOrganizationLabel && { + organizationLabel: selectedOrganizationLabel, + }), + }; + + return useQuery({ + ...options, + queryKey: getZimbraPlatformMailingListsQueryKey( + platformId, + queryParameters, + ), + queryFn: () => getZimbraPlatformMailingLists(platformId, queryParameters), + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && + !!platformId, + }) as UseQueryResult; +}; diff --git a/packages/manager/apps/zimbra/src/hooks/useOrganization.ts b/packages/manager/apps/zimbra/src/hooks/useOrganization.ts index a6039151df06..fb2e487c6483 100644 --- a/packages/manager/apps/zimbra/src/hooks/useOrganization.ts +++ b/packages/manager/apps/zimbra/src/hooks/useOrganization.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { useLocation } from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom'; import { usePlatform } from '@/hooks'; import { getZimbraPlatformOrganizationDetails, @@ -8,9 +8,8 @@ import { export const useOrganization = (organizationId?: string, noCache?: boolean) => { const { platformId } = usePlatform(); - const location = useLocation(); - const params = new URLSearchParams(location.search); - const selectedOrganizationId = params.get('organizationId'); + const [searchParams] = useSearchParams(); + const selectedOrganizationId = searchParams.get('organizationId'); return useQuery({ queryKey: getZimbraPlatformOrganizationDetailsQueryKey( platformId, diff --git a/packages/manager/apps/zimbra/src/hooks/useOrganizationsList.ts b/packages/manager/apps/zimbra/src/hooks/useOrganizationsList.ts index 5a70d92a4518..7b8858cf9734 100644 --- a/packages/manager/apps/zimbra/src/hooks/useOrganizationsList.ts +++ b/packages/manager/apps/zimbra/src/hooks/useOrganizationsList.ts @@ -24,8 +24,10 @@ export const useOrganizationList = ( queryKey: getZimbraPlatformOrganizationQueryKey(platformId), queryFn: ({ pageParam }) => getZimbraPlatformOrganization({ platformId, pageParam }), - enabled: - (typeof options.enabled !== 'undefined' ? options.enabled : true) && + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && !!platformId, getNextPageParam: (lastPage: { cursorNext?: string }) => lastPage.cursorNext, diff --git a/packages/manager/apps/zimbra/src/hooks/usePlatform.ts b/packages/manager/apps/zimbra/src/hooks/usePlatform.ts index f8acb8200df1..3237789e8359 100644 --- a/packages/manager/apps/zimbra/src/hooks/usePlatform.ts +++ b/packages/manager/apps/zimbra/src/hooks/usePlatform.ts @@ -5,12 +5,13 @@ import { } from '@/api/platform'; export const usePlatform = () => { - const { data, isLoading, isError, error } = useQuery({ + const { data, isLoading, isError, error, ...rest } = useQuery({ queryKey: [getZimbraPlatformListQueryKey], queryFn: () => getZimbraPlatformList(), }); return { + ...rest, isLoading, isError, error, diff --git a/packages/manager/apps/zimbra/src/hooks/useTasks.ts b/packages/manager/apps/zimbra/src/hooks/useTasks.ts new file mode 100644 index 000000000000..debfc478f1ce --- /dev/null +++ b/packages/manager/apps/zimbra/src/hooks/useTasks.ts @@ -0,0 +1,29 @@ +import { + useQuery, + UseQueryOptions, + UseQueryResult, +} from '@tanstack/react-query'; +import { usePlatform, useOrganization } from '@/hooks'; +import { + getZimbraPlatformTask, + getZimbraPlatformTaskQueryKey, + TaskType, +} from '@/api/task'; + +type UseTasksParams = Omit; + +export const useTasks = (options: UseTasksParams = {}) => { + const { platformId } = usePlatform(); + const { data: organization } = useOrganization(); + + return useQuery({ + ...options, + queryKey: getZimbraPlatformTaskQueryKey(platformId, organization?.id), + queryFn: () => getZimbraPlatformTask(platformId, organization?.id), + enabled: (query) => + (typeof options.enabled === 'function' + ? options.enabled(query) + : typeof options.enabled !== 'boolean' || options.enabled) && + !!platformId, + }) as UseQueryResult; +}; diff --git a/packages/manager/apps/zimbra/src/pages/__test__/404.spec.tsx b/packages/manager/apps/zimbra/src/pages/__test__/404.spec.tsx new file mode 100644 index 000000000000..899db0c6b272 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/__test__/404.spec.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import NotFoundPage from '../404'; +import { render } from '@/utils/test.provider'; + +describe('404 page', () => { + it('should display page correctly', async () => { + const { findByText } = render(); + const title = await findByText('404 - route not found'); + expect(title).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/__test__/_app.spec.tsx b/packages/manager/apps/zimbra/src/pages/__test__/_app.spec.tsx new file mode 100644 index 000000000000..af72e2ad3bf4 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/__test__/_app.spec.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import App from '../_app'; +import { render } from '@/utils/test.provider'; + +describe('App', () => { + it('should render correctly', async () => { + const { getByTestId } = render( + +
+
, + ); + + expect(getByTestId('test')).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/__test__/layout.spec.tsx b/packages/manager/apps/zimbra/src/pages/__test__/layout.spec.tsx new file mode 100644 index 000000000000..a52b4dbd5f6e --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/__test__/layout.spec.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import Layout from '../layout'; +import { render, waitFor } from '@/utils/test.provider'; + +describe('Layout', () => { + it('should render correctly', async () => { + const { queryByTestId, container } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + expect(container).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/AutoReplies.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/AutoReplies.tsx new file mode 100644 index 000000000000..ee01b5ead825 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/AutoReplies.tsx @@ -0,0 +1,101 @@ +import { + Datagrid, + DatagridColumn, + Notifications, +} from '@ovh-ux/manager-react-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_SIZE, + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, +} from '@ovhcloud/ods-components'; +import { OsdsButton, OsdsIcon } from '@ovhcloud/ods-components/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Outlet } from 'react-router-dom'; + +export type AutoRepliesItem = { + id: string; + name: string; + from: string; + until: string; + copyTo: string; +}; + +const items: AutoRepliesItem[] = [ + { + id: '1', + name: 'to@example1.com', + from: '11/02/2023', + until: '11/02/2024', + copyTo: 'copy@example1.com', + }, + { + id: '2', + name: 'to@example2.com', + from: '11/03/2023', + until: '11/03/2024', + copyTo: 'copy@example2.com', + }, +]; +const columns: DatagridColumn[] = [ + { + id: 'name', + cell: (item) =>
{item.name}
, + label: 'zimbra_auto_replies_name', + }, + { + id: 'from', + cell: (item) =>
{item.from}
, + label: 'zimbra_auto_replies_from', + }, + { + id: 'until', + cell: (item) =>
{item.until}
, + label: 'zimbra_auto_replies_until', + }, + { + id: 'copyTo', + cell: (item) =>
{item.copyTo}
, + label: 'zimbra_auto_replies_copyTo', + }, + { + id: 'deleteButton', + cell: () => ( + + + + ), + label: '', + }, +]; +export function AutoReplies() { + const { t } = useTranslation('autoReplies'); + + return ( +
+ + + ({ + ...column, + label: t(column.label), + }))} + items={items} + totalItems={items.length} + /> +
+ ); +} + +export default AutoReplies; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/__test__/AutoReplies.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/__test__/AutoReplies.spec.tsx new file mode 100644 index 000000000000..481045863f38 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/__test__/AutoReplies.spec.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import AutoReplies from '../AutoReplies'; +import { render } from '@/utils/test.provider'; + +describe('Redirections page', () => { + it('should display page correctly', () => { + const { getByTestId } = render(); + const wrapper = getByTestId('autoreplies'); + + expect(wrapper).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.component.tsx similarity index 79% rename from packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.component.tsx index fe0aa44e2573..2fac4212b396 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ActionButtonDomain.component.tsx @@ -16,10 +16,20 @@ const ActionButtonDomain: React.FC = ({ const hrefDeleteDomain = useGenerateUrl('./delete', 'href', { deleteDomainId: domainItem.id, }); + const hrefEditDomain = useGenerateUrl('./edit', 'href', { + editDomainId: domainItem.id, + }); const { platformUrn } = usePlatform(); const actionItems = [ { id: 1, + href: hrefEditDomain, + label: t('zimbra_domains_tooltip_configure'), + urn: platformUrn, + iamActions: [IAM_ACTIONS.domain.edit], + }, + { + id: 2, href: hrefDeleteDomain, label: t('zimbra_domains_tooltip_delete'), urn: platformUrn, diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx new file mode 100644 index 000000000000..b42c44648b96 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx @@ -0,0 +1,583 @@ +import React, { useCallback, useState } from 'react'; +import { + LinkType, + Links, + Subtitle, + useNotifications, + Clipboard, +} from '@ovh-ux/manager-react-components'; + +import { Trans, useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; +import { + OsdsFormField, + OsdsRadio, + OsdsRadioButton, + OsdsRadioGroup, + OsdsSelect, + OsdsSelectOption, + OsdsSpinner, + OsdsText, + OsdsButton, + OsdsInput, + OsdsMessage, + OsdsCheckboxButton, + OsdsCheckbox, +} from '@ovhcloud/ods-components/react'; +import { + ODS_THEME_COLOR_HUE, + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { + ODS_ICON_NAME, + ODS_INPUT_TYPE, + ODS_MESSAGE_TYPE, + ODS_RADIO_BUTTON_SIZE, + ODS_SPINNER_MODE, + ODS_SPINNER_SIZE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, + OdsCheckboxCheckedChangeEventDetail, + OdsInputValueChangeEvent, + OdsSelectValueChangeEventDetail, + OsdsCheckboxCustomEvent, + OsdsRadioGroupCustomEvent, + OsdsSelectCustomEvent, +} from '@ovhcloud/ods-components'; +import { useMutation, useQuery } from '@tanstack/react-query'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { + useOrganization, + useOrganizationList, + usePlatform, + useGenerateUrl, +} from '@/hooks'; +import { + DomainBodyParamsType, + getDomainsZoneList, + getDomainsZoneListQueryKey, + getZimbraPlatformDomainsQueryKey, + postZimbraDomain, +} from '@/api/domain'; +import queryClient from '@/queryClient'; +import { GUIDES_LIST } from '@/guides.constants'; +import { DomainType } from '@/api/domain/type'; +import { DNS_CONFIG_TYPE, DnsRecordType, FEATURE_FLAGS } from '@/utils'; +import GuideLink from '@/components/GuideLink'; + +export default function AddDomain() { + const { t } = useTranslation('domains/addDomain'); + const navigate = useNavigate(); + + const { addError, addSuccess } = useNotifications(); + + const { platformId } = usePlatform(); + const { data, isLoading } = useOrganizationList(); + const { data: organization } = useOrganization(); + const [selectedOrganization, setSelectedOrganization] = useState( + organization?.id || '', + ); + + const goBackUrl = useGenerateUrl('..', 'path'); + const onClose = () => navigate(goBackUrl); + const backLinkUrl = useGenerateUrl('..', 'href'); + + const { data: domains, isLoading: isLoadingDomain } = useQuery({ + queryKey: getDomainsZoneListQueryKey, + queryFn: () => getDomainsZoneList(), + }); + + const [selectedRadioDomain, setSelectedRadioDomain] = useState( + !FEATURE_FLAGS.DOMAIN_NOT_OVH ? 'ovhDomain' : '', + ); + const [selectedDomainName, setSelectedDomainName] = useState(''); + const [cnameToCheck, setCnameToCheck] = useState(''); + const [ + selectedRadioConfigurationType, + setSelectedRadioConfigurationType, + ] = useState( + !FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION ? DNS_CONFIG_TYPE.STANDARD : '', + ); + + const [expertConfigItemsState, setExpertConfigItemsState] = useState< + Record + >({}); + + const expertConfigItems = [ + { + name: DnsRecordType.SRV, + label: t('zimbra_domains_add_domain_configuration_expert_configure_srv'), + }, + { + name: DnsRecordType.MX, + label: t('zimbra_domains_add_domain_configuration_expert_configure_mx'), + }, + { + name: DnsRecordType.SPF, + label: t('zimbra_domains_add_domain_configuration_expert_configure_spf'), + }, + { + name: DnsRecordType.DKIM, + label: t('zimbra_domains_add_domain_configuration_expert_configure_dkim'), + }, + ]; + + const handleOrganizationChange = ( + event: OsdsSelectCustomEvent, + ) => { + setSelectedOrganization(event.detail.value); + }; + const handleDomainOvhChange = ( + event: OsdsSelectCustomEvent, + ) => { + setSelectedDomainName(event.detail.value as string); + if (FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION) { + setSelectedRadioConfigurationType(''); + } + setExpertConfigItemsState({}); + }; + + const ovhDomain = selectedRadioDomain === 'ovhDomain'; + + const isExpertConfigurationSelected = + selectedRadioConfigurationType === 'expertConfiguration'; + + const handleRadioDomainChange = useCallback( + ( + event: OsdsRadioGroupCustomEvent<{ + newValue?: string; + previousValue?: string; + }>, + ) => { + const type = `${event.detail.newValue}` || ''; + setSelectedRadioDomain(type); + setSelectedDomainName(''); + }, + [setSelectedRadioDomain], + ); + + const handleRadioConfigurationTypeChange = useCallback( + ( + event: OsdsRadioGroupCustomEvent<{ + newValue?: string; + previousValue?: string; + }>, + ) => { + const type = `${event.detail.newValue}` || ''; + setSelectedRadioConfigurationType(type); + setExpertConfigItemsState({}); + }, + [setSelectedRadioConfigurationType], + ); + + const handleExpertConfigItemsChange = useCallback( + (event: OsdsCheckboxCustomEvent) => { + setExpertConfigItemsState((prev) => ({ + ...prev, + [event.target.name as string]: event.detail.checked, + })); + }, + [expertConfigItemsState], + ); + + const { mutate: addDomain, isPending: isSending } = useMutation({ + mutationFn: (params: DomainBodyParamsType) => { + return postZimbraDomain(platformId, params); + }, + onSuccess: (domain: DomainType) => { + addSuccess( + + {t('zimbra_domains_add_domain_success_message')} + , + true, + ); + if (domain.currentState.expectedDNSConfig.ownership.cname) { + setCnameToCheck(domain.currentState.expectedDNSConfig.ownership.cname); + } + }, + onError: (error: ApiError) => { + addError( + + {t('zimbra_domains_add_domain_error_message', { + error: error?.response?.data?.message, + })} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformDomainsQueryKey(platformId), + }); + + onClose(); + }, + }); + + const handleAddDomainClick = () => { + const formData = { + organizationId: selectedOrganization, + name: selectedDomainName, + autoConfigureMX: selectedRadioDomain !== 'externalDomain', + }; + addDomain(formData); + }; + + const handleInputChange = (event: OdsInputValueChangeEvent) => { + setSelectedDomainName(event.detail.value as string); + }; + + return ( +
+ + {!cnameToCheck ? ( + <> + + {t('zimbra_domains_add_domain_title_select')} + + + +
+ + {t('zimbra_domains_add_domain_organization')} + +
+ handleOrganizationChange(event)} + className="mt-2 w-1/2" + data-testid="select-organization" + > + + {t('zimbra_domains_add_domain_organization_select')} + + {data?.map((item) => ( + + {item.targetSpec?.name} + + ))} + + {isLoading && ( +
+ +
+ )} +
+ {FEATURE_FLAGS.DOMAIN_NOT_OVH && + selectedOrganization && + !isLoadingDomain && ( + + handleRadioDomainChange(value)} + > + + + + + {t('zimbra_domains_add_domain_select_title')} + + + + + + + + + {t('zimbra_domains_add_domain_input_title')} + + + + + + {isLoadingDomain && ( +
+ +
+ )} +
+ )} + {selectedOrganization && selectedRadioDomain && ( + +
+ + {t('zimbra_domains_add_domain_title')} + +
+ {ovhDomain && domains ? ( + handleDomainOvhChange(event)} + > + + + {t('zimbra_domains_add_domain_select')} + + + {domains.map((domain: string) => ( + + {domain} + + ))} + + ) : ( + <> + + + + {t( + 'zimbra_domains_add_domain_warning_modification_domain', + )} + + + + )} +
+ )} + {FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION && + selectedRadioDomain && + ovhDomain && + selectedDomainName && ( + + + {t('zimbra_domains_add_domain_configuration_title')} + + + {t('zimbra_domains_add_domain_configuration_description')} + + + handleRadioConfigurationTypeChange(value) + } + > + {[DNS_CONFIG_TYPE.STANDARD, DNS_CONFIG_TYPE.EXPERT].map( + (type) => ( + + +
+ + {t( + `zimbra_domains_add_domain_configuration_choice_${type}`, + )} + + + {t( + `zimbra_domains_add_domain_configuration_choice_${type}_info`, + )} + +
+
+
+ ), + )} +
+
+ )} + {isExpertConfigurationSelected && ( + + + + + {expertConfigItems.map(({ name, label }) => ( + + + + + {label} + + + + + ))} + + )} + + ) : ( + <> + + {t('zimbra_domains_add_domain_configuration_cname_title')} + + + {t('zimbra_domains_add_domain_configuration_cname_description')} + + + + {t('zimbra_domains_add_domain_configuration_info')} + + + + {t('zimbra_domains_add_domain_configuration_part_1')} + {t('zimbra_domains_add_domain_configuration_part_2')} + + + + + + + {t('zimbra_domains_add_domain_cta_access_domains')} + + + )} + {!cnameToCheck && ( + + + {isSending && ( + + )} + {t('zimbra_domains_add_domain_cta_confirm')} + + + )} +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.tsx deleted file mode 100644 index 5d46c17097de..000000000000 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { - LinkType, - Links, - Subtitle, - useNotifications, -} from '@ovh-ux/manager-react-components'; -import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; -import { - OsdsFormField, - OsdsSelect, - OsdsSelectOption, - OsdsSpinner, - OsdsText, - OsdsButton, -} from '@ovhcloud/ods-components/react'; -import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; -import { - ODS_SPINNER_MODE, - ODS_SPINNER_SIZE, - ODS_TEXT_LEVEL, - ODS_TEXT_SIZE, -} from '@ovhcloud/ods-components'; -import { useMutation, useQuery } from '@tanstack/react-query'; - -import { ApiError } from '@ovh-ux/manager-core-api'; -import { - useOrganization, - useOrganizationList, - usePlatform, - useGenerateUrl, -} from '@/hooks'; -import { - DomainBodyParamsType, - getDomainsZoneList, - getDomainsZoneListQueryKey, - getZimbraPlatformDomainsQueryKey, - postZimbraDomain, -} from '@/api/domain'; -import queryClient from '@/queryClient'; - -export default function AddDomain() { - const { t } = useTranslation('domains/addDomain'); - const { platformId } = usePlatform(); - - const { data, isLoading } = useOrganizationList(); - const { addError, addSuccess } = useNotifications(); - const navigate = useNavigate(); - - const { data: organization } = useOrganization(); - const [selectedOrganization, setSelectedOrganization] = useState( - organization?.id || '', - ); - const goBackUrl = useGenerateUrl('..', 'path'); - const onClose = () => navigate(goBackUrl); - - const { data: domains, isLoading: isLoadingDomain } = useQuery({ - queryKey: getDomainsZoneListQueryKey, - queryFn: () => getDomainsZoneList(), - }); - - const [selectedDomainName, setSelectedDomainName] = useState(''); - - const { mutate: addDomain, isPending: isSending } = useMutation({ - mutationFn: (params: DomainBodyParamsType) => { - return postZimbraDomain(platformId, params); - }, - onSuccess: () => { - addSuccess( - - {t('zimbra_domains_add_domain_success_message')} - , - true, - ); - }, - onError: (error: ApiError) => { - addError( - - {t('zimbra_domains_add_domain_error_message', { - error: error?.response?.data?.message, - })} - , - true, - ); - }, - onSettled: () => { - queryClient.invalidateQueries({ - queryKey: getZimbraPlatformDomainsQueryKey(platformId), - }); - - onClose(); - }, - }); - - const handleAddDomainClick = () => { - const formData = { - organizationId: selectedOrganization, - name: selectedDomainName, - autoConfigureMX: true, - }; - addDomain(formData); - }; - - useEffect(() => { - if (organization && !isLoading) { - setSelectedOrganization(organization?.id); - } - }, [organization, isLoading]); - - const backLinkUrl = useGenerateUrl('..', 'href'); - - return ( -
- - - {t('zimbra_domains_add_domain_title_select')} - - -
- - {t('zimbra_domains_add_domain_organization')} - -
- - setSelectedOrganization(e.detail.value as string) - } - className="mt-2 w-1/2" - data-testid="select-organization" - > - - {t('zimbra_domains_add_domain_organization_select')} - - {data?.map((item) => ( - - {item.currentState?.name} - - ))} - - {isLoading && ( -
- -
- )} -
- - {selectedOrganization && !isLoadingDomain && ( - -
- - {t('zimbra_domains_add_domain_title')} - -
- - setSelectedDomainName(e.detail.value as string) - } - {...(isLoadingDomain ? { disabled: true } : {})} - > - - - {t('zimbra_domains_add_domain_select')} - - - {domains?.map((domain: string) => ( - - {domain} - - ))} - - {isLoadingDomain && ( -
- -
- )} -
- )} - - - - - {isSending && ( - - )} - - {t('zimbra_domains_add_domain_cta_confirm')} - - -
- ); -} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx index 029b4e549cc3..e27657df3818 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx @@ -26,7 +26,6 @@ import { Notifications, } from '@ovh-ux/manager-react-components'; import { Outlet } from 'react-router-dom'; - import { useOverridePage, useDomains, @@ -34,12 +33,19 @@ import { usePlatform, useOrganizationList, } from '@/hooks'; -import ActionButtonDomain from './ActionButtonDomain'; +import ActionButtonDomain from './ActionButtonDomain.component'; import LabelChip from '@/components/LabelChip'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; -import { DATAGRID_REFRESH_INTERVAL, DATAGRID_REFRESH_ON_MOUNT } from '@/utils'; +import { + DATAGRID_REFRESH_INTERVAL, + DATAGRID_REFRESH_ON_MOUNT, + DnsRecordType, + FEATURE_FLAGS, +} from '@/utils'; import Loading from '@/components/Loading/Loading'; -import { ResourceStatus } from '@/api/api.type'; +import { DiagnosticBadge } from '@/components/DiagnosticBadge'; +import { DomainType } from '@/api/domain/type'; +import { AccountStatistics, ResourceStatus } from '@/api/api.type'; export type DomainsItem = { id: string; @@ -66,26 +72,54 @@ const columns: DatagridColumn[] = [ }, { id: 'organization', - cell: (item) => - item.organizationLabel && ( - {item.organizationLabel} - ), + cell: (item) => ( + {item.organizationLabel} + ), label: 'zimbra_domains_datagrid_organization_label', }, { id: 'account', - cell: (item) => - item.account && ( - - {item.account} - - ), + cell: (item) => ( + + {item.account} + + ), label: 'zimbra_domains_datagrid_account_number', }, + { + id: 'diagnostic', + cell: (item) => { + return ( + <> + + + + + + ); + }, + label: 'zimbra_domains_datagrid_diagnostic_label', + }, { id: 'tooltip', cell: (item: DomainsItem) => , @@ -117,13 +151,14 @@ export default function Domains() { const hrefAddDomain = useGenerateUrl('./add', 'href'); const items: DomainsItem[] = - data?.map((item) => ({ + data?.map((item: DomainType) => ({ name: item.currentState.name, id: item.id, organizationId: item.currentState.organizationId, organizationLabel: item.currentState.organizationLabel, account: item.currentState.accountsStatistics.reduce( - (acc, current) => acc + current.configuredAccountsCount, + (acc: number, current: AccountStatistics) => + acc + current.configuredAccountsCount, 0, ), status: item.resourceStatus, @@ -193,10 +228,18 @@ export default function Domains() { ) : ( <> ({ - ...column, - label: t(column.label), - }))} + columns={columns + .filter( + (c) => + !( + !FEATURE_FLAGS.DOMAIN_DIAGNOSTICS && + c.id === 'diagnostic' + ), + ) + .map((column) => ({ + ...column, + label: t(column.label), + }))} items={items} totalItems={items.length} hasNextPage={!isFetchingNextPage && hasNextPage} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx similarity index 92% rename from packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx index e6c8dba1a2f8..22f055e55abd 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { useSearchParams, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { @@ -28,21 +28,15 @@ export default function ModalDeleteDomain() { const deleteDomainId = searchParams.get('deleteDomainId'); const { platformId } = usePlatform(); - const { data, isLoading } = useAccountList({ + const { data: accounts, isLoading } = useAccountList({ domainId: deleteDomainId, }); const { addError, addSuccess } = useNotifications(); - const [hasEmailAccount, setHasEmailAccount] = useState(false); - const goBackUrl = useGenerateUrl('..', 'path'); const onClose = () => navigate(goBackUrl); - useEffect(() => { - setHasEmailAccount(data?.length > 0); - }, [isLoading]); - const { mutate: deleteDomain, isPending: isSending } = useMutation({ mutationFn: (domainId: string) => { return deleteZimbraPlatformDomain(platformId, domainId); @@ -85,7 +79,7 @@ export default function ModalDeleteDomain() { }); const handleDeleteClick = () => { - deleteDomain(deleteDomainId); + deleteDomain(deleteDomainId as string); }; return ( @@ -98,7 +92,7 @@ export default function ModalDeleteDomain() { primaryButton={{ label: t('zimbra_domain_delete'), action: handleDeleteClick, - disabled: hasEmailAccount || isSending, + disabled: accounts?.length > 0 || isSending || !deleteDomainId, testid: 'delete-btn', }} > @@ -111,7 +105,7 @@ export default function ModalDeleteDomain() { > {t('zimbra_domain_delete_modal_content')}
- {hasEmailAccount && ( + {accounts?.length > 0 && ( { + switch (dnsRecordTypeKey) { + case DnsRecordTypeKey.MX: + return isOvhDomain + ? [ + 'zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part1', + 'zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part2', + 'zimbra_domain_modal_diagnostic_mx_content_header_ovh_hosted_domain_part3', + ] + : [ + 'zimbra_domain_modal_diagnostic_mx_content_header_part1', + 'zimbra_domain_modal_diagnostic_mx_content_header_part2', + 'zimbra_domain_modal_diagnostic_mx_content_header_part3', + ]; + case DnsRecordTypeKey.SRV: + return isOvhDomain + ? [ + 'zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part1', + 'zimbra_domain_modal_diagnostic_srv_content_header_ovh_hosted_domain_part2', + ] + : ['zimbra_domain_modal_diagnostic_srv_content_header']; + + case DnsRecordTypeKey.SPF: + return isOvhDomain + ? [ + 'zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part1', + 'zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part2', + 'zimbra_domain_modal_diagnostic_spf_content_header_ovh_hosted_domain_part3', + ] + : ['zimbra_domain_modal_diagnostic_spf_content_header']; + default: + return []; + } +}; + +export default function ModalDiagnosticDnsRecord( + props: Readonly, +) { + const { t } = useTranslation('domains/diagnostic'); + const navigate = useNavigate(); + const goBackUrl = useGenerateUrl('..', 'path'); + const onClose = () => navigate(goBackUrl); + + const [searchParams] = useSearchParams(); + const domainId = searchParams.get('domainId') || props.domainId; + + // fetch these informations + // check CRB-387 for this + const isOvhDomain = + searchParams.get('isOvhDomain') === 'true' || props.isOvhDomain; + const dnsRecordType = + searchParams.get('dnsRecordType') || props.dnsRecordType; + const dnsRecordTypeKey = getDnsRecordTypeKeyFromDnsRecordType( + dnsRecordType as DnsRecordType, + ); + + const [domain, setDomain] = useState(); + const { data, isLoading } = useDomain(domainId); + + useEffect(() => { + setDomain(data); + }, [isLoading]); + + // this should be in data.currentState.expectedDNSConfig.srv + const srvFields = { + subdomain: '_autodiscover._tcp', + priority: '0', + weight: '0', + port: '443', + target: 'ex5.mail.ovh.net.', + }; + + // this should be in data.currentState.expectedDNSConfig.mx + const mxFields = [ + { priority: 1, target: 'mx0.mail.ovh.net' }, + { priority: 5, target: 'mx1.mail.ovh.net' }, + { priority: 10, target: 'mx2.mail.ovh.net' }, + { priority: 100, target: 'mx3.mail.ovh.net' }, + ]; + + // this should be in data.currentState.expectedDNSConfig.spf + const spfFields = { + subdomain: '_autodiscover._tcp', + target: '"v=spf1 include:mx.ovh.com ~all"', + }; + + const handleValidationClick = () => { + // send the request to fix the record + onClose(); + }; + + if (dnsRecordTypeKey === DnsRecordTypeKey.NONE) { + onClose(); + } + + const getPrimaryButtonProps = () => { + const buttonProps = { + label: t( + `zimbra_domain_modal_diagnostic_${dnsRecordTypeKey}_action_validate`, + ), + action: handleValidationClick, + testid: `diagnostic-${dnsRecordTypeKey}-modal-primary-btn`, + }; + + if (isOvhDomain) { + return buttonProps; + } + + if (dnsRecordType === DnsRecordType.MX) { + return { + ...buttonProps, + label: t(`zimbra_domain_modal_diagnostic_mx_action_test`), + }; + } + + return null; + }; + + return ( + + {domain && ( +
+ {getContentHeaderKeys(dnsRecordTypeKey, isOvhDomain).map((key) => ( + + + ), + }} + /> + + ))} + {dnsRecordType === DnsRecordType.SRV && ( +
+ + + {t( + `zimbra_domain_modal_diagnostic_${dnsRecordTypeKey}_domain`, + )} + + + + {domain?.currentState?.name} + +
+ )} + {!isOvhDomain && ( +
+ + + {t(`zimbra_domain_modal_diagnostic_fields`)} {dnsRecordType} + + +
+ {mxFields && dnsRecordType === DnsRecordType.MX && ( +
+ {mxFields.map(({ priority, target }) => ( + + {t(`zimbra_domain_modal_diagnostic_field_priority`)} + {priority} + {' ; '} + {t(`zimbra_domain_modal_diagnostic_field_target`)} + {target} + + ))} +
+ )} + {(dnsRecordType === DnsRecordType.SRV || + dnsRecordType === DnsRecordType.SPF) && ( +
+ {Object.entries( + dnsRecordType === DnsRecordType.SRV + ? srvFields + : spfFields, + ).map(([key, value]) => ( + + {t(`zimbra_domain_modal_diagnostic_field_${key}`)} + {value} + + ))} +
+ )} +
+
+ )} + {!isOvhDomain && dnsRecordType === DnsRecordType.MX ? ( + + + + ) : null} +
+ )} +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalEditDomain.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalEditDomain.component.tsx new file mode 100644 index 000000000000..9b99a2bc7611 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalEditDomain.component.tsx @@ -0,0 +1,173 @@ +import React, { useEffect, useState } from 'react'; +import { useSearchParams, useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_SIZE, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_COLOR_HUE, +} from '@ovhcloud/ods-common-theming'; +import { ODS_INPUT_TYPE } from '@ovhcloud/ods-components'; +import { + OsdsFormField, + OsdsInput, + OsdsSelect, + OsdsSelectOption, + OsdsText, +} from '@ovhcloud/ods-components/react'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useMutation } from '@tanstack/react-query'; +import { + useDomain, + useGenerateUrl, + useOrganizationList, + usePlatform, +} from '@/hooks'; +import { + getZimbraPlatformDomainsQueryKey, + putZimbraDomain, +} from '@/api/domain'; +import Modal from '@/components/Modals/Modal'; +import queryClient from '@/queryClient'; + +export default function ModalEditDomain() { + const { t } = useTranslation('domains/edit'); + const navigate = useNavigate(); + + const [searchParams] = useSearchParams(); + const editDomainId = searchParams.get('editDomainId'); + const [selectedOrganization, setSelectedOrganization] = useState(''); + + const { platformId } = usePlatform(); + + const { data: detailDomain, isLoading: isLoadingDomain } = useDomain( + editDomainId, + ); + const { + data: organizationsList, + isLoading: isLoadingOrganizations, + } = useOrganizationList(); + + const { addError, addSuccess } = useNotifications(); + + const goBackUrl = useGenerateUrl('..', 'path'); + const onClose = () => navigate(goBackUrl); + + const { mutate: handleEditDomain, isPending: isSending } = useMutation({ + mutationFn: () => + putZimbraDomain(platformId, detailDomain.id, { + organizationId: selectedOrganization, + }), + onSuccess: () => { + addSuccess( + + {t('zimbra_domain_edit_success_message')} + , + true, + ); + }, + onError: (error: ApiError) => { + addError( + + {t('zimbra_domain_edit_error_message', { + error: error?.response?.data?.message, + })} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformDomainsQueryKey(platformId), + }); + + onClose(); + }, + }); + + useEffect(() => { + if (detailDomain && organizationsList) { + setSelectedOrganization(detailDomain.currentState.organizationId); + } + }, [detailDomain, organizationsList]); + + return ( + + <> + +
+ + {t('zimbra_domain_edit_domain_label')} + +
+ +
+ +
+ + {t('zimbra_domain_edit_organization_label')} + +
+ + setSelectedOrganization(e.detail.value as string) + } + data-testid="select-organization" + > + {organizationsList?.map((organization) => ( + + {organization.currentState.label} + + ))} + +
+ +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ActionButtonDomain.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ActionButtonDomain.spec.tsx index 554c12ce6b16..9555a94ad12e 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ActionButtonDomain.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ActionButtonDomain.spec.tsx @@ -1,29 +1,23 @@ import React from 'react'; -import { vi, describe, expect } from 'vitest'; -import ActionButtonDomain from '../ActionButtonDomain'; +import { describe, expect } from 'vitest'; +import ActionButtonDomain from '../ActionButtonDomain.component'; import { render } from '@/utils/test.provider'; import domainTranslation from '@/public/translations/domains/Messages_fr_FR.json'; -import { domainMock, platformMock } from '@/api/_mock_'; - -vi.mock('@/hooks', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - usePlatform: vi.fn(() => ({ - platformUrn: platformMock[0].iam.urn, - })), - }; -}); +import { domainDetailMock } from '@/api/_mock_'; describe('Domains datagrid action menu', () => { it('we have good number of item with good content', () => { const { container } = render( - , + , ); - expect(container.querySelectorAll('osds-menu-item').length).toBe(1); + expect(container.querySelectorAll('osds-menu-item').length).toBe(2); expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + domainTranslation.zimbra_domains_tooltip_configure, + ); + + expect(container.querySelectorAll('osds-menu-item')[1]).toHaveTextContent( domainTranslation.zimbra_domains_tooltip_delete, ); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/AddDomains.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/AddDomains.spec.tsx index 5ef2b2e7d09f..6a3b71a9b68d 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/AddDomains.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/AddDomains.spec.tsx @@ -1,36 +1,198 @@ import React from 'react'; -import { vi, describe, expect } from 'vitest'; -import AddDomain from '../AddDomain'; -import { render } from '@/utils/test.provider'; +import { describe, expect, it } from 'vitest'; +import { act } from 'react-dom/test-utils'; +import { render, fireEvent, screen, waitFor } from '@/utils/test.provider'; +import AddDomain from '../AddDomain.page'; import addDomainTranslation from '@/public/translations/domains/addDomain/Messages_fr_FR.json'; -import { platformMock, organizationListMock } from '@/api/_mock_'; -import 'element-internals-polyfill'; -import '@testing-library/jest-dom'; - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useOrganization: vi.fn(() => ({ - data: null, - isLoading: false, - })), - useOrganizationList: vi.fn(() => ({ - data: organizationListMock, - isLoading: false, - })), - useOverridePage: vi.fn(() => true), - useGenerateUrl: vi.fn(() => null), + +describe('Add Domain page', () => { + const clickSelectOrganization = async (selectOrganization) => { + await act(async () => { + fireEvent.change(selectOrganization, { + target: { value: '1903b491-4d10-4000-8b70-f474d1abe601' }, + }); + selectOrganization.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { value: '1903b491-4d10-4000-8b70-f474d1abe601' }, + }), + ); + }); + }; + + const clickRadioDomainOvh = async (radioGroup) => { + await act(async () => { + radioGroup.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { newValue: 'ovhDomain' }, + }), + ); + }); + }; + + const clickRadioDomainExternal = async (radioGroup) => { + await act(async () => { + radioGroup.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { newValue: 'externalDomain' }, + }), + ); + }); + }; + + const clickRadioConfigType = async (radioGroup, type) => { + await act(async () => { + radioGroup.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { newValue: type }, + }), + ); + }); + }; + + const clickIsselectedDomainOvh = async (selectDomain) => { + await act(async () => { + fireEvent.change(selectDomain, { target: { value: 'test.fr' } }); + selectDomain.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { value: 'test.fr' }, + }), + ); + }); + }; + + const clickIsselectedDomainExternal = async (input) => { + await act(async () => { + fireEvent.change(input, { target: { value: 'external-example.com' } }); + input.dispatchEvent( + new CustomEvent('odsValueChange', { + detail: { value: 'external-example.com' }, + }), + ); + }); }; -}); -describe('Add Domains page', () => { - const { getByTestId } = render(); it('Page should display correctly', () => { - const page = getByTestId('add-domain-page'); + render(); + + const page = screen.getByTestId('add-domain-page'); expect(page).toHaveTextContent( addDomainTranslation.zimbra_domains_add_domain_title_select, ); }); + + it('Button should be disabled if organization is selected but no domain name is provided', async () => { + const { getByTestId } = render(); + + const selectOrganization = getByTestId('select-organization'); + await clickSelectOrganization(selectOrganization); + + // No domain is selected or input is provided + const submitButton = getByTestId('add-domain-submit-btn'); + expect(submitButton).toBeDisabled(); + }); + + // TODO: Remove skip when FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION && FEATURE_FLAGS.DOMAIN_NOT_OVH are removed + it.skip('Button should not be enabled when only organization and domain name are provided if domain is ovh', async () => { + const { getByTestId } = render(); + + const selectOrganization = getByTestId('select-organization'); + await clickSelectOrganization(selectOrganization); + + const radioGroup = getByTestId('radio-group'); + await waitFor(() => { + expect(radioGroup).toBeDefined(); + }); + + await clickRadioDomainOvh(radioGroup); + + const selectedDomain = getByTestId('select-domain'); + await clickIsselectedDomainOvh(selectedDomain); + + await waitFor(() => { + expect(selectedDomain).toBeDefined(); + expect(getByTestId('add-domain-submit-btn')).toBeDisabled(); + }); + }); + + // TODO: Remove skip when FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION && FEATURE_FLAGS.DOMAIN_NOT_OVH are removed + it.skip('Button should be enabled when organization, domain name and configuration type standard are provided if domain name is ovh', async () => { + const { getByTestId } = render(); + + const selectOrganization = getByTestId('select-organization'); + await clickSelectOrganization(selectOrganization); + + const radioGroup = getByTestId('radio-group'); + await waitFor(() => { + expect(radioGroup).toBeDefined(); + }); + + await clickRadioDomainOvh(radioGroup); + + const selectedDomain = getByTestId('select-domain'); + await clickIsselectedDomainOvh(selectedDomain); + + const selectedRadioConfigType = getByTestId('radio-group-config'); + await clickRadioConfigType( + selectedRadioConfigType, + 'standardConfiguration', + ); + + await waitFor(() => { + expect(selectedDomain).toBeDefined(); + expect(getByTestId('add-domain-submit-btn')).toBeEnabled(); + }); + }); + + // TODO: Remove skip when FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION && FEATURE_FLAGS.DOMAIN_NOT_OVH are removed + it.skip('Button should be enabled when organization, domain name and configuration type expert are provided if domain name is ovh', async () => { + const { getByTestId } = render(); + + const selectOrganization = getByTestId('select-organization'); + await clickSelectOrganization(selectOrganization); + + const radioGroup = getByTestId('radio-group'); + await waitFor(() => { + expect(radioGroup).toBeDefined(); + }); + + await clickRadioDomainOvh(radioGroup); + + const selectedDomain = getByTestId('select-domain'); + await clickIsselectedDomainOvh(selectedDomain); + + const selectedRadioConfigType = getByTestId('radio-group-config'); + await clickRadioConfigType(selectedRadioConfigType, 'expertConfiguration'); + + await waitFor(() => { + expect(selectedDomain).toBeDefined(); + expect(getByTestId('add-domain-submit-btn')).toBeEnabled(); + }); + }); + + // TODO: Remove skip when FEATURE_FLAGS.DOMAIN_DNS_CONFIGURATION && FEATURE_FLAGS.DOMAIN_NOT_OVH are removed + it.skip('Button should be enabled when an external domain name is provided', async () => { + const { getByTestId } = render(); + + const selectOrganization = getByTestId('select-organization'); + await clickSelectOrganization(selectOrganization); + + const radioGroup = getByTestId('radio-group'); + await waitFor(() => { + expect(radioGroup).toBeDefined(); + }); + + await clickRadioDomainExternal(radioGroup); + + const externalDomainInput = getByTestId('input-external-domain'); + await clickIsselectedDomainExternal(externalDomainInput); + expect(externalDomainInput).toHaveValue('external-example.com'); + + const warningMessage = screen.getByText( + addDomainTranslation.zimbra_domains_add_domain_warning_modification_domain, + ); + expect(warningMessage).toBeVisible(); + + const submitButton = getByTestId('add-domain-submit-btn'); + expect(submitButton).toBeEnabled(); + }); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/Domains.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/Domains.spec.tsx index 987836bc0eeb..82d33670cf90 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/Domains.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/Domains.spec.tsx @@ -1,51 +1,23 @@ import React from 'react'; import { vi, describe, expect } from 'vitest'; import Domains from '../Domains'; -import { render } from '@/utils/test.provider'; +import { render, waitFor } from '@/utils/test.provider'; import domainTranslation from '@/public/translations/domains/Messages_fr_FR.json'; -import { domainMock, platformMock, organizationListMock } from '@/api/_mock_'; +import { useGenerateUrl } from '@/hooks'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - platformUrn: platformMock[0].iam.urn, - })), - useDomains: vi.fn(() => ({ - data: domainMock, - })), - useOrganizationList: vi.fn(() => ({ - data: organizationListMock, - isLoading: false, - })), - useGenerateUrl: vi.fn( - () => '#/00000000-0000-0000-0000-000000000001/domains/add?', - ), - useOverridePage: vi.fn(() => false), - }; -}); - -vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - Notifications: vi.fn().mockReturnValue(
Notifications
), - Datagrid: vi.fn().mockReturnValue(
Datagrid
), - }; -}); - -afterEach(() => { - vi.clearAllMocks(); -}); +const addUrl = '#/00000000-0000-0000-0000-000000000001/domains/add?'; describe('Domains page', () => { - it('Page should display correctly', () => { + it('Page should display correctly', async () => { + vi.mocked(useGenerateUrl).mockReturnValue(addUrl); const { getByTestId } = render(); + + await waitFor(() => { + expect(getByTestId('add-domain-btn')).toBeInTheDocument(); + }); + const button = getByTestId('add-domain-btn'); - expect(button).toHaveAttribute( - 'href', - '#/00000000-0000-0000-0000-000000000001/domains/add?', - ); + expect(button).toHaveAttribute('href', addUrl); expect(button).toHaveTextContent( domainTranslation.zimbra_domains_add_domain_title, ); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalDeleteDomain.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalDeleteDomain.spec.tsx index 7a20ad60e973..c89f58661cd2 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalDeleteDomain.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalDeleteDomain.spec.tsx @@ -2,50 +2,20 @@ import React from 'react'; import 'element-internals-polyfill'; import '@testing-library/jest-dom'; import { vi, describe, expect } from 'vitest'; -import { render } from '@/utils/test.provider'; -import { platformMock, accountMock } from '@/api/_mock_'; -import ModalDeleteDomain from '../ModalDeleteDomain'; +import { useSearchParams } from 'react-router-dom'; +import { render, waitFor, act, fireEvent } from '@/utils/test.provider'; +import ModalDeleteDomain from '../ModalDeleteDomain.component'; import domainsDeleteTranslation from '@/public/translations/domains/delete/Messages_fr_FR.json'; +import { getZimbraPlatformAccounts } from '@/api/account'; +import { deleteZimbraPlatformDomain } from '@/api/domain'; +import { domainDetailMock } from '@/api/_mock_'; -const { useAccountListMock } = vi.hoisted(() => ({ - useAccountListMock: vi.fn(() => ({ - data: accountMock, - isLoading: false, - })), -})); - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useGenerateUrl: vi.fn(), - useAccountList: useAccountListMock, - }; -}); - -vi.mock('react-router-dom', () => ({ - useNavigate: vi.fn(), - MemoryRouter: vi.fn(() => ), - useSearchParams: vi.fn(() => [ - new URLSearchParams({ - deleteDomainId: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - }), - ]), -})); - -vi.mock('@ovh-ux/manager-react-components', () => { - return { - useNotifications: vi.fn(() => ({ - addError: () => vi.fn(), - addSuccess: () => vi.fn(), - })), - }; -}); - -afterEach(() => { - vi.restoreAllMocks(); -}); +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + deleteDomainId: domainDetailMock.id, + }), + vi.fn(), +]); describe('Domains delete modal', () => { it('check if it is displayed', () => { @@ -57,21 +27,34 @@ describe('Domains delete modal', () => { ); }); - it('if have email use the domain', () => { - const { getByTestId } = render(); + it('if have email use the domain', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + expect(getByTestId('banner-message')).toBeVisible(); expect(getByTestId('delete-btn')).toBeDisabled(); }); - it('if there is not email use the domain', () => { - useAccountListMock.mockImplementation( - vi.fn(() => ({ - data: [], - isLoading: false, - })), - ); + it('if there is not email use the domain', async () => { + vi.mocked(getZimbraPlatformAccounts).mockReturnValue({ data: [] }); const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const btn = getByTestId('delete-btn'); + expect(queryByTestId('banner-message')).toBeNull(); - expect(getByTestId('delete-btn')).not.toBeDisabled(); + expect(btn).toBeEnabled(); + + await act(() => { + fireEvent.click(btn); + }); + + expect(deleteZimbraPlatformDomain).toHaveBeenCalledOnce(); }); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalEditDomain.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalEditDomain.spec.tsx new file mode 100644 index 000000000000..a85a067ca4c3 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalEditDomain.spec.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import 'element-internals-polyfill'; +import '@testing-library/jest-dom'; +import { vi, describe, expect } from 'vitest'; +import { useSearchParams } from 'react-router-dom'; +import { fireEvent, render, waitFor, act } from '@/utils/test.provider'; +import { domainDetailMock } from '@/api/_mock_'; +import ModalEditDomain from '../ModalEditDomain.component'; +import domainsEditTranslation from '@/public/translations/domains/edit/Messages_fr_FR.json'; +import { putZimbraDomain } from '@/api/domain'; + +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editDomainId: domainDetailMock.id, + }), + vi.fn(), +]); + +describe('Domains edit modal', () => { + it('check if it is displayed', () => { + const { getByTestId } = render(); + const modal = getByTestId('modal'); + expect(modal).toHaveProperty( + 'headline', + domainsEditTranslation.zimbra_domain_edit_modal_title, + ); + }); + + it('check if disabled input have the domain name', async () => { + const { getByTestId } = render(); + + await waitFor(() => { + expect(getByTestId('input-domain')).toBeInTheDocument(); + }); + + expect(getByTestId('input-domain')).toHaveProperty( + 'value', + domainDetailMock.currentState.name, + ); + }); + + it('check the status of confirm cta', async () => { + const { getByTestId } = render(); + const confirmCta = getByTestId('edit-btn'); + const selectOrganization = getByTestId('select-organization'); + expect(confirmCta).toBeDisabled(); + + await act(() => { + fireEvent.change(selectOrganization, { + target: { value: '1903b491-4d10-4000-8b70-f474d1abe601' }, + }); + + // it seems we have to manually trigger the ods event + selectOrganization.odsValueChange.emit({ + value: '1903b491-4d10-4000-8b70-f474d1abe601', + }); + }); + + expect(confirmCta).toBeEnabled(); + + await act(() => { + fireEvent.click(confirmCta); + }); + + expect(putZimbraDomain).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalsDiagnosticDNSRecord.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalsDiagnosticDNSRecord.spec.tsx new file mode 100644 index 000000000000..20983bcbd6b8 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/__test__/ModalsDiagnosticDNSRecord.spec.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import 'element-internals-polyfill'; +import '@testing-library/jest-dom'; +import { vi, describe, expect } from 'vitest'; +import { useSearchParams } from 'react-router-dom'; +import { render } from '@/utils/test.provider'; +import { DnsRecordType } from '@/utils'; +import { domainDetailMock } from '@/api/_mock_'; +import ModalDiagnosticDnsRecord from '../ModalDiagnosticDnsRecord.component'; +import domainDiagnosticTranslation from '@/public/translations/domains/diagnostic/Messages_fr_FR.json'; + +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + domainId: domainDetailMock.id, + }), + vi.fn(), +]); + +describe('Domain diagnostic modalc ', () => { + it('should display diagnostic modal', () => { + const { getByTestId } = render( + , + ); + const modal = getByTestId('modal'); + expect(modal).toHaveProperty( + 'headline', + domainDiagnosticTranslation.zimbra_domain_modal_diagnostic_srv_title, + ); + expect( + getByTestId('diagnostic-srv-modal-secondary-btn'), + ).toBeInTheDocument(); + }); +}); + +describe('Domain diagnostic modal MX', () => { + it('should display diagnostic modal', () => { + const { getByTestId } = render( + , + ); + const modal = getByTestId('modal'); + expect(modal).toHaveProperty( + 'headline', + domainDiagnosticTranslation.zimbra_domain_modal_diagnostic_mx_title, + ); + expect( + getByTestId('diagnostic-mx-modal-secondary-btn'), + ).toBeInTheDocument(); + }); +}); + +describe('Domain diagnostic modal SPF', () => { + it('should display diagnostic modal', () => { + const { getByTestId } = render( + , + ); + const modal = getByTestId('modal'); + expect(modal).toHaveProperty( + 'headline', + domainDiagnosticTranslation.zimbra_domain_modal_diagnostic_spf_title, + ); + expect( + getByTestId('diagnostic-spf-modal-secondary-btn'), + ).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AccountTabsPanel.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AccountTabsPanel.component.tsx new file mode 100644 index 000000000000..b16e8d036848 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AccountTabsPanel.component.tsx @@ -0,0 +1,62 @@ +import React, { useState, useEffect } from 'react'; +import { NavLink, useLocation, useNavigate } from 'react-router-dom'; +import { + OsdsTabs, + OsdsTabBar, + OsdsTabBarItem, +} from '@ovhcloud/ods-components/react'; + +export type TabItemProps = { + name: string; + title: string; + pathMatchers?: RegExp[]; + to: string; + hidden?: boolean; +}; + +export type TabsProps = { + tabs: TabItemProps[]; +}; + +export const AccountTabsPanel: React.FC = ({ tabs }) => { + const [activePanel, setActivePanel] = useState(''); + const location = useLocation(); + const navigate = useNavigate(); + + useEffect(() => { + if (!location.pathname) { + setActivePanel(tabs[0].name); + navigate(tabs[0].to); + } else { + const activeTab = tabs.find( + (tab) => + tab.to === location.pathname || + tab.pathMatchers?.some((pathMatcher) => + pathMatcher.test(location.pathname), + ), + ); + if (activeTab) { + setActivePanel(activeTab.name); + } + } + }, [location.pathname]); + + return ( + + + {tabs.map( + (tab: TabItemProps) => + !tab.hidden && ( + + {tab.title} + + ), + )} + + + ); +}; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonAlias.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonAlias.component.tsx new file mode 100644 index 000000000000..c1f7d2b4b802 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonAlias.component.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ActionMenu } from '@ovh-ux/manager-react-components'; +import { useSearchParams } from 'react-router-dom'; +import { AliasItem } from './EmailAccountsAlias.page'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { ResourceStatus } from '@/api/api.type'; + +interface ActionButtonAliasAccountProps { + aliasItem: AliasItem; +} + +const ActionButtonAlias: React.FC = ({ + aliasItem, +}) => { + const { t } = useTranslation('accounts/alias'); + const { platformUrn } = usePlatform(); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + + const hrefDeleteAlias = useGenerateUrl('./delete', 'href', { + deleteAliasId: aliasItem.id, + editEmailAccountId, + }); + const actionItems = [ + { + id: 1, + href: hrefDeleteAlias, + urn: platformUrn, + iamActions: [IAM_ACTIONS.alias.delete], + label: t('zimbra_account_alias_datagrid_tooltip_delete'), + }, + ]; + return ( + + ); +}; + +export default ActionButtonAlias; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx similarity index 95% rename from packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx index 011de1c6f25d..e1c640661c58 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx @@ -16,7 +16,7 @@ const ActionButtonEmail: React.FC = ({ const { t } = useTranslation('accounts'); const { platformUrn } = usePlatform(); - const hrefEditEmailAccount = useGenerateUrl('./edit', 'href', { + const hrefEditEmailAccount = useGenerateUrl('./settings', 'href', { editEmailAccountId: emailsItem.id, }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx new file mode 100644 index 000000000000..e46acebd6755 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx @@ -0,0 +1,147 @@ +import React, { useEffect, useState } from 'react'; +import { LinkType, Links, Subtitle } from '@ovh-ux/manager-react-components'; +import { useTranslation } from 'react-i18next'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; +import { useDomains, useGenerateUrl, usePlatform, useAccount } from '@/hooks'; +import Loading from '@/components/Loading/Loading'; +import { TabItemProps, AccountTabsPanel } from './AccountTabsPanel.component'; +import { urls } from '@/routes/routes.constants'; +import EmailAccountSettings from './EmailAccountSettings.page'; +import EmailAccountsAlias from './EmailAccountsAlias.page'; +import Redirections from '../Redirections/Redirections'; +import { FEATURE_FLAGS } from '@/utils'; + +export default function AddAndEditAccount() { + const { t } = useTranslation('accounts/addAndEdit'); + const location = useLocation(); + const navigate = useNavigate(); + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const [isLoading, setIsLoading] = useState(true); + const goBackUrl = useGenerateUrl('..', 'path'); + const [isSettingsTab, setIsSettingsTab] = useState(false); + const [isAliasTab, setIsAliasTab] = useState(false); + const [isRedirectionsTab, setIsRedirectionsTab] = useState(false); + + const goBack = () => { + return navigate(goBackUrl); + }; + + const { + data: editAccountDetail, + isLoading: isLoadingEmailDetailRequest, + } = useAccount({ + accountId: editEmailAccountId, + enabled: !!editEmailAccountId, + }); + + const { data: domainList, isLoading: isLoadingDomainRequest } = useDomains(); + + function activatedTabs(pathMatchers: RegExp[]) { + return pathMatchers?.some((pathMatcher) => + pathMatcher.test(location.pathname), + ); + } + function computePathMatchers(routes: string[]) { + return routes.map( + (path) => new RegExp(path.replace(':serviceName', platformId)), + ); + } + const pathMatcherSettingsTabs = computePathMatchers([ + urls.email_accounts_add, + urls.email_accounts_edit, + ]); + + const pathMatcherAliasTabs = computePathMatchers([ + urls.email_accounts_alias, + urls.email_accounts_alias_add, + urls.email_accounts_alias_delete, + ]); + + const pathMatcherRedirectionsTabs = computePathMatchers([ + urls.email_accounts_redirections, + urls.email_accounts_redirections_add, + urls.email_accounts_redirections_delete, + ]); + + useEffect(() => { + if (!isLoadingEmailDetailRequest && !isLoadingDomainRequest && platformId) { + setIsSettingsTab(activatedTabs(pathMatcherSettingsTabs)); + setIsAliasTab(activatedTabs(pathMatcherAliasTabs)); + setIsRedirectionsTab(activatedTabs(pathMatcherRedirectionsTabs)); + setIsLoading(false); + } + }, [isLoadingEmailDetailRequest, isLoadingDomainRequest, location.pathname]); + + const params = { + editEmailAccountId, + }; + + const hrefSettings = useGenerateUrl(`../settings`, 'path', params); + const hrefAlias = useGenerateUrl('../alias', 'path', params); + const hrefRedirections = useGenerateUrl('../redirections', 'path', params); + + const tabsList: TabItemProps[] = [ + { + name: 'settings', + title: t('zimbra_account_edit_tabs_settings'), + to: hrefSettings, + pathMatchers: pathMatcherSettingsTabs, + }, + { + name: 'alias', + title: t('zimbra_account_edit_tabs_alias'), + to: hrefAlias, + pathMatchers: pathMatcherAliasTabs, + hidden: !FEATURE_FLAGS.ALIAS, + }, + { + name: 'redirections', + title: t('zimbra_account_edit_tabs_redirections'), + to: hrefRedirections, + pathMatchers: pathMatcherRedirectionsTabs, + hidden: !FEATURE_FLAGS.REDIRECTIONS, + }, + ]; + + return ( + <> + {isLoading && } + {!isLoading && ( + <> +
+ + + {!editAccountDetail + ? t('zimbra_account_add_title') + : t('zimbra_account_edit_title', { + account: editAccountDetail?.currentState?.email, + })} + +
+ {editAccountDetail && ( +
+ +
+ )} + {isSettingsTab && ( + + )} + {isAliasTab && } + {isRedirectionsTab && } + + )} + + ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.tsx deleted file mode 100644 index f76bddf391bf..000000000000 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.tsx +++ /dev/null @@ -1,678 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { - LinkType, - Links, - Subtitle, - useNotifications, -} from '@ovh-ux/manager-react-components'; -import { useTranslation } from 'react-i18next'; -import { useNavigate, useSearchParams } from 'react-router-dom'; -import { - OsdsButton, - OsdsFormField, - OsdsIcon, - OsdsInput, - OsdsMessage, - OsdsPassword, - OsdsSelect, - OsdsSelectOption, - OsdsText, - OsdsTextarea, - OsdsTooltip, - OsdsTooltipContent, -} from '@ovhcloud/ods-components/react'; -import { - ODS_THEME_COLOR_HUE, - ODS_THEME_COLOR_INTENT, - ODS_THEME_TYPOGRAPHY_LEVEL, - ODS_THEME_TYPOGRAPHY_SIZE, -} from '@ovhcloud/ods-common-theming'; -import { - ODS_BUTTON_VARIANT, - ODS_ICON_NAME, - ODS_ICON_SIZE, - ODS_INPUT_SIZE, - ODS_INPUT_TYPE, - ODS_MESSAGE_TYPE, - ODS_TEXTAREA_SIZE, - ODS_TOOLTIP_VARIANT, -} from '@ovhcloud/ods-components'; -import { useMutation, useQuery } from '@tanstack/react-query'; -import { ApiError } from '@ovh-ux/manager-core-api'; -import { useGenerateUrl, usePlatform, useDomains } from '@/hooks'; -import { - AccountBodyParamsType, - getZimbraPlatformAccountDetail, - getZimbraPlatformAccountDetailQueryKey, - getZimbraPlatformAccountsQueryKey, - postZimbraPlatformAccount, - putZimbraPlatformAccount, -} from '@/api/account'; -import Loading from '@/components/Loading/Loading'; -import queryClient from '@/queryClient'; - -export default function AddAndEditAccount() { - const { t } = useTranslation('accounts/addAndEdit'); - const navigate = useNavigate(); - const { addError, addSuccess } = useNotifications(); - const { platformId } = usePlatform(); - const [searchParams] = useSearchParams(); - const editEmailAccountId = searchParams.get('editEmailAccountId'); - const [isLoading, setIsLoading] = useState(true); - const [isFormValid, setIsFormValid] = useState(false); - const [selectedDomainOrganization, setSelectedDomainOrganization] = useState( - '', - ); - const goBackUrl = useGenerateUrl('..', 'path'); - - const goBack = () => { - return navigate(goBackUrl); - }; - - type FieldType = { - value: string; - touched: boolean; - hasError?: boolean; - required?: boolean; - }; - - interface FormTypeInterface { - [key: string]: FieldType; - } - - interface FormInputRegexInterface { - [key: string]: RegExp; - } - - const formInputRegex: FormInputRegexInterface = { - account: /^(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*)(?:(?:[.|+])(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*))*$/, - password: /^(?=.*[\d!@#$€%^&*()\\[\]{}\-_+=~`|:;"'<>,./?])(?=.*[A-Z])(?=(.*)).{10,64}$/, - }; - - const [form, setForm] = useState({ - ...{ - account: { - value: '', - touched: false, - hasError: false, - required: true, - }, - domain: { - value: '', - touched: false, - required: true, - }, - lastName: { - value: '', - touched: false, - }, - firstName: { - value: '', - touched: false, - }, - displayName: { - value: '', - touched: false, - }, - password: { - value: '', - touched: false, - hasError: false, - required: !editEmailAccountId, - }, - }, - ...(editEmailAccountId && { - description: { - value: '', - touched: false, - }, - }), - }); - - const { - data: editAccountDetail, - isLoading: isLoadingEmailDetailRequest, - } = useQuery({ - queryKey: getZimbraPlatformAccountDetailQueryKey( - platformId, - editEmailAccountId, - ), - queryFn: () => - getZimbraPlatformAccountDetail(platformId, editEmailAccountId), - enabled: !!platformId && !!editEmailAccountId, - }); - - const { data: domainList, isLoading: isLoadingDomainRequest } = useDomains(); - - useEffect(() => { - if (!isLoadingEmailDetailRequest && !isLoadingDomainRequest) { - if (editAccountDetail) { - const newForm: FormTypeInterface = form; - const { - email, - lastName, - firstName, - displayName, - description, - } = editAccountDetail.currentState; - const [account, domain] = email.split('@'); - newForm.account.value = account; - newForm.domain.value = domain; - newForm.lastName.value = lastName; - newForm.firstName.value = firstName; - newForm.displayName.value = displayName; - newForm.description.value = description; - setForm((oldForm) => ({ ...oldForm, ...newForm })); - } - setIsLoading(false); - } - }, [ - isLoading, - isLoadingEmailDetailRequest, - isLoadingDomainRequest, - editAccountDetail, - domainList, - ]); - - const checkValidityField = (name: string, value: string) => { - return formInputRegex[name] - ? formInputRegex[name].test(value) || - (!form[name].required && form[name].value === '') - : true; - }; - - const checkValidityForm = () => { - const touched = Object.values(form).find((field) => field.touched); - const error = Object.values(form).find( - (field) => field.hasError || (field.required && field.value === ''), - ); - return touched && !error; - }; - - const handleFormChange = ( - name: string, - value: string, - untouched?: boolean, - ) => { - const newForm: FormTypeInterface = form; - newForm[name] = { - value, - touched: !untouched, - required: form[name].required, - hasError: !checkValidityField(name, value), - }; - - if ( - ['firstName', 'lastName'].includes(name) && - value && - !newForm.displayName.touched - ) { - newForm.displayName = { - ...newForm.displayName, - value: [newForm.lastName.value, newForm.firstName.value] - .filter((x) => x) - .join(' '), - }; - } - - setForm((oldForm) => ({ ...oldForm, ...newForm })); - setIsFormValid(checkValidityForm); - }; - - const handleDomainChange = (selectedDomain: string) => { - const organizationLabel = domainList.find( - ({ currentState }) => currentState.name === selectedDomain, - )?.currentState.organizationLabel; - handleFormChange('domain', selectedDomain); - setSelectedDomainOrganization(organizationLabel); - }; - - const { mutate: addOrEditEmailAccount, isPending: isSending } = useMutation({ - mutationFn: (params: AccountBodyParamsType) => { - return editEmailAccountId - ? putZimbraPlatformAccount(platformId, editEmailAccountId, params) - : postZimbraPlatformAccount(platformId, params); - }, - onSuccess: () => { - addSuccess( - - {t( - editEmailAccountId - ? 'zimbra_account_edit_success_message' - : 'zimbra_account_add_success_message', - )} - , - true, - ); - }, - onError: (error: ApiError) => { - addError( - - {t( - editEmailAccountId - ? 'zimbra_account_edit_error_message' - : 'zimbra_account_add_error_message', - { - error: error?.response?.data?.message, - }, - )} - , - true, - ); - }, - onSettled: () => { - queryClient.invalidateQueries({ - queryKey: getZimbraPlatformAccountsQueryKey(platformId), - }); - - goBack(); - }, - }); - - const handleSaveClick = () => { - const { - account: { value: account }, - domain: { value: domain }, - } = form; - - let dataBody = { - email: `${account}@${domain}`, - }; - - Object.entries(form).forEach(([key, { value }]) => { - if ( - ![ - 'account', - 'domain', - editEmailAccountId && form.password.value === '' ? 'password' : '', - ].includes(key) - ) { - dataBody = { ...dataBody, [key]: value }; - } - }); - - addOrEditEmailAccount(dataBody); - }; - - return ( - <> - {isLoading && } - {!isLoading && ( - <> -
- - - {!editAccountDetail - ? t('zimbra_account_add_title') - : t('zimbra_account_edit_title', { - account: editAccountDetail?.currentState?.email, - })} - -
- -
- - {t('zimbra_account_add_input_mandatory')} - - - -
- - {t('zimbra_account_add_input_email_label')} * - -
-
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={({ detail: { name, value } }) => { - handleFormChange(name, value); - }} - required - className="rounded-r-none border-r-0 w-1/2" - data-testid="input-account" - > - - - handleDomainChange(e.detail.value as string) - } - data-testid="select-domain" - > - - {t('zimbra_account_add_select_domain_placeholder')} - - {domainList?.map(({ currentState: domain }) => ( - - {domain.name} - - ))} - -
-
- - {t('zimbra_account_add_input_email_helper')} - {[1, 2, 3].map((elm) => ( - - - {t(`zimbra_account_add_input_email_helper_rule_${elm}`)} - - ))} - -
-
- {selectedDomainOrganization && ( - - - {t('zimbra_account_add_message_organization', { - organizationLabel: selectedDomainOrganization, - })} - - - )} -
- -
- - {t('zimbra_account_add_input_lastName_label')} - -
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={({ detail: { name, value } }) => { - handleFormChange(name, value); - }} - > -
- - -
- - {t('zimbra_account_add_input_firstName_label')} - -
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={({ detail: { name, value } }) => { - handleFormChange(name, value); - }} - > -
-
- -
- -
- - {t('zimbra_account_add_input_displayName_label')} - - - - - {t('zimbra_account_add_input_displayName_tooltip')} - - - - - -
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={(e) => { - const { - detail: { name, value }, - } = e; - handleFormChange( - name, - value, - e.target !== document.activeElement, - ); - }} - > -
-
- - {editAccountDetail && ( -
- -
- - {t('zimbra_account_add_input_description_label')} - -
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={({ detail: { name, value } }) => { - handleFormChange(name, value); - }} - > -
-
- )} - -
- -
- - {t('zimbra_account_add_input_password_label')} - {!editAccountDetail && ' *'} - -
- - handleFormChange(name, value.toString()) - } - onOdsValueChange={({ detail: { name, value } }) => { - handleFormChange(name, value); - }} - data-testid="input-password" - > -
- - {t('zimbra_account_add_input_password_helper')} - {[1, 2, 3].map((elm) => ( - - -{' '} - {t( - `zimbra_account_add_input_password_helper_rule_${elm}`, - )} - - ))} - -
-
-
- -
- - {!editAccountDetail - ? t('zimbra_account_add_button_confirm') - : t('zimbra_account_add_button_save')} - - - {editAccountDetail && ( - - {t('zimbra_account_add_button_cancel')} - - )} -
-
- - )} - - ); -} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx new file mode 100644 index 000000000000..e8c66551d79a --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx @@ -0,0 +1,534 @@ +import React, { useEffect, useState } from 'react'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { useTranslation } from 'react-i18next'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { + OsdsButton, + OsdsFormField, + OsdsInput, + OsdsMessage, + OsdsPassword, + OsdsSelect, + OsdsSelectOption, + OsdsText, + OsdsTextarea, +} from '@ovhcloud/ods-components/react'; +import { + ODS_THEME_COLOR_HUE, + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_VARIANT, + ODS_INPUT_SIZE, + ODS_INPUT_TYPE, + ODS_MESSAGE_TYPE, + ODS_TEXTAREA_SIZE, +} from '@ovhcloud/ods-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useMutation } from '@tanstack/react-query'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { + AccountBodyParamsType, + AccountType, + getZimbraPlatformAccountsQueryKey, + postZimbraPlatformAccount, + putZimbraPlatformAccount, +} from '@/api/account'; +import { DomainType } from '@/api/domain'; +import { formInputRegex } from './account.constants'; +import { + checkValidityField, + checkValidityForm, + FormTypeInterface, +} from '@/utils'; +import queryClient from '@/queryClient'; + +export default function EmailAccountSettings({ + domainList = [], + editAccountDetail = null, +}: Readonly<{ + domainList: DomainType[]; + editAccountDetail: AccountType; +}>) { + const { t } = useTranslation('accounts/addAndEdit'); + const navigate = useNavigate(); + const { addError, addSuccess } = useNotifications(); + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const [isFormValid, setIsFormValid] = useState(false); + const [selectedDomainOrganization, setSelectedDomainOrganization] = useState( + '', + ); + const goBackUrl = useGenerateUrl('..', 'path'); + + const goBack = () => { + return navigate(goBackUrl); + }; + + const [form, setForm] = useState({ + ...{ + account: { + value: '', + touched: false, + hasError: false, + required: true, + }, + domain: { + value: '', + touched: false, + required: true, + }, + lastName: { + value: '', + touched: false, + }, + firstName: { + value: '', + touched: false, + }, + displayName: { + value: '', + touched: false, + }, + password: { + value: '', + touched: false, + hasError: false, + required: !editEmailAccountId, + }, + }, + ...(editEmailAccountId && { + description: { + value: '', + touched: false, + }, + }), + }); + + useEffect(() => { + if (editAccountDetail) { + const newForm: FormTypeInterface = form; + const { + email, + lastName, + firstName, + displayName, + description, + } = editAccountDetail.currentState; + const [account, domain] = email.split('@'); + newForm.account.value = account; + newForm.domain.value = domain; + newForm.lastName.value = lastName; + newForm.firstName.value = firstName; + newForm.displayName.value = displayName; + newForm.description.value = description; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + } + }, []); + + const handleFormChange = (name: string, value: string) => { + const newForm: FormTypeInterface = form; + newForm[name] = { + ...form[name], + value, + touched: true, + hasError: !checkValidityField(name, value, formInputRegex, form), + }; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + setIsFormValid(checkValidityForm(form)); + }; + + const handleDomainChange = (selectedDomain: string) => { + const organizationLabel = domainList.find( + ({ currentState }) => currentState.name === selectedDomain, + )?.currentState.organizationLabel; + handleFormChange('domain', selectedDomain); + setSelectedDomainOrganization(organizationLabel); + }; + + const { mutate: addOrEditEmailAccount, isPending: isSending } = useMutation({ + mutationFn: (params: AccountBodyParamsType) => { + return editEmailAccountId + ? putZimbraPlatformAccount(platformId, editEmailAccountId, params) + : postZimbraPlatformAccount(platformId, params); + }, + onSuccess: () => { + addSuccess( + + {t( + editEmailAccountId + ? 'zimbra_account_edit_success_message' + : 'zimbra_account_add_success_message', + )} + , + true, + ); + }, + onError: (error: ApiError) => { + addError( + + {t( + editEmailAccountId + ? 'zimbra_account_edit_error_message' + : 'zimbra_account_add_error_message', + { + error: error?.response?.data?.message, + }, + )} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformAccountsQueryKey(platformId), + }); + goBack(); + }, + }); + + const handleSaveClick = () => { + const { + account: { value: account }, + domain: { value: domain }, + } = form; + let dataBody = { + email: `${account}@${domain}`, + }; + Object.entries(form).forEach(([key, { value }]) => { + if ( + ![ + 'account', + 'domain', + editEmailAccountId && form.password.value === '' ? 'password' : '', + ].includes(key) + ) { + dataBody = { ...dataBody, [key]: value }; + } + }); + + addOrEditEmailAccount(dataBody); + }; + + return ( +
+ + {t('zimbra_account_add_input_mandatory')} + + + +
+ + {t('zimbra_account_add_input_email_label')} * + +
+
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + required + className="rounded-r-none w-1/2" + data-testid="input-account" + > + + + handleDomainChange(e.detail.value as string) + } + data-testid="select-domain" + > + + {t('zimbra_account_add_select_domain_placeholder')} + + {domainList?.map(({ currentState: domain }) => ( + + {domain.name} + + ))} + +
+
+ + {t('zimbra_account_add_input_email_helper')} + {[1, 2, 3].map((elm) => ( + + - {t(`zimbra_account_add_input_email_helper_rule_${elm}`)} + + ))} + +
+
+ {selectedDomainOrganization && ( + + + {t('zimbra_account_add_message_organization', { + organizationLabel: selectedDomainOrganization, + })} + + + )} +
+ +
+ + {t('zimbra_account_add_input_lastName_label')} + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > +
+ + +
+ + {t('zimbra_account_add_input_firstName_label')} + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > +
+
+ +
+ +
+ + {t('zimbra_account_add_input_displayName_label')} + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > +
+
+ + {editAccountDetail && ( +
+ +
+ + {t('zimbra_account_add_input_description_label')} + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > +
+
+ )} + +
+ +
+ + {t('zimbra_account_add_input_password_label')} + {!editAccountDetail && ' *'} + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + data-testid="input-password" + > +
+ + {t('zimbra_account_add_input_password_helper')} + {[1, 2, 3].map((elm) => ( + + - {t(`zimbra_account_add_input_password_helper_rule_${elm}`)} + + ))} + +
+
+
+ +
+ + {!editAccountDetail + ? t('zimbra_account_add_button_confirm') + : t('zimbra_account_add_button_save')} + + + {editAccountDetail && ( + + {t('zimbra_account_add_button_cancel')} + + )} +
+
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccounts.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccounts.tsx index 227a9314b5aa..3cb652eb7029 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccounts.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccounts.tsx @@ -42,7 +42,7 @@ import { } from '@/hooks'; import LabelChip from '@/components/LabelChip'; import guidesConstants from '@/guides.constants'; -import ActionButtonEmail from './ActionButtonEmail'; +import ActionButtonEmail from './ActionButtonEmail.component'; import { convertOctets, DATAGRID_REFRESH_INTERVAL, @@ -80,24 +80,22 @@ const columns: DatagridColumn[] = [ }, { id: 'organization', - cell: (item) => - item.organizationLabel && ( - {item.organizationLabel} - ), + cell: (item) => ( + {item.organizationLabel} + ), label: 'zimbra_account_datagrid_organization_label', }, { id: 'offer', - cell: (item) => - item.offer && ( - - {item.offer} - - ), + cell: (item) => ( + + {item.offer} + + ), label: 'zimbra_account_datagrid_offer_label', }, { diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx new file mode 100644 index 000000000000..6e5f710b54a8 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx @@ -0,0 +1,134 @@ +import React from 'react'; +import { + Datagrid, + DatagridColumn, + ManagerButton, + Notifications, + Subtitle, +} from '@ovh-ux/manager-react-components'; +import { OsdsIcon, OsdsText } from '@ovhcloud/ods-components/react'; +import { + ODS_BUTTON_SIZE, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { useTranslation } from 'react-i18next'; +import { useQuery } from '@tanstack/react-query'; +import { Outlet, useSearchParams } from 'react-router-dom'; +import { + AliasType, + getZimbraPlatformAlias, + getZimbraPlatformAliasQueryKey, +} from '@/api/alias'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import ActionButtonAlias from './ActionButtonAlias.component'; +import { BadgeStatus } from '@/components/BadgeStatus'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { ResourceStatus } from '@/api/api.type'; +import Loading from '@/components/Loading/Loading'; + +export type AliasItem = { + id: string; + alias: string; + status: ResourceStatus; +}; + +export default function EmailAccountsAlias() { + const { t } = useTranslation('accounts/alias'); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const { platformId, platformUrn } = usePlatform(); + const { data, isLoading } = useQuery({ + queryKey: getZimbraPlatformAliasQueryKey(platformId), + queryFn: () => getZimbraPlatformAlias(platformId), + enabled: !!platformId, + }); + + const columns: DatagridColumn[] = [ + { + id: 'alias', + cell: (item: AliasItem) => ( + + {item.alias} + + ), + label: 'zimbra_account_alias_datagrid_alias_label', + }, + { + id: 'status', + cell: (item: AliasItem) => ( + + ), + label: 'zimbra_account_alias_datagrid_status_label', + }, + { + id: 'tooltip', + cell: (item: AliasItem) => , + label: '', + }, + ]; + + const hrefAddAlias = useGenerateUrl('./add', 'href', { editEmailAccountId }); + + const items: AliasItem[] = + data?.map((item: AliasType) => ({ + id: item.id, + alias: item.currentState.alias, + status: item.resourceStatus, + })) ?? []; + + return ( +
+ + + {platformUrn && ( + <> +
+ {t('zimbra_account_alias_title')} +
+
+ + + + + {t('zimbra_account_alias_cta')} + +
+ {isLoading ? ( + + ) : ( + ({ + ...column, + label: t(column.label), + }))} + items={items} + totalItems={items.length} + /> + )} + + )} +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx new file mode 100644 index 000000000000..f04309640671 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx @@ -0,0 +1,249 @@ +import React, { useEffect, useState } from 'react'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_SIZE, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_COLOR_HUE, +} from '@ovhcloud/ods-common-theming'; +import { + OsdsFormField, + OsdsInput, + OsdsSelect, + OsdsSelectOption, + OsdsText, +} from '@ovhcloud/ods-components/react'; +import { ODS_INPUT_SIZE, ODS_INPUT_TYPE } from '@ovhcloud/ods-components'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { useMutation } from '@tanstack/react-query'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useDomains, useGenerateUrl, usePlatform, useAccount } from '@/hooks'; +import Modal from '@/components/Modals/Modal'; +import { + getZimbraPlatformAliasQueryKey, + postZimbraPlatformAlias, +} from '@/api/alias'; +import { formInputRegex } from './account.constants'; +import { + checkValidityField, + checkValidityForm, + FormTypeInterface, +} from '@/utils'; +import queryClient from '@/queryClient'; + +export default function ModalAddAndEditOrganization() { + const { t } = useTranslation('accounts/alias/add'); + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const [isLoading, setIsLoading] = useState(true); + const { addError, addSuccess } = useNotifications(); + const navigate = useNavigate(); + const goBackUrl = useGenerateUrl('..', 'path', { editEmailAccountId }); + const goBack = () => navigate(goBackUrl); + + const [form, setForm] = useState({ + alias: { + value: '', + hasError: false, + required: true, + touched: false, + }, + domain: { + value: '', + hasError: false, + required: true, + touched: false, + }, + }); + + const [isFormValid, setIsFormValid] = useState(false); + + const { data: domainList, isLoading: isLoadingDomain } = useDomains(); + + const { + data: editAccountDetail, + isLoading: isLoadingEmailDetail, + } = useAccount({ accountId: editEmailAccountId }); + + useEffect(() => { + if (!isLoadingDomain && !isLoadingEmailDetail && platformId) { + setIsLoading(false); + } + }, [isLoadingDomain, isLoadingEmailDetail]); + + const { mutate: handleNewAliasClick, isPending: isSubmitting } = useMutation({ + mutationFn: () => { + const { + alias: { value: alias }, + domain: { value: domain }, + } = form; + + const dataBody = { + alias: `${alias}@${domain}`, + aliasTarget: editAccountDetail?.currentState.email, + organizationId: editAccountDetail?.currentState.organizationId, + }; + return postZimbraPlatformAlias(platformId, dataBody); + }, + onSuccess: () => { + addSuccess( + + {t('zimbra_account_alias_add_success_message')} + , + true, + ); + }, + onError: (error: ApiError) => { + addError( + + {t('zimbra_account_alias_add_error_message', { + error: error?.response?.data?.message, + })} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformAliasQueryKey(platformId), + }); + goBack(); + }, + }); + + const handleFormChange = (name: string, value: string) => { + const newForm: FormTypeInterface = form; + newForm[name] = { + ...form[name], + value, + touched: true, + hasError: !checkValidityField(name, value, formInputRegex, form), + }; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + setIsFormValid(checkValidityForm(form)); + }; + + return ( + + <> + + {t('zimbra_account_alias_add_description', { + account: editAccountDetail?.currentState.email, + })} + + + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + required + className="rounded-r-none border-r-0 w-1/2" + data-testid="input-alias" + > + + + handleFormChange(name, value as string) + } + data-testid="select-domain" + > + + {t('zimbra_account_alias_add_select_domain_placeholder')} + + {domainList?.map(({ currentState: domain }) => ( + + {domain.name} + + ))} + +
+
+ + {t('zimbra_account_alias_add_input_email_helper')} + {[1, 2, 3].map((elm) => ( + + -{' '} + {t(`zimbra_account_alias_add_input_email_helper_rule_${elm}`)} + + ))} + +
+
+ +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx new file mode 100644 index 000000000000..09c5b7f66fde --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import { useSearchParams, useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_SIZE, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_COLOR_HUE, +} from '@ovhcloud/ods-common-theming'; +import { OsdsText } from '@ovhcloud/ods-components/react'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { useMutation } from '@tanstack/react-query'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import Modal from '@/components/Modals/Modal'; +import { + deleteZimbraPlatformAlias, + getZimbraPlatformAliasQueryKey, +} from '@/api/alias'; +import queryClient from '@/queryClient'; + +export default function ModalDeleteDomain() { + const { t } = useTranslation('accounts/alias/delete'); + const navigate = useNavigate(); + + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const deleteAliasId = searchParams.get('deleteAliasId'); + + const { platformId } = usePlatform(); + + const { addError, addSuccess } = useNotifications(); + + const goBackUrl = useGenerateUrl('..', 'path', { editEmailAccountId }); + const goBack = () => navigate(goBackUrl); + + const { mutate: handleDeleteClick, isPending: isDeleting } = useMutation({ + mutationFn: () => deleteZimbraPlatformAlias(platformId, deleteAliasId), + onSuccess: () => { + addSuccess( + + {t('zimbra_account_alias_delete_success_message')} + , + true, + ); + }, + onError: (error: ApiError) => { + addError( + + {t('zimbra_account_alias_delete_error_message', { + error: error?.response?.data?.message, + })} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformAliasQueryKey(platformId), + }); + goBack(); + }, + }); + + return ( + + + {t('zimbra_account_alias_delete_modal_description')} + + + ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.component.tsx similarity index 100% rename from packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.component.tsx diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonAlias.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonAlias.spec.tsx new file mode 100644 index 000000000000..cd65cf3d0582 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonAlias.spec.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import ActionButtonAlias from '../ActionButtonAlias.component'; +import { render } from '@/utils/test.provider'; +import aliasTranslation from '@/public/translations/accounts/alias/Messages_fr_FR.json'; +import { aliasMock } from '@/api/_mock_'; +import { ResourceStatus } from '@/api/api.type'; + +describe('Alias datagrid action menu', () => { + it('should render correctly with enabled button', () => { + const { container } = render( + , + ); + + expect(container.querySelectorAll('osds-menu-item').length).toBe(1); + + expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + aliasTranslation.zimbra_account_alias_datagrid_tooltip_delete, + ); + + expect(container.querySelectorAll('osds-menu-item')[0]).toBeEnabled(); + }); + + it('should render correctly with disabled button', () => { + const { container } = render( + , + ); + + expect(container.querySelectorAll('osds-menu-item').length).toBe(1); + + expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + aliasTranslation.zimbra_account_alias_datagrid_tooltip_delete, + ); + + expect(container.querySelectorAll('osds-menu-item')[0]).toBeDisabled(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonEmail.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonEmail.spec.tsx index c059abe0b926..2603e46f2e70 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonEmail.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ActionButtonEmail.spec.tsx @@ -1,24 +1,14 @@ import React from 'react'; -import { vi, describe, expect } from 'vitest'; -import ActionButtonEmail from '../ActionButtonEmail'; +import { describe, expect } from 'vitest'; +import ActionButtonEmail from '../ActionButtonEmail.component'; import { render } from '@/utils/test.provider'; import accountTranslation from '@/public/translations/accounts/Messages_fr_FR.json'; -import { accountMock, platformMock } from '@/api/_mock_'; - -vi.mock('@/hooks', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - usePlatform: vi.fn(() => ({ - platformUrn: platformMock[0].iam.urn, - })), - }; -}); +import { accountsMock } from '@/api/_mock_'; describe('EmailAccounts datagrid action menu', () => { it('we have good number of item with good content', () => { const { container } = render( - , + , ); expect(container.querySelectorAll('osds-menu-item').length).toBe(2); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/AddAndEditEmailAccount.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/AddAndEditEmailAccount.spec.tsx index acc59ffc3032..5172b2574a21 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/AddAndEditEmailAccount.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/AddAndEditEmailAccount.spec.tsx @@ -2,97 +2,101 @@ import React from 'react'; import 'element-internals-polyfill'; import '@testing-library/jest-dom'; import { vi, describe, expect } from 'vitest'; -import { act } from 'react-dom/test-utils'; -import { fireEvent, render } from '@/utils/test.provider'; -import { accountMock, domainMock, platformMock } from '@/api/_mock_'; -import AddAndEditEmailAccount from '../AddAndEditEmailAccount'; +import { Location, useLocation, useSearchParams } from 'react-router-dom'; +import { fireEvent, render, waitFor, act } from '@/utils/test.provider'; +import { accountDetailMock } from '@/api/_mock_'; +import AddAndEditEmailAccount from '../AddAndEditEmailAccount.page'; import emailAccountAddAndEditTranslation from '@/public/translations/accounts/addAndEdit/Messages_fr_FR.json'; +import emailAccountAliasTranslation from '@/public/translations/accounts/alias/Messages_fr_FR.json'; +import redirectionsTranslation from '@/public/translations/redirections/Messages_fr_FR.json'; -const { useSearchParamsMock } = vi.hoisted(() => ({ - useSearchParamsMock: vi.fn(() => [new URLSearchParams()]), -})); - -const { useQueryMock } = vi.hoisted(() => ({ - useQueryMock: vi.fn(() => ({ - data: null, - isLoading: false, - })), -})); - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useGenerateUrl: vi.fn(), - useDomains: vi.fn(() => ({ - data: domainMock, - isLoading: false, - })), - }; -}); +describe('email account add and edit page', () => { + it('if there is not editEmailAccountId params', async () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/00000000-0000-0000-0000-000000000001/email_accounts/settings', + } as Location); -vi.mock('react-router-dom', () => ({ - useNavigate: vi.fn(), - MemoryRouter: vi.fn(() => ), - useSearchParams: useSearchParamsMock, -})); - -vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - useNotifications: vi.fn(() => ({ - addError: () => vi.fn(), - addSuccess: () => vi.fn(), - })), - }; -}); + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams(), + vi.fn(), + ]); -vi.mock('@tanstack/react-query', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - useQuery: useQueryMock, - }; -}); + const { getByTestId, queryByTestId } = render(); -afterEach(() => { - vi.restoreAllMocks(); -}); + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); -describe('email account add and edit page', () => { - it('if there is not editEmailAccountId params', () => { - const { getByTestId } = render(); expect(getByTestId('page-title')).toHaveTextContent( emailAccountAddAndEditTranslation.zimbra_account_add_title, ); }); - it('if there is editEmailAccountId params', () => { - useSearchParamsMock.mockImplementation( - vi.fn(() => [ - new URLSearchParams({ - editEmailAccountId: '19097ad4-2880-4000-8b03-9d110f0b8f80', - }), - ]), - ); - useQueryMock.mockImplementation( - vi.fn(() => ({ - data: accountMock[0], - isLoading: false, - })), - ); - const { getByTestId } = render(); + it('if there is editEmailAccountId params', async () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/00000000-0000-0000-0000-000000000001/email_accounts/settings', + search: `?editEmailAccountId=${accountDetailMock}`, + } as Location); + + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editEmailAccountId: accountDetailMock.id, + }), + vi.fn(), + ]); + + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + expect(getByTestId('page-title')).toHaveTextContent( emailAccountAddAndEditTranslation.zimbra_account_edit_title.replace( '{{ account }}', - accountMock[0].currentState?.email, + accountDetailMock.currentState?.email, ), ); }); - it('check validity form', () => { + it('test alias tabs page', () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/00000000-0000-0000-0000-000000000001/email_accounts/alias', + } as Location); + + const { getByText } = render(); + + expect( + getByText(emailAccountAliasTranslation.zimbra_account_alias_title), + ).toBeInTheDocument(); + }); + + it('should display redirection tab page', () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: + '/00000000-0000-0000-0000-000000000001/email_accounts/redirections', + } as Location); + + const { getByText } = render(); + + expect( + getByText(redirectionsTranslation.zimbra_redirections_account_title), + ).toBeInTheDocument(); + }); + + it('check validity form', async () => { + vi.mocked(useLocation).mockReturnValue({ + pathname: '/00000000-0000-0000-0000-000000000001/email_accounts/settings', + search: `?editEmailAccountId=${accountDetailMock}`, + } as Location); + + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editEmailAccountId: accountDetailMock.id, + }), + vi.fn(), + ]); + const { getByTestId } = render(); const button = getByTestId('confirm-btn'); @@ -102,15 +106,17 @@ describe('email account add and edit page', () => { expect(button).not.toBeEnabled(); - act(() => { - inputAccount.odsInputBlur.emit({ name: 'account', value: '' }); + await act(() => { + fireEvent.change(inputPassword, { target: { value: '' } }); inputPassword.odsBlur.emit({ name: 'password', value: '' }); + fireEvent.change(inputAccount, { target: { value: '' } }); + inputAccount.odsInputBlur.emit({ name: 'account', value: '' }); }); expect(inputAccount).toHaveAttribute('color', 'error'); - expect(inputPassword).toHaveAttribute('color', 'error'); + expect(inputPassword).toHaveAttribute('color', 'default'); - act(() => { + await act(() => { fireEvent.change(inputAccount, { target: { value: 'account' } }); fireEvent.change(selectDomain, { target: { value: 'domain' } }); fireEvent.change(inputPassword, { @@ -129,7 +135,7 @@ describe('email account add and edit page', () => { expect(inputPassword).toHaveAttribute('color', 'default'); expect(button).toBeEnabled(); - act(() => { + await act(() => { // Uppercased + digit + 10 characters total inputPassword.odsValueChange.emit({ name: 'password', @@ -140,7 +146,7 @@ describe('email account add and edit page', () => { expect(inputPassword).toHaveAttribute('color', 'default'); expect(button).toBeEnabled(); - act(() => { + await act(() => { // No uppercased + digit or special + 10 characters total inputPassword.odsValueChange.emit({ name: 'password', @@ -151,7 +157,7 @@ describe('email account add and edit page', () => { expect(inputPassword).toHaveAttribute('color', 'error'); expect(button).not.toBeEnabled(); - act(() => { + await act(() => { // Uppercased + special + 10 characters total inputPassword.odsValueChange.emit({ name: 'password', @@ -162,7 +168,7 @@ describe('email account add and edit page', () => { expect(inputPassword).toHaveAttribute('color', 'default'); expect(button).toBeEnabled(); - act(() => { + await act(() => { // Uppercased + digit or special but 9 characters total inputPassword.odsValueChange.emit({ name: 'password', diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/EmailAccount.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/EmailAccount.spec.tsx index d12ee48a00ab..8bbf3178c9cc 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/EmailAccount.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/EmailAccount.spec.tsx @@ -1,61 +1,23 @@ import React from 'react'; import { vi, describe, expect } from 'vitest'; import EmailAccounts from '../EmailAccounts'; -import { render } from '@/utils/test.provider'; +import { render, waitFor } from '@/utils/test.provider'; import accountTranslation from '@/public/translations/accounts/Messages_fr_FR.json'; -import { - accountMock, - platformMock, - domainMock, - organizationDetailMock, -} from '@/api/_mock_'; +import { useGenerateUrl } from '@/hooks'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - platformUrn: platformMock[0].iam.urn, - })), - useOrganization: vi.fn(() => ({ - data: organizationDetailMock, - isLoading: false, - })), - useAccountList: vi.fn(() => ({ - data: accountMock, - isLoading: false, - })), - useDomains: vi.fn(() => ({ - data: domainMock, - isLoading: false, - })), - useGenerateUrl: vi.fn( - () => '#/00000000-0000-0000-0000-000000000001/email_accounts/add?', - ), - useOverridePage: vi.fn(() => false), - }; -}); - -vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - Notifications: vi.fn().mockReturnValue(
Notifications
), - Datagrid: vi.fn().mockReturnValue(
Datagrid
), - }; -}); - -afterEach(() => { - vi.clearAllMocks(); -}); +const addUrl = '#/00000000-0000-0000-0000-000000000001/email_accounts/add?'; describe('EmailAccounts page', () => { - it('Page should display correctly', () => { + it('Page should display correctly', async () => { + vi.mocked(useGenerateUrl).mockReturnValue(addUrl); const { getByTestId } = render(); + + await waitFor(() => { + expect(getByTestId('add-account-btn')).toBeInTheDocument(); + }); + const button = getByTestId('add-account-btn'); - expect(button).toHaveAttribute( - 'href', - '#/00000000-0000-0000-0000-000000000001/email_accounts/add?', - ); + expect(button).toHaveAttribute('href', addUrl); expect(button).toHaveTextContent( accountTranslation.zimbra_account_account_add, ); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalAddAlias.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalAddAlias.spec.tsx new file mode 100644 index 000000000000..c96ab9b94446 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalAddAlias.spec.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import 'element-internals-polyfill'; +import '@testing-library/jest-dom'; +import { vi, describe, expect } from 'vitest'; +import { act } from 'react-dom/test-utils'; +import { useResolvedPath, useSearchParams } from 'react-router-dom'; +import { fireEvent, render, screen, waitFor } from '@/utils/test.provider'; +import { accountDetailMock } from '@/api/_mock_'; +import ModalAddAlias from '../ModalAddAlias.component'; +import emailAccountAliasAddTranslation from '@/public/translations/accounts/alias/add/Messages_fr_FR.json'; + +vi.mocked(useResolvedPath).mockReturnValue({ + pathname: '/:serviceName/email_accounts/alias/add', + search: '', + hash: '', +}); + +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editEmailAccountId: accountDetailMock.id, + }), + vi.fn(), +]); + +describe('add alias modal', () => { + it('if modal are displayed', async () => { + const { queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + screen.getByText( + emailAccountAliasAddTranslation.zimbra_account_alias_add_description.replace( + '{{ account }}', + accountDetailMock.currentState?.email, + ), + ); + }); + + it('check validity form', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const button = getByTestId('confirm-btn'); + const inputAccount = getByTestId('input-alias'); + const selectDomain = getByTestId('select-domain'); + + expect(button).not.toBeEnabled(); + + act(() => { + inputAccount.odsInputBlur.emit({ name: 'alias', value: '' }); + }); + + expect(inputAccount).toHaveAttribute('color', 'error'); + + act(() => { + fireEvent.change(inputAccount, { target: { value: 'alias' } }); + fireEvent.change(selectDomain, { target: { value: 'domain' } }); + + // it seems we have to manually trigger the ods event + inputAccount.odsValueChange.emit({ name: 'alias', value: 'alias' }); + selectDomain.odsValueChange.emit({ name: 'domain', value: 'domain' }); + }); + + expect(inputAccount).toHaveAttribute('color', 'default'); + expect(button).toBeEnabled(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteAlias.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteAlias.spec.tsx new file mode 100644 index 000000000000..31645c1ffba1 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteAlias.spec.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import 'element-internals-polyfill'; +import '@testing-library/jest-dom'; +import { vi, describe, expect } from 'vitest'; +import { useSearchParams } from 'react-router-dom'; +import { render, act, waitFor, fireEvent } from '@/utils/test.provider'; +import { aliasMock, accountsMock } from '@/api/_mock_'; +import ModalDeleteAlias from '../ModalDeleteAlias.component'; +import accountAliasDeleteTranslation from '@/public/translations/accounts/alias/delete/Messages_fr_FR.json'; +import { deleteZimbraPlatformAlias } from '@/api/alias'; + +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editEmailAccountId: accountsMock[0].id, + deleteAliasId: aliasMock[0].id, + }), + vi.fn(), +]); + +describe('Alias delete modal', () => { + it('should render correctly', () => { + const { getByTestId } = render(); + const modal = getByTestId('modal'); + expect(modal).toHaveProperty( + 'headline', + accountAliasDeleteTranslation.zimbra_account_alias_delete_modal_title, + ); + }); + + it('should delete alias', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + expect(getByTestId('delete-btn')).not.toBeDisabled(); + + await act(() => { + fireEvent.click(getByTestId('delete-btn')); + }); + + expect(deleteZimbraPlatformAlias).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteEmailAccount.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteEmailAccount.spec.tsx index 8cf34c66d4b3..fce1443728c4 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteEmailAccount.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/__test__/ModalDeleteEmailAccount.spec.tsx @@ -2,42 +2,19 @@ import React from 'react'; import 'element-internals-polyfill'; import '@testing-library/jest-dom'; import { vi, describe, expect } from 'vitest'; -import { fireEvent, render } from '@/utils/test.provider'; -import { platformMock, accountMock } from '@/api/_mock_'; -import ModalDeleteEmailAccount from '../ModalDeleteEmailAccount'; +import { useSearchParams } from 'react-router-dom'; +import { fireEvent, render, act } from '@/utils/test.provider'; +import { domainDetailMock } from '@/api/_mock_'; +import ModalDeleteEmailAccount from '../ModalDeleteEmailAccount.component'; import accountsDeleteTranslation from '@/public/translations/accounts/delete/Messages_fr_FR.json'; +import { deleteZimbraPlatformAccount } from '@/api/account'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useGenerateUrl: vi.fn(), - useAccount: vi.fn(() => ({ - data: accountMock[0], - isLoading: false, - })), - }; -}); - -vi.mock('react-router-dom', () => ({ - useNavigate: vi.fn(), - MemoryRouter: vi.fn(() => ), - useSearchParams: vi.fn(() => [ - new URLSearchParams({ - deleteDomainId: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - }), - ]), -})); - -vi.mock('@ovh-ux/manager-react-components', () => { - return { - useNotifications: vi.fn(() => ({ - addError: () => vi.fn(), - addSuccess: () => vi.fn(), - })), - }; -}); +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + deleteDomainId: domainDetailMock.id, + }), + vi.fn(), +]); describe('Domains delete modal', () => { it('check if it is displayed', () => { @@ -48,10 +25,19 @@ describe('Domains delete modal', () => { ); }); - it('check transition from step 1 to step 2', () => { + it('check transition from step 1 to step 2 and delete', async () => { const { getByTestId } = render(); expect(getByTestId('text-step-1')).toBeVisible(); - fireEvent.click(getByTestId('primary-btn')); + await act(() => { + fireEvent.click(getByTestId('primary-btn')); + }); + expect(getByTestId('text-step-2')).toBeVisible(); + + await act(() => { + fireEvent.click(getByTestId('primary-btn')); + }); + + expect(deleteZimbraPlatformAccount).toHaveBeenCalledOnce(); }); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/account.constants.ts b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/account.constants.ts new file mode 100644 index 000000000000..8eb4e82b4c13 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/account.constants.ts @@ -0,0 +1,7 @@ +import { FormInputRegexInterface } from '@/utils'; + +export const formInputRegex: FormInputRegexInterface = { + alias: /^(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*)(?:(?:[.|+])(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*))*$/, + account: /^(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*)(?:(?:[.|+])(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*))*$/, + password: /^(?=.*[\d!@#$€%^&*()\\[\]{}\-_+=~`|:;"'<>,./?])(?=.*[A-Z])(?=(.*)).{10,64}$/, +}; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/GeneralInformation.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/GeneralInformation.tsx index 61150d7055e0..6bed7266cb09 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/GeneralInformation.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/GeneralInformation.tsx @@ -1,32 +1,22 @@ -import React, { useContext } from 'react'; -import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import React from 'react'; import { OsdsTile, OsdsDivider } from '@ovhcloud/ods-components/react'; -import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core'; -import { - LinkType, - Links, - ManagerText, - Subtitle, -} from '@ovh-ux/manager-react-components'; +import { ManagerText, Subtitle } from '@ovh-ux/manager-react-components'; import { useTranslation } from 'react-i18next'; import { AccountStatistics } from '@/api/api.type'; import { TileBlock } from '@/components/TileBlock'; import { BadgeStatus } from '@/components/BadgeStatus'; import { useOrganization, usePlatform } from '@/hooks'; -import { OngoingTasks } from './OngoingTasks'; -import { GUIDES_LIST } from '@/guides.constants'; +// import { OngoingTasks } from './OngoingTasks'; +import { Guide, GUIDES_LIST } from '@/guides.constants'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import GuideLink from '@/components/GuideLink'; interface GuideLinks { - [key: string]: string | undefined; + [key: string]: Guide; } function GeneralInformation() { const { t } = useTranslation('dashboard'); - const context = useContext(ShellContext); - const { ovhSubsidiary } = context.environment.getUser(); - const webmail = GUIDES_LIST.webmail.url; - const { data: platform, platformUrn } = usePlatform(); const { data: organisation } = useOrganization(); @@ -35,12 +25,7 @@ function GeneralInformation() { return (
- +
); }); @@ -58,6 +43,7 @@ function GeneralInformation() { {t('zimbra_dashboard_tile_status_title')} {organisation && ( @@ -100,6 +86,7 @@ function GeneralInformation() { > {platformUrn && ( @@ -124,11 +111,10 @@ function GeneralInformation() {
{t('zimbra_dashboard_tile_usefulLinks_title')} {guideLinks({ - zimbra_dashboard_webmail: webmail, + zimbra_dashboard_webmail: GUIDES_LIST.webmail, zimbra_dashboard_administrator_guide: - GUIDES_LIST.administrator_guide.url[ovhSubsidiary], - zimbra_dashboard_user_guides: - GUIDES_LIST.user_guide.url[ovhSubsidiary], + GUIDES_LIST.administrator_guide, + zimbra_dashboard_user_guides: GUIDES_LIST.user_guide, })}
diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/OngoingTasks.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/OngoingTasks.tsx index c83408e450c5..a4453594821b 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/OngoingTasks.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/OngoingTasks.tsx @@ -1,32 +1,21 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useQuery } from '@tanstack/react-query'; import { OsdsIcon, OsdsLink } from '@ovhcloud/ods-components/react'; import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-components'; -import { - getZimbraPlatformTask, - getZimbraPlatformTaskQueryKey, -} from '@/api/task'; -import { useOrganization, usePlatform } from '@/hooks'; +import { useTasks } from '@/hooks'; export const OngoingTasks: React.FC = () => { const { t } = useTranslation('dashboard'); const [loadMore, setLoadMore] = useState(false); const [tasksDiplayed, setTasksDiplayed] = useState([]); - const { data: organisation } = useOrganization(); - const { platformId } = usePlatform(); - const { data } = useQuery({ - queryKey: getZimbraPlatformTaskQueryKey(platformId, organisation?.id), - queryFn: () => getZimbraPlatformTask(platformId, organisation?.id), - enabled: !!platformId, - }); + const { data } = useTasks(); useEffect(() => { setTasksDiplayed(loadMore ? data : data?.slice(0, 5)); }, [loadMore, data]); return ( -
+
{tasksDiplayed?.map((task) => ( {`${task.type} ${task.message}`} ))} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/GeneralInformation.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/GeneralInformation.spec.tsx new file mode 100644 index 000000000000..66cb3ca408e3 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/GeneralInformation.spec.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { describe, expect, vi } from 'vitest'; +import { useSearchParams } from 'react-router-dom'; +import GeneralInformation from '../GeneralInformation'; +import { render } from '@/utils/test.provider'; +import dashboardTranslation from '@/public/translations/dashboard/Messages_fr_FR.json'; +import { organizationDetailMock } from '@/api/_mock_'; + +describe('General Informations page', () => { + it('should display page correctly', async () => { + const { findByText, getByTestId, queryByTestId } = render( + , + ); + + const title = await findByText( + dashboardTranslation.zimbra_dashboard_tile_status_title, + ); + const serviceStatus = queryByTestId('tileblock-orga'); + const accounts = getByTestId('platform-accounts'); + + expect(title).toBeVisible(); + expect(serviceStatus).toBeNull(); + expect(accounts).toBeInTheDocument(); + }); + + it('should display organization status', async () => { + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + organizationId: organizationDetailMock.id, + }), + vi.fn(), + ]); + + const { findByText, getByTestId } = render(); + + const title = await findByText( + dashboardTranslation.zimbra_dashboard_tile_status_title, + ); + + const serviceStatus = getByTestId('tileblock-orga'); + + expect(title).toBeVisible(); + expect(serviceStatus).toBeInTheDocument(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/OngoingTasks.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/OngoingTasks.spec.tsx new file mode 100644 index 000000000000..7d6537d0642a --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/GeneralInformation/__test__/OngoingTasks.spec.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import { OngoingTasks } from '../OngoingTasks'; +import { render } from '@/utils/test.provider'; + +describe('OngoingTasks component', () => { + it('should display component correctly', async () => { + const { getByTestId } = render(); + + const wrap = getByTestId('ongoingtasks'); + + expect(wrap).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx new file mode 100644 index 000000000000..e70ae4e7dc05 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ActionMenu } from '@ovh-ux/manager-react-components'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { MailingListItem } from './MailingLists'; +import { ResourceStatus } from '@/api/api.type'; + +interface ActionButtonMailingListProps { + mailingListItem: MailingListItem; +} + +const ActionButtonMailingList: React.FC = ({ + mailingListItem, +}) => { + const { t } = useTranslation('mailinglists'); + const { platformUrn } = usePlatform(); + + const hrefDeleteMailingList = useGenerateUrl('./delete', 'href', { + deleteMailingListId: mailingListItem.id, + }); + + const hrefEditMailingList = useGenerateUrl('./settings', 'href', { + editMailingListId: mailingListItem.id, + }); + + const hrefDefineMembersMailingList = useGenerateUrl( + './define_members', + 'href', + { + mailingListId: mailingListItem.id, + }, + ); + + const hrefConfigureDelegationMailingList = useGenerateUrl( + './configure_delegation', + 'href', + { + mailingListId: mailingListItem.id, + }, + ); + + const actionItems = [ + { + id: 1, + href: hrefEditMailingList, + urn: platformUrn, + iamActions: [IAM_ACTIONS.mailingList.edit], + label: t('zimbra_mailinglists_datagrid_action_edit'), + }, + { + id: 2, + href: hrefDefineMembersMailingList, + urn: platformUrn, + iamActions: [IAM_ACTIONS.mailingList.edit], + label: t('zimbra_mailinglists_datagrid_action_define_members'), + }, + { + id: 3, + href: hrefConfigureDelegationMailingList, + urn: platformUrn, + iamActions: [IAM_ACTIONS.mailingList.edit], + label: t('zimbra_mailinglists_datagrid_action_configure_delegation'), + }, + { + id: 4, + href: hrefDeleteMailingList, + urn: platformUrn, + iamActions: [IAM_ACTIONS.mailingList.delete], + label: t('zimbra_mailinglists_datagrid_action_delete'), + }, + ]; + + return ( + + ); +}; + +export default ActionButtonMailingList; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx new file mode 100644 index 000000000000..246e2080b411 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx @@ -0,0 +1,78 @@ +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; +import { Links, LinkType, Subtitle } from '@ovh-ux/manager-react-components'; +import { + useDomains, + useGenerateUrl, + usePlatform, + useMailingList, +} from '@/hooks'; +import Loading from '@/components/Loading/Loading'; +import MailingListSettings from './MailingListSettings.page'; + +export default function AddAndEditMailingList() { + const { t } = useTranslation('mailinglists/addAndEdit'); + const location = useLocation(); + const navigate = useNavigate(); + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const editMailingListId = searchParams.get('editMailingListId'); + const [isLoading, setIsLoading] = useState(true); + const goBackUrl = useGenerateUrl('..', 'path'); + + const goBack = () => { + return navigate(goBackUrl); + }; + + const { + data: editMailingListDetail, + isLoading: isLoadingMailingListDetailRequest, + } = useMailingList({ mailingListId: editMailingListId }); + + const { data: domainList, isLoading: isLoadingDomainRequest } = useDomains(); + + useEffect(() => { + if ( + !isLoadingMailingListDetailRequest && + !isLoadingDomainRequest && + platformId + ) { + setIsLoading(false); + } + }, [ + isLoadingMailingListDetailRequest, + isLoadingDomainRequest, + location.pathname, + ]); + + return ( + <> + {isLoading && } + {!isLoading && ( + <> +
+ + + {!editMailingListDetail + ? t('zimbra_mailinglist_add_title') + : t('zimbra_mailinglist_edit_title')} + +
+ + + )} + + ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx new file mode 100644 index 000000000000..ded5e55e2a32 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx @@ -0,0 +1,601 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { useTranslation } from 'react-i18next'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { + OsdsButton, + OsdsFormField, + OsdsInput, + OsdsMessage, + OsdsRadio, + OsdsRadioButton, + OsdsRadioGroup, + OsdsSelect, + OsdsSelectOption, + OsdsText, + OsdsToggle, + OsdsTooltipContent, + OsdsIcon, + OsdsTooltip, +} from '@ovhcloud/ods-components/react'; +import { + ODS_THEME_COLOR_HUE, + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_VARIANT, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_INPUT_SIZE, + ODS_INPUT_TYPE, + ODS_MESSAGE_TYPE, + ODS_RADIO_BUTTON_SIZE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useMutation } from '@tanstack/react-query'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { + postZimbraPlatformMailingList, + putZimbraPlatformMailingList, + MailingListType, + MailingListBodyParamsType, + ReplyToChoices, + ModerationChoices, + getZimbraPlatformMailingListsQueryKey, +} from '@/api/mailinglist'; +import { DomainType } from '@/api/domain'; +import { formInputRegex } from './mailingList.constants'; +import { + checkValidityField, + checkValidityForm, + FormTypeInterface, +} from '@/utils'; +import queryClient from '@/queryClient'; + +const replyToChoices = [ + { + value: ReplyToChoices.LIST, + key: 'zimbra_mailinglist_add_reply_to_list', + }, + { + value: ReplyToChoices.SENDER, + key: 'zimbra_mailinglist_add_reply_to_sender', + }, + { + value: ReplyToChoices.MAILBOX, + key: 'zimbra_mailinglist_add_reply_to_another_mailbox', + }, +]; + +const moderationChoices = [ + { + value: ModerationChoices.ALL, + key: 'zimbra_mailinglist_add_moderation_choice_all', + }, + { + value: ModerationChoices.SUBSONLY, + key: 'zimbra_mailinglist_add_moderation_choice_subs_only', + }, + { + value: ModerationChoices.NONE, + key: 'zimbra_mailinglist_add_moderation_choice_none', + }, +]; + +// fetch this from api ? +const languageList = ['FR', 'EN', 'ES']; + +export default function MailingListSettings({ + domainList = [], + editMailingListDetail = null, +}: Readonly<{ + domainList: DomainType[]; + editMailingListDetail: MailingListType; +}>) { + const { t } = useTranslation('mailinglists/addAndEdit'); + const navigate = useNavigate(); + const { addError, addSuccess } = useNotifications(); + const { platformId } = usePlatform(); + const [searchParams] = useSearchParams(); + const editMailingListId = searchParams.get('editMailingListId'); + const organizationIdParam = searchParams.get('organizationId'); + const [isFormValid, setIsFormValid] = useState(false); + const [selectedDomainOrganization, setSelectedDomainOrganization] = useState( + '', + ); + const goBackUrl = useGenerateUrl('..', 'path'); + + const goBack = () => { + return navigate(goBackUrl); + }; + + const [form, setForm] = useState({ + ...{ + account: { + value: '', + touched: false, + required: true, + }, + domain: { + value: '', + touched: false, + required: true, + }, + defaultReplyTo: { + value: '', + touched: false, + required: true, + }, + owner: { + value: '', + touched: false, + required: true, + }, + language: { + value: '', + touched: false, + required: true, + }, + moderationOption: { + value: '', + touched: false, + required: false, + }, + subscriberModeration: { + value: '', + touched: false, + required: false, + }, + }, + }); + + const getDataBody = useCallback( + (formRef: FormTypeInterface) => { + const { + account: { value: account }, + domain: { value: domain }, + } = form; + + let dataBody = { + email: `${account}@${domain}`, + }; + + Object.entries(formRef).forEach(([key, { value }]) => { + if (!['account', 'domain'].includes(key)) { + dataBody = { ...dataBody, [key]: value }; + } + }); + + return dataBody; + }, + [form], + ); + + useEffect(() => { + if (editMailingListDetail) { + const newForm: FormTypeInterface = form; + const { + email, + defaultReplyTo, + language, + owner, + moderationOption, + } = editMailingListDetail.currentState; + const [account, domain] = email.split('@'); + newForm.account.value = account; + newForm.domain.value = domain; + newForm.defaultReplyTo.value = defaultReplyTo; + newForm.owner.value = owner; + newForm.language.value = language; + newForm.moderationOption.value = moderationOption; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + } + }, []); + + const handleFormChange = (name: string, value: string) => { + const newForm: FormTypeInterface = form; + newForm[name] = { + ...form[name], + value, + touched: true, + hasError: !checkValidityField(name, value, formInputRegex, form), + }; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + setIsFormValid(checkValidityForm(form)); + }; + + const handleDomainChange = (selectedDomain: string) => { + const organizationLabel = domainList.find( + ({ currentState }) => currentState.name === selectedDomain, + )?.currentState.organizationLabel; + handleFormChange('domain', selectedDomain); + setSelectedDomainOrganization(organizationLabel); + }; + + const { mutate: addOrEditMailingList, isPending: isSending } = useMutation({ + mutationFn: (params: MailingListBodyParamsType) => { + return editMailingListId + ? putZimbraPlatformMailingList(platformId, editMailingListId, params) + : postZimbraPlatformMailingList(platformId, params); + }, + onSuccess: () => { + addSuccess( + + {t( + editMailingListId + ? 'zimbra_mailinglist_edit_success_message' + : 'zimbra_mailinglist_add_success_message', + )} + , + true, + ); + }, + onError: (error: ApiError) => { + addError( + + {t( + editMailingListId + ? 'zimbra_mailinglist_edit_error_message' + : 'zimbra_mailinglist_add_error_message', + { + error: error.response?.data?.message, + }, + )} + , + true, + ); + }, + onSettled: () => { + queryClient.invalidateQueries({ + queryKey: getZimbraPlatformMailingListsQueryKey(platformId), + }); + goBack(); + }, + }); + + const handleSavelick = () => { + addOrEditMailingList(getDataBody(form)); + }; + + return ( +
+ + {!editMailingListId + ? t('zimbra_mailinglist_add_header') + : t('zimbra_mailinglist_edit_header')} + + + {t('zimbra_mailinglist_mandatory_fields')} + + +
+ + {t('zimbra_mailinglist_add_input_email_label')} * + +
+
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > + + + handleDomainChange(e.detail.value as string) + } + data-testid="select-domain" + > + + {t('zimbra_mailinglist_add_select_domain_placeholder')} + + {domainList?.map(({ currentState: domain }) => ( + + {domain.name} + + ))} + +
+
+ {selectedDomainOrganization && !organizationIdParam && ( + + + {t('zimbra_mailinglist_add_message_organization', { + organization: selectedDomainOrganization, + })} + + + )} + +
+ + {t('zimbra_mailinglist_add_input_owner_label')} * + +
+
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + > +
+
+ +
+ + {t('zimbra_mailinglist_add_reply_to_label')} * + +
+
+ + handleFormChange('defaultReplyTo', event.detail.newValue) + } + > + {replyToChoices.map(({ value, key }) => ( + + + + + {t(key)} + + + + + ))} + +
+
+ +
+ + {t('zimbra_mailinglist_add_language_label')} * + +
+
+ + handleFormChange(e.detail.name, e.detail.value as string) + } + > + + {t('zimbra_mailinglist_add_select_language_placeholder')} + + {languageList?.map((lang) => ( + + {lang} + + ))} + +
+
+ +
+ + {t('zimbra_mailinglist_add_moderation_choice_label')} + +
+
+ + handleFormChange('moderationOption', event.detail.newValue) + } + > + {moderationChoices.map(({ value, key }) => ( + + + + + {t(key)} + + + + + ))} + + + handleFormChange( + 'subscriberModeration', + form.subscriberModeration.value === 'true' ? 'false' : 'true', + ) + } + {...(form.subscriberModeration.value === 'true' + ? { checked: true } + : {})} + > +
+ + {t('zimbra_mailinglist_add_subscriber_moderation')} + + + + + {t( + 'zimbra_mailinglist_add_subscriber_moderation_tooltip', + )} + + + + + + {t('zimbra_mailinglist_add_subscriber_moderation_info', { + max: 250, + })} + +
+
+
+
+
+ + {t('zimbra_mailinglist_add_button_confirm')} + + {editMailingListId && ( + + {t('zimbra_mailinglist_add_button_cancel')} + + )} +
+
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx new file mode 100644 index 000000000000..bbf254bd4eb7 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx @@ -0,0 +1,219 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { OsdsIcon, OsdsText } from '@ovhcloud/ods-components/react'; +import { Outlet } from 'react-router-dom'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_SIZE, + ODS_ICON_NAME, + ODS_ICON_SIZE, + ODS_TEXT_COLOR_HUE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { + Datagrid, + DatagridColumn, + ManagerButton, + Notifications, +} from '@ovh-ux/manager-react-components'; + +import { + usePlatform, + useGenerateUrl, + useMailingLists, + useOverridePage, +} from '@/hooks'; +import ActionButtonMailingList from './ActionButtonMailingList.component'; +import LabelChip from '@/components/LabelChip'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { ResourceStatus } from '@/api/api.type'; +import { MailingListType } from '@/api/mailinglist'; +import { DATAGRID_REFRESH_INTERVAL, DATAGRID_REFRESH_ON_MOUNT } from '@/utils'; +import Loading from '@/components/Loading/Loading'; + +export type MailingListItem = { + id: string; + name: string; + organizationLabel: string; + organizationId: string; + owner: string; + aliases: number; + moderators: number; + subscribers: number; + status: ResourceStatus; +}; + +const columns: DatagridColumn[] = [ + { + id: 'domains', + cell: (item) => ( + + {item.name} + + ), + label: 'zimbra_mailinglists_datagrid_name_label', + }, + { + id: 'organization', + cell: (item) => + item.organizationLabel && ( + {item.organizationLabel} + ), + label: 'zimbra_mailinglists_datagrid_organization_label', + }, + { + id: 'owner', + cell: (item) => ( + + {item.owner} + + ), + label: 'zimbra_mailinglists_datagrid_owner_label', + }, + { + id: 'aliases', + cell: (item) => ( + + {item.aliases} + + ), + label: 'zimbra_mailinglists_datagrid_aliases_label', + }, + { + id: 'moderators', + cell: (item) => ( + + {item.moderators} + + ), + label: 'zimbra_mailinglists_datagrid_moderators_label', + }, + { + id: 'subscribers', + cell: (item) => ( + + {item.subscribers} + + ), + label: 'zimbra_mailinglists_datagrid_subscribers_label', + }, + { + id: 'tooltip', + cell: (item) => , + label: '', + }, +]; + +export const getMailingListItem = (data: MailingListType): MailingListItem => { + return { + id: data?.id, + name: data?.currentState?.email, + organizationLabel: data?.currentState?.organizationLabel, + organizationId: data?.currentState?.organizationId, + owner: data?.currentState?.owner, + aliases: 0, + moderators: 0, + subscribers: data?.currentState?.members?.length || 0, + status: data?.resourceStatus, + }; +}; + +export const getMailingListItems = ( + data: MailingListType[], +): MailingListItem[] => { + return data?.map(getMailingListItem) ?? []; +}; + +export default function MailingLists() { + const { t } = useTranslation('mailinglists'); + const { platformUrn, data: platformData } = usePlatform(); + const { data, isLoading } = useMailingLists({ + refetchInterval: DATAGRID_REFRESH_INTERVAL, + refetchOnMount: DATAGRID_REFRESH_ON_MOUNT, + }); + const isOverridedPage = useOverridePage(); + + const items: MailingListItem[] = getMailingListItems(data); + + const hrefAddMailingList = useGenerateUrl('./add', 'href'); + + // this will need to be updated + const quota = platformData?.currentState?.quota || 0; + + return ( +
+ + + {platformUrn && !isOverridedPage && ( + <> +
+
+ + {t('zimbra_mailinglists_quota_label')} + {` ${quota}/1000`} + +
+ + + + + {t('zimbra_mailinglists_datagrid_cta')} + +
+ {isLoading ? ( + + ) : ( + ({ + ...column, + label: t(column.label), + }))} + items={items} + totalItems={items.length} + /> + )} + + )} +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/ActionButtonMailingList.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/ActionButtonMailingList.spec.tsx new file mode 100644 index 000000000000..84747c77cb71 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/ActionButtonMailingList.spec.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import ActionButtonMailingList from '../ActionButtonMailingList.component'; +import { render } from '@/utils/test.provider'; +import mailingListsTranslation from '@/public/translations/mailinglists/Messages_fr_FR.json'; +import { mailingListDetailMock } from '@/api/_mock_'; +import { getMailingListItem } from '../MailingLists'; + +describe('MailingLists datagrid action menu', () => { + it('should display 4 actions buttons', () => { + const { container } = render( + , + ); + + expect(container.querySelectorAll('osds-menu-item').length).toBe(4); + + expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + mailingListsTranslation.zimbra_mailinglists_datagrid_action_edit, + ); + + expect(container.querySelectorAll('osds-menu-item')[1]).toHaveTextContent( + mailingListsTranslation.zimbra_mailinglists_datagrid_action_define_members, + ); + + expect(container.querySelectorAll('osds-menu-item')[2]).toHaveTextContent( + mailingListsTranslation.zimbra_mailinglists_datagrid_action_configure_delegation, + ); + + expect(container.querySelectorAll('osds-menu-item')[3]).toHaveTextContent( + mailingListsTranslation.zimbra_mailinglists_datagrid_action_delete, + ); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/AddAndEditMailingList.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/AddAndEditMailingList.spec.tsx new file mode 100644 index 000000000000..225b95771f71 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/AddAndEditMailingList.spec.tsx @@ -0,0 +1,119 @@ +import React from 'react'; +import 'element-internals-polyfill'; +import '@testing-library/jest-dom'; +import { vi, describe, expect } from 'vitest'; +import { act } from 'react-dom/test-utils'; +import { useSearchParams } from 'react-router-dom'; +import { render, waitFor, fireEvent } from '@/utils/test.provider'; +import { mailingListsMock } from '@/api/_mock_'; +import AddAndEditMailingList from '../AddAndEditMailingList.page'; +import mailingListsAddAndEditTranslation from '@/public/translations/mailinglists/addAndEdit/Messages_fr_FR.json'; +import { ModerationChoices, ReplyToChoices } from '@/api/mailinglist'; +import { navigate } from '@/utils/test.setup'; + +describe('mailing lists add and edit page', () => { + const editMailingListId = mailingListsMock[0].id; + + it('should be in add mode if no editMailingListId param', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + expect(getByTestId('page-title')).toHaveTextContent( + mailingListsAddAndEditTranslation.zimbra_mailinglist_add_title, + ); + }); + + it('should be add page and enable/disable button based on form validity', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const button = getByTestId('confirm-btn'); + const inputAccount = getByTestId('input-account'); + const selectDomain = getByTestId('select-domain'); + const inputOwner = getByTestId('input-owner'); + const replyTo = getByTestId('radio-group-reply-to'); + const selectLanguage = getByTestId('select-language'); + const moderationOption = getByTestId('radio-group-moderation-option'); + + expect(button).not.toBeEnabled(); + + act(() => { + inputAccount.odsInputBlur.emit({ name: 'account', value: '' }); + inputOwner.odsInputBlur.emit({ name: 'owner', value: '' }); + }); + + expect(inputAccount).toHaveAttribute('color', 'error'); + expect(inputOwner).toHaveAttribute('color', 'error'); + expect(button).not.toBeEnabled(); + + act(() => { + inputAccount.odsValueChange.emit({ name: 'account', value: 'account' }); + selectDomain.odsValueChange.emit({ name: 'domain', value: 'domain' }); + inputOwner.odsValueChange.emit({ + name: 'owner', + value: 'testowner', + }); + selectLanguage.odsValueChange.emit({ name: 'language', value: 'FR' }); + replyTo.odsValueChange.emit({ + name: 'defaultReplyTo', + value: ReplyToChoices.LIST, + }); + moderationOption.odsValueChange.emit({ + name: 'moderationOption', + value: ModerationChoices.ALL, + }); + }); + + expect(inputAccount).toHaveAttribute('color', 'default'); + expect(inputOwner).toHaveAttribute('color', 'default'); + expect(button).toBeEnabled(); + + act(() => { + inputOwner.odsValueChange.emit({ + name: 'owner', + value: 't', + }); + }); + + expect(button).not.toBeEnabled(); + }); + + it('should be in edit mode if editMailingListId param is present', async () => { + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editMailingListId, + }), + vi.fn(), + ]); + + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + expect(getByTestId('page-title')).toHaveTextContent( + mailingListsAddAndEditTranslation.zimbra_mailinglist_edit_title, + ); + }); + + it('should go back when back button pressed', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + act(() => { + fireEvent.click(getByTestId('back-btn')); + }); + + expect(navigate).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/MailingLists.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/MailingLists.spec.tsx new file mode 100644 index 000000000000..46d5f75ba830 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/__test__/MailingLists.spec.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { vi, describe, expect } from 'vitest'; +import { render, waitFor } from '@/utils/test.provider'; +import mailingListsTranslation from '@/public/translations/mailinglists/Messages_fr_FR.json'; +import MailingLists from '../MailingLists'; +import { useGenerateUrl } from '@/hooks'; + +const addUrl = '#/00000000-0000-0000-0000-000000000001/mailing_lists/add'; + +describe('Mailing Lists page', () => { + it('should display add button correctly', async () => { + vi.mocked(useGenerateUrl).mockReturnValue(addUrl); + + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const button = getByTestId('add-mailinglist-btn'); + expect(button).toHaveAttribute('href', addUrl); + expect(button).toHaveTextContent( + mailingListsTranslation.zimbra_mailinglists_datagrid_cta, + ); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/mailingList.constants.ts b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/mailingList.constants.ts new file mode 100644 index 000000000000..ec21810871c8 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/mailingList.constants.ts @@ -0,0 +1,6 @@ +import { FormInputRegexInterface } from '@/utils'; + +export const formInputRegex: FormInputRegexInterface = { + account: /^(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*)(?:(?:[.|+])(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*))*$/, + owner: /^[A-Za-z0-9]{2,20}$/, +}; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx similarity index 100% rename from packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx similarity index 92% rename from packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx index 94e5e7ca50f4..90e2ee471642 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx @@ -34,21 +34,12 @@ import { putZimbraPlatformOrganization, } from '@/api/organization'; import queryClient from '@/queryClient'; - -type FieldType = { - value: string; - required: boolean; - touched: boolean; - hasError: boolean; -}; - -interface FormTypeInterface { - [key: string]: FieldType; -} - -interface FormInputRegexInterface { - [key: string]: RegExp; -} +import { + checkValidityField, + checkValidityForm, + FormInputRegexInterface, + FormTypeInterface, +} from '@/utils'; export default function ModalAddAndEditOrganization() { const { t } = useTranslation('organizations/addAndEdit'); @@ -147,31 +138,16 @@ export default function ModalAddAndEditOrganization() { addOrEditOrganization({ name, label }); }; - const checkValidityField = (name: string, value: string) => { - return formInputRegex[name] - ? formInputRegex[name].test(value) || - (!form[name].required && form[name].value === '') - : true; - }; - - const checkValidityForm = () => { - const touched = Object.values(form).find((field) => field.touched); - const error = Object.values(form).find( - (field) => field.hasError || (field.required && field.value === ''), - ); - return touched && !error; - }; - const handleFormChange = (name: string, value: string) => { const newForm: FormTypeInterface = form; newForm[name] = { ...form[name], value, touched: true, - hasError: !checkValidityField(name, value), + hasError: !checkValidityField(name, value, formInputRegex, form), }; setForm((oldForm) => ({ ...oldForm, ...newForm })); - setIsFormValid(checkValidityForm); + setIsFormValid(checkValidityForm(form)); }; useEffect(() => { diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx similarity index 90% rename from packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.tsx rename to packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx index e69d4101b752..67f257988ca5 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { useSearchParams, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { @@ -25,16 +25,18 @@ export default function ModalDeleteOrganization() { const deleteOrganizationId = searchParams.get('deleteOrganizationId'); const { t } = useTranslation('organizations/delete'); const { platformId } = usePlatform(); + const { data: domains, isLoading } = useDomains({ + organizationId: deleteOrganizationId, + }); + const { addError, addSuccess } = useNotifications(); - const [hasDomain, setHasDomain] = useState(false); const navigate = useNavigate(); const onClose = () => navigate('..'); const { mutate: deleteOrganization, isPending: isSending } = useMutation({ - mutationFn: (organizationId: string) => { - return deleteZimbraPlatformOrganization(platformId, organizationId); - }, + mutationFn: (organizationId: string) => + deleteZimbraPlatformOrganization(platformId, organizationId), onSuccess: () => { addSuccess( { - setHasDomain(data?.length > 0); - }, [isLoading]); - return ( 0 || + isSending || + isLoading || + !deleteOrganizationId, }} > <> @@ -110,7 +108,7 @@ export default function ModalDeleteOrganization() { {t('zimbra_organization_delete_modal_content')} - {hasDomain && ( + {domains?.length > 0 && ( { - const actual: any = await importOriginal(); - return { - ...actual, - usePlatform: vi.fn(() => ({ - platformUrn: platformMock[0].iam.urn, - })), - }; -}); +import { organizationDetailMock } from '@/api/_mock_'; describe('Organizations datagrid action menu', () => { it('we have good number of item with good content', () => { const { container } = render( - , + , ); expect(container.querySelectorAll('osds-menu-item').length).toBe(2); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalAddAndEditOrganization.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalAddAndEditOrganization.spec.tsx index ebd683752c33..2f085a244cc4 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalAddAndEditOrganization.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalAddAndEditOrganization.spec.tsx @@ -2,47 +2,15 @@ import React from 'react'; import 'element-internals-polyfill'; import '@testing-library/jest-dom'; import { vi, describe, expect } from 'vitest'; -import { act } from 'react-dom/test-utils'; -import { fireEvent, render } from '@/utils/test.provider'; -import { platformMock } from '@/api/_mock_'; -import ModalAddAndEditOrganization from '../ModalAddAndEditOrganization'; +import { useSearchParams } from 'react-router-dom'; +import { fireEvent, render, act, waitFor } from '@/utils/test.provider'; +import ModalAddAndEditOrganization from '../ModalAddAndEditOrganization.page'; import organizationsAddAndEditTranslation from '@/public/translations/organizations/addAndEdit/Messages_fr_FR.json'; - -const { useSearchParamsMock } = vi.hoisted(() => ({ - useSearchParamsMock: vi.fn(() => [new URLSearchParams()]), -})); - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useGenerateUrl: vi.fn(), - useOrganization: vi.fn(() => ({ - data: null, - isLoading: false, - })), - }; -}); - -vi.mock('react-router-dom', () => ({ - useNavigate: vi.fn(), - MemoryRouter: vi.fn(() => ), - useSearchParams: useSearchParamsMock, -})); - -vi.mock('@ovh-ux/manager-react-components', () => { - return { - useNotifications: vi.fn(() => ({ - addError: () => vi.fn(), - addSuccess: () => vi.fn(), - })), - }; -}); - -afterEach(() => { - vi.restoreAllMocks(); -}); +import { organizationDetailMock } from '@/api/_mock_'; +import { + postZimbraPlatformOrganization, + putZimbraPlatformOrganization, +} from '@/api/organization'; describe('Organizations add and edit modal', () => { it('if i have not editOrganizationId params', () => { @@ -55,13 +23,13 @@ describe('Organizations add and edit modal', () => { }); it('if i have editOrganizationId params', () => { - useSearchParamsMock.mockImplementation( - vi.fn(() => [ - new URLSearchParams({ - editOrganizationId: '1903b491-4d10-4000-8b70-f474d1abe601', - }), - ]), - ); + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editOrganizationId: organizationDetailMock.id, + }), + vi.fn(), + ]); + const { getByTestId } = render(); const modal = getByTestId('modal'); expect(modal).toHaveProperty( @@ -70,8 +38,14 @@ describe('Organizations add and edit modal', () => { ); }); - it('check validity form', () => { - const { getByTestId } = render(); + it('check validity form', async () => { + const { getByTestId, queryByTestId } = render( + , + ); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); const button = getByTestId('confirm-btn'); const input1 = getByTestId('input-name'); @@ -79,8 +53,8 @@ describe('Organizations add and edit modal', () => { expect(getByTestId('confirm-btn')).not.toBeEnabled(); - act(() => { - input1.odsInputBlur.emit({ name: 'name', value: '' }); + await act(() => { + fireEvent.change(input1, { target: { value: '' } }); }); expect(input1).toHaveAttribute('color', 'error'); @@ -89,31 +63,20 @@ describe('Organizations add and edit modal', () => { organizationsAddAndEditTranslation.zimbra_organization_add_form_input_name_error, ); - act(() => { + await act(() => { fireEvent.change(input1, { target: { value: 'Name' } }); fireEvent.change(input2, { target: { value: 'Label' } }); - - // it seems we have to manually trigger the ods event - input1.odsValueChange.emit({ name: 'name', value: 'Name' }); - input2.odsValueChange.emit({ name: 'label', value: 'Label' }); }); expect(input1).toHaveAttribute('color', 'default'); expect(input2).toHaveAttribute('color', 'default'); expect(button).toBeEnabled(); - act(() => { + await act(() => { fireEvent.change(input1, { target: { value: 'Name' } }); fireEvent.change(input2, { target: { value: 'NoValidLabelWithMore12Digit' }, }); - - // it seems we have to manually trigger the ods event - input1.odsValueChange.emit({ name: 'name', value: 'Name' }); - input2.odsValueChange.emit({ - name: 'label', - value: 'NoValidLabelWithMore12Digit', - }); }); expect(input1).toHaveAttribute('color', 'default'); @@ -128,4 +91,76 @@ describe('Organizations add and edit modal', () => { expect(button).not.toBeEnabled(); }); + + it('should add a new organization', async () => { + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({}), + vi.fn(), + ]); + const { getByTestId, queryByTestId } = render( + , + ); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const button = getByTestId('confirm-btn'); + const input1 = getByTestId('input-name'); + const input2 = getByTestId('input-label'); + + expect(button).not.toBeEnabled(); + + await act(() => { + fireEvent.change(input1, { target: { value: 'Name' } }); + fireEvent.change(input2, { target: { value: 'Label' } }); + }); + + expect(input1).toHaveAttribute('color', 'default'); + expect(input2).toHaveAttribute('color', 'default'); + + expect(button).toBeEnabled(); + + await act(() => { + fireEvent.click(button); + }); + + expect(postZimbraPlatformOrganization).toHaveBeenCalledOnce(); + }); + + it('should add a new organization', async () => { + vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + editOrganizationId: organizationDetailMock.id, + }), + vi.fn(), + ]); + const { getByTestId, queryByTestId } = render( + , + ); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + const button = getByTestId('confirm-btn'); + const input1 = getByTestId('input-name'); + const input2 = getByTestId('input-label'); + + await act(() => { + fireEvent.change(input1, { target: { value: 'Name' } }); + fireEvent.change(input2, { target: { value: 'Label' } }); + }); + + expect(input1).toHaveAttribute('color', 'default'); + expect(input2).toHaveAttribute('color', 'default'); + + expect(button).toBeEnabled(); + + await act(() => { + fireEvent.click(button); + }); + + expect(putZimbraPlatformOrganization).toHaveBeenCalledOnce(); + }); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalDeleteOrganization.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalDeleteOrganization.spec.tsx index 8b93e747f8e9..4c88c8451b47 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalDeleteOrganization.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/ModalDeleteOrganization.spec.tsx @@ -2,53 +2,23 @@ import React from 'react'; import 'element-internals-polyfill'; import '@testing-library/jest-dom'; import { vi, describe, expect } from 'vitest'; -import { render } from '@/utils/test.provider'; -import { platformMock, domainMock } from '@/api/_mock_'; -import ModalDeleteOrganization from '../ModalDeleteOrganization'; +import { useSearchParams } from 'react-router-dom'; +import { render, waitFor, fireEvent, act } from '@/utils/test.provider'; +import ModalDeleteOrganization from '../ModalDeleteOrganization.component'; import organizationsDeleteTranslation from '@/public/translations/organizations/delete/Messages_fr_FR.json'; +import { organizationDetailMock } from '@/api/_mock_'; +import { deleteZimbraPlatformOrganization } from '@/api/organization'; +import { getZimbraPlatformDomains } from '@/api/domain'; -const { useDomainsMock } = vi.hoisted(() => ({ - useDomainsMock: vi.fn(() => ({ - data: domainMock, - isLoading: false, - })), -})); - -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - })), - useGenerateUrl: vi.fn(), - useDomains: useDomainsMock, - }; -}); - -vi.mock('react-router-dom', () => ({ - useNavigate: vi.fn(), - MemoryRouter: vi.fn(() => ), - useSearchParams: vi.fn(() => [ - new URLSearchParams({ - deleteOrganizationId: '1903b491-4d10-4000-8b70-f474d1abe601', - }), - ]), -})); - -vi.mock('@ovh-ux/manager-react-components', () => { - return { - useNotifications: vi.fn(() => ({ - addError: () => vi.fn(), - addSuccess: () => vi.fn(), - })), - }; -}); - -afterEach(() => { - vi.restoreAllMocks(); -}); +vi.mocked(useSearchParams).mockReturnValue([ + new URLSearchParams({ + deleteOrganizationId: organizationDetailMock.id, + }), + vi.fn(), +]); describe('Organizations delete modal', () => { - it('check if it is displayed', () => { + it('should render modal', () => { const { getByTestId } = render(); const modal = getByTestId('modal'); expect(modal).toHaveProperty( @@ -57,21 +27,33 @@ describe('Organizations delete modal', () => { ); }); - it('if there is domain in organization', () => { - const { getByTestId } = render(); + it('should have button disabled if domains', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + expect(getByTestId('banner-message')).toBeVisible(); expect(getByTestId('delete-btn')).toBeDisabled(); }); - it('if there is not domain in organization', () => { - useDomainsMock.mockImplementation( - vi.fn(() => ({ - data: [], - isLoading: false, - })), - ); + it('should delete org if no domains and clicked', async () => { + vi.mocked(getZimbraPlatformDomains).mockReturnValue({ data: [] }); + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + expect(queryByTestId('banner-message')).toBeNull(); expect(getByTestId('delete-btn')).not.toBeDisabled(); + + await act(() => { + fireEvent.click(getByTestId('delete-btn')); + }); + + expect(deleteZimbraPlatformOrganization).toHaveBeenCalledOnce(); }); }); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/Organizations.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/Organizations.spec.tsx index ff86d96dc3ac..4f19e80f7006 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/Organizations.spec.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/__test__/Organizations.spec.tsx @@ -1,46 +1,23 @@ import React from 'react'; import { vi, describe, expect } from 'vitest'; import Organizations from '../Organizations'; -import { render } from '@/utils/test.provider'; +import { render, waitFor } from '@/utils/test.provider'; import organizationsTranslation from '@/public/translations/organizations/Messages_fr_FR.json'; -import { organizationListMock, platformMock } from '@/api/_mock_'; +import { useGenerateUrl } from '@/hooks'; -vi.mock('@/hooks', () => { - return { - usePlatform: vi.fn(() => ({ - platformId: platformMock[0].id, - platformUrn: platformMock[0].iam.urn, - })), - useOrganizationList: vi.fn(() => ({ - data: organizationListMock, - })), - useGenerateUrl: vi.fn( - () => '#/00000000-0000-0000-0000-000000000001/organizations/add?', - ), - }; -}); - -vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { - const actual: any = await importOriginal(); - return { - ...actual, - Notifications: vi.fn().mockReturnValue(
Notifications
), - Datagrid: vi.fn().mockReturnValue(
Datagrid
), - }; -}); - -afterEach(() => { - vi.clearAllMocks(); -}); +const addUrl = '#/00000000-0000-0000-0000-000000000001/organizations/add?'; describe('Organizations page', () => { - it('Page should display correctly', () => { + it('Page should display correctly', async () => { + vi.mocked(useGenerateUrl).mockReturnValue(addUrl); const { getByTestId } = render(); + + await waitFor(() => { + expect(getByTestId('add-organization-btn')).toBeInTheDocument(); + }); + const button = getByTestId('add-organization-btn'); - expect(button).toHaveAttribute( - 'href', - '#/00000000-0000-0000-0000-000000000001/organizations/add?', - ); + expect(button).toHaveAttribute('href', addUrl); expect(button).toHaveTextContent( organizationsTranslation.add_organisation_cta, ); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx new file mode 100644 index 000000000000..8913db0808df --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ActionMenu } from '@ovh-ux/manager-react-components'; +import { useSearchParams } from 'react-router-dom'; +import { RedirectionsItem } from './Redirections'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { ResourceStatus } from '@/api/api.type'; +import { FEATURE_FLAGS } from '@/utils'; + +interface ActionButtonRedirectionsAccountProps { + redirectionsItem: RedirectionsItem; +} + +const ActionButtonRedirections: React.FC = ({ + redirectionsItem, +}) => { + const { t } = useTranslation('redirections'); + const { platformUrn } = usePlatform(); + + const [searchParams] = useSearchParams(); + const params = Object.fromEntries(searchParams.entries()); + + const hrefEditRedirections = useGenerateUrl('./edit', 'href', { + editRedirectionId: redirectionsItem.id, + ...params, + }); + + const hrefDeleteRedirections = useGenerateUrl('./delete', 'href', { + deleteRedirectionId: redirectionsItem.id, + ...params, + }); + + const actionItems = [ + { + id: 1, + href: hrefEditRedirections, + urn: platformUrn, + iamActions: [IAM_ACTIONS.redirection.edit], + label: t('zimbra_redirections_datagrid_tooltip_modification'), + hidden: !FEATURE_FLAGS.REDIRECTIONS_EDIT, + }, + { + id: 2, + href: hrefDeleteRedirections, + urn: platformUrn, + iamActions: [IAM_ACTIONS.redirection.delete], + label: t('zimbra_redirections_datagrid_tooltip_delete'), + }, + ]; + return ( + !i.hidden)} + isCompact + /> + ); +}; + +export default ActionButtonRedirections; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx new file mode 100644 index 000000000000..089e94627ce6 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx @@ -0,0 +1,339 @@ +import React, { useState } from 'react'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { + ODS_THEME_COLOR_INTENT, + ODS_THEME_TYPOGRAPHY_LEVEL, + ODS_THEME_TYPOGRAPHY_SIZE, +} from '@ovhcloud/ods-common-theming'; +import { + OsdsCheckboxButton, + OsdsFormField, + OsdsInput, + OsdsSelect, + OsdsSelectOption, + OsdsText, +} from '@ovhcloud/ods-components/react'; +import { useTranslation } from 'react-i18next'; +import { + ODS_CHECKBOX_BUTTON_SIZE, + ODS_INPUT_SIZE, + ODS_INPUT_TYPE, +} from '@ovhcloud/ods-components'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import Modal from '@/components/Modals/Modal'; +import { useAccount, useDomains, useGenerateUrl } from '@/hooks'; +import { + FormTypeInterface, + FormInputRegexInterface, + checkValidityField, + checkValidityForm, + ACCOUNT_REGEX, + EMAIL_REGEX, +} from '@/utils'; +import Loading from '@/components/Loading/Loading'; + +export default function ModalAddAndEditRedirections() { + const { t } = useTranslation('redirections/addAndEdit'); + const navigate = useNavigate(); + + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const editRedirectionId = searchParams.get('editRedirectionId'); + const params = Object.fromEntries(searchParams.entries()); + delete params.editRedirectionId; + + const goBackUrl = useGenerateUrl('..', 'path', params); + const onClose = () => navigate(goBackUrl); + + const { addError, addSuccess } = useNotifications(); + const [isFormValid, setIsFormValid] = useState(false); + + const { data: domainList, isLoading: isLoadingDomain } = useDomains({ + enabled: !editEmailAccountId && !editRedirectionId, + }); + + const { data: accountDetail, isLoading: isLoadingAccount } = useAccount({ + accountId: editEmailAccountId, + enabled: !!editEmailAccountId, + }); + + const formInputRegex: FormInputRegexInterface = { + account: ACCOUNT_REGEX, + to: EMAIL_REGEX, + }; + + const [form, setForm] = useState({ + account: { + value: '', + touched: false, + hasError: false, + required: !editEmailAccountId, + }, + domain: { + value: '', + touched: false, + hasError: false, + required: !editEmailAccountId, + }, + to: { + value: '', + touched: false, + hasError: false, + required: true, + }, + checked: { + value: '', + touched: false, + hasError: false, + required: false, + }, + }); + + const handleFormChange = (name: string, value: string) => { + const newForm: FormTypeInterface = form; + newForm[name] = { + value, + touched: true, + required: form[name].required, + hasError: !checkValidityField(name, value, formInputRegex, form), + }; + setForm((oldForm) => ({ ...oldForm, ...newForm })); + setIsFormValid(checkValidityForm(form)); + }; + + /* const getDataBody = useCallback( + (formRef: FormTypeInterface) => { + const { + account: { value: account }, + domain: { value: domain }, + } = form; + + let dataBody: Record = {}; + + dataBody.from = + account && domain + ? `${account}@${domain}` + : accountDetail?.currentState.email; + + Object.entries(formRef).forEach(([key, { value }]) => { + if (!['account', 'domain'].includes(key)) { + dataBody = { ...dataBody, [key]: value }; + } + }); + + dataBody.checked = dataBody?.checked === 'checked'; + + return dataBody; + }, + [form], + ); */ + + const handleClickConfirm = () => { + if (isFormValid) { + addSuccess( + t( + editRedirectionId + ? 'zimbra_redirections_edit_success' + : 'zimbra_redirections_add_success', + ), + ); + } else { + addError( + t( + editRedirectionId + ? 'zimbra_redirections_edit_error' + : 'zimbra_redirections_add_error', + ), + ); + } + onClose(); + }; + + return ( + + <> + +
{t('zimbra_redirections_edit_1')}
+
+ +
{t('zimbra_redirections_edit_2')}
+
+ + +
+ + {t('zimbra_redirections_add_form_input_name_title_from')} * + +
+ {editEmailAccountId || editRedirectionId ? ( + + ) : ( + <> +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => { + handleFormChange(name, value); + }} + required + className="rounded-r-none border-r-0 w-1/2" + data-testid="input-account" + > + + + handleFormChange(name, value as string) + } + > + + {t('zimbra_redirections_add_select_domain_placeholder')} + + {domainList?.map(({ currentState: domain }) => ( + + {domain.name} + + ))} + +
+ {isLoadingDomain && ( +
+ +
+ )} + + )} +
+ +
+ + {t('zimbra_redirections_add_form_input_name_title_to')} * + +
+ + handleFormChange(name, value.toString()) + } + onOdsValueChange={({ detail: { name, value } }) => + handleFormChange(name, value) + } + required + /> +
+ + + + handleFormChange( + 'checked', + form.checked.value === 'checked' ? '' : 'checked', + ) + } + > + + + {t('zimbra_redirections_add_form_input_checkbox')} + + + + + +
+ ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx new file mode 100644 index 000000000000..f842dbb31331 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { OsdsText } from '@ovhcloud/ods-components/react'; +import { + ODS_TEXT_COLOR_HUE, + ODS_TEXT_LEVEL, + ODS_TEXT_SIZE, +} from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import Modal from '@/components/Modals/Modal'; +import { useGenerateUrl } from '@/hooks'; + +export default function ModalDeleteRedirections() { + const { t } = useTranslation('redirections/delete'); + const navigate = useNavigate(); + + const [searchParams] = useSearchParams(); + const params = Object.fromEntries(searchParams.entries()); + delete params.deleteRedirectionId; + + const goBackUrl = useGenerateUrl('..', 'path', params); + const goBack = () => navigate(goBackUrl); + + const buttonProps = { + color: ODS_THEME_COLOR_INTENT.primary, + action: goBack, + }; + + return ( + + <> + + {t('zimbra_redirections_delete_modal_content')} + + + + {t('zimbra_redirections_delete_modal_from')} + + + + {t('zimbra_redirections_delete_modal_to')} + + + + ); +} diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/Redirections.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/Redirections.tsx new file mode 100644 index 000000000000..36492e33fa1d --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/Redirections.tsx @@ -0,0 +1,137 @@ +import React from 'react'; +import { + Datagrid, + DatagridColumn, + ManagerButton, + Notifications, + Subtitle, +} from '@ovh-ux/manager-react-components'; +import { useTranslation } from 'react-i18next'; +import { Outlet, useSearchParams } from 'react-router-dom'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { + ODS_BUTTON_SIZE, + ODS_ICON_NAME, + ODS_ICON_SIZE, +} from '@ovhcloud/ods-components'; +import { OsdsIcon } from '@ovhcloud/ods-components/react'; +import ActionButtonRedirections from './ActionButtonRedirections.component'; +import { useGenerateUrl, usePlatform } from '@/hooks'; +import { IAM_ACTIONS } from '@/utils/iamAction.constants'; +import { ResourceStatus } from '@/api/api.type'; +import Loading from '@/components/Loading/Loading'; + +export type RedirectionsItem = { + id: string; + from: string; + to: string; + organization: string; + status: ResourceStatus; +}; + +const items: RedirectionsItem[] = [ + { + status: ResourceStatus.ERROR, + from: 'from@example.com', + to: 'to@example.com', + organization: 'Test Organization', + id: '1', + }, + { + status: ResourceStatus.READY, + from: 'from@example.com', + to: 'to2@example.com', + organization: 'Test Organization', + id: '2', + }, +]; + +const columns: DatagridColumn[] = [ + { + id: 'from', + cell: (item) =>
{item.from}
, + label: 'zimbra_redirections_from', + }, + { + id: 'to', + cell: (item) =>
{item.to}
, + label: 'zimbra_redirections_to', + }, + { + id: 'organization', + cell: (item) =>
{item.organization}
, + label: 'zimbra_redirections_organization', + }, + { + id: 'tooltip', + cell: (item) => ( + + ), + label: '', + }, +]; + +export function Redirections() { + const { t } = useTranslation('redirections'); + const { platformUrn } = usePlatform(); + const [searchParams] = useSearchParams(); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + const hrefAddRedirection = useGenerateUrl('./add', 'href'); + // to update + const isLoading = false; + + return ( +
+ {!editEmailAccountId && } + + {platformUrn && ( + <> + {editEmailAccountId && ( +
+ {t('zimbra_redirections_account_title')} +
+ )} +
+ + + + + {t('zimbra_redirections_cta')} + +
+ {isLoading ? ( + + ) : ( + ({ + ...column, + label: t(column.label), + }))} + items={items} + totalItems={items.length} + /> + )} + + )} +
+ ); +} + +export default Redirections; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ActionButtonRedirections.component.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ActionButtonRedirections.component.spec.tsx new file mode 100644 index 000000000000..9cc0a247f5a9 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ActionButtonRedirections.component.spec.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import ActionButtonRedirections from '../ActionButtonRedirections.component'; +import { render } from '@/utils/test.provider'; +import { FEATURE_FLAGS } from '@/utils'; +import redirectionsTranslation from '@/public/translations/redirections/Messages_fr_FR.json'; +import { ResourceStatus } from '@/api/api.type'; + +describe('Redirections datagrid action menu', () => { + it('renders with menu enabled and 2 items', () => { + const { container } = render( + , + ); + + if (FEATURE_FLAGS.REDIRECTIONS_EDIT) { + expect(container.querySelectorAll('osds-menu-item').length).toBe(2); + + expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + redirectionsTranslation.zimbra_redirections_datagrid_tooltip_modification, + ); + + expect(container.querySelectorAll('osds-menu-item')[1]).toHaveTextContent( + redirectionsTranslation.zimbra_redirections_datagrid_tooltip_delete, + ); + } else { + expect(container.querySelectorAll('osds-menu-item').length).toBe(1); + + expect(container.querySelectorAll('osds-menu-item')[0]).toHaveTextContent( + redirectionsTranslation.zimbra_redirections_datagrid_tooltip_delete, + ); + } + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalAddAndEditRedirections.page.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalAddAndEditRedirections.page.spec.tsx new file mode 100644 index 000000000000..25b0339e4cbb --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalAddAndEditRedirections.page.spec.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { describe, expect, it } from 'vitest'; +import { act } from 'react-dom/test-utils'; +import ModalAddAndEditRedirections from '../ModalAddAndEditRedirections.page'; +import { render, fireEvent } from '@/utils/test.provider'; + +describe('ModalAddAndEditRedirections Component', () => { + it('should render and enable the confirm button when form is valid', async () => { + const { getByTestId } = render(); + + const confirmButton = getByTestId('confirm-btn'); + const checkbox = getByTestId('field-checkbox'); + const inputAccount = getByTestId('input-account'); + const selectDomain = getByTestId('select-domain'); + const inputTo = getByTestId('input-to'); + + expect(confirmButton).toBeDisabled(); + + act(() => { + inputAccount.odsValueChange.emit({ name: 'account', value: '' }); + selectDomain.odsValueChange.emit({ name: 'domain', value: '' }); + inputTo.odsValueChange.emit({ name: 'to', value: '' }); + }); + + expect(inputAccount).toHaveAttribute('color', 'error'); + expect(inputTo).toHaveAttribute('color', 'error'); + + expect(confirmButton).toBeDisabled(); + + act(() => { + inputAccount.odsValueChange.emit({ name: 'account', value: 'account' }); + selectDomain.odsValueChange.emit({ name: 'domain', value: 'domain' }); + inputTo.odsValueChange.emit({ name: 'to', value: 'test@test.fr' }); + }); + + expect(inputAccount).toHaveAttribute('color', 'default'); + expect(inputTo).toHaveAttribute('color', 'default'); + + expect(confirmButton).toBeEnabled(); + + act(() => { + fireEvent.click(checkbox); + }); + + expect(confirmButton).toBeEnabled(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalDeleteRedirections.component.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalDeleteRedirections.component.spec.tsx new file mode 100644 index 000000000000..d2632980e680 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/ModalDeleteRedirections.component.spec.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { describe, expect, it } from 'vitest'; +import ModalDeleteRedirections from '../ModalDeleteRedirections.component'; +import { render, fireEvent, screen } from '@/utils/test.provider'; + +describe('ModalDeleteRedirections Component', () => { + it('should render correctly', () => { + render(); + expect(screen.getByTestId('cancel-btn')).toBeInTheDocument(); + expect(screen.getByTestId('delete-btn')).toBeInTheDocument(); + + const cancelButton = screen.getByTestId('cancel-btn'); + const deleteButton = screen.getByTestId('delete-btn'); + + expect(cancelButton).not.toBeDisabled(); + expect(deleteButton).not.toBeDisabled(); + }); + + it('should trigger the correct action on cancel', () => { + render(); + const cancelButton = screen.getByTestId('cancel-btn'); + fireEvent.click(cancelButton); + }); + + it('should trigger the correct action on delete', () => { + render(); + const deleteButton = screen.getByTestId('delete-btn'); + fireEvent.click(deleteButton); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/Redirections.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/Redirections.spec.tsx new file mode 100644 index 000000000000..2e203dfa87d9 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/__test__/Redirections.spec.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import { waitFor } from '@testing-library/dom'; +import Redirections from '../Redirections'; +import { render } from '@/utils/test.provider'; +import redirectionsTranslation from '@/public/translations/redirections/Messages_fr_FR.json'; + +describe('Redirections page', () => { + it('should display page correctly', async () => { + const { getByTestId } = render(); + + await waitFor(() => { + const button = getByTestId('add-redirection-btn'); + expect(button).toHaveTextContent( + redirectionsTranslation.zimbra_redirections_cta, + ); + }); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/__test__/_layout.spec.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/__test__/_layout.spec.tsx new file mode 100644 index 000000000000..340a4d4ec9b0 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/dashboard/__test__/_layout.spec.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { describe, expect } from 'vitest'; +import Layout from '../_layout'; +import { render, waitFor } from '@/utils/test.provider'; + +describe('Layout dashboard', () => { + it('should render correctly', async () => { + const { getByTestId, queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('spinner')).toBeNull(); + }); + + expect(getByTestId('breadcrumb')).toBeVisible(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/pages/onboarding/__test__/index.spec.tsx b/packages/manager/apps/zimbra/src/pages/onboarding/__test__/index.spec.tsx new file mode 100644 index 000000000000..6990664020c8 --- /dev/null +++ b/packages/manager/apps/zimbra/src/pages/onboarding/__test__/index.spec.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { describe, expect, vi } from 'vitest'; +import Onboarding from '../index'; +import { render, act, fireEvent } from '@/utils/test.provider'; +import onboardingTranslation from '@/public/translations/onboarding/Messages_fr_FR.json'; + +describe('Onboarding page', () => { + it('should display page correctly', async () => { + const { findByText } = render(); + + const title = await findByText(onboardingTranslation.title); + expect(title).toBeVisible(); + }); + + it('should call window open on click', async () => { + const { findByText } = render(); + + const spy = vi.spyOn(window, 'open'); + + const button = await findByText(onboardingTranslation.orderButtonLabel); + + await act(() => { + fireEvent.click(button); + }); + + expect(spy).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/manager/apps/zimbra/src/routes/routes.constants.ts b/packages/manager/apps/zimbra/src/routes/routes.constants.ts index 1262570a2e18..ec6aae1e1864 100644 --- a/packages/manager/apps/zimbra/src/routes/routes.constants.ts +++ b/packages/manager/apps/zimbra/src/routes/routes.constants.ts @@ -6,5 +6,32 @@ export const urls = { organizations: '/:serviceName/organizations', organizationsDelete: '/:serviceName/organizations/delete', domains: '/:serviceName/domains', + domainsEdit: '/:serviceName/domains/edit', + domainsDelete: '/:serviceName/domains/delete', + domains_diagnostic: '/:serviceName/domains/diagnostic', email_accounts: '/:serviceName/email_accounts', + email_accounts_add: '/:serviceName/email_accounts/add', + email_accounts_edit: '/:serviceName/email_accounts/settings', + email_accounts_alias: '/:serviceName/email_accounts/alias', + email_accounts_alias_add: '/:serviceName/email_accounts/alias/add', + email_accounts_alias_delete: '/:serviceName/email_accounts/alias/delete', + email_accounts_redirections: '/:serviceName/email_accounts/redirections', + email_accounts_redirections_add: + '/:serviceName/email_accounts/redirections/add', + email_accounts_redirections_edit: + '/:serviceName/email_accounts/redirections/edit', + email_accounts_redirections_delete: + '/:serviceName/email_accounts/redirections/delete', + mailing_lists: '/:serviceName/mailing_lists', + mailing_lists_add: '/:serviceName/mailing_lists/add', + mailing_lists_edit: '/:serviceName/mailing_lists/edit', + mailing_lists_delete: '/:serviceName/mailing_lists/delete', + mailing_lists_configure_delegation: + '/:serviceName/mailing_lists/configure_delegation', + mailing_lists_define_members: '/:serviceName/mailing_lists/define_members', + redirections: '/:serviceName/redirections', + redirections_add: '/:serviceName/redirections/add', + redirections_edit: '/:serviceName/redirections/edit', + redirections_delete: '/:serviceName/redirections/delete', + auto_replies: '/:serviceName/auto_replies', }; diff --git a/packages/manager/apps/zimbra/src/routes/routes.tsx b/packages/manager/apps/zimbra/src/routes/routes.tsx index 2d3604f78a74..0ea36f3af209 100644 --- a/packages/manager/apps/zimbra/src/routes/routes.tsx +++ b/packages/manager/apps/zimbra/src/routes/routes.tsx @@ -39,7 +39,7 @@ export const Routes: any = [ path: 'add', ...lazyRouteConfig(() => import( - '@/pages/dashboard/Organizations/ModalAddAndEditOrganization' + '@/pages/dashboard/Organizations/ModalAddAndEditOrganization.page' ), ), }, @@ -47,7 +47,7 @@ export const Routes: any = [ path: 'edit', ...lazyRouteConfig(() => import( - '@/pages/dashboard/Organizations/ModalAddAndEditOrganization' + '@/pages/dashboard/Organizations/ModalAddAndEditOrganization.page' ), ), }, @@ -55,7 +55,7 @@ export const Routes: any = [ path: 'delete', ...lazyRouteConfig(() => import( - '@/pages/dashboard/Organizations/ModalDeleteOrganization' + '@/pages/dashboard/Organizations/ModalDeleteOrganization.component' ), ), }, @@ -70,14 +70,30 @@ export const Routes: any = [ { path: 'add', ...lazyRouteConfig(() => - import('@/pages/dashboard/Domains/AddDomain'), + import('@/pages/dashboard/Domains/AddDomain.page'), ), handle: { isOverridePage: true }, }, + { + path: 'edit', + ...lazyRouteConfig(() => + import('@/pages/dashboard/Domains/ModalEditDomain.component'), + ), + }, { path: 'delete', ...lazyRouteConfig(() => - import('@/pages/dashboard/Domains/ModalDeleteDomain'), + import( + '@/pages/dashboard/Domains/ModalDeleteDomain.component' + ), + ), + }, + { + path: 'diagnostic', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/Domains/ModalDiagnosticDnsRecord.component' + ), ), }, ], @@ -92,7 +108,129 @@ export const Routes: any = [ path: 'add', ...lazyRouteConfig(() => import( - '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount' + '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' + ), + ), + handle: { isOverridePage: true }, + }, + { + path: 'settings', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' + ), + ), + handle: { isOverridePage: true }, + }, + { + path: 'alias', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' + ), + ), + handle: { isOverridePage: true }, + children: [ + { + path: 'add', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/ModalAddAlias.component' + ), + ), + }, + { + path: 'delete', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/ModalDeleteAlias.component' + ), + ), + }, + ], + }, + { + path: 'redirections', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' + ), + ), + handle: { isOverridePage: true }, + children: [ + { + path: 'add', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' + ), + ), + }, + { + path: 'edit', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' + ), + ), + }, + { + path: 'delete', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/Redirections/ModalDeleteRedirections.component' + ), + ), + }, + ], + }, + { + path: 'delete', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.component' + ), + ), + }, + ], + }, + { + path: 'mailing_lists', + ...lazyRouteConfig(() => + import('@/pages/dashboard/MailingLists/MailingLists'), + ), + children: [ + { + path: 'add', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/MailingLists/AddAndEditMailingList.page' + ), + ), + handle: { isOverridePage: true }, + }, + { + path: 'settings', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/MailingLists/AddAndEditMailingList.page' + ), + ), + handle: { isOverridePage: true }, + }, + ], + }, + { + path: 'redirections', + ...lazyRouteConfig(() => + import('@/pages/dashboard/Redirections/Redirections'), + ), + children: [ + { + path: 'add', + ...lazyRouteConfig(() => + import( + '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), handle: { isOverridePage: true }, @@ -101,7 +239,7 @@ export const Routes: any = [ path: 'edit', ...lazyRouteConfig(() => import( - '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount' + '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), handle: { isOverridePage: true }, @@ -110,14 +248,22 @@ export const Routes: any = [ path: 'delete', ...lazyRouteConfig(() => import( - '@/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount' + '@/pages/dashboard/Redirections/ModalDeleteRedirections.component' ), ), + handle: { isOverridePage: true }, }, ], }, + { + path: 'auto_replies', + ...lazyRouteConfig(() => + import('@/pages/dashboard/AutoReplies/AutoReplies'), + ), + }, ], }, + { path: 'onboarding', ...lazyRouteConfig(() => import('@/pages/onboarding')), diff --git a/packages/manager/apps/zimbra/src/utils/dnsconfig.constants.ts b/packages/manager/apps/zimbra/src/utils/dnsconfig.constants.ts new file mode 100644 index 000000000000..0dd1b1448434 --- /dev/null +++ b/packages/manager/apps/zimbra/src/utils/dnsconfig.constants.ts @@ -0,0 +1,34 @@ +export const DNS_CONFIG_TYPE = { + STANDARD: 'standard', + EXPERT: 'expert', +}; + +export enum DnsRecordType { + SRV = 'SRV', + MX = 'MX', + SPF = 'SPF', + DKIM = 'DKIM', +} + +export enum DnsRecordTypeKey { + SRV = 'srv', + MX = 'mx', + SPF = 'spf', + DKIM = 'dkim', + NONE = 'none', +} + +export const getDnsRecordTypeKeyFromDnsRecordType = ( + type: DnsRecordType, +): DnsRecordTypeKey => { + switch (type) { + case DnsRecordType.SRV: + return DnsRecordTypeKey.SRV; + case DnsRecordType.SPF: + return DnsRecordTypeKey.SPF; + case DnsRecordType.MX: + return DnsRecordTypeKey.MX; + default: + return DnsRecordTypeKey.NONE; + } +}; diff --git a/packages/manager/apps/zimbra/src/utils/form.ts b/packages/manager/apps/zimbra/src/utils/form.ts new file mode 100644 index 000000000000..e62b67c69c29 --- /dev/null +++ b/packages/manager/apps/zimbra/src/utils/form.ts @@ -0,0 +1,38 @@ +export type FieldType = { + value: string; + touched: boolean; + hasError?: boolean; + required?: boolean; +}; + +export interface FormTypeInterface { + [key: string]: FieldType; +} + +export interface FormInputRegexInterface { + [key: string]: RegExp; +} + +export const checkValidityField = ( + name: string, + value: string, + formInputRegex: FormInputRegexInterface, + form: FormTypeInterface, +) => { + return formInputRegex[name] + ? formInputRegex[name].test(value) || + (!form[name].required && form[name].value === '') + : true; +}; + +export const checkValidityForm = (form: FormTypeInterface) => { + const touched = Object.values(form).find((field) => field.touched); + const error = Object.values(form).find( + (field) => field.hasError || (field.required && field.value === ''), + ); + return touched && !error; +}; + +export const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + +export const ACCOUNT_REGEX = /^(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*)(?:(?:[.|+])(?:[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*))*$/; diff --git a/packages/manager/apps/zimbra/src/utils/iamAction.constants.ts b/packages/manager/apps/zimbra/src/utils/iamAction.constants.ts index 76d37c4a144c..a678e8f37993 100644 --- a/packages/manager/apps/zimbra/src/utils/iamAction.constants.ts +++ b/packages/manager/apps/zimbra/src/utils/iamAction.constants.ts @@ -7,15 +7,30 @@ export const IAM_ACTIONS = { edit: `${IAM_ACTIONS_PREFIX}account/edit`, get: `${IAM_ACTIONS_PREFIX}account/get`, }, + alias: { + create: `${IAM_ACTIONS_PREFIX}alias/create`, + delete: `${IAM_ACTIONS_PREFIX}alias/delete`, + }, domain: { create: `${IAM_ACTIONS_PREFIX}domain/create`, delete: `${IAM_ACTIONS_PREFIX}domain/delete`, + edit: `${IAM_ACTIONS_PREFIX}domain/edit`, + }, + mailingList: { + create: `${IAM_ACTIONS_PREFIX}mailingList/create`, + delete: `${IAM_ACTIONS_PREFIX}mailingList/delete`, + edit: `${IAM_ACTIONS_PREFIX}mailingList/edit`, }, organization: { create: `${IAM_ACTIONS_PREFIX}organization/create`, delete: `${IAM_ACTIONS_PREFIX}organization/delete`, edit: `${IAM_ACTIONS_PREFIX}organization/edit`, }, + redirection: { + create: `${IAM_ACTIONS_PREFIX}redirection/create`, + delete: `${IAM_ACTIONS_PREFIX}redirection/delete`, + edit: `${IAM_ACTIONS_PREFIX}redirection/edit`, + }, platform: { get: `${IAM_ACTIONS_PREFIX}get`, }, diff --git a/packages/manager/apps/zimbra/src/utils/index.ts b/packages/manager/apps/zimbra/src/utils/index.ts index 47c99dd804b7..78cca26bb980 100644 --- a/packages/manager/apps/zimbra/src/utils/index.ts +++ b/packages/manager/apps/zimbra/src/utils/index.ts @@ -1,4 +1,17 @@ export * from './convertOctets'; +export * from './dnsconfig.constants'; +export * from './form'; export const DATAGRID_REFRESH_INTERVAL = 5_000; export const DATAGRID_REFRESH_ON_MOUNT = 'always'; +export const FEATURE_FLAGS = { + ALIAS: false, + REDIRECTIONS: false, + REDIRECTIONS_EDIT: false, + AUTOREPLIES: false, + MAILINGLISTS: false, + DOMAIN_DIAGNOSTICS: false, + DOMAIN_DNS_CONFIGURATION: false, + DOMAIN_NOT_OVH: false, + ORDER: false, +}; diff --git a/packages/manager/apps/zimbra/src/utils/test.provider.tsx b/packages/manager/apps/zimbra/src/utils/test.provider.tsx index 4b23d1336e2a..73a0afa2c379 100644 --- a/packages/manager/apps/zimbra/src/utils/test.provider.tsx +++ b/packages/manager/apps/zimbra/src/utils/test.provider.tsx @@ -3,18 +3,32 @@ import i18n from 'i18next'; import React, { ComponentType } from 'react'; import { I18nextProvider, initReactI18next } from 'react-i18next'; import { MemoryRouter } from 'react-router-dom'; -import { QueryClientProvider } from '@tanstack/react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { + ShellContext, + ShellContextType, +} from '@ovh-ux/manager-react-shell-client'; import dashboardTranslation from '@/public/translations/dashboard/Messages_fr_FR.json'; import organizationsTranslation from '@/public/translations/organizations/Messages_fr_FR.json'; import organizationsAddAndEditTranslation from '@/public/translations/organizations/addAndEdit/Messages_fr_FR.json'; import organizationsDeleteTranslation from '@/public/translations/organizations/delete/Messages_fr_FR.json'; import domainsTranslation from '@/public/translations/domains/Messages_fr_FR.json'; import domainsAddDomainTranslation from '@/public/translations/domains/addDomain/Messages_fr_FR.json'; +import domainsEditTranslation from '@/public/translations/domains/edit/Messages_fr_FR.json'; import domainsDeleteTranslation from '@/public/translations/domains/delete/Messages_fr_FR.json'; +import domainsDiagnosticTranslation from '@/public/translations/domains/diagnostic/Messages_fr_FR.json'; import accountTranslation from '@/public/translations/accounts/Messages_fr_FR.json'; import accountAddAndEditTranslation from '@/public/translations/accounts/addAndEdit/Messages_fr_FR.json'; +import accountAliasTranslation from '@/public/translations/accounts/alias/Messages_fr_FR.json'; +import accountAliasAddTranslation from '@/public/translations/accounts/alias/add/Messages_fr_FR.json'; +import accountAliasDeleteTranslation from '@/public/translations/accounts/alias/delete/Messages_fr_FR.json'; import accountDeleteTranslation from '@/public/translations/accounts/delete/Messages_fr_FR.json'; -import queryClient from '@/queryClient'; +import mailingListsTranslation from '@/public/translations/mailinglists/Messages_fr_FR.json'; +import mailingListsAddAndEditTranslation from '@/public/translations/mailinglists/addAndEdit/Messages_fr_FR.json'; +import redirectionsTranslation from '@/public/translations/redirections/Messages_fr_FR.json'; +import redirectionsAddAndEditTranslation from '@/public/translations/redirections/addAndEdit/Messages_fr_FR.json'; +import redirectionsDeleteTranslation from '@/public/translations/redirections/delete/Messages_fr_FR.json'; +import onboardingTranslation from '@/public/translations/onboarding/Messages_fr_FR.json'; import '@testing-library/jest-dom'; import 'element-internals-polyfill'; @@ -29,21 +43,73 @@ i18n.use(initReactI18next).init({ 'organizations/delete': organizationsDeleteTranslation, domains: domainsTranslation, 'domains/addDomain': domainsAddDomainTranslation, + 'domains/edit': domainsEditTranslation, 'domains/delete': domainsDeleteTranslation, + 'domains/diagnostic': domainsDiagnosticTranslation, accounts: accountTranslation, 'accounts/addAndEdit': accountAddAndEditTranslation, + 'accounts/alias': accountAliasTranslation, + 'accounts/alias/add': accountAliasAddTranslation, + 'accounts/alias/delete': accountAliasDeleteTranslation, 'accounts/delete': accountDeleteTranslation, + mailinglists: mailingListsTranslation, + 'mailinglists/addAndEdit': mailingListsAddAndEditTranslation, + redirections: redirectionsTranslation, + 'redirections/addAndEdit': redirectionsAddAndEditTranslation, + 'redirections/delete': redirectionsDeleteTranslation, + onboarding: onboardingTranslation, }, }, ns: ['dashboard'], }); -const Wrappers = ({ children }: { children: React.ReactNode }) => { +export const getShellContext = () => { + return { + environment: { + getUser: () => ({ + ovhSubsidiary: 'FR', + }), + }, + shell: { + routing: { + onHashChange: () => undefined, + stopListenForHashChange: () => undefined, + listenForHashChange: () => undefined, + }, + }, + } as ShellContextType; +}; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}); + +export const wrapper = ({ children }: { children: React.ReactNode }) => { return ( - - {children} - + + {children} + + + ); +}; + +export const wrapperWithI18n = ({ + children, +}: { + children: React.ReactNode; +}) => { + return ( + + + + {children} + + ); }; @@ -52,8 +118,7 @@ const customRender = ( ui: React.JSX.Element, options?: Omit, ): RenderResult => - render(ui, { wrapper: Wrappers as ComponentType, ...options }); + render(ui, { wrapper: wrapperWithI18n as ComponentType, ...options }); export * from '@testing-library/react'; - export { customRender as render }; diff --git a/packages/manager/apps/zimbra/src/utils/test.setup.tsx b/packages/manager/apps/zimbra/src/utils/test.setup.tsx new file mode 100644 index 000000000000..24fac8758bd0 --- /dev/null +++ b/packages/manager/apps/zimbra/src/utils/test.setup.tsx @@ -0,0 +1,194 @@ +import { vi } from 'vitest'; +import { + accountsMock, + domainsMock, + mailingListsMock, + organizationListMock, + platformMock, + taskMocks, + aliasMock, + domainZone, +} from '@/api/_mock_'; +import { AccountType } from '@/api/account'; +import { DomainType } from '@/api/domain'; + +const mocksAxios = vi.hoisted(() => ({ + get: vi.fn(), + post: vi.fn(), + put: vi.fn(), + delete: vi.fn(), +})); + +vi.mock('axios', async (importActual) => { + const actual = await importActual(); + + const mockAxios = { + default: { + ...actual.default, + get: mocksAxios.get, + post: mocksAxios.post, + put: mocksAxios.put, + delete: mocksAxios.delete, + create: vi.fn(() => ({ + ...actual.default.create(), + get: mocksAxios.get, + post: mocksAxios.post, + put: mocksAxios.put, + delete: mocksAxios.delete, + })), + }, + }; + + return mockAxios; +}); + +vi.mock('@/hooks', async (importActual) => { + return { + ...(await importActual()), + useGenerateUrl: vi.fn(), + }; +}); + +vi.mock('@/api/account', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformAccountDetail: vi.fn((_platformId, accountId) => { + return Promise.resolve( + accountsMock.find((acc: AccountType) => acc.id === accountId), + ); + }), + getZimbraPlatformAccounts: vi.fn(() => { + return Promise.resolve({ + data: accountsMock, + }); + }), + deleteZimbraPlatformAccount: vi.fn(() => { + return Promise.resolve(); + }), + }; +}); + +vi.mock('@/api/domain', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformDomainDetail: vi.fn((_platformId, domainId) => { + return Promise.resolve( + domainsMock.find((dom: DomainType) => dom.id === domainId), + ); + }), + getZimbraPlatformDomains: vi.fn(() => { + return Promise.resolve({ + data: domainsMock, + }); + }), + getDomainsZoneList: vi.fn(() => { + return Promise.resolve(domainZone); + }), + putZimbraDomain: vi.fn(() => { + return Promise.resolve(); + }), + deleteZimbraPlatformDomain: vi.fn(() => { + return Promise.resolve(); + }), + }; +}); + +vi.mock('@/api/alias', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformAliasDetail: vi.fn((_platformId, aliasId) => { + return Promise.resolve(aliasMock.find((alias) => alias.id === aliasId)); + }), + getZimbraPlatformAlias: vi.fn(() => { + return Promise.resolve(aliasMock); + }), + deleteZimbraPlatformAlias: vi.fn(() => { + return Promise.resolve(); + }), + }; +}); + +vi.mock('@/api/mailinglist', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformMailingListDetails: vi.fn((_platformId, mlId) => { + return Promise.resolve(mailingListsMock.find((ml) => ml.id === mlId)); + }), + getZimbraPlatformMailingLists: vi.fn(() => { + return Promise.resolve(mailingListsMock); + }), + }; +}); + +vi.mock('@/api/organization', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformOrganizationDetails: vi.fn((_platformId, orgId) => { + return Promise.resolve( + organizationListMock.find((org) => org.id === orgId), + ); + }), + getZimbraPlatformOrganization: vi.fn(() => { + return Promise.resolve({ + data: organizationListMock, + }); + }), + postZimbraPlatformOrganization: vi.fn(() => { + return Promise.resolve(); + }), + putZimbraPlatformOrganization: vi.fn(() => { + return Promise.resolve(); + }), + deleteZimbraPlatformOrganization: vi.fn(() => { + return Promise.resolve(); + }), + }; +}); + +vi.mock('@/api/platform', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformList: vi.fn(() => { + return Promise.resolve(platformMock); + }), + }; +}); + +vi.mock('@/api/task', async (importActual) => { + return { + ...(await importActual()), + getZimbraPlatformTask: vi.fn(() => { + return Promise.resolve(taskMocks); + }), + }; +}); + +vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => { + return { + ...(await importOriginal< + typeof import('@ovh-ux/manager-react-components') + >()), + }; +}); + +export const navigate = vi.fn(); + +vi.mock('react-router-dom', async (importActual) => { + return { + ...(await importActual()), + useLocation: vi.fn(() => ({ + pathname: '', + search: '', + })), + useResolvedPath: vi.fn(() => ({ + pathname: '', + })), + useNavigate: vi.fn(() => navigate), + useSearchParams: vi.fn(() => [new URLSearchParams(), vi.fn()]), + useMatches: vi.fn(() => []), + }; +}); + +afterEach(() => { + vi.clearAllMocks(); +}); diff --git a/packages/manager/apps/zimbra/tsconfig.json b/packages/manager/apps/zimbra/tsconfig.json index 8e9c91916e2a..478190f4b45e 100644 --- a/packages/manager/apps/zimbra/tsconfig.json +++ b/packages/manager/apps/zimbra/tsconfig.json @@ -28,9 +28,7 @@ "node_modules", "dist", "types", - "src/pages/dashboard/Organizations/__test__", - "src/pages/dashboard/Domains/__test__", - "src/pages/dashboard/EmailAccounts/__test__", - "src/hook/__test__" + "src/**/*.spec.ts", + "src/**/*.spec.tsx" ] } diff --git a/packages/manager/apps/zimbra/vitest.config.js b/packages/manager/apps/zimbra/vitest.config.js index ce6b3faa5017..6352fd8efafb 100644 --- a/packages/manager/apps/zimbra/vitest.config.js +++ b/packages/manager/apps/zimbra/vitest.config.js @@ -1,5 +1,5 @@ import path from 'path'; -import { defineConfig } from 'vite'; +import { defineConfig, coverageConfigDefaults } from 'vitest/config'; import react from '@vitejs/plugin-react'; // https://vitejs.dev/config/ @@ -14,18 +14,18 @@ export default defineConfig({ 'src/configInterface.ts', 'src/api', 'src/zimbra.config.ts', - 'src/__tests__', 'src/vite-*.ts', 'src/App.tsx', - 'src/hooks/__tests__', 'src/hooks/index.ts', 'src/hooks/types.ts', 'src/index.tsx', 'src/routes/routes.tsx', 'src/utils/index.ts', 'src/**/*constants.ts', + ...coverageConfigDefaults.exclude, ], }, + setupFiles: ['src/utils/test.setup.tsx'], }, resolve: { alias: { diff --git a/yarn.lock b/yarn.lock index 709b37e3c8d2..a6e838c93669 100644 --- a/yarn.lock +++ b/yarn.lock @@ -701,6 +701,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== + "@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" @@ -711,6 +716,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== + "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -819,6 +829,13 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@babel/parser@^7.25.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" + integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== + dependencies: + "@babel/types" "^7.25.8" + "@babel/parser@^7.7.0": version "7.10.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" @@ -1924,6 +1941,15 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.4", "@babel/types@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" + integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== + dependencies: + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -9446,6 +9472,24 @@ strip-literal "^2.0.0" test-exclude "^6.0.0" +"@vitest/coverage-v8@^2.1.2": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.3.tgz#22d519e5e56385ec126305492f5a3cfe5b44b14d" + integrity sha512-2OJ3c7UPoFSmBZwqD2VEkUw6A/tzPF0LmW0ZZhhB8PFxuc+9IBG/FaSM+RLEenc7ljzFvGN+G0nGQoZnh7sy2A== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@bcoe/v8-coverage" "^0.2.3" + debug "^4.3.6" + istanbul-lib-coverage "^3.2.2" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^5.0.6" + istanbul-reports "^3.1.7" + magic-string "^0.30.11" + magicast "^0.3.4" + std-env "^3.7.0" + test-exclude "^7.0.1" + tinyrainbow "^1.2.0" + "@vitest/expect@1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.3.1.tgz#d4c14b89c43a25fd400a6b941f51ba27fe0cb918" @@ -9483,6 +9527,25 @@ chai "^5.1.1" tinyrainbow "^1.2.0" +"@vitest/expect@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.3.tgz#4b9a6fff22be4c4cd5d57e687cfda611b514b0ad" + integrity sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ== + dependencies: + "@vitest/spy" "2.1.3" + "@vitest/utils" "2.1.3" + chai "^5.1.1" + tinyrainbow "^1.2.0" + +"@vitest/mocker@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.3.tgz#a3593b426551be5715fa108faf04f8a9ddb0a9cc" + integrity sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ== + dependencies: + "@vitest/spy" "2.1.3" + estree-walker "^3.0.3" + magic-string "^0.30.11" + "@vitest/pretty-format@2.0.5", "@vitest/pretty-format@^2.0.5": version "2.0.5" resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" @@ -9490,6 +9553,13 @@ dependencies: tinyrainbow "^1.2.0" +"@vitest/pretty-format@2.1.3", "@vitest/pretty-format@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.3.tgz#48b9b03de75507d1d493df7beb48dc39a1946a3e" + integrity sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ== + dependencies: + tinyrainbow "^1.2.0" + "@vitest/runner@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.4.0.tgz#907c2d17ad5975b70882c25ab7a13b73e5a28da9" @@ -9516,6 +9586,14 @@ "@vitest/utils" "2.0.5" pathe "^1.1.2" +"@vitest/runner@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.3.tgz#20a6da112007dfd92969951df189c6da66c9dac4" + integrity sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ== + dependencies: + "@vitest/utils" "2.1.3" + pathe "^1.1.2" + "@vitest/snapshot@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.4.0.tgz#2945b3fb53767a3f4f421919e93edfef2935b8bd" @@ -9543,6 +9621,15 @@ magic-string "^0.30.10" pathe "^1.1.2" +"@vitest/snapshot@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.3.tgz#1b405a9c40a82563605b13fdc045217751069e58" + integrity sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg== + dependencies: + "@vitest/pretty-format" "2.1.3" + magic-string "^0.30.11" + pathe "^1.1.2" + "@vitest/spy@1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" @@ -9571,6 +9658,13 @@ dependencies: tinyspy "^3.0.0" +"@vitest/spy@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.3.tgz#2c8a457673094ec4c1ab7c50cb11c58e3624ada2" + integrity sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ== + dependencies: + tinyspy "^3.0.0" + "@vitest/ui@^1.4.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-1.6.0.tgz#ffcc97ebcceca7fec840c29ab68632d0cd01db93" @@ -9624,6 +9718,15 @@ loupe "^3.1.1" tinyrainbow "^1.2.0" +"@vitest/utils@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.3.tgz#e52aa5745384091b151cbdf79bb5a3ad2bea88d2" + integrity sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA== + dependencies: + "@vitest/pretty-format" "2.1.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + "@volar/language-core@1.11.1", "@volar/language-core@~1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-1.11.1.tgz#ecdf12ea8dc35fb8549e517991abcbf449a5ad4f" @@ -13510,7 +13613,7 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.3.5: +debug@^4.3.5, debug@^4.3.6: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -16512,6 +16615,18 @@ glob@^10.0.0, glob@^10.3.10: minipass "^7.0.4" path-scurry "^1.10.2" +glob@^10.4.1: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -18353,7 +18468,16 @@ istanbul-lib-source-maps@^5.0.4: debug "^4.1.1" istanbul-lib-coverage "^3.0.0" -istanbul-reports@^3.0.2, istanbul-reports@^3.1.3, istanbul-reports@^3.1.5, istanbul-reports@^3.1.6: +istanbul-lib-source-maps@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== + dependencies: + "@jridgewell/trace-mapping" "^0.3.23" + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3, istanbul-reports@^3.1.5, istanbul-reports@^3.1.6, istanbul-reports@^3.1.7: version "3.1.7" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== @@ -18389,6 +18513,15 @@ jackspeak@^2.3.6: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -20685,6 +20818,13 @@ magic-string@^0.30.10: dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" +magic-string@^0.30.11: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + magicast@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.3.tgz#a15760f982deec9dabc5f314e318d7c6bddcb27b" @@ -20694,6 +20834,15 @@ magicast@^0.3.3: "@babel/types" "^7.23.6" source-map-js "^1.0.2" +magicast@^0.3.4: + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== + dependencies: + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" + majo@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/majo/-/majo-0.6.3.tgz#ac8f35a64c644c87eaccddf940891f157a183846" @@ -21171,6 +21320,13 @@ minimatch@^9.0.1, minimatch@^9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimatch@~3.0.3: version "3.0.8" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" @@ -21256,6 +21412,11 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + minisearch@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.3.0.tgz#985a2f1ca3c73c2d65af94f0616bfe57164b0b6b" @@ -22521,6 +22682,11 @@ p-waterfall@^2.1.1: dependencies: p-reduce "^2.0.0" +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -22799,6 +22965,14 @@ path-scurry@^1.10.2: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" @@ -26839,6 +27013,15 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +test-exclude@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-7.0.1.tgz#20b3ba4906ac20994e275bbcafd68d510264c2a2" + integrity sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^10.4.1" + minimatch "^9.0.4" + text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -26933,11 +27116,16 @@ tinybench@^2.5.1: resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.6.0.tgz#1423284ee22de07c91b3752c048d2764714b341b" integrity sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA== -tinybench@^2.8.0: +tinybench@^2.8.0, tinybench@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== +tinyexec@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98" + integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== + tinypool@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.2.tgz#84013b03dc69dacb322563a475d4c0a9be00f82a" @@ -28305,6 +28493,16 @@ vite-node@2.0.5: tinyrainbow "^1.2.0" vite "^5.0.0" +vite-node@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.3.tgz#8291d31f91c69dc22fea7909f4394c2b3cc2e2d9" + integrity sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA== + dependencies: + cac "^6.7.14" + debug "^4.3.6" + pathe "^1.1.2" + vite "^5.0.0" + vite-plugin-dts@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-3.5.1.tgz#58c225f7ecabff2ed76027e003e1ec8ca964a078" @@ -28501,6 +28699,31 @@ vitest@^2.0.5: vite-node "2.0.5" why-is-node-running "^2.3.0" +vitest@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.3.tgz#dae1055dd328621b59fc6e594fd988fbf2e5370e" + integrity sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA== + dependencies: + "@vitest/expect" "2.1.3" + "@vitest/mocker" "2.1.3" + "@vitest/pretty-format" "^2.1.3" + "@vitest/runner" "2.1.3" + "@vitest/snapshot" "2.1.3" + "@vitest/spy" "2.1.3" + "@vitest/utils" "2.1.3" + chai "^5.1.1" + debug "^4.3.6" + magic-string "^0.30.11" + pathe "^1.1.2" + std-env "^3.7.0" + tinybench "^2.9.0" + tinyexec "^0.3.0" + tinypool "^1.0.0" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.1.3" + why-is-node-running "^2.3.0" + void-elements@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"