mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-12 10:55:51 +02:00
feat: deploy config to remote nodes #359
This commit is contained in:
parent
e75dce92ad
commit
1c1da92363
46 changed files with 1480 additions and 605 deletions
|
@ -8,6 +8,8 @@ export interface Config {
|
|||
chatgpt_messages: ChatComplicationMessage[]
|
||||
filepath: string
|
||||
modified_at: string
|
||||
sync_node_ids?: number[]
|
||||
sync_overwrite?: false
|
||||
}
|
||||
|
||||
class ConfigCurd extends Curd<Config> {
|
||||
|
@ -23,8 +25,13 @@ class ConfigCurd extends Curd<Config> {
|
|||
return http.post('/config_mkdir', { base_path: basePath, folder_name: name })
|
||||
}
|
||||
|
||||
rename(basePath: string, origName: string, newName: string) {
|
||||
return http.post('/config_rename', { base_path: basePath, orig_name: origName, new_name: newName })
|
||||
rename(basePath: string, origName: string, newName: string, syncNodeIds: number[]) {
|
||||
return http.post('/config_rename', {
|
||||
base_path: basePath,
|
||||
orig_name: origName,
|
||||
new_name: newName,
|
||||
sync_node_ids: syncNodeIds,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ const otp = {
|
|||
recovery_code,
|
||||
})
|
||||
},
|
||||
secure_session_status() {
|
||||
return http.get('/otp_secure_session_status')
|
||||
},
|
||||
}
|
||||
|
||||
export default otp
|
||||
|
|
18
app/src/components/Notification/cert.ts
Normal file
18
app/src/components/Notification/cert.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
export function syncCertificateSuccess(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} successfully',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name })
|
||||
}
|
||||
|
||||
export function syncCertificateError(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
if (data.status_code === 404) {
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the remote Nginx UI to the latest version',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name }, true)
|
||||
}
|
||||
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name, resp: data.resp_body }, true)
|
||||
}
|
37
app/src/components/Notification/config.ts
Normal file
37
app/src/components/Notification/config.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
export function syncConfigSuccess(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
return $gettext('Sync Config %{config_name} to %{env_name} successfully',
|
||||
{ config_name: data.config_name, env_name: data.env_name })
|
||||
}
|
||||
|
||||
export function syncConfigError(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
if (data.status_code === 404) {
|
||||
return $gettext('Sync config %{cert_name} to %{env_name} failed, please upgrade the remote Nginx UI to the latest version',
|
||||
{ config_name: data.config_name, env_name: data.env_name }, true)
|
||||
}
|
||||
|
||||
return $gettext('Sync config %{config_name} to %{env_name} failed, response: %{resp}',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name, resp: data.resp_body }, true)
|
||||
}
|
||||
|
||||
export function syncRenameConfigSuccess(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
return $gettext('Rename %{orig_path} to %{new_path} on %{env_name} successfully',
|
||||
{ orig_path: data.orig_path, new_path: data.orig_path, env_name: data.env_name })
|
||||
}
|
||||
|
||||
export function syncRenameConfigError(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
if (data.status_code === 404) {
|
||||
return $gettext('Rename %{orig_path} to %{new_path} on %{env_name} failed, please upgrade the remote Nginx UI to the latest version',
|
||||
{ orig_path: data.orig_path, new_path: data.orig_path, env_name: data.env_name }, true)
|
||||
}
|
||||
|
||||
return $gettext('Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}',
|
||||
{ orig_path: data.orig_path, new_path: data.orig_path, resp: data.resp_body, env_name: data.env_name }, true)
|
||||
}
|
|
@ -1,4 +1,11 @@
|
|||
import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
|
||||
import { syncCertificateError, syncCertificateSuccess } from '@/components/Notification/cert'
|
||||
import {
|
||||
syncConfigError,
|
||||
syncConfigSuccess,
|
||||
syncRenameConfigError,
|
||||
syncRenameConfigSuccess,
|
||||
} from '@/components/Notification/config'
|
||||
|
||||
export const detailRender = (args: customRender) => {
|
||||
switch (args.record.title) {
|
||||
|
@ -6,26 +13,15 @@ export const detailRender = (args: customRender) => {
|
|||
return syncCertificateSuccess(args.text)
|
||||
case 'Sync Certificate Error':
|
||||
return syncCertificateError(args.text)
|
||||
case 'Sync Rename Configuration Success':
|
||||
return syncRenameConfigSuccess(args.text)
|
||||
case 'Sync Rename Configuration Error':
|
||||
return syncRenameConfigError(args.text)
|
||||
case 'Sync Configuration Success':
|
||||
return syncConfigSuccess(args.text)
|
||||
case 'Sync Configuration Error':
|
||||
return syncConfigError(args.text)
|
||||
default:
|
||||
return args.text
|
||||
}
|
||||
}
|
||||
|
||||
function syncCertificateSuccess(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} successfully',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name })
|
||||
}
|
||||
|
||||
function syncCertificateError(text: string) {
|
||||
const data = JSON.parse(text)
|
||||
|
||||
if (data.status_code === 404) {
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the remote Nginx UI to the latest version',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name }, true)
|
||||
}
|
||||
|
||||
return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}',
|
||||
{ cert_name: data.cert_name, env_name: data.env_name, resp: data.resp_body }, true)
|
||||
}
|
||||
|
|
|
@ -5,11 +5,6 @@ import OTPAuthorization from '@/components/OTP/OTPAuthorization.vue'
|
|||
import otp from '@/api/otp'
|
||||
import { useUserStore } from '@/pinia'
|
||||
|
||||
export interface OTPModalProps {
|
||||
onOk?: (secureSessionId: string) => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
const useOTPModal = () => {
|
||||
const refOTPAuthorization = ref<typeof OTPAuthorization>()
|
||||
const randomId = Math.random().toString(36).substring(2, 8)
|
||||
|
@ -26,68 +21,72 @@ const useOTPModal = () => {
|
|||
document.head.appendChild(style)
|
||||
}
|
||||
|
||||
const open = async ({ onOk, onCancel }: OTPModalProps) => {
|
||||
const open = async (): Promise<string> => {
|
||||
const { status } = await otp.status()
|
||||
if (!status) {
|
||||
onOk?.('')
|
||||
|
||||
return
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!status) {
|
||||
resolve('')
|
||||
|
||||
const cookies = useCookies(['nginx-ui-2fa'])
|
||||
const ssid = cookies.get('secure_session_id')
|
||||
if (ssid) {
|
||||
onOk?.(ssid)
|
||||
secureSessionId.value = ssid
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
const cookies = useCookies(['nginx-ui-2fa'])
|
||||
const ssid = cookies.get('secure_session_id')
|
||||
if (ssid) {
|
||||
resolve(ssid)
|
||||
secureSessionId.value = ssid
|
||||
|
||||
injectStyles()
|
||||
let container: HTMLDivElement | null = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
return
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
render(null, container!)
|
||||
document.body.removeChild(container!)
|
||||
container = null
|
||||
}
|
||||
injectStyles()
|
||||
let container: HTMLDivElement | null = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
|
||||
const verify = (passcode: string, recovery: string) => {
|
||||
otp.start_secure_session(passcode, recovery).then(r => {
|
||||
cookies.set('secure_session_id', r.session_id, { maxAge: 60 * 3 })
|
||||
onOk?.(r.session_id)
|
||||
close()
|
||||
secureSessionId.value = r.session_id
|
||||
}).catch(async () => {
|
||||
refOTPAuthorization.value?.clearInput()
|
||||
await message.error($gettext('Invalid passcode or recovery code'))
|
||||
})
|
||||
}
|
||||
const close = () => {
|
||||
render(null, container!)
|
||||
document.body.removeChild(container!)
|
||||
container = null
|
||||
}
|
||||
|
||||
const vnode = createVNode(Modal, {
|
||||
open: true,
|
||||
title: $gettext('Two-factor authentication required'),
|
||||
centered: true,
|
||||
maskClosable: false,
|
||||
class: randomId,
|
||||
footer: false,
|
||||
onCancel: () => {
|
||||
close()
|
||||
onCancel?.()
|
||||
},
|
||||
}, {
|
||||
default: () => h(
|
||||
OTPAuthorization,
|
||||
{
|
||||
ref: refOTPAuthorization,
|
||||
class: 'mt-3',
|
||||
onOnSubmit: verify,
|
||||
const verify = (passcode: string, recovery: string) => {
|
||||
otp.start_secure_session(passcode, recovery).then(r => {
|
||||
cookies.set('secure_session_id', r.session_id, { maxAge: 60 * 3 })
|
||||
resolve(r.session_id)
|
||||
close()
|
||||
secureSessionId.value = r.session_id
|
||||
}).catch(async () => {
|
||||
refOTPAuthorization.value?.clearInput()
|
||||
await message.error($gettext('Invalid passcode or recovery code'))
|
||||
})
|
||||
}
|
||||
|
||||
const vnode = createVNode(Modal, {
|
||||
open: true,
|
||||
title: $gettext('Two-factor authentication required'),
|
||||
centered: true,
|
||||
maskClosable: false,
|
||||
class: randomId,
|
||||
footer: false,
|
||||
onCancel: () => {
|
||||
close()
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
reject()
|
||||
},
|
||||
),
|
||||
})
|
||||
}, {
|
||||
default: () => h(
|
||||
OTPAuthorization,
|
||||
{
|
||||
ref: refOTPAuthorization,
|
||||
class: 'mt-3',
|
||||
onOnSubmit: verify,
|
||||
},
|
||||
),
|
||||
})
|
||||
|
||||
render(vnode, container)
|
||||
render(vnode, container!)
|
||||
})
|
||||
}
|
||||
|
||||
return { open }
|
||||
|
|
|
@ -194,9 +194,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "Auto-renewal enabled for %{name}"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "Back"
|
||||
|
||||
|
@ -369,7 +369,7 @@ msgstr ""
|
|||
msgid "Configuration Name"
|
||||
msgstr "Configuration Name"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "Configurations"
|
||||
|
||||
|
@ -420,12 +420,12 @@ msgstr "Created at"
|
|||
msgid "Create Another"
|
||||
msgstr "Create Another"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "Created at"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "Create Another"
|
||||
|
@ -474,8 +474,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "Dashboard"
|
||||
|
||||
|
@ -803,6 +803,10 @@ msgstr "Enabled successfully"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Encrypt website with Let's Encrypt"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr ""
|
||||
|
@ -1191,8 +1195,8 @@ msgstr ""
|
|||
"Make sure you have configured a reverse proxy for .well-known directory to "
|
||||
"HTTPChallengePort (default: 9180) before getting the certificate."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "Manage Configs"
|
||||
|
||||
|
@ -1239,6 +1243,7 @@ msgstr "Advance Mode"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
#, fuzzy
|
||||
msgid "Modify"
|
||||
msgstr "Modify Config"
|
||||
|
@ -1703,7 +1708,8 @@ msgstr "Saved successfully"
|
|||
msgid "Removed successfully"
|
||||
msgstr "Saved successfully"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
|
@ -194,9 +194,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "Renovación automática habilitada por %{name}"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "Volver"
|
||||
|
||||
|
@ -362,7 +362,7 @@ msgstr "El archivo de configuración se probó exitosamente"
|
|||
msgid "Configuration Name"
|
||||
msgstr "Nombre de la configuración"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "Configuraciones"
|
||||
|
||||
|
@ -412,12 +412,12 @@ msgstr "Crear"
|
|||
msgid "Create Another"
|
||||
msgstr "Crear otro"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "Crear"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "Crear otro"
|
||||
|
@ -466,8 +466,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "Panel"
|
||||
|
||||
|
@ -778,6 +778,10 @@ msgstr "Habilitado con éxito"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Encriptar sitio web con Let's Encrypt"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "Entorno"
|
||||
|
@ -1152,8 +1156,8 @@ msgstr ""
|
|||
"Asegúrese de haber configurado un proxy reverso para el directorio .well-"
|
||||
"known en HTTPChallengePort antes de obtener el certificado."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "Administrar configuraciones"
|
||||
|
||||
|
@ -1198,6 +1202,7 @@ msgstr "Modo de ejecución"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Modify"
|
||||
msgstr "Modificar"
|
||||
|
||||
|
@ -1660,7 +1665,8 @@ msgstr "Eliminado con éxito"
|
|||
msgid "Removed successfully"
|
||||
msgstr "Eliminado con éxito"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
msgid "Rename"
|
||||
msgstr "Renombrar"
|
||||
|
|
|
@ -197,9 +197,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "Renouvellement automatique activé pour %{name}"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "Retour"
|
||||
|
||||
|
@ -369,7 +369,7 @@ msgstr "Le fichier de configuration est testé avec succès"
|
|||
msgid "Configuration Name"
|
||||
msgstr "Nom de la configuration"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "Configurations"
|
||||
|
||||
|
@ -420,12 +420,12 @@ msgstr "Créé le"
|
|||
msgid "Create Another"
|
||||
msgstr "Créer un autre"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "Créé le"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "Créer un autre"
|
||||
|
@ -474,8 +474,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "Dashboard"
|
||||
|
||||
|
@ -803,6 +803,10 @@ msgstr "Activé avec succès"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Crypter le site Web avec Let's Encrypt"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr ""
|
||||
|
@ -1193,8 +1197,8 @@ msgstr ""
|
|||
"Assurez vous d'avoir configuré un reverse proxy pour le répertoire .well-"
|
||||
"known vers HTTPChallengePort avant d'obtenir le certificat."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "Gérer les configurations"
|
||||
|
||||
|
@ -1241,6 +1245,7 @@ msgstr "Mode d'exécution"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Modify"
|
||||
msgstr "Modifier"
|
||||
|
||||
|
@ -1710,7 +1715,8 @@ msgstr "Enregistré avec succès"
|
|||
msgid "Removed successfully"
|
||||
msgstr "Enregistré avec succès"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
|
@ -193,9 +193,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "%{name}에 대한 자동 갱신 활성화됨"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "뒤로"
|
||||
|
||||
|
@ -360,7 +360,7 @@ msgstr "구성 파일 테스트 성공"
|
|||
msgid "Configuration Name"
|
||||
msgstr "구성 이름"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "구성들"
|
||||
|
||||
|
@ -410,12 +410,12 @@ msgstr "생성"
|
|||
msgid "Create Another"
|
||||
msgstr "다른 것 생성하기"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "생성"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "다른 것 생성하기"
|
||||
|
@ -464,8 +464,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "대시보드"
|
||||
|
||||
|
@ -776,6 +776,11 @@ msgstr "성공적으로 활성화됨"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Let's Encrypt로 웹사이트 암호화"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
#, fuzzy
|
||||
msgid "Enter"
|
||||
msgstr "간격"
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "환경"
|
||||
|
@ -1170,8 +1175,8 @@ msgstr ""
|
|||
"인증서를 획득하기 전에 .well-known 디렉토리에 대한역방향 프록시를 "
|
||||
"HTTPChallengePort(기본값: 9180)로 구성했는지 확인하세요."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "구성 관리"
|
||||
|
||||
|
@ -1218,6 +1223,7 @@ msgstr "실행 모드"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
#, fuzzy
|
||||
msgid "Modify"
|
||||
msgstr "설정 수정"
|
||||
|
@ -1686,7 +1692,8 @@ msgstr "성공적으로 제거됨"
|
|||
msgid "Removed successfully"
|
||||
msgstr "성공적으로 제거됨"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
|
@ -181,8 +181,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr ""
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143
|
||||
#: src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99
|
||||
#: src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
|
@ -347,7 +348,7 @@ msgstr ""
|
|||
msgid "Configuration Name"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr ""
|
||||
|
||||
|
@ -397,12 +398,12 @@ msgstr ""
|
|||
msgid "Create Another"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
msgid "Create File"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50
|
||||
#: src/views/config/Config.vue:100
|
||||
#: src/views/config/ConfigList.vue:116
|
||||
msgid "Create Folder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -449,9 +450,9 @@ msgid "Customize the name of local server to be displayed in the environment ind
|
|||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39
|
||||
#: src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79
|
||||
#: src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr ""
|
||||
|
||||
|
@ -768,6 +769,10 @@ msgstr ""
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228
|
||||
#: src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
|
@ -1129,9 +1134,9 @@ msgid "Make sure you have configured a reverse proxy for .well-known directory t
|
|||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:102
|
||||
#: src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84
|
||||
#: src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1178,6 +1183,7 @@ msgstr ""
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Modify"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1623,7 +1629,7 @@ msgid "Removed successfully"
|
|||
msgstr ""
|
||||
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/Config.vue:130
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
msgid "Rename"
|
||||
msgstr ""
|
||||
|
|
|
@ -195,9 +195,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "Автообновление включено для %{name}"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "Назад"
|
||||
|
||||
|
@ -371,7 +371,7 @@ msgstr "Проверка конфигурации успешна"
|
|||
msgid "Configuration Name"
|
||||
msgstr "Название конфигурации"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "Конфигурации"
|
||||
|
||||
|
@ -422,12 +422,12 @@ msgstr "Создан в"
|
|||
msgid "Create Another"
|
||||
msgstr "Создать еще"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "Создан в"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "Создать еще"
|
||||
|
@ -476,8 +476,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "Доска"
|
||||
|
||||
|
@ -807,6 +807,10 @@ msgstr "Активировано успешно"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Использовать для сайта Let's Encrypt"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "Окружение"
|
||||
|
@ -1199,8 +1203,8 @@ msgstr ""
|
|||
"Убедитесь, что вы настроили обратный прокси-сервер для каталога .well-known "
|
||||
"на HTTPChallengePort перед получением сертификата»."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "Конфигурации"
|
||||
|
||||
|
@ -1247,6 +1251,7 @@ msgstr "Расширенный режим"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
#, fuzzy
|
||||
msgid "Modify"
|
||||
msgstr "Изменить"
|
||||
|
@ -1716,7 +1721,8 @@ msgstr "Успешно сохранено"
|
|||
msgid "Removed successfully"
|
||||
msgstr "Успешно сохранено"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
|
@ -195,9 +195,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "Đã bật tự động gia hạn SSL cho %{name}"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "Quay lại"
|
||||
|
||||
|
@ -371,7 +371,7 @@ msgstr "Tệp cấu hình được kiểm tra thành công"
|
|||
msgid "Configuration Name"
|
||||
msgstr "Tên cấu hình"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "Cấu hình"
|
||||
|
||||
|
@ -422,12 +422,12 @@ msgstr "Ngày tạo"
|
|||
msgid "Create Another"
|
||||
msgstr "Tạo thêm"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "Ngày tạo"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "Tạo thêm"
|
||||
|
@ -476,8 +476,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "Bảng điều khiển"
|
||||
|
||||
|
@ -808,6 +808,10 @@ msgstr "Đã bật"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "Bảo mật trang web với Let's Encrypt"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "Environment"
|
||||
|
@ -1201,8 +1205,8 @@ msgstr ""
|
|||
"Đảm bảo rằng bạn đã định cấu hình proxy ngược (reverse proxy) thư mục .well-"
|
||||
"known tới HTTPChallengePort (default: 9180) trước khi ký chứng chỉ SSL."
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "Quản lý cấu hình"
|
||||
|
||||
|
@ -1248,6 +1252,7 @@ msgstr "Run Mode"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
#, fuzzy
|
||||
msgid "Modify"
|
||||
msgstr "Sửa"
|
||||
|
@ -1718,7 +1723,8 @@ msgstr "Xoá thành công"
|
|||
msgid "Removed successfully"
|
||||
msgstr "Xoá thành công"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
Binary file not shown.
|
@ -184,9 +184,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "成功启用 %{name} 自动续签"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "返回"
|
||||
|
||||
|
@ -344,7 +344,7 @@ msgstr "配置文件测试成功"
|
|||
msgid "Configuration Name"
|
||||
msgstr "配置名称"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "配置"
|
||||
|
||||
|
@ -394,11 +394,11 @@ msgstr "创建"
|
|||
msgid "Create Another"
|
||||
msgstr "再创建一个"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
msgid "Create File"
|
||||
msgstr "创建文件"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
msgid "Create Folder"
|
||||
msgstr "创建文件夹"
|
||||
|
||||
|
@ -445,8 +445,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr "自定义显示在环境指示器中的本地服务器名称。"
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "仪表盘"
|
||||
|
||||
|
@ -751,6 +751,10 @@ msgstr "启用成功"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "用 Let's Encrypt 对网站进行加密"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr "进入"
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "环境"
|
||||
|
@ -1123,8 +1127,8 @@ msgstr ""
|
|||
"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 "
|
||||
"HTTPChallengePort。"
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "配置管理"
|
||||
|
||||
|
@ -1168,6 +1172,7 @@ msgstr "模型"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Modify"
|
||||
msgstr "修改"
|
||||
|
||||
|
@ -1612,7 +1617,8 @@ msgstr "移除成功"
|
|||
msgid "Removed successfully"
|
||||
msgstr "删除成功"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
msgid "Rename"
|
||||
msgstr "重命名"
|
||||
|
|
|
@ -197,9 +197,9 @@ msgid "Auto-renewal enabled for %{name}"
|
|||
msgstr "已啟用 %{name} 的自動續簽"
|
||||
|
||||
#: src/views/certificate/CertificateEditor.vue:247
|
||||
#: src/views/config/Config.vue:143 src/views/config/ConfigEditor.vue:196
|
||||
#: src/views/domain/DomainEdit.vue:253 src/views/nginx_log/NginxLog.vue:168
|
||||
#: src/views/stream/StreamEdit.vue:245
|
||||
#: src/views/config/ConfigEditor.vue:196 src/views/config/ConfigList.vue:173
|
||||
#: src/views/config/ConfigList.vue:99 src/views/domain/DomainEdit.vue:253
|
||||
#: src/views/nginx_log/NginxLog.vue:168 src/views/stream/StreamEdit.vue:245
|
||||
msgid "Back"
|
||||
msgstr "返回"
|
||||
|
||||
|
@ -366,7 +366,7 @@ msgstr "設定檔案測試成功"
|
|||
msgid "Configuration Name"
|
||||
msgstr "設定名稱"
|
||||
|
||||
#: src/views/config/Config.vue:91
|
||||
#: src/views/config/ConfigList.vue:91
|
||||
msgid "Configurations"
|
||||
msgstr "設定"
|
||||
|
||||
|
@ -417,12 +417,12 @@ msgstr "建立時間"
|
|||
msgid "Create Another"
|
||||
msgstr "再建立一個"
|
||||
|
||||
#: src/views/config/Config.vue:99
|
||||
#: src/views/config/ConfigList.vue:109
|
||||
#, fuzzy
|
||||
msgid "Create File"
|
||||
msgstr "建立時間"
|
||||
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/Config.vue:100
|
||||
#: src/views/config/components/Mkdir.vue:50 src/views/config/ConfigList.vue:116
|
||||
#, fuzzy
|
||||
msgid "Create Folder"
|
||||
msgstr "再建立一個"
|
||||
|
@ -471,8 +471,8 @@ msgid ""
|
|||
"indicator."
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:39 src/views/config/Config.vue:57
|
||||
#: src/views/config/ConfigEditor.vue:118 src/views/config/ConfigEditor.vue:79
|
||||
#: src/routes/index.ts:39 src/views/config/ConfigEditor.vue:118
|
||||
#: src/views/config/ConfigEditor.vue:79 src/views/config/ConfigList.vue:57
|
||||
msgid "Dashboard"
|
||||
msgstr "儀表板"
|
||||
|
||||
|
@ -788,6 +788,10 @@ msgstr "成功啟用"
|
|||
msgid "Encrypt website with Let's Encrypt"
|
||||
msgstr "用 Let's Encrypt 對網站進行加密"
|
||||
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/index.ts:228 src/views/environment/Environment.vue:34
|
||||
msgid "Environment"
|
||||
msgstr "環境"
|
||||
|
@ -1172,8 +1176,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"在取得憑證前,請確保您已將 .well-known 目錄反向代理到 HTTPChallengePort。"
|
||||
|
||||
#: src/routes/index.ts:102 src/views/config/Config.vue:62
|
||||
#: src/views/config/ConfigEditor.vue:123 src/views/config/ConfigEditor.vue:84
|
||||
#: src/routes/index.ts:102 src/views/config/ConfigEditor.vue:123
|
||||
#: src/views/config/ConfigEditor.vue:84 src/views/config/ConfigList.vue:62
|
||||
msgid "Manage Configs"
|
||||
msgstr "管理設定"
|
||||
|
||||
|
@ -1220,6 +1224,7 @@ msgstr "執行模式"
|
|||
#: src/components/ChatGPT/ChatGPT.vue:248
|
||||
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:181
|
||||
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:532
|
||||
#: src/views/config/ConfigList.vue:151
|
||||
msgid "Modify"
|
||||
msgstr "修改"
|
||||
|
||||
|
@ -1681,7 +1686,8 @@ msgstr "儲存成功"
|
|||
msgid "Removed successfully"
|
||||
msgstr "儲存成功"
|
||||
|
||||
#: src/views/config/components/Rename.vue:52 src/views/config/Config.vue:130
|
||||
#: src/views/config/components/Rename.vue:52
|
||||
#: src/views/config/ConfigList.vue:159
|
||||
#: src/views/domain/ngx_conf/NgxUpstream.vue:123
|
||||
#, fuzzy
|
||||
msgid "Rename"
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import type { AxiosRequestConfig } from 'axios'
|
||||
import axios from 'axios'
|
||||
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import NProgress from 'nprogress'
|
||||
import { useSettingsStore, useUserStore } from '@/pinia'
|
||||
import 'nprogress/nprogress.css'
|
||||
|
||||
import router from '@/routes'
|
||||
import useOTPModal from '@/components/OTP/useOTPModal'
|
||||
|
||||
const user = useUserStore()
|
||||
const settings = useSettingsStore()
|
||||
|
@ -58,8 +60,14 @@ instance.interceptors.response.use(
|
|||
},
|
||||
async error => {
|
||||
NProgress.done()
|
||||
|
||||
const otpModal = useOTPModal()
|
||||
const cookies = useCookies(['nginx-ui-2fa'])
|
||||
switch (error.response.status) {
|
||||
case 401:
|
||||
cookies.remove('secure_session_id')
|
||||
await otpModal.open()
|
||||
break
|
||||
case 403:
|
||||
user.logout()
|
||||
await router.push('/login')
|
||||
|
|
|
@ -97,7 +97,7 @@ export const routes: RouteRecordRaw[] = [
|
|||
{
|
||||
path: 'config',
|
||||
name: 'Manage Configs',
|
||||
component: () => import('@/views/config/Config.vue'),
|
||||
component: () => import('@/views/config/ConfigList.vue'),
|
||||
meta: {
|
||||
name: () => $gettext('Manage Configs'),
|
||||
icon: FileOutlined,
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":"2.0.0-beta.28","build_id":147,"total_build":351}
|
||||
{"version":"2.0.0-beta.28","build_id":149,"total_build":353}
|
|
@ -1,8 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
||||
import { formatDateTime } from '@/lib/helper'
|
||||
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
|
||||
import type { Config } from '@/api/config'
|
||||
import config from '@/api/config'
|
||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||
import ngx from '@/api/ngx'
|
||||
|
@ -10,7 +12,10 @@ import InspectConfig from '@/views/config/InspectConfig.vue'
|
|||
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
||||
import type { ChatComplicationMessage } from '@/api/openai'
|
||||
import { useBreadcrumbs } from '@/composables/useBreadcrumbs'
|
||||
import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
|
||||
import { useSettingsStore } from '@/pinia'
|
||||
|
||||
const settings = useSettingsStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const refForm = ref()
|
||||
|
@ -32,10 +37,12 @@ const data = ref({
|
|||
name: '',
|
||||
content: '',
|
||||
filepath: '',
|
||||
})
|
||||
sync_node_ids: [] as number[],
|
||||
sync_overwrite: false,
|
||||
} as Config)
|
||||
|
||||
const historyChatgptRecord = ref([]) as Ref<ChatComplicationMessage[]>
|
||||
const activeKey = ref(['basic', 'chatgpt'])
|
||||
const activeKey = ref(['basic', 'deploy', 'chatgpt'])
|
||||
const modifiedAt = ref('')
|
||||
const nginxConfigBase = ref('')
|
||||
|
||||
|
@ -145,6 +152,8 @@ function save() {
|
|||
filepath: data.value.filepath,
|
||||
new_filepath: newPath.value,
|
||||
content: data.value.content,
|
||||
sync_node_ids: data.value.sync_node_ids,
|
||||
sync_overwrite: data.value.sync_overwrite,
|
||||
}).then(r => {
|
||||
data.value.content = r.content
|
||||
message.success($gettext('Saved successfully'))
|
||||
|
@ -261,6 +270,29 @@ function goBack() {
|
|||
</AFormItem>
|
||||
</AForm>
|
||||
</ACollapsePanel>
|
||||
<ACollapsePanel
|
||||
v-if="!settings.is_remote"
|
||||
key="deploy"
|
||||
:header="$gettext('Deploy')"
|
||||
>
|
||||
<NodeSelector
|
||||
v-model:target="data.sync_node_ids"
|
||||
hidden-local
|
||||
/>
|
||||
<div class="node-deploy-control">
|
||||
<div class="overwrite">
|
||||
<ACheckbox v-model:checked="data.sync_overwrite">
|
||||
{{ $gettext('Overwrite') }}
|
||||
</ACheckbox>
|
||||
<ATooltip placement="bottom">
|
||||
<template #title>
|
||||
{{ $gettext('Overwrite exist file') }}
|
||||
</template>
|
||||
<InfoCircleOutlined />
|
||||
</ATooltip>
|
||||
</div>
|
||||
</div>
|
||||
</ACollapsePanel>
|
||||
<ACollapsePanel
|
||||
key="chatgpt"
|
||||
header="ChatGPT"
|
||||
|
@ -295,4 +327,19 @@ function goBack() {
|
|||
:deep(.ant-collapse > .ant-collapse-item > .ant-collapse-header) {
|
||||
padding: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.overwrite {
|
||||
margin-right: 15px;
|
||||
|
||||
span {
|
||||
color: #9b9b9b;
|
||||
}
|
||||
}
|
||||
|
||||
.node-deploy-control {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -90,14 +90,31 @@ const refRename = ref()
|
|||
<template>
|
||||
<ACard :title="$gettext('Configurations')">
|
||||
<template #extra>
|
||||
<a
|
||||
class="mr-4"
|
||||
<AButton
|
||||
v-if="basePath"
|
||||
type="link"
|
||||
size="small"
|
||||
@click="goBack"
|
||||
>
|
||||
{{ $gettext('Back') }}
|
||||
</AButton>
|
||||
<AButton
|
||||
type="link"
|
||||
size="small"
|
||||
@click="router.push({
|
||||
path: '/config/add',
|
||||
query: { basePath: basePath || undefined },
|
||||
})"
|
||||
>{{ $gettext('Create File') }}</a>
|
||||
<a @click="() => refMkdir.open(basePath)">{{ $gettext('Create Folder') }}</a>
|
||||
>
|
||||
{{ $gettext('Create File') }}
|
||||
</AButton>
|
||||
<AButton
|
||||
type="link"
|
||||
size="small"
|
||||
@click="() => refMkdir.open(basePath)"
|
||||
>
|
||||
{{ $gettext('Create Folder') }}
|
||||
</AButton>
|
||||
</template>
|
||||
<InspectConfig ref="refInspectConfig" />
|
||||
<StdTable
|
||||
|
@ -110,24 +127,37 @@ const refRename = ref()
|
|||
row-key="name"
|
||||
:get-params="getParams"
|
||||
disable-query-params
|
||||
@click-edit="(r, row) => {
|
||||
if (!row.is_dir) {
|
||||
$router.push({
|
||||
path: `/config/${basePath}${r}/edit`,
|
||||
})
|
||||
}
|
||||
else {
|
||||
$router.push({
|
||||
query: {
|
||||
dir: basePath + r,
|
||||
},
|
||||
})
|
||||
}
|
||||
}"
|
||||
disable-modify
|
||||
>
|
||||
<template #actions="{ record }">
|
||||
<AButton
|
||||
type="link"
|
||||
size="small"
|
||||
@click="() => {
|
||||
if (!record.is_dir) {
|
||||
$router.push({
|
||||
path: `/config/${basePath}${record.name}/edit`,
|
||||
})
|
||||
}
|
||||
else {
|
||||
$router.push({
|
||||
query: {
|
||||
dir: basePath + record.name,
|
||||
},
|
||||
})
|
||||
}
|
||||
}"
|
||||
>
|
||||
{{ $gettext('Modify') }}
|
||||
</AButton>
|
||||
<ADivider type="vertical" />
|
||||
<a @click="() => refRename.open(basePath, record.name)">{{ $gettext('Rename') }}</a>
|
||||
<AButton
|
||||
type="link"
|
||||
size="small"
|
||||
@click="() => refRename.open(basePath, record.name, record.is_dir)"
|
||||
>
|
||||
{{ $gettext('Rename') }}
|
||||
</AButton>
|
||||
</template>
|
||||
</StdTable>
|
||||
<Mkdir
|
|
@ -27,17 +27,15 @@ function ok() {
|
|||
refForm.value.validate().then(() => {
|
||||
const otpModal = useOTPModal()
|
||||
|
||||
otpModal.open({
|
||||
onOk() {
|
||||
config.mkdir(data.value.basePath, data.value.name).then(() => {
|
||||
visible.value = false
|
||||
otpModal.open().then(() => {
|
||||
config.mkdir(data.value.basePath, data.value.name).then(() => {
|
||||
visible.value = false
|
||||
|
||||
message.success($gettext('Created successfully'))
|
||||
emit('created')
|
||||
}).catch(e => {
|
||||
message.error(`${$gettext('Server error')} ${e?.message}`)
|
||||
})
|
||||
},
|
||||
message.success($gettext('Created successfully'))
|
||||
emit('created')
|
||||
}).catch(e => {
|
||||
message.error(`${$gettext('Server error')} ${e?.message}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,22 +2,27 @@
|
|||
import { message } from 'ant-design-vue'
|
||||
import config from '@/api/config'
|
||||
import useOTPModal from '@/components/OTP/useOTPModal'
|
||||
import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
|
||||
|
||||
const emit = defineEmits(['renamed'])
|
||||
const visible = ref(false)
|
||||
const isDirFlag = ref(false)
|
||||
|
||||
const data = ref({
|
||||
basePath: '',
|
||||
orig_name: '',
|
||||
new_name: '',
|
||||
sync_node_ids: [] as number[],
|
||||
})
|
||||
|
||||
const refForm = ref()
|
||||
function open(basePath: string, origName: string) {
|
||||
|
||||
function open(basePath: string, origName: string, isDir: boolean) {
|
||||
visible.value = true
|
||||
data.value.orig_name = origName
|
||||
data.value.new_name = origName
|
||||
data.value.basePath = basePath
|
||||
isDirFlag.value = isDir
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
|
@ -26,20 +31,18 @@ defineExpose({
|
|||
|
||||
function ok() {
|
||||
refForm.value.validate().then(() => {
|
||||
const { basePath, orig_name, new_name } = data.value
|
||||
const { basePath, orig_name, new_name, sync_node_ids } = data.value
|
||||
|
||||
const otpModal = useOTPModal()
|
||||
|
||||
otpModal.open({
|
||||
onOk() {
|
||||
config.rename(basePath, orig_name, new_name).then(() => {
|
||||
visible.value = false
|
||||
message.success($gettext('Rename successfully'))
|
||||
emit('renamed')
|
||||
}).catch(e => {
|
||||
message.error(`${$gettext('Server error')} ${e?.message}`)
|
||||
})
|
||||
},
|
||||
otpModal.open().then(() => {
|
||||
config.rename(basePath, orig_name, new_name, sync_node_ids).then(() => {
|
||||
visible.value = false
|
||||
message.success($gettext('Rename successfully'))
|
||||
emit('renamed')
|
||||
}).catch(e => {
|
||||
message.error(`${$gettext('Server error')} ${e?.message}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -72,6 +75,15 @@ function ok() {
|
|||
>
|
||||
<AInput v-model:value="data.new_name" />
|
||||
</AFormItem>
|
||||
<AFormItem
|
||||
v-if="isDirFlag"
|
||||
:label="$gettext('Sync')"
|
||||
>
|
||||
<NodeSelector
|
||||
v-model:target="data.sync_node_ids"
|
||||
hidden-local
|
||||
/>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</AModal>
|
||||
</template>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { FitAddon } from '@xterm/addon-fit'
|
|||
import _ from 'lodash'
|
||||
import ws from '@/lib/websocket'
|
||||
import useOTPModal from '@/components/OTP/useOTPModal'
|
||||
import otp from '@/api/otp'
|
||||
|
||||
let term: Terminal | null
|
||||
let ping: NodeJS.Timeout
|
||||
|
@ -14,30 +15,29 @@ const websocket = shallowRef()
|
|||
const lostConnection = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
otp.secure_session_status()
|
||||
|
||||
const otpModal = useOTPModal()
|
||||
|
||||
otpModal.open({
|
||||
onOk(secureSessionId: string) {
|
||||
websocket.value = ws(`/api/pty?X-Secure-Session-ID=${secureSessionId}`, false)
|
||||
otpModal.open().then(secureSessionId => {
|
||||
websocket.value = ws(`/api/pty?X-Secure-Session-ID=${secureSessionId}`, false)
|
||||
|
||||
nextTick(() => {
|
||||
initTerm()
|
||||
websocket.value.onmessage = wsOnMessage
|
||||
websocket.value.onopen = wsOnOpen
|
||||
websocket.value.onerror = () => {
|
||||
lostConnection.value = true
|
||||
}
|
||||
websocket.value.onclose = () => {
|
||||
lostConnection.value = true
|
||||
}
|
||||
})
|
||||
},
|
||||
onCancel() {
|
||||
if (window.history.length > 1)
|
||||
router.go(-1)
|
||||
else
|
||||
router.push('/')
|
||||
},
|
||||
nextTick(() => {
|
||||
initTerm()
|
||||
websocket.value.onmessage = wsOnMessage
|
||||
websocket.value.onopen = wsOnOpen
|
||||
websocket.value.onerror = () => {
|
||||
lostConnection.value = true
|
||||
}
|
||||
websocket.value.onclose = () => {
|
||||
lostConnection.value = true
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
if (window.history.length > 1)
|
||||
router.go(-1)
|
||||
else
|
||||
router.push('/')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue