Selaa lähdekoodia

feat(wip): upstream editor #138

0xJacky 1 vuosi sitten
vanhempi
commit
43074728bf

+ 2 - 2
app/gettext.config.cjs

@@ -1,9 +1,9 @@
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const i18n = require('./i18n.json')
 
-module.exports = {
+module.export = {
   input: {
-    include: ["**/*.js", "**/*.ts", "**/*.vue", "**/*.jsx", "**/*.tsx"]
+    include: ['**/*.js', '**/*.ts', '**/*.vue', '**/*.jsx', '**/*.tsx'],
   },
   output: {
     locales: Object.keys(i18n),

+ 1 - 1
app/src/language/LINGUAS

@@ -1 +1 @@
-en zh_CN zh_TW fr_FR es ru_RU vi_VN
+en

+ 32 - 21
app/src/language/en/app.po

@@ -17,7 +17,7 @@ msgstr "About"
 msgid "Access Logs"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -189,7 +189,7 @@ msgstr "Certificate is valid"
 msgid "Certificate Status"
 msgstr "Certificate Status"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "Certificate Status"
@@ -454,6 +454,10 @@ msgstr "Are you sure you want to remove this directive?"
 msgid "Do you want to remove this server?"
 msgstr "Are you sure you want to remove this directive?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "Domain Config Created Successfully"
@@ -583,7 +587,7 @@ msgstr ""
 msgid "Executable Path"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -649,7 +653,7 @@ msgstr "Save error %{msg}"
 msgid "Format successfully"
 msgstr "Saved successfully"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "Certificate is valid"
@@ -711,7 +715,7 @@ msgstr ""
 msgid "HTTP01"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 msgid "Import"
 msgstr ""
 
@@ -745,6 +749,20 @@ msgstr "Enabled successfully"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "Intermediate Certification Authorities: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "Certificate is valid"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "Certificate Status"
+
 #: src/language/constants.ts:24
 #, fuzzy
 msgid "Issued certificate successfully"
@@ -838,7 +856,7 @@ msgstr "Manage Sites"
 msgid "Manage Users"
 msgstr "Manage Users"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 #, fuzzy
 msgid "Managed Certificate"
 msgstr "Certificate is valid"
@@ -872,7 +890,7 @@ msgstr "Modify Config"
 msgid "Multi-line Directive"
 msgstr "Single Directive"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -956,7 +974,7 @@ msgstr "No"
 msgid "Node Secret"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1202,6 +1220,7 @@ msgid "Renew Certificate Success"
 msgstr "Certificate is valid"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Enabled successfully"
@@ -1335,13 +1354,13 @@ msgstr "Certificate Status"
 msgid "SSL Certificate Key Content"
 msgstr "Certificate Status"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "Certificate Status"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -1357,7 +1376,7 @@ msgstr "Login"
 msgid "Stable"
 msgstr "Enabled"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "Status"
@@ -1462,7 +1481,7 @@ msgid ""
 "continue?"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr ""
@@ -1515,7 +1534,7 @@ msgstr "Username"
 msgid "Username (*)"
 msgstr "Username (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 
@@ -1572,18 +1591,10 @@ msgstr ""
 msgid "You can check Nginx UI upgrade at this page."
 msgstr ""
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "Certificate Status"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "Leave blank for no change"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "Certificate is valid"
-
 #, fuzzy
 #~ msgid "Config Name"
 #~ msgstr "Configuration Name"

+ 32 - 21
app/src/language/es/app.po

@@ -22,7 +22,7 @@ msgstr "Acerca de"
 msgid "Access Logs"
 msgstr "Registros de acceso"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -187,7 +187,7 @@ msgstr "El certificado es válido"
 msgid "Certificate Status"
 msgstr "Estado del Certificado"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "Estado del Certificado"
@@ -444,6 +444,10 @@ msgstr "¿Quieres habilitar TLS?"
 msgid "Do you want to remove this server?"
 msgstr "¿Quieres eliminar este servidor?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "Configuración de dominio creada con éxito"
@@ -570,7 +574,7 @@ msgstr "Registros de acceso"
 msgid "Executable Path"
 msgstr "Ruta ejecutable"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -635,7 +639,7 @@ msgstr "Error de formato %{msg}"
 msgid "Format successfully"
 msgstr "Formateado correctamente"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "Cambiar Certificado"
@@ -697,7 +701,7 @@ msgstr "Puerto HTTP"
 msgid "HTTP01"
 msgstr "HTTP01"
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 #, fuzzy
 msgid "Import"
 msgstr "Exportar"
@@ -731,6 +735,20 @@ msgstr "Instalación exitosa"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "Autoridades de certificación intermedias: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "Obtener certificado"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "Estado del Certificado"
+
 #: src/language/constants.ts:24
 msgid "Issued certificate successfully"
 msgstr "Certificado emitido con éxito"
@@ -821,7 +839,7 @@ msgstr "Administrar sitios"
 msgid "Manage Users"
 msgstr "Administrar usuarios"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 #, fuzzy
 msgid "Managed Certificate"
 msgstr "Cambiar Certificado"
@@ -853,7 +871,7 @@ msgstr "Modificar configuración"
 msgid "Multi-line Directive"
 msgstr "Directiva multilínea"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -934,7 +952,7 @@ msgstr "No"
 msgid "Node Secret"
 msgstr "Secreto del nodo"
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1182,6 +1200,7 @@ msgid "Renew Certificate Success"
 msgstr "Cambiar Certificado"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Habilitado con éxito"
@@ -1313,12 +1332,12 @@ msgstr "Contenido de certificado SSL"
 msgid "SSL Certificate Key Content"
 msgstr "Contenido de la llave del certificado SSL"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr "Ruta de la llave del certificado SSL"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr "Ruta del certificado SSL"
@@ -1332,7 +1351,7 @@ msgstr "Acceso"
 msgid "Stable"
 msgstr "Estable"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "Estado"
@@ -1442,7 +1461,7 @@ msgstr ""
 "de la autoridad al backend, y debemos guardar este archivo y volver a cargar "
 "Nginx. ¿Estás seguro de que quieres continuar?"
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "Tipo"
@@ -1492,7 +1511,7 @@ msgstr "Nombre de usuario"
 msgid "Username (*)"
 msgstr "Nombre de usuario (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 
@@ -1551,18 +1570,10 @@ msgstr "Estás usando la última versión"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "Puede consultar la actualización de Nginx UI en esta página."
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "Estado del Certificado"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "Para no modificar dejar en blanco"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "Obtener certificado"
-
 #, fuzzy
 #~ msgid "Auto Cert is enabled"
 #~ msgstr "Certificado automático"

+ 32 - 21
app/src/language/fr_FR/app.po

@@ -19,7 +19,7 @@ msgstr "À propos"
 msgid "Access Logs"
 msgstr "Journaux d'accès"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -188,7 +188,7 @@ msgstr "Le certificat est valide"
 msgid "Certificate Status"
 msgstr "État du certificat"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "État du certificat"
@@ -447,6 +447,10 @@ msgstr "Voulez-vous activer TLS ?"
 msgid "Do you want to remove this server?"
 msgstr "Voulez-vous supprimer ce serveur ?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "La configuration du domaine a été créée avec succès"
@@ -579,7 +583,7 @@ msgstr "Journaux d'erreurs"
 msgid "Executable Path"
 msgstr "Chemin exécutable"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -645,7 +649,7 @@ msgstr "Erreur de format %{msg}"
 msgid "Format successfully"
 msgstr "Formaté avec succès"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "Changer de certificat"
@@ -707,7 +711,7 @@ msgstr "Port HTTP"
 msgid "HTTP01"
 msgstr "HTTP01"
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 #, fuzzy
 msgid "Import"
 msgstr "Exporter"
@@ -741,6 +745,20 @@ msgstr "Installé avec succès"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "Autorités de certification intermédiaires : %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "Obtenir un certificat"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "État du certificat"
+
 #: src/language/constants.ts:24
 msgid "Issued certificate successfully"
 msgstr "Certificat délivré avec succès"
@@ -835,7 +853,7 @@ msgstr "Gérer les sites"
 msgid "Manage Users"
 msgstr "Gérer les utilisateurs"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 #, fuzzy
 msgid "Managed Certificate"
 msgstr "Changer de certificat"
@@ -867,7 +885,7 @@ msgstr "Modifier la configuration"
 msgid "Multi-line Directive"
 msgstr "Directive multiligne"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -950,7 +968,7 @@ msgstr "Non"
 msgid "Node Secret"
 msgstr "Secret Jwt"
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1202,6 +1220,7 @@ msgid "Renew Certificate Success"
 msgstr "Changer de certificat"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Activé avec succès"
@@ -1333,12 +1352,12 @@ msgstr "Contenu de la certification SSL"
 msgid "SSL Certificate Key Content"
 msgstr "Contenu de la clé de certification SSL"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr "Chemin de la clé du certificat SSL"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr "Chemin du certificat SSL"
@@ -1353,7 +1372,7 @@ msgstr "Connexion"
 msgid "Stable"
 msgstr "Tableau"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "Statut"
@@ -1466,7 +1485,7 @@ msgstr ""
 "transmettre la demande de l'autorité au backend, et nous devons enregistrer "
 "ce fichier et recharger le Nginx. Êtes-vous sûr de vouloir continuer?"
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "Type"
@@ -1517,7 +1536,7 @@ msgstr "Nom d'utilisateur"
 msgid "Username (*)"
 msgstr "Nom d'utilisateur (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 
@@ -1576,18 +1595,10 @@ msgstr "Vous utilisez la dernière version"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "Vous pouvez vérifier la mise à niveau de Nginx UI sur cette page."
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "État du certificat"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "Laisser vide pour aucun changement"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "Obtenir un certificat"
-
 #, fuzzy
 #~ msgid "Auto Cert is enabled"
 #~ msgstr "Auto Cert"

+ 30 - 13
app/src/language/messages.pot

@@ -11,7 +11,7 @@ msgstr ""
 msgid "Access Logs"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32
 #: src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50
@@ -182,7 +182,7 @@ msgid "Certificate Status"
 msgstr ""
 
 #: src/routes/index.ts:101
-#: src/views/certificate/Certificate.vue:117
+#: src/views/certificate/Certificate.vue:122
 msgid "Certificates"
 msgstr ""
 
@@ -436,6 +436,10 @@ msgstr ""
 msgid "Do you want to remove this server?"
 msgstr ""
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr ""
@@ -564,7 +568,7 @@ msgstr ""
 msgid "Executable Path"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -628,7 +632,7 @@ msgstr ""
 msgid "Format successfully"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 msgid "General Certificate"
 msgstr ""
 
@@ -688,7 +692,7 @@ msgstr ""
 msgid "HTTP01"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 msgid "Import"
 msgstr ""
 
@@ -722,6 +726,18 @@ msgstr ""
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr ""
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+msgid "Issue wildcard certificate"
+msgstr ""
+
+#: src/views/certificate/WildcardCertificate.vue:58
+msgid "Issue Wildcard Certificate"
+msgstr ""
+
 #: src/language/constants.ts:24
 msgid "Issued certificate successfully"
 msgstr ""
@@ -808,7 +824,7 @@ msgstr ""
 msgid "Manage Users"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 msgid "Managed Certificate"
 msgstr ""
 
@@ -839,7 +855,7 @@ msgstr ""
 msgid "Multi-line Directive"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13
 #: src/views/config/config.ts:9
@@ -923,7 +939,7 @@ msgstr ""
 msgid "Node Secret"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1159,6 +1175,7 @@ msgid "Renew Certificate Success"
 msgstr ""
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 msgid "Renew successfully"
 msgstr ""
 
@@ -1290,12 +1307,12 @@ msgstr ""
 msgid "SSL Certificate Key Content"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr ""
@@ -1309,7 +1326,7 @@ msgstr ""
 msgid "Stable"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:79
+#: src/views/certificate/Certificate.vue:81
 #: src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
@@ -1400,7 +1417,7 @@ msgstr ""
 msgid "To make sure the certification auto-renewal can work normally, we need to add a location which can proxy the request from authority to backend, and we need to save this file and reload the Nginx. Are you sure you want to continue?"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:39
+#: src/views/certificate/Certificate.vue:41
 #: src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
@@ -1455,7 +1472,7 @@ msgstr ""
 msgid "Username (*)"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 

+ 32 - 21
app/src/language/ru_RU/app.po

@@ -17,7 +17,7 @@ msgstr "О проекте"
 msgid "Access Logs"
 msgstr "Журнал доступа"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -189,7 +189,7 @@ msgstr "Сертификат действителен"
 msgid "Certificate Status"
 msgstr "Статус сертификата"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "Статус сертификата"
@@ -454,6 +454,10 @@ msgstr "Включить TLS?"
 msgid "Do you want to remove this server?"
 msgstr "Вы хотите удалить этот сервер?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "Конфигурация домена успешно создана"
@@ -585,7 +589,7 @@ msgstr "Ошибка логирования"
 msgid "Executable Path"
 msgstr "Исполняемый путь"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -651,7 +655,7 @@ msgstr "Ошибка форматирования %{msg}"
 msgid "Format successfully"
 msgstr "Форматирование успешно"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "Сертификат действителен"
@@ -713,7 +717,7 @@ msgstr "Порт HTTP"
 msgid "HTTP01"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 #, fuzzy
 msgid "Import"
 msgstr "Экспорт"
@@ -748,6 +752,20 @@ msgstr "Установленно"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "Промежуточные центры сертификации: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "Получить сертификат"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "Статус сертификата"
+
 #: src/language/constants.ts:24
 #, fuzzy
 msgid "Issued certificate successfully"
@@ -841,7 +859,7 @@ msgstr "Сайты"
 msgid "Manage Users"
 msgstr "Пользователи"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 #, fuzzy
 msgid "Managed Certificate"
 msgstr "Сертификат действителен"
@@ -875,7 +893,7 @@ msgstr "Изменить конфигурацию"
 msgid "Multi-line Directive"
 msgstr "Одиночная директива"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -960,7 +978,7 @@ msgstr "Нет"
 msgid "Node Secret"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1208,6 +1226,7 @@ msgid "Renew Certificate Success"
 msgstr "Сертификат действителен"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Активировано успешно"
@@ -1341,13 +1360,13 @@ msgstr "Содержание сертификата SSL"
 msgid "SSL Certificate Key Content"
 msgstr "Содержание ключа сертификата SSL"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 #, fuzzy
 msgid "SSL Certificate Key Path"
 msgstr "Путь к ключу сертификата SSL"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 #, fuzzy
 msgid "SSL Certificate Path"
@@ -1363,7 +1382,7 @@ msgstr "Логин"
 msgid "Stable"
 msgstr "Таблица"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "Статус"
@@ -1469,7 +1488,7 @@ msgid ""
 "continue?"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "Тип"
@@ -1522,7 +1541,7 @@ msgstr "Имя пользователя"
 msgid "Username (*)"
 msgstr "Имя пользователя (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 
@@ -1579,18 +1598,10 @@ msgstr "Вы используете последнюю версию"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "Вы можете проверить обновление Nginx UI на этой странице."
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "Статус сертификата"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "Оставьте пустым без изменений"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "Получить сертификат"
-
 #, fuzzy
 #~ msgid "Auto Cert is enabled"
 #~ msgstr "Авто Сертификат"

+ 32 - 21
app/src/language/vi_VN/app.po

@@ -17,7 +17,7 @@ msgstr "Tác giả"
 msgid "Access Logs"
 msgstr "Log truy cập"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -189,7 +189,7 @@ msgstr "Chứng chỉ SSL hợp lệ"
 msgid "Certificate Status"
 msgstr "Trạng thái chứng chỉ"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "Chứng chỉ"
@@ -454,6 +454,10 @@ msgstr "Bạn muốn bật TLS ?"
 msgid "Do you want to remove this server?"
 msgstr "Bạn muốn xóa máy chủ này ?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "Tên miền đã được tạo"
@@ -585,7 +589,7 @@ msgstr "Log lỗi"
 msgid "Executable Path"
 msgstr "Đường dẫn thực thi"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr "Đã hết hạn"
 
@@ -651,7 +655,7 @@ msgstr "Lưu lỗi %{msg}"
 msgid "Format successfully"
 msgstr "Định dạng thành công"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "Chứng chỉ chung"
@@ -713,7 +717,7 @@ msgstr ""
 msgid "HTTP01"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 #, fuzzy
 msgid "Import"
 msgstr "Xuất"
@@ -748,6 +752,20 @@ msgstr "Cài đặt thành công"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "Cơ quan cấp chứng chỉ: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "Gia hạn SSL"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "Thêm chứng chỉ SSL"
+
 #: src/language/constants.ts:24
 #, fuzzy
 msgid "Issued certificate successfully"
@@ -841,7 +859,7 @@ msgstr "Quản lý Website"
 msgid "Manage Users"
 msgstr "Người dùng"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 msgid "Managed Certificate"
 msgstr ""
 
@@ -874,7 +892,7 @@ msgstr "Sửa cấu hình"
 msgid "Multi-line Directive"
 msgstr "Single Directive"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -958,7 +976,7 @@ msgstr "Không"
 msgid "Node Secret"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr "Không phải sau khi"
 
@@ -1208,6 +1226,7 @@ msgid "Renew Certificate Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "Gia hạn chứng chỉ SSL"
@@ -1340,12 +1359,12 @@ msgstr ""
 msgid "SSL Certificate Key Content"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr ""
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr ""
@@ -1359,7 +1378,7 @@ msgstr ""
 msgid "Stable"
 msgstr "Ổn định"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "Trạng thái"
@@ -1467,7 +1486,7 @@ msgstr ""
 "quyền đến chương trình phụ trợ và chúng tôi cần lưu tệp này và tải lại "
 "Nginx. Bạn có chắc chắn muốn Tiếp tục?"
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "Loại"
@@ -1520,7 +1539,7 @@ msgstr "Username"
 msgid "Username (*)"
 msgstr "Username (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr "Hợp lệ"
 
@@ -1581,18 +1600,10 @@ msgstr "Bạn đang sử dụng phiên bản mới nhất"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "Bạn có thể kiểm tra nâng cấp Nginx UI tại trang này"
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "Thêm chứng chỉ SSL"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "Bỏ trống nếu không thay đổi"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "Gia hạn SSL"
-
 #, fuzzy
 #~ msgid "Config Name"
 #~ msgstr "Tên cấu hình"

+ 32 - 22
app/src/language/zh_CN/app.po

@@ -21,7 +21,7 @@ msgstr "关于"
 msgid "Access Logs"
 msgstr "访问日志"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -185,7 +185,7 @@ msgstr "此证书有效"
 msgid "Certificate Status"
 msgstr "证书状态"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 msgid "Certificates"
 msgstr "证书"
 
@@ -435,6 +435,10 @@ msgstr "你想启用TLS吗?"
 msgid "Do you want to remove this server?"
 msgstr "你想删除这个服务器吗?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr "域名"
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "域名配置文件创建成功"
@@ -557,7 +561,7 @@ msgstr "错误日志"
 msgid "Executable Path"
 msgstr "可执行文件路径"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr "已过期"
 
@@ -620,7 +624,7 @@ msgstr "保存错误 %{msg}"
 msgid "Format successfully"
 msgstr "格式化成功"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 msgid "General Certificate"
 msgstr "普通证书"
 
@@ -680,7 +684,7 @@ msgstr "HTTP 监听端口"
 msgid "HTTP01"
 msgstr "HTTP01"
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 msgid "Import"
 msgstr "导入"
 
@@ -712,6 +716,20 @@ msgstr "安装成功"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "中级证书颁发机构: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "更新证书"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "添加证书"
+
 #: src/language/constants.ts:24
 msgid "Issued certificate successfully"
 msgstr "证书申请成功"
@@ -798,7 +816,7 @@ msgstr "网站管理"
 msgid "Manage Users"
 msgstr "用户管理"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 msgid "Managed Certificate"
 msgstr "托管证书"
 
@@ -828,7 +846,7 @@ msgstr "修改配置文件"
 msgid "Multi-line Directive"
 msgstr "多行指令"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -909,7 +927,7 @@ msgstr "取消"
 msgid "Node Secret"
 msgstr "节点密钥"
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr "有效期"
 
@@ -1147,6 +1165,7 @@ msgid "Renew Certificate Success"
 msgstr "证书续期成功"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 msgid "Renew successfully"
 msgstr "更新成功"
 
@@ -1273,12 +1292,12 @@ msgstr "SSL 证书内容"
 msgid "SSL Certificate Key Content"
 msgstr "SSL 证书密钥内容"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr "SSL证书密钥路径"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr "SSL证书路径"
@@ -1291,7 +1310,7 @@ msgstr "SSO 登录"
 msgid "Stable"
 msgstr "稳定"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "状态"
@@ -1392,7 +1411,7 @@ msgstr ""
 "为了确保认证自动更新能够正常工作,我们需要添加一个能够代理从权威机构到后端的"
 "请求的 Location,并且我们需要保存这个文件并重新加载Nginx。你确定要继续吗?"
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "类型"
@@ -1442,7 +1461,7 @@ msgstr "用户名"
 msgid "Username (*)"
 msgstr "用户名 (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr "有效的"
 
@@ -1499,15 +1518,9 @@ msgstr "您使用的是最新版本"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "你可以在这个页面检查Nginx UI的升级。"
 
-#~ msgid "Add Certificate"
-#~ msgstr "添加证书"
-
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "留空不会有任何变化。"
 
-#~ msgid "Renew certificate"
-#~ msgstr "更新证书"
-
 #~ msgid "Auto Cert is enabled"
 #~ msgstr "自动更新已启用"
 
@@ -1591,9 +1604,6 @@ msgstr "你可以在这个页面检查Nginx UI的升级。"
 #~ msgid "Inspect Configurations"
 #~ msgstr "检查配置"
 
-#~ msgid "Domain"
-#~ msgstr "域名"
-
 #~ msgid "server_name parameters more than one"
 #~ msgstr "server_name 指令包含多个参数"
 

+ 32 - 24
app/src/language/zh_TW/app.po

@@ -22,7 +22,7 @@ msgstr "關於"
 msgid "Access Logs"
 msgstr "存取日誌"
 
-#: src/views/certificate/Certificate.vue:104
+#: src/views/certificate/Certificate.vue:106
 #: src/views/certificate/DNSCredential.vue:32 src/views/config/config.ts:36
 #: src/views/domain/DomainList.vue:50 src/views/environment/Environment.vue:105
 #: src/views/notification/Notification.vue:38 src/views/user/User.vue:46
@@ -187,7 +187,7 @@ msgstr "此憑證有效"
 msgid "Certificate Status"
 msgstr "憑證狀態"
 
-#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:117
+#: src/routes/index.ts:101 src/views/certificate/Certificate.vue:122
 #, fuzzy
 msgid "Certificates"
 msgstr "憑證狀態"
@@ -442,6 +442,10 @@ msgstr "您想啟用 TLS 嗎?"
 msgid "Do you want to remove this server?"
 msgstr "您要移除此伺服器嗎?"
 
+#: src/views/certificate/WildcardCertificate.vue:69
+msgid "Domain"
+msgstr "網域"
+
 #: src/views/domain/DomainAdd.vue:151
 msgid "Domain Config Created Successfully"
 msgstr "網域設定檔成功建立"
@@ -565,7 +569,7 @@ msgstr "錯誤日誌"
 msgid "Executable Path"
 msgstr "可執行檔路徑"
 
-#: src/views/certificate/Certificate.vue:92
+#: src/views/certificate/Certificate.vue:94
 msgid "Expired"
 msgstr ""
 
@@ -629,7 +633,7 @@ msgstr "格式錯誤 %{msg}"
 msgid "Format successfully"
 msgstr "成功格式化"
 
-#: src/views/certificate/Certificate.vue:45
+#: src/views/certificate/Certificate.vue:47
 #, fuzzy
 msgid "General Certificate"
 msgstr "更換憑證"
@@ -690,7 +694,7 @@ msgstr "HTTP 監聽埠"
 msgid "HTTP01"
 msgstr "HTTP01"
 
-#: src/views/certificate/Certificate.vue:120
+#: src/views/certificate/Certificate.vue:129
 #, fuzzy
 msgid "Import"
 msgstr "匯出"
@@ -724,6 +728,20 @@ msgstr "安裝成功"
 msgid "Intermediate Certification Authorities: %{issuer}"
 msgstr "中級憑證頒發機構: %{issuer}"
 
+#: src/views/certificate/WildcardCertificate.vue:84
+msgid "Issue"
+msgstr ""
+
+#: src/views/certificate/Certificate.vue:137
+#, fuzzy
+msgid "Issue wildcard certificate"
+msgstr "取得憑證"
+
+#: src/views/certificate/WildcardCertificate.vue:58
+#, fuzzy
+msgid "Issue Wildcard Certificate"
+msgstr "憑證狀態"
+
 #: src/language/constants.ts:24
 msgid "Issued certificate successfully"
 msgstr "成功頒發憑證"
@@ -813,7 +831,7 @@ msgstr "管理網站"
 msgid "Manage Users"
 msgstr "管理使用者"
 
-#: src/views/certificate/Certificate.vue:44
+#: src/views/certificate/Certificate.vue:46
 #, fuzzy
 msgid "Managed Certificate"
 msgstr "更換憑證"
@@ -845,7 +863,7 @@ msgstr "修改設定"
 msgid "Multi-line Directive"
 msgstr "多行指令"
 
-#: src/views/certificate/Certificate.vue:22
+#: src/views/certificate/Certificate.vue:24
 #: src/views/certificate/CertificateEditor.vue:145
 #: src/views/certificate/DNSCredential.vue:13 src/views/config/config.ts:9
 #: src/views/domain/cert/ChangeCert.vue:21
@@ -926,7 +944,7 @@ msgstr "取消"
 msgid "Node Secret"
 msgstr "Node Secret"
 
-#: src/views/certificate/Certificate.vue:98
+#: src/views/certificate/Certificate.vue:100
 msgid "Not After"
 msgstr ""
 
@@ -1171,6 +1189,7 @@ msgid "Renew Certificate Success"
 msgstr "更換憑證"
 
 #: src/views/certificate/RenewCert.vue:25
+#: src/views/certificate/WildcardCertificate.vue:47
 #, fuzzy
 msgid "Renew successfully"
 msgstr "啟用成功"
@@ -1302,12 +1321,12 @@ msgstr "SSL 認證內容"
 msgid "SSL Certificate Key Content"
 msgstr "SSL 憑證金鑰內容"
 
-#: src/views/certificate/Certificate.vue:71
+#: src/views/certificate/Certificate.vue:73
 #: src/views/certificate/CertificateEditor.vue:163
 msgid "SSL Certificate Key Path"
 msgstr "SSL 憑證金鑰路徑"
 
-#: src/views/certificate/Certificate.vue:63
+#: src/views/certificate/Certificate.vue:65
 #: src/views/certificate/CertificateEditor.vue:154
 msgid "SSL Certificate Path"
 msgstr "SSL 憑證路徑"
@@ -1321,7 +1340,7 @@ msgstr "登入"
 msgid "Stable"
 msgstr "穩定"
 
-#: src/views/certificate/Certificate.vue:79 src/views/domain/DomainList.vue:25
+#: src/views/certificate/Certificate.vue:81 src/views/domain/DomainList.vue:25
 #: src/views/environment/Environment.vue:78
 msgid "Status"
 msgstr "狀態"
@@ -1426,7 +1445,7 @@ msgstr ""
 "為了確保憑證自動續期能夠正常運作,我們需要新增一個 Location 來代理從授權後端"
 "的請求,我們需要儲存這個檔案並重新載入 Nginx。你確定你要繼續嗎?"
 
-#: src/views/certificate/Certificate.vue:39 src/views/config/config.ts:14
+#: src/views/certificate/Certificate.vue:41 src/views/config/config.ts:14
 #: src/views/notification/Notification.vue:15
 msgid "Type"
 msgstr "類型"
@@ -1476,7 +1495,7 @@ msgstr "使用者名稱"
 msgid "Username (*)"
 msgstr "使用者名稱 (*)"
 
-#: src/views/certificate/Certificate.vue:88
+#: src/views/certificate/Certificate.vue:90
 msgid "Valid"
 msgstr ""
 
@@ -1535,18 +1554,10 @@ msgstr "您正在使用最新版本"
 msgid "You can check Nginx UI upgrade at this page."
 msgstr "您可以在此頁面檢查 Nginx UI 的升級。"
 
-#, fuzzy
-#~ msgid "Add Certificate"
-#~ msgstr "憑證狀態"
-
 #, fuzzy
 #~ msgid "Leave blank will not change anything."
 #~ msgstr "留空表示不修改"
 
-#, fuzzy
-#~ msgid "Renew certificate"
-#~ msgstr "取得憑證"
-
 #, fuzzy
 #~ msgid "Auto Cert is enabled"
 #~ msgstr "自動憑證"
@@ -1614,9 +1625,6 @@ msgstr "您可以在此頁面檢查 Nginx UI 的升級。"
 #~ msgid "Inspect Configurations"
 #~ msgstr "檢查設定"
 
-#~ msgid "Domain"
-#~ msgstr "網域"
-
 #~ msgid "server_name parameters more than one"
 #~ msgstr "server_name 指令包含多個參數"
 

+ 4 - 1
app/src/views/domain/components/RightSettings.vue

@@ -62,7 +62,10 @@ function on_change_enabled(checked: boolean) {
 </script>
 
 <template>
-  <ACard class="right-settings">
+  <ACard
+    class="right-settings"
+    :bordered="false"
+  >
     <ContextHolder />
     <ACollapse
       v-model:activeKey="active_key"

+ 1 - 3
app/src/views/domain/ngx_conf/LocationEditor.vue

@@ -44,9 +44,7 @@ function remove(index: number) {
 </script>
 
 <template>
-  <h2>
-    {{ $gettext('Locations') }}
-  </h2>
+  <h3>{{ $gettext('Locations') }}</h3>
   <AEmpty v-if="!locations" />
   <Draggable
     v-else

+ 28 - 143
app/src/views/domain/ngx_conf/NgxConfigEditor.vue

@@ -1,17 +1,13 @@
 <script setup lang="ts">
 import { useGettext } from 'vue3-gettext'
-import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
 import Modal from 'ant-design-vue/lib/modal'
-import type { ComputedRef, Ref } from 'vue'
-import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
-import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
-import Cert from '@/views/domain/cert/Cert.vue'
-import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
-import ConfigTemplate from '@/views/domain/ngx_conf/config_template/ConfigTemplate.vue'
+import type { ComputedRef } from 'vue'
 import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
 import template from '@/api/template'
 import type { NgxConfig, NgxDirective } from '@/api/ngx'
 import type { CertificateInfo } from '@/api/cert'
+import NgxServer from '@/views/domain/ngx_conf/NgxServer.vue'
+import NgxUpstream from '@/views/domain/ngx_conf/NgxUpstream.vue'
 
 const props = defineProps<{
   autoCert: boolean
@@ -29,10 +25,15 @@ const save_site_config = inject('save_site_config') as () => Promise<void>
 
 const [modal, ContextHolder] = Modal.useModal()
 
+const current_server_index = ref(0)
+
+provide('current_server_index', current_server_index)
+
 const route = useRoute()
 
-const current_server_index = ref(0)
-const name = ref(route.params.name) as Ref<string>
+onMounted(() => {
+  current_server_index.value = Number.parseInt((route.query?.server_idx ?? 0) as string)
+})
 
 const ngx_config = inject('ngx_config') as NgxConfig
 
@@ -67,6 +68,8 @@ const current_server_directives = computed(() => {
   return ngx_config.servers?.[current_server_index.value]?.directives
 })
 
+provide('current_server_directives', current_server_directives)
+
 const directivesMap: ComputedRef<Record<string, NgxDirective[]>> = computed(() => {
   const map: Record<string, NgxDirective[]> = {}
 
@@ -136,8 +139,6 @@ function change_tls(status: boolean) {
   }
 }
 
-provide('current_server_directives', current_server_directives)
-
 const support_ssl = computed(() => {
   const servers = ngx_config.servers
   for (const server_key in servers) {
@@ -151,17 +152,6 @@ const support_ssl = computed(() => {
   return false
 })
 
-const current_support_ssl = computed(() => {
-  if (directivesMap.value.listen) {
-    for (const v of directivesMap.value.listen) {
-      if (v?.params.indexOf('ssl') > 0)
-        return true
-    }
-  }
-
-  return false
-})
-
 const autoCertRef = computed({
   get() {
     return props.autoCert
@@ -171,57 +161,6 @@ const autoCertRef = computed({
   },
 })
 
-onMounted(() => {
-  current_server_index.value = Number.parseInt((route.query?.server_idx ?? 0) as string)
-})
-
-const router = useRouter()
-
-const servers_length = computed(() => {
-  return ngx_config.servers.length
-})
-
-watch(servers_length, () => {
-  if (current_server_index.value >= servers_length.value)
-    current_server_index.value = servers_length.value - 1
-  else if (current_server_index.value < 0)
-    current_server_index.value = 0
-})
-
-watch(current_server_index, () => {
-  router.push({
-    query: {
-      server_idx: current_server_index.value.toString(),
-    },
-  })
-})
-
-function add_server() {
-  ngx_config.servers.push({
-    comments: '',
-    locations: [],
-    directives: [],
-  })
-}
-
-function remove_server(index: number) {
-  modal.confirm({
-    title: $gettext('Do you want to remove this server?'),
-    mask: false,
-    centered: true,
-    okText: $gettext('OK'),
-    cancelText: $gettext('Cancel'),
-    onOk() {
-      ngx_config?.servers?.splice(index, 1)
-    },
-  })
-}
-
-const ngx_directives = computed(() => {
-  return ngx_config?.servers?.[current_server_index.value]?.directives
-})
-
-provide('ngx_directives', ngx_directives)
 provide('directivesMap', directivesMap)
 </script>
 
@@ -235,77 +174,23 @@ provide('directivesMap', directivesMap)
       <ASwitch @change="confirm_change_tls" />
     </AFormItem>
 
-    <h2>{{ $gettext('Custom') }}</h2>
-    <CodeEditor
-      v-model:content="ngx_config.custom"
-      default-height="150px"
-    />
+    <div class="mb-4">
+      <h2>{{ $gettext('Custom') }}</h2>
+      <CodeEditor
+        v-model:content="ngx_config.custom"
+        default-height="150px"
+      />
+    </div>
 
-    <ATabs v-model:activeKey="current_server_index">
-      <ATabPane
-        v-for="(v, k) in ngx_config.servers"
-        :key="k"
-      >
-        <template #tab>
-          Server {{ k + 1 }}
-          <ADropdown>
-            <MoreOutlined />
-            <template #overlay>
-              <AMenu>
-                <AMenuItem>
-                  <a @click="remove_server(k)">{{ $gettext('Delete') }}</a>
-                </AMenuItem>
-              </AMenu>
-            </template>
-          </ADropdown>
-        </template>
-        <LogEntry
-          :ngx-config="ngx_config"
-          :current-server-idx="current_server_index"
-          :name="name"
-        />
-
-        <div class="tab-content">
-          <template v-if="current_support_ssl && enabled">
-            <Cert
-              v-if="current_support_ssl"
-              v-model:enabled="autoCertRef"
-              :config-name="ngx_config.name"
-              :cert-info="certInfo?.[k]"
-              :current-server-index="current_server_index"
-              @callback="$emit('callback')"
-            />
-          </template>
-
-          <template v-if="v.comments">
-            <h3>{{ $gettext('Comments') }}</h3>
-            <ATextarea
-              v-model:value="v.comments"
-              :bordered="false"
-            />
-          </template>
-          <DirectiveEditor />
-          <br>
-          <ConfigTemplate :current-server-index="current_server_index" />
-          <br>
-          <LocationEditor
-            :current-server-index="current_server_index"
-            :locations="v.locations"
-          />
-        </div>
-      </ATabPane>
-
-      <template #rightExtra>
-        <AButton
-          type="link"
-          size="small"
-          @click="add_server"
-        >
-          <PlusOutlined />
-          {{ $gettext('Add') }}
-        </AButton>
-      </template>
-    </ATabs>
+    <NgxUpstream />
+
+    <ADivider />
+
+    <NgxServer
+      v-model:auto-cert="autoCertRef"
+      :enabled="enabled"
+      :cert-info="certInfo"
+    />
   </div>
 </template>
 

+ 181 - 0
app/src/views/domain/ngx_conf/NgxServer.vue

@@ -0,0 +1,181 @@
+<script setup lang="ts">
+
+import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
+import { useGettext } from 'vue3-gettext'
+import type { ComputedRef, Ref } from 'vue'
+import Modal from 'ant-design-vue/lib/modal'
+import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
+import ConfigTemplate from '@/views/domain/ngx_conf/config_template/ConfigTemplate.vue'
+import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
+import Cert from '@/views/domain/cert/Cert.vue'
+import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
+import type { NgxConfig, NgxDirective } from '@/api/ngx'
+import type { CertificateInfo } from '@/api/cert'
+
+const props = defineProps<{
+  autoCert: boolean
+  enabled: boolean
+  certInfo?: {
+    [key: number]: CertificateInfo
+  }
+}>()
+
+const emit = defineEmits(['callback', 'update:autoCert'])
+
+const { $gettext } = useGettext()
+
+const [modal, ContextHolder] = Modal.useModal()
+
+const current_server_index = inject('current_server_index') as Ref<number>
+const route = useRoute()
+const name = computed(() => route.params.name) as ComputedRef<string>
+
+const ngx_config = inject('ngx_config') as NgxConfig
+
+const directivesMap = inject('directivesMap') as ComputedRef<Record<string, NgxDirective[]>>
+
+const current_support_ssl = computed(() => {
+  if (directivesMap.value.listen) {
+    for (const v of directivesMap.value.listen) {
+      if (v?.params.indexOf('ssl') > 0)
+        return true
+    }
+  }
+
+  return false
+})
+
+const autoCertRef = computed({
+  get() {
+    return props.autoCert
+  },
+  set(value) {
+    emit('update:autoCert', value)
+  },
+})
+
+const router = useRouter()
+
+const servers_length = computed(() => {
+  return ngx_config.servers.length
+})
+
+watch(servers_length, () => {
+  if (current_server_index.value >= servers_length.value)
+    current_server_index.value = servers_length.value - 1
+  else if (current_server_index.value < 0)
+    current_server_index.value = 0
+})
+
+watch(current_server_index, () => {
+  router.push({
+    query: {
+      server_idx: current_server_index.value.toString(),
+    },
+  })
+})
+
+function add_server() {
+  ngx_config.servers.push({
+    comments: '',
+    locations: [],
+    directives: [],
+  })
+}
+
+function remove_server(index: number) {
+  modal.confirm({
+    title: $gettext('Do you want to remove this server?'),
+    mask: false,
+    centered: true,
+    okText: $gettext('OK'),
+    cancelText: $gettext('Cancel'),
+    onOk() {
+      ngx_config?.servers?.splice(index, 1)
+      current_server_index.value = (index > 1 ? index - 1 : 0)
+    },
+  })
+}
+
+const ngx_directives = computed(() => {
+  return ngx_config?.servers?.[current_server_index.value]?.directives
+})
+
+provide('ngx_directives', ngx_directives)
+</script>
+
+<template>
+  <div>
+    <h2>Server</h2>
+    <ContextHolder />
+    <ATabs v-model:activeKey="current_server_index">
+      <ATabPane
+        v-for="(v, k) in ngx_config.servers"
+        :key="k"
+      >
+        <template #tab>
+          Server {{ k + 1 }}
+          <ADropdown>
+            <MoreOutlined />
+            <template #overlay>
+              <AMenu>
+                <AMenuItem>
+                  <a @click="remove_server(k)">{{ $gettext('Delete') }}</a>
+                </AMenuItem>
+              </AMenu>
+            </template>
+          </ADropdown>
+        </template>
+        <LogEntry
+          :ngx-config="ngx_config"
+          :current-server-idx="current_server_index"
+          :name="name"
+        />
+
+        <div class="tab-content">
+          <template v-if="current_support_ssl && enabled">
+            <Cert
+              v-if="current_support_ssl"
+              v-model:enabled="autoCertRef"
+              :config-name="ngx_config.name"
+              :cert-info="certInfo?.[k]"
+              :current-server-index="current_server_index"
+              @callback="$emit('callback')"
+            />
+          </template>
+
+          <template v-if="v.comments">
+            <h3>{{ $gettext('Comments') }}</h3>
+            <ATextarea
+              v-model:value="v.comments"
+              :bordered="false"
+            />
+          </template>
+          <DirectiveEditor />
+          <br>
+          <ConfigTemplate :current-server-index="current_server_index" />
+          <br>
+          <LocationEditor
+            :current-server-index="current_server_index"
+            :locations="v.locations"
+          />
+        </div>
+      </ATabPane>
+
+      <template #rightExtra>
+        <AButton
+          type="link"
+          size="small"
+          @click="add_server"
+        >
+          <PlusOutlined />
+          {{ $gettext('Add') }}
+        </AButton>
+      </template>
+    </ATabs>
+  </div>
+</template>
+
+<style scoped lang="less">
+
+</style>

+ 97 - 0
app/src/views/domain/ngx_conf/NgxUpstream.vue

@@ -0,0 +1,97 @@
+<script setup lang="ts">
+import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
+import { useGettext } from 'vue3-gettext'
+import Modal from 'ant-design-vue/lib/modal'
+import type { NgxConfig } from '@/api/ngx'
+import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
+
+const { $gettext } = useGettext()
+
+const [modal, ContextHolder] = Modal.useModal()
+
+const ngx_config = inject('ngx_config') as NgxConfig
+const current_upstream_index = ref(0)
+function add_upstream() {
+  ngx_config.upstreams?.push({
+    name: '',
+    comments: '',
+    directives: [],
+  })
+}
+
+function remove_upstream(index: number) {
+  modal.confirm({
+    title: $gettext('Do you want to remove this upstream?'),
+    mask: false,
+    centered: true,
+    okText: $gettext('OK'),
+    cancelText: $gettext('Cancel'),
+    onOk() {
+      ngx_config?.upstreams?.splice(index, 1)
+      current_upstream_index.value = (index > 1 ? index - 1 : 0)
+    },
+  })
+}
+
+const ngx_directives = computed(() => {
+  return ngx_config?.upstreams?.[current_upstream_index.value]?.directives
+})
+
+provide('ngx_directives', ngx_directives)
+</script>
+
+<template>
+  <div>
+    <h2>Upstream</h2>
+    <ContextHolder />
+    <ATabs v-model:activeKey="current_upstream_index">
+      <ATabPane
+        v-for="(v, k) in ngx_config.upstreams"
+        :key="k"
+      >
+        <template #tab>
+          Upstream {{ v.name }}
+          <ADropdown>
+            <MoreOutlined />
+            <template #overlay>
+              <AMenu>
+                <AMenuItem>
+                  <a @click="remove_upstream(k)">{{ $gettext('Delete') }}</a>
+                </AMenuItem>
+              </AMenu>
+            </template>
+          </ADropdown>
+        </template>
+
+        <div class="tab-content">
+          <div class="mb-4">
+            <h2>{{ $gettext('Name') }}</h2>
+            <AInput v-model:value="v.name" />
+          </div>
+
+          <div class="mb-4">
+            <h2>{{ $gettext('Comments') }}</h2>
+            <ATextarea v-model:value="v.comments" />
+          </div>
+
+          <DirectiveEditor />
+        </div>
+      </ATabPane>
+
+      <template #rightExtra>
+        <AButton
+          type="link"
+          size="small"
+          @click="add_upstream"
+        >
+          <PlusOutlined />
+          {{ $gettext('Add') }}
+        </AButton>
+      </template>
+    </ATabs>
+  </div>
+</template>
+
+<style scoped lang="less">
+
+</style>

+ 2 - 2
app/src/views/domain/ngx_conf/config_template/ConfigTemplate.vue

@@ -82,9 +82,9 @@ provide('ngx_directives', ngx_directives)
 
 <template>
   <div>
-    <h2>
+    <h3>
       {{ $gettext('Config Templates') }}
-    </h2>
+    </h3>
     <div class="config-list-wrapper">
       <AList
         :grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 2, xl: 2, xxl: 2, xxxl: 2 }"

+ 4 - 4
app/src/views/domain/ngx_conf/directive/DirectiveAdd.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { reactive, ref } from 'vue'
+import { type ComputedRef, reactive, ref } from 'vue'
 import { useGettext } from 'vue3-gettext'
 import { DeleteOutlined } from '@ant-design/icons-vue'
 import CodeEditor from '@/components/CodeEditor'
@@ -13,7 +13,7 @@ const emit = defineEmits(['save'])
 
 const { $gettext } = useGettext()
 
-const ngx_directives = inject('ngx_directives') as NgxDirective[]
+const ngx_directives = inject('ngx_directives') as ComputedRef<NgxDirective[]>
 const directive = reactive({ directive: '', params: '' })
 const adding = ref(false)
 const mode = ref('default')
@@ -30,9 +30,9 @@ function save() {
     directive.directive = ''
 
   if (props.idx)
-    ngx_directives.splice(props.idx + 1, 0, { directive: directive.directive, params: directive.params })
+    ngx_directives.value.splice(props.idx + 1, 0, { directive: directive.directive, params: directive.params })
   else
-    ngx_directives.push({ directive: directive.directive, params: directive.params })
+    ngx_directives.value.push({ directive: directive.directive, params: directive.params })
 
   emit('save', props.idx)
 }

+ 1 - 2
app/src/views/domain/ngx_conf/directive/DirectiveEditor.vue

@@ -19,7 +19,7 @@ provide('current_idx', current_idx)
 </script>
 
 <template>
-  <h2>{{ $gettext('Directives') }}</h2>
+  <h3>{{ $gettext('Directives') }}</h3>
 
   <Draggable
     :list="ngx_directives"
@@ -41,7 +41,6 @@ provide('current_idx', current_idx)
   <DirectiveAdd
     v-if="!readonly"
     v-auto-animate
-    :ngx_directives="ngx_directives"
   />
 </template>
 

+ 6 - 6
app/src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue

@@ -2,7 +2,7 @@
 import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
 
 import { useGettext } from 'vue3-gettext'
-import { ref, watch } from 'vue'
+import { type ComputedRef, ref, watch } from 'vue'
 import { message } from 'ant-design-vue'
 import config from '@/api/config'
 import CodeEditor from '@/components/CodeEditor'
@@ -15,17 +15,17 @@ const props = defineProps<{
 
 const { $gettext, interpolate } = useGettext()
 
-const ngx_directives = inject('ngx_directives') as NgxDirective[]
+const ngx_directives = inject('ngx_directives') as ComputedRef<NgxDirective[]>
 
 function remove(index: number) {
-  ngx_directives.splice(index, 1)
+  ngx_directives.value.splice(index, 1)
 }
 
 const content = ref('')
 
 function init() {
-  if (ngx_directives[props.index].directive === 'include') {
-    config.get(ngx_directives[props.index].params).then(r => {
+  if (ngx_directives.value[props.index].directive === 'include') {
+    config.get(ngx_directives.value[props.index].params).then(r => {
       content.value = r.content
     })
   }
@@ -34,7 +34,7 @@ function init() {
 watch(props, init)
 
 function save() {
-  config.save(ngx_directives[props.index].params, { content: content.value }).then(r => {
+  config.save(ngx_directives.value[props.index].params, { content: content.value }).then(r => {
     content.value = r.content
     message.success($gettext('Saved successfully'))
   }).catch(r => {