mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
fix: compose 验证、提交按钮合并 (#806)
This commit is contained in:
parent
d7f53862e9
commit
5b68332b9a
@ -213,15 +213,7 @@ func (u *ContainerService) ComposeUpdate(req dto.ComposeUpdate) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
|
func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
|
||||||
if req.From == "template" {
|
if req.From == "template" || req.From == "edit" {
|
||||||
template, err := composeRepo.Get(commonRepo.WithByID(req.Template))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.From = "edit"
|
|
||||||
req.File = template.Content
|
|
||||||
}
|
|
||||||
if req.From == "edit" {
|
|
||||||
dir := fmt.Sprintf("%s/docker/compose/%s", constant.DataDir, req.Name)
|
dir := fmt.Sprintf("%s/docker/compose/%s", constant.DataDir, req.Name)
|
||||||
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
||||||
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||||
|
@ -40,10 +40,10 @@ type daemonJsonItem struct {
|
|||||||
|
|
||||||
func (u *DockerService) LoadDockerStatus() string {
|
func (u *DockerService) LoadDockerStatus() string {
|
||||||
status := constant.StatusRunning
|
status := constant.StatusRunning
|
||||||
// stdout, err := cmd.Exec("systemctl is-active docker")
|
stdout, err := cmd.Exec("systemctl is-active docker")
|
||||||
// if string(stdout) != "active\n" || err != nil {
|
if string(stdout) != "active\n" || err != nil {
|
||||||
// status = constant.Stopped
|
status = constant.Stopped
|
||||||
// }
|
}
|
||||||
|
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
|
@ -545,12 +545,11 @@ const message = {
|
|||||||
|
|
||||||
compose: 'Compose',
|
compose: 'Compose',
|
||||||
fromChangeHelper: 'Switching the source will clear the current edited content. Do you want to continue?',
|
fromChangeHelper: 'Switching the source will clear the current edited content. Do you want to continue?',
|
||||||
composeHelper:
|
|
||||||
'The current content has passed the format verification. Please click Submit to complete the creation',
|
|
||||||
composePathHelper: 'Config file save path: {0}',
|
composePathHelper: 'Config file save path: {0}',
|
||||||
apps: 'Apps',
|
apps: 'Apps',
|
||||||
local: 'Local',
|
local: 'Local',
|
||||||
createCompose: 'Create compose',
|
createCompose: 'Create compose',
|
||||||
|
template: 'Template',
|
||||||
composeTemplate: 'Compose template',
|
composeTemplate: 'Compose template',
|
||||||
createComposeTemplate: 'Create compose template',
|
createComposeTemplate: 'Create compose template',
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
@ -994,7 +993,7 @@ const message = {
|
|||||||
update: 'update',
|
update: 'update',
|
||||||
upgrade: 'upgrade',
|
upgrade: 'upgrade',
|
||||||
versioneSelect: 'Please select a version',
|
versioneSelect: 'Please select a version',
|
||||||
operatorHelper: 'Operation {0} will be performed on the selected application, continue? ',
|
operatorHelper: 'Operation {0} will be performed on the selected application, Do you want to continue? ',
|
||||||
checkInstalledWarn: '{0} is not detected, please enter the app store and click to install!',
|
checkInstalledWarn: '{0} is not detected, please enter the app store and click to install!',
|
||||||
gotoInstalled: 'Go to install',
|
gotoInstalled: 'Go to install',
|
||||||
search: 'Search',
|
search: 'Search',
|
||||||
@ -1023,7 +1022,7 @@ const message = {
|
|||||||
updatePrompt: 'The current application is the latest version',
|
updatePrompt: 'The current application is the latest version',
|
||||||
installPrompt: 'No apps installed yet',
|
installPrompt: 'No apps installed yet',
|
||||||
updateHelper: 'Updating parameters may cause the application to fail to start, please operate with caution',
|
updateHelper: 'Updating parameters may cause the application to fail to start, please operate with caution',
|
||||||
updateWarn: 'Update parameters need to rebuild the application, continue? ',
|
updateWarn: 'Update parameters need to rebuild the application, Do you want to continue? ',
|
||||||
busPort: 'Service Port',
|
busPort: 'Service Port',
|
||||||
},
|
},
|
||||||
website: {
|
website: {
|
||||||
@ -1161,7 +1160,8 @@ const message = {
|
|||||||
HTTPAlso: 'HTTP can be accessed directly',
|
HTTPAlso: 'HTTP can be accessed directly',
|
||||||
sslConfig: 'SSL options',
|
sslConfig: 'SSL options',
|
||||||
disbaleHTTTPS: 'Disable HTTPS',
|
disbaleHTTTPS: 'Disable HTTPS',
|
||||||
disbaleHTTTPSHelper: 'Disabling HTTPS will delete the certificate related configuration, whether to continue',
|
disbaleHTTTPSHelper:
|
||||||
|
'Disabling HTTPS will delete the certificate related configuration, Do you want to continue?',
|
||||||
SSLHelper:
|
SSLHelper:
|
||||||
'Note: Do not use SSL certificates for illegal websites \n If HTTPS access cannot be used after opening, please check whether the security group has correctly released port 443',
|
'Note: Do not use SSL certificates for illegal websites \n If HTTPS access cannot be used after opening, please check whether the security group has correctly released port 443',
|
||||||
SSLConfig: 'Certificate Settings',
|
SSLConfig: 'Certificate Settings',
|
||||||
|
@ -80,8 +80,8 @@ const message = {
|
|||||||
Rollbacking: '快照回滚中,请稍候...',
|
Rollbacking: '快照回滚中,请稍候...',
|
||||||
},
|
},
|
||||||
msg: {
|
msg: {
|
||||||
delete: '删除 操作不可回滚,是否继续',
|
delete: '删除 操作不可回滚,是否继续?',
|
||||||
clean: '清空 操作不可回滚,是否继续',
|
clean: '清空 操作不可回滚,是否继续?',
|
||||||
deleteTitle: '删除',
|
deleteTitle: '删除',
|
||||||
deleteSuccess: '删除成功',
|
deleteSuccess: '删除成功',
|
||||||
loginSuccess: '登录成功',
|
loginSuccess: '登录成功',
|
||||||
@ -562,11 +562,11 @@ const message = {
|
|||||||
|
|
||||||
compose: '编排',
|
compose: '编排',
|
||||||
fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?',
|
fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?',
|
||||||
composeHelper: '当前内容已通过格式验证,请点击确认完成创建',
|
|
||||||
composePathHelper: '配置文件保存路径: {0}',
|
composePathHelper: '配置文件保存路径: {0}',
|
||||||
apps: '应用商店',
|
apps: '应用商店',
|
||||||
local: '本地',
|
local: '本地',
|
||||||
createCompose: '创建编排',
|
createCompose: '创建编排',
|
||||||
|
template: '模版',
|
||||||
composeTemplate: '编排模版',
|
composeTemplate: '编排模版',
|
||||||
createComposeTemplate: '创建编排模版',
|
createComposeTemplate: '创建编排模版',
|
||||||
description: '描述',
|
description: '描述',
|
||||||
@ -935,7 +935,7 @@ const message = {
|
|||||||
mfaHelper2: '使用手机应用扫描以下二维码,获取 6 位验证码',
|
mfaHelper2: '使用手机应用扫描以下二维码,获取 6 位验证码',
|
||||||
mfaHelper3: '输入手机应用上的 6 位数字',
|
mfaHelper3: '输入手机应用上的 6 位数字',
|
||||||
sslDisable: '禁用',
|
sslDisable: '禁用',
|
||||||
sslDisableHelper: '禁用 https 服务,需要重启面板才能生效,是否继续!',
|
sslDisableHelper: '禁用 https 服务,需要重启面板才能生效,是否继续?',
|
||||||
|
|
||||||
monitor: '监控',
|
monitor: '监控',
|
||||||
enableMonitor: '监控状态',
|
enableMonitor: '监控状态',
|
||||||
@ -1166,7 +1166,7 @@ const message = {
|
|||||||
HTTPAlso: 'HTTP可直接访问',
|
HTTPAlso: 'HTTP可直接访问',
|
||||||
sslConfig: 'SSL 选项',
|
sslConfig: 'SSL 选项',
|
||||||
disbaleHTTTPS: '禁用 HTTPS',
|
disbaleHTTTPS: '禁用 HTTPS',
|
||||||
disbaleHTTTPSHelper: '禁用 HTTPS会删除证书相关配置,是否继续',
|
disbaleHTTTPSHelper: '禁用 HTTPS会删除证书相关配置,是否继续?',
|
||||||
SSLHelper: '注意:请勿将SSL证书用于非法网站 \n 如开启后无法使用HTTPS访问,请检查安全组是否正确放行443端口',
|
SSLHelper: '注意:请勿将SSL证书用于非法网站 \n 如开启后无法使用HTTPS访问,请检查安全组是否正确放行443端口',
|
||||||
SSLConfig: '证书设置',
|
SSLConfig: '证书设置',
|
||||||
SSLProConfig: 'SSL 协议设置',
|
SSLProConfig: 'SSL 协议设置',
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="form.from === 'edit' || form.from === 'template'" prop="name">
|
<el-form-item v-if="form.from === 'edit' || form.from === 'template'" prop="name">
|
||||||
<el-input @input="changePath" v-model.trim="form.name">
|
<el-input @input="changePath" v-model.trim="form.name">
|
||||||
<template #prepend>{{ $t('file.dir') }}</template>
|
<template #prefix>
|
||||||
|
<span style="margin-right: 8px">{{ $t('file.dir') }}</span>
|
||||||
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<span class="input-help">
|
<span class="input-help">
|
||||||
{{ $t('container.composePathHelper', [composeFile]) }}
|
{{ $t('container.composePathHelper', [composeFile]) }}
|
||||||
@ -44,6 +46,7 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="form.from === 'template'" prop="template">
|
<el-form-item v-if="form.from === 'template'" prop="template">
|
||||||
<el-select v-model="form.template" @change="changeTemplate">
|
<el-select v-model="form.template" @change="changeTemplate">
|
||||||
|
<template #prefix>{{ $t('container.template') }}</template>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in templateOptions"
|
v-for="item in templateOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -70,11 +73,9 @@
|
|||||||
:lineWrapping="true"
|
:lineWrapping="true"
|
||||||
:matchBrackets="true"
|
:matchBrackets="true"
|
||||||
theme="cobalt"
|
theme="cobalt"
|
||||||
@change="hasChecked = false"
|
|
||||||
:styleActiveLine="true"
|
:styleActiveLine="true"
|
||||||
:extensions="extensions"
|
:extensions="extensions"
|
||||||
v-model="form.file"
|
v-model="form.file"
|
||||||
:disabled="onCreating"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<codemirror
|
<codemirror
|
||||||
@ -103,10 +104,7 @@
|
|||||||
<el-button @click="drawerVisiable = false">
|
<el-button @click="drawerVisiable = false">
|
||||||
{{ $t('commons.button.cancel') }}
|
{{ $t('commons.button.cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button :disabled="buttonDisabled" @click="onTest(formRef)">
|
<el-button type="primary" :disabled="onCreating" @click="onSubmit(formRef)">
|
||||||
{{ $t('commons.button.verify') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" :disabled="buttonDisabled || !hasChecked" @click="onSubmit(formRef)">
|
|
||||||
{{ $t('commons.button.confirm') }}
|
{{ $t('commons.button.confirm') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
@ -128,7 +126,6 @@ import { listComposeTemplate, testCompose, upCompose } from '@/api/modules/conta
|
|||||||
import { loadBaseDir } from '@/api/modules/setting';
|
import { loadBaseDir } from '@/api/modules/setting';
|
||||||
import { LoadFile } from '@/api/modules/files';
|
import { LoadFile } from '@/api/modules/files';
|
||||||
import { formatImageStdout } from '@/utils/docker';
|
import { formatImageStdout } from '@/utils/docker';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
|
|
||||||
@ -145,13 +142,10 @@ const logInfo = ref();
|
|||||||
|
|
||||||
const drawerVisiable = ref(false);
|
const drawerVisiable = ref(false);
|
||||||
const templateOptions = ref();
|
const templateOptions = ref();
|
||||||
const buttonDisabled = ref(false);
|
|
||||||
|
|
||||||
const baseDir = ref();
|
const baseDir = ref();
|
||||||
const composeFile = ref();
|
const composeFile = ref();
|
||||||
|
|
||||||
const hasChecked = ref();
|
|
||||||
|
|
||||||
let timer: NodeJS.Timer | null = null;
|
let timer: NodeJS.Timer | null = null;
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@ -178,7 +172,6 @@ const acceptParams = (): void => {
|
|||||||
form.from = 'edit';
|
form.from = 'edit';
|
||||||
form.path = '';
|
form.path = '';
|
||||||
form.file = '';
|
form.file = '';
|
||||||
hasChecked.value = false;
|
|
||||||
logInfo.value = '';
|
logInfo.value = '';
|
||||||
loadTemplates();
|
loadTemplates();
|
||||||
loadPath();
|
loadPath();
|
||||||
@ -186,7 +179,6 @@ const acceptParams = (): void => {
|
|||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
||||||
const changeTemplate = () => {
|
const changeTemplate = () => {
|
||||||
hasChecked.value = false;
|
|
||||||
for (const item of templateOptions.value) {
|
for (const item of templateOptions.value) {
|
||||||
if (form.template === item.id) {
|
if (form.template === item.id) {
|
||||||
form.file = item.content;
|
form.file = item.content;
|
||||||
@ -203,14 +195,11 @@ const changeFrom = () => {
|
|||||||
type: 'info',
|
type: 'info',
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
hasChecked.value = false;
|
if (oldFrom.value === 'template') {
|
||||||
if (form.from === 'template') {
|
form.template = null;
|
||||||
if (!form.template && templateOptions.value && templateOptions.value.length !== 0) {
|
form.file = '';
|
||||||
form.template = templateOptions.value[0].id;
|
|
||||||
}
|
|
||||||
changeTemplate();
|
|
||||||
}
|
}
|
||||||
if (form.from === 'edit') {
|
if (oldFrom.value === 'edit') {
|
||||||
form.file = '';
|
form.file = '';
|
||||||
}
|
}
|
||||||
oldFrom.value = form.from;
|
oldFrom.value = form.from;
|
||||||
@ -243,18 +232,21 @@ const changePath = async () => {
|
|||||||
type FormInstance = InstanceType<typeof ElForm>;
|
type FormInstance = InstanceType<typeof ElForm>;
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
const onTest = async (formEl: FormInstance | undefined) => {
|
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
logInfo.value = '';
|
logInfo.value = '';
|
||||||
await testCompose(form)
|
await testCompose(form)
|
||||||
.then((res) => {
|
.then(async (res) => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
MsgSuccess(i18n.global.t('container.composeHelper'));
|
onCreating.value = true;
|
||||||
hasChecked.value = true;
|
mode.value = 'log';
|
||||||
|
const res = await upCompose(form);
|
||||||
|
logInfo.value = '';
|
||||||
|
loadLogs(res.data);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@ -263,19 +255,6 @@ const onTest = async (formEl: FormInstance | undefined) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
onCreating.value = true;
|
|
||||||
mode.value = 'log';
|
|
||||||
const res = await upCompose(form);
|
|
||||||
logInfo.value = '';
|
|
||||||
buttonDisabled.value = true;
|
|
||||||
loadLogs(res.data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadLogs = async (path: string) => {
|
const loadLogs = async (path: string) => {
|
||||||
timer = setInterval(async () => {
|
timer = setInterval(async () => {
|
||||||
const res = await LoadFile({ path: path });
|
const res = await LoadFile({ path: path });
|
||||||
@ -294,14 +273,12 @@ const loadLogs = async (path: string) => {
|
|||||||
onCreating.value = false;
|
onCreating.value = false;
|
||||||
clearInterval(Number(timer));
|
clearInterval(Number(timer));
|
||||||
timer = null;
|
timer = null;
|
||||||
buttonDisabled.value = false;
|
|
||||||
}
|
}
|
||||||
}, 1000 * 3);
|
}, 1000 * 3);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadDir = async (path: string) => {
|
const loadDir = async (path: string) => {
|
||||||
form.path = path;
|
form.path = path;
|
||||||
hasChecked.value = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@ -313,3 +290,5 @@ defineExpose({
|
|||||||
acceptParams,
|
acceptParams,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user