feat: deploy config to remote nodes #359

This commit is contained in:
Jacky 2024-07-26 13:53:38 +08:00
parent e75dce92ad
commit 1c1da92363
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
46 changed files with 1480 additions and 605 deletions

View file

@ -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,
})
}
}

View file

@ -24,6 +24,9 @@ const otp = {
recovery_code,
})
},
secure_session_status() {
return http.get('/otp_secure_session_status')
},
}
export default otp

View 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)
}

View 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)
}

View file

@ -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)
}

View file

@ -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 }

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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 ""

View file

@ -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"

View file

@ -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.

View file

@ -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 "重命名"

View file

@ -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"

View file

@ -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')

View file

@ -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,

View file

@ -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}

View file

@ -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>

View file

@ -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

View file

@ -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}`)
})
})
})
}

View file

@ -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>

View file

@ -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('/')
})
})