feat: 数据库详情界面样式调整

pull/107/head
ssongliu 2023-02-01 14:02:20 +08:00 committed by ssongliu
parent 6ae7274095
commit d22b0a1368
30 changed files with 1361 additions and 1126 deletions

View File

@ -40,11 +40,11 @@ type daemonJsonItem struct {
func (u *DockerService) LoadDockerStatus() string {
status := constant.StatusRunning
cmd := exec.Command("systemctl", "is-active", "docker")
stdout, err := cmd.CombinedOutput()
if string(stdout) != "active\n" || err != nil {
status = constant.Stopped
}
// cmd := exec.Command("systemctl", "is-active", "docker")
// stdout, err := cmd.CombinedOutput()
// if string(stdout) != "active\n" || err != nil {
// status = constant.Stopped
// }
return status
}

View File

@ -17,7 +17,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 700px"
style="margin-top: 10px; height: calc(100vh - 350px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"

View File

@ -596,7 +596,6 @@ export default {
batchInput: '',
quickCommand: '',
groupDeleteHelper: ' default ',
quickCmd: '',
command: '',
addHost: '',
localhost: '',

View File

@ -1,59 +1,66 @@
<template>
<el-drawer v-model="composeVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.compose') }}</span>
</div>
<DrawerHeader :header="$t('container.compose')" :back="handleClose" />
</template>
<div v-loading="loading">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('container.name')" prop="name">
<el-input v-model.trim="form.name"></el-input>
</el-form-item>
<el-form-item :label="$t('container.from')">
<el-radio-group v-model="form.from">
<el-radio label="edit">{{ $t('container.edit') }}</el-radio>
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
<el-radio label="template">{{ $t('container.composeTemplate') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.from === 'path'" prop="path">
<el-input
disabled
:placeholder="$t('commons.example') + '/tmp/docker-compose.yml'"
v-model="form.path"
>
<template #append>
<FileList @choose="loadDir" :dir="false"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item v-if="form.from === 'template'" prop="template">
<el-select v-model="form.template">
<el-option v-for="item in templateOptions" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item v-if="form.from === 'edit'">
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 251px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.file"
:readOnly="true"
/>
</el-form-item>
<el-form ref="formRef" label-position="top" :model="form" :rules="rules" label-width="80px">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.name')" prop="name">
<el-input v-model.trim="form.name"></el-input>
</el-form-item>
<el-form-item :label="$t('container.from')">
<el-radio-group v-model="form.from">
<el-radio label="edit">{{ $t('container.edit') }}</el-radio>
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
<el-radio label="template">{{ $t('container.composeTemplate') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.from === 'path'" prop="path">
<el-input
disabled
:placeholder="$t('commons.example') + '/tmp/docker-compose.yml'"
v-model="form.path"
>
<template #append>
<FileList @choose="loadDir" :dir="false"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item v-if="form.from === 'template'" prop="template">
<el-select v-model="form.template">
<el-option
v-for="item in templateOptions"
:key="item.id"
:value="item.id"
:label="item.name"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.from === 'edit'">
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 351px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.file"
:readOnly="true"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="composeVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
@ -74,7 +81,7 @@ import { ElForm, ElMessage } from 'element-plus';
import { listComposeTemplate, upCompose } from '@/api/modules/container';
const extensions = [javascript(), oneDark];
const composeVisiable = ref(false);
const drawerVisiable = ref(false);
const templateOptions = ref();
const loading = ref(false);
@ -106,7 +113,7 @@ const loadTemplates = async () => {
};
const acceptParams = (): void => {
composeVisiable.value = true;
drawerVisiable.value = true;
form.name = '';
form.from = 'edit';
form.path = '';
@ -115,6 +122,10 @@ const acceptParams = (): void => {
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();
@ -128,7 +139,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
loading.value = false;
emit('search');
composeVisiable.value = false;
drawerVisiable.value = false;
})
.finally(() => {
loading.value = false;

View File

@ -1,186 +1,195 @@
<template>
<el-drawer v-model="createVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.createContainer') }}</span>
</div>
<DrawerHeader :header="$t('container.createContainer')" :back="handleClose" />
</template>
<el-form ref="formRef" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('container.name')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.image')" prop="image">
<el-select style="width: 100%" filterable v-model="form.image">
<el-option v-for="(item, index) of images" :key="index" :value="item.option" :label="item.option" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.port')">
<el-radio-group v-model="form.publishAllPorts" class="ml-4">
<el-radio :label="false">{{ $t('container.exposePort') }}</el-radio>
<el-radio :label="true">{{ $t('container.exposeAll') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="!form.publishAllPorts">
<el-card style="width: 100%">
<table style="width: 100%" class="tab-table">
<tr v-if="form.exposedPorts.length !== 0">
<th scope="col" width="48%" align="left">
<label>{{ $t('container.serverPort') }}</label>
</th>
<th scope="col" width="48%" align="left">
<label>{{ $t('container.containerPort') }}</label>
</th>
<th align="left"></th>
</tr>
<tr v-for="(row, index) in form.exposedPorts" :key="index">
<td width="48%">
<el-input-number
:min="0"
:max="65535"
style="width: 100%"
controls-position="right"
v-model.number="row.hostPort"
/>
</td>
<td width="48%">
<el-input-number
:min="0"
:max="65535"
style="width: 100%"
controls-position="right"
v-model.number="row.containerPort"
/>
</td>
<td>
<el-button link style="font-size: 10px" @click="handlePortsDelete(index)">
{{ $t('commons.button.delete') }}
</el-button>
</td>
</tr>
<tr>
<td align="left">
<el-button @click="handlePortsAdd()">{{ $t('commons.button.add') }}</el-button>
</td>
</tr>
</table>
</el-card>
</el-form-item>
<el-form-item :label="$t('container.cmd')" prop="cmdStr">
<el-input
type="textarea"
:placeholder="$t('container.cmdHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.cmdStr"
/>
</el-form-item>
<el-form-item prop="autoRemove">
<el-checkbox v-model="form.autoRemove">{{ $t('container.autoRemove') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('container.cpuQuota')" prop="nanoCPUs">
<el-input type="number" style="width: 40%" v-model.number="form.nanoCPUs">
<template #append>
<el-select v-model="form.cpuUnit" disabled style="width: 65px">
<el-option label="Core" value="Core" />
<el-form ref="formRef" label-position="top" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.name')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.image')" prop="image">
<el-select style="width: 100%" filterable v-model="form.image">
<el-option
v-for="(item, index) of images"
:key="index"
:value="item.option"
:label="item.option"
/>
</el-select>
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.memoryLimit')" prop="memoryItem">
<el-input style="width: 40%" v-model.number="form.memoryItem">
<template #append>
<el-select v-model="form.memoryUnit" placeholder="Select" style="width: 65px">
<el-option label="KB" value="KB" />
<el-option label="MB" value="MB" />
<el-option label="GB" value="GB" />
</el-select>
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.mount')">
<el-card style="width: 100%">
<table style="width: 100%" class="tab-table">
<tr v-if="form.volumes.length !== 0">
<th scope="col" width="42%" align="left">
<label>{{ $t('container.serverPath') }}</label>
</th>
<th scope="col" width="12%" align="left">
<label>{{ $t('container.mode') }}</label>
</th>
<th scope="col" width="42%" align="left">
<label>{{ $t('container.containerDir') }}</label>
</th>
<th align="left"></th>
</tr>
<tr v-for="(row, index) in form.volumes" :key="index">
<td width="42%">
<el-select
style="width: 100%"
allow-create
clearable
:placeholder="$t('commons.msg.inputOrSelect')"
filterable
v-model="row.sourceDir"
>
<el-option
v-for="(item, indexV) of volumes"
:key="indexV"
:value="item.option"
:label="item.option"
/>
</el-form-item>
<el-form-item :label="$t('container.port')">
<el-radio-group v-model="form.publishAllPorts" class="ml-4">
<el-radio :label="false">{{ $t('container.exposePort') }}</el-radio>
<el-radio :label="true">{{ $t('container.exposeAll') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="!form.publishAllPorts">
<el-card style="width: 100%">
<table style="width: 100%" class="tab-table">
<tr v-if="form.exposedPorts.length !== 0">
<th scope="col" width="48%" align="left">
<label>{{ $t('container.serverPort') }}</label>
</th>
<th scope="col" width="48%" align="left">
<label>{{ $t('container.containerPort') }}</label>
</th>
<th align="left"></th>
</tr>
<tr v-for="(row, index) in form.exposedPorts" :key="index">
<td width="48%">
<el-input-number
:min="0"
:max="65535"
style="width: 100%"
controls-position="right"
v-model.number="row.hostPort"
/>
</td>
<td width="48%">
<el-input-number
:min="0"
:max="65535"
style="width: 100%"
controls-position="right"
v-model.number="row.containerPort"
/>
</td>
<td>
<el-button link style="font-size: 10px" @click="handlePortsDelete(index)">
{{ $t('commons.button.delete') }}
</el-button>
</td>
</tr>
<tr>
<td align="left">
<el-button @click="handlePortsAdd()">{{ $t('commons.button.add') }}</el-button>
</td>
</tr>
</table>
</el-card>
</el-form-item>
<el-form-item :label="$t('container.cmd')" prop="cmdStr">
<el-input
type="textarea"
:placeholder="$t('container.cmdHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.cmdStr"
/>
</el-form-item>
<el-form-item prop="autoRemove">
<el-checkbox v-model="form.autoRemove">{{ $t('container.autoRemove') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('container.cpuQuota')" prop="nanoCPUs">
<el-input type="number" style="width: 40%" v-model.number="form.nanoCPUs">
<template #append>
<el-select v-model="form.cpuUnit" disabled style="width: 65px">
<el-option label="Core" value="Core" />
</el-select>
</td>
<td width="12%">
<el-select style="width: 100%" filterable v-model="row.mode">
<el-option value="rw" :label="$t('container.modeRW')" />
<el-option value="ro" :label="$t('container.modeR')" />
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.memoryLimit')" prop="memoryItem">
<el-input style="width: 40%" v-model.number="form.memoryItem">
<template #append>
<el-select v-model="form.memoryUnit" placeholder="Select" style="width: 65px">
<el-option label="KB" value="KB" />
<el-option label="MB" value="MB" />
<el-option label="GB" value="GB" />
</el-select>
</td>
<td width="42%">
<el-input v-model="row.containerDir" />
</td>
<td>
<el-button link style="font-size: 10px" @click="handleVolumesDelete(index)">
{{ $t('commons.button.delete') }}
</el-button>
</td>
</tr>
<tr>
<td align="left">
<el-button @click="handleVolumesAdd()">{{ $t('commons.button.add') }}</el-button>
</td>
</tr>
</table>
</el-card>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelsStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelsStr"
/>
</el-form-item>
<el-form-item :label="$t('container.env')" prop="envStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.envStr"
/>
</el-form-item>
<el-form-item :label="$t('container.restartPolicy')" prop="restartPolicy">
<el-radio-group v-model="form.restartPolicy">
<el-radio label="unless-stopped">{{ $t('container.unlessStopped') }}</el-radio>
<el-radio label="on-failure">{{ $t('container.onFailure') }}</el-radio>
<el-radio label="no">{{ $t('container.no') }}</el-radio>
</el-radio-group>
</el-form-item>
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.mount')">
<el-card style="width: 100%">
<table style="width: 100%" class="tab-table">
<tr v-if="form.volumes.length !== 0">
<th scope="col" width="42%" align="left">
<label>{{ $t('container.serverPath') }}</label>
</th>
<th scope="col" width="12%" align="left">
<label>{{ $t('container.mode') }}</label>
</th>
<th scope="col" width="42%" align="left">
<label>{{ $t('container.containerDir') }}</label>
</th>
<th align="left"></th>
</tr>
<tr v-for="(row, index) in form.volumes" :key="index">
<td width="42%">
<el-select
style="width: 100%"
allow-create
clearable
:placeholder="$t('commons.msg.inputOrSelect')"
filterable
v-model="row.sourceDir"
>
<el-option
v-for="(item, indexV) of volumes"
:key="indexV"
:value="item.option"
:label="item.option"
/>
</el-select>
</td>
<td width="12%">
<el-select style="width: 100%" filterable v-model="row.mode">
<el-option value="rw" :label="$t('container.modeRW')" />
<el-option value="ro" :label="$t('container.modeR')" />
</el-select>
</td>
<td width="42%">
<el-input v-model="row.containerDir" />
</td>
<td>
<el-button link style="font-size: 10px" @click="handleVolumesDelete(index)">
{{ $t('commons.button.delete') }}
</el-button>
</td>
</tr>
<tr>
<td align="left">
<el-button @click="handleVolumesAdd()">
{{ $t('commons.button.add') }}
</el-button>
</td>
</tr>
</table>
</el-card>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelsStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelsStr"
/>
</el-form-item>
<el-form-item :label="$t('container.env')" prop="envStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.envStr"
/>
</el-form-item>
<el-form-item :label="$t('container.restartPolicy')" prop="restartPolicy">
<el-radio-group v-model="form.restartPolicy">
<el-radio label="unless-stopped">{{ $t('container.unlessStopped') }}</el-radio>
<el-radio label="on-failure">{{ $t('container.onFailure') }}</el-radio>
<el-radio label="no">{{ $t('container.no') }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="createVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -201,7 +210,7 @@ import { Container } from '@/api/interface/container';
const loading = ref(false);
const createVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
name: '',
image: '',
@ -226,13 +235,17 @@ const images = ref();
const volumes = ref();
const acceptParams = (): void => {
createVisiable.value = true;
drawerVisiable.value = true;
form.restartPolicy = 'no';
form.memoryUnit = 'MB';
loadImageOptions();
loadVolumeOptions();
};
const handleClose = () => {
drawerVisiable.value = false;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const rules = reactive({
@ -306,7 +319,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
createVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;

View File

@ -1,79 +1,81 @@
<template>
<el-drawer
v-model="buildVisiable"
v-model="drawerVisiable"
:destroy-on-close="true"
@close="onCloseLog"
:close-on-click-modal="false"
size="50%"
>
<template #header>
<div class="card-header">
<span>{{ $t('container.imageBuild') }}</span>
</div>
<DrawerHeader :header="$t('container.imageBuild')" :back="handleClose" />
</template>
<el-form ref="formRef" :model="form" label-width="80px" :rules="rules">
<el-form-item :label="$t('container.name')" prop="name">
<el-input :placeholder="$t('container.imageNameHelper')" v-model.trim="form.name" clearable />
</el-form-item>
<el-form-item label="Dockerfile" prop="from">
<el-radio-group v-model="form.from">
<el-radio label="edit">{{ $t('container.edit') }}</el-radio>
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form ref="formRef" label-position="top" :model="form" label-width="80px" :rules="rules">
<el-form-item :label="$t('container.name')" prop="name">
<el-input :placeholder="$t('container.imageNameHelper')" v-model.trim="form.name" clearable />
</el-form-item>
<el-form-item label="Dockerfile" prop="from">
<el-radio-group v-model="form.from">
<el-radio label="edit">{{ $t('container.edit') }}</el-radio>
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your Dockerfile here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 520px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.dockerfile"
:readOnly="true"
/>
</el-form-item>
<el-form-item v-else :rules="Rules.requiredSelect" prop="dockerfile">
<el-input clearable v-model="form.dockerfile">
<template #append>
<FileList @choose="loadBuildDir" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.tag')">
<el-input
:placeholder="$t('container.tagHelper')"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.tagStr"
/>
</el-form-item>
</el-form>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="#Define or paste the content of your Dockerfile here"
placeholder="Waiting for build output..."
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 350px)"
style="max-height: 300px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.dockerfile"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
</el-form-item>
<el-form-item v-else :rules="Rules.requiredSelect" prop="dockerfile">
<el-input clearable v-model="form.dockerfile">
<template #append>
<FileList @choose="loadBuildDir" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.tag')">
<el-input
:placeholder="$t('container.tagHelper')"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.tagStr"
/>
</el-form-item>
</el-form>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="Waiting for build output..."
:indent-with-tab="true"
:tabSize="4"
style="max-height: 300px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="buttonDisabled" @click="buildVisiable = false">
<el-button :disabled="buttonDisabled" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="buttonDisabled" type="primary" @click="onSubmit(formRef)">
@ -107,7 +109,7 @@ let timer: NodeJS.Timer | null = null;
const buttonDisabled = ref(false);
const buildVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
from: 'path',
dockerfile: '',
@ -127,7 +129,7 @@ const rules = reactive({
dockerfile: [Rules.requiredInput, { validator: varifyPath, trigger: 'change', required: true }],
});
const acceptParams = async () => {
buildVisiable.value = true;
drawerVisiable.value = true;
form.from = 'path';
form.dockerfile = '';
form.tagStr = '';
@ -135,9 +137,12 @@ const acceptParams = async () => {
logInfo.value = '';
buttonDisabled.value = false;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();

View File

@ -1,56 +1,58 @@
<template>
<el-drawer
v-model="pullVisiable"
v-model="drawerVisiable"
@close="onCloseLog"
:destroy-on-close="true"
:close-on-click-modal="false"
size="50%"
>
<template #header>
<div class="card-header">
<span>{{ $t('container.imagePull') }}</span>
</div>
<DrawerHeader :header="$t('container.imagePull')" :back="handleClose" />
</template>
<el-form ref="formRef" :model="form" label-width="80px">
<el-form-item :label="$t('container.from')">
<el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox>
</el-form-item>
<el-form-item
v-if="form.fromRepo"
:label="$t('container.repoName')"
:rules="Rules.requiredSelect"
prop="repoID"
>
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.imageName')" :rules="Rules.requiredInput" prop="imageName">
<el-input v-model.trim="form.imageName">
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form ref="formRef" label-position="top" :model="form" label-width="80px">
<el-form-item :label="$t('container.from')">
<el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox>
</el-form-item>
<el-form-item
v-if="form.fromRepo"
:label="$t('container.repoName')"
:rules="Rules.requiredSelect"
prop="repoID"
>
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.imageName')" :rules="Rules.requiredInput" prop="imageName">
<el-input v-model.trim="form.imageName">
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="Waiting for pull output..."
:indent-with-tab="true"
:tabSize="4"
style="max-height: 300px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="Waiting for pull output..."
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 415px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="buttonDisabled" @click="pullVisiable = false">
<el-button :disabled="buttonDisabled" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="buttonDisabled" type="primary" @click="onSubmit(formRef)">
@ -73,7 +75,7 @@ import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { LoadFile } from '@/api/modules/files';
const pullVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
fromRepo: true,
repoID: null as number,
@ -97,7 +99,7 @@ interface DialogProps {
const repos = ref();
const acceptParams = async (params: DialogProps): Promise<void> => {
pullVisiable.value = true;
drawerVisiable.value = true;
form.fromRepo = true;
form.imageName = '';
repos.value = params.repos;
@ -107,6 +109,10 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();

View File

@ -1,53 +1,61 @@
<template>
<el-drawer
v-model="pushVisiable"
v-model="drawerVisiable"
@close="onCloseLog"
:destroy-on-close="true"
:close-on-click-modal="false"
size="50%"
>
<template #header>
<div class="card-header">
<span>{{ $t('container.imagePush') }}</span>
</div>
<DrawerHeader :header="$t('container.imagePush')" :back="handleClose" />
</template>
<el-form ref="formRef" :model="form" label-width="80px">
<el-form-item label="Tag" :rules="Rules.requiredSelect" prop="tagName">
<el-select filterable v-model="form.tagName">
<el-option v-for="item in form.tags" :key="item" :value="item" :label="item" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.repoName')" :rules="Rules.requiredSelect" prop="repoID">
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option v-for="item in dialogData.repos" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.label')" :rules="Rules.requiredInput" prop="name">
<el-input v-model.trim="form.name">
<template #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form ref="formRef" label-position="top" :model="form" label-width="80px">
<el-form-item label="Tag" :rules="Rules.requiredSelect" prop="tagName">
<el-select filterable v-model="form.tagName">
<el-option v-for="item in form.tags" :key="item" :value="item" :label="item" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.repoName')" :rules="Rules.requiredSelect" prop="repoID">
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option
v-for="item in dialogData.repos"
:key="item.id"
:value="item.id"
:label="item.name"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('container.label')" :rules="Rules.requiredInput" prop="name">
<el-input v-model.trim="form.name">
<template #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="Waiting for push output..."
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 415px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
</el-col>
</el-row>
<codemirror
v-if="logVisiable"
:autofocus="true"
placeholder="Waiting for push output..."
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 301px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:readOnly="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="buttonDisabled" @click="pushVisiable = false">
<el-button :disabled="buttonDisabled" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="buttonDisabled" type="primary" @click="onSubmit(formRef)">
@ -70,7 +78,7 @@ import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { LoadFile } from '@/api/modules/files';
const pushVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
tags: [] as Array<string>,
tagName: '',
@ -99,16 +107,19 @@ const dialogData = ref<DialogProps>({
});
const acceptParams = async (params: DialogProps): Promise<void> => {
pushVisiable.value = true;
drawerVisiable.value = true;
form.tags = params.tags;
form.repoID = 1;
form.tagName = '';
form.name = '';
dialogData.value.repos = params.repos;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();

View File

@ -1,38 +1,41 @@
<template>
<el-drawer v-model="saveVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.exportImage') }}</span>
</div>
<DrawerHeader :header="$t('container.exportImage')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="formRef" :model="form" label-width="80px">
<el-form-item label="Tag" :rules="Rules.requiredSelect" prop="tagName">
<el-select filterable v-model="form.tagName">
<el-option
:disabled="item.indexOf(':<none>') !== -1"
v-for="item in form.tags"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('container.path')" :rules="Rules.requiredSelect" prop="path">
<el-input disabled v-model="form.path">
<template #append>
<FileList @choose="loadSaveDir" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.fileName')" :rules="Rules.requiredInput" prop="name">
<el-input v-model="form.name">
<template #append>.tar</template>
</el-input>
</el-form-item>
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item label="Tag" :rules="Rules.requiredSelect" prop="tagName">
<el-select filterable v-model="form.tagName">
<el-option
:disabled="item.indexOf(':<none>') !== -1"
v-for="item in form.tags"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('container.path')" :rules="Rules.requiredSelect" prop="path">
<el-input disabled v-model="form.path">
<template #append>
<FileList @choose="loadSaveDir" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.fileName')" :rules="Rules.requiredInput" prop="name">
<el-input v-model="form.name">
<template #append>.tar</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabeld="loading" @click="saveVisiable = false">
<el-button :disabeld="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabeld="loading" type="primary" @click="onSubmit(formRef)">
@ -54,7 +57,7 @@ import { Container } from '@/api/interface/container';
const loading = ref(false);
const saveVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
tags: [] as Array<string>,
tagName: '',
@ -72,16 +75,19 @@ const dialogData = ref<DialogProps>({
});
const acceptParams = async (params: DialogProps): Promise<void> => {
saveVisiable.value = true;
drawerVisiable.value = true;
form.tags = params.tags;
form.path = '';
form.tagName = '';
form.name = '';
dialogData.value.repos = params.repos;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();
@ -93,7 +99,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
await imageSave(form)
.then(() => {
loading.value = false;
saveVisiable.value = false;
drawerVisiable.value = false;
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})

View File

@ -1,33 +1,36 @@
<template>
<el-drawer v-model="tagVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>Tag {{ $t('container.image') }}</span>
</div>
<DrawerHeader :header="'Tag ' + $t('container.image')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="formRef" :model="form" label-width="80px">
<el-form-item :label="$t('container.from')">
<el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox>
</el-form-item>
<el-form-item
v-if="form.fromRepo"
:label="$t('container.repoName')"
:rules="Rules.requiredSelect"
prop="repoID"
>
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.imageName')" :rules="Rules.requiredInput" prop="targetName">
<el-input v-model="form.targetName">
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.from')">
<el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox>
</el-form-item>
<el-form-item
v-if="form.fromRepo"
:label="$t('container.repoName')"
:rules="Rules.requiredSelect"
prop="repoID"
>
<el-select style="width: 100%" filterable v-model="form.repoID">
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.imageName')" :rules="Rules.requiredInput" prop="targetName">
<el-input v-model="form.targetName">
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabeld="loading" @click="tagVisiable = false">
<el-button :disabeld="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabeld="loading" type="primary" @click="onSubmit(formRef)">
@ -48,7 +51,7 @@ import { Container } from '@/api/interface/container';
const loading = ref(false);
const tagVisiable = ref(false);
const drawerVisiable = ref(false);
const repos = ref();
const form = reactive({
sourceID: '',
@ -63,16 +66,19 @@ interface DialogProps {
}
const acceptParams = async (params: DialogProps): Promise<void> => {
tagVisiable.value = true;
drawerVisiable.value = true;
form.repoID = 1;
form.sourceID = params.sourceID;
form.targetName = '';
form.fromRepo = true;
repos.value = params.repos;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();
@ -87,7 +93,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
await imageTag(form)
.then(() => {
loading.value = false;
tagVisiable.value = false;
drawerVisiable.value = false;
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})

View File

@ -1,51 +1,53 @@
<template>
<el-drawer v-model="createVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.createNetwork') }}</span>
</div>
<DrawerHeader :header="$t('container.createNetwork')" :back="handleClose" />
</template>
<el-form ref="formRef" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('container.networkName')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.driver')" prop="driver">
<el-select v-model="form.driver">
<el-option label="bridge" value="bridge" />
<el-option label="ipvlan" value="ipvlan" />
<el-option label="macvlan" value="macvlan" />
<el-option label="overlay" value="overlay" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.optionStr"
/>
</el-form-item>
<el-form-item :label="$t('container.subnet')" prop="subnet">
<el-input clearable v-model.trim="form.subnet" />
</el-form-item>
<el-form-item :label="$t('container.gateway')" prop="gateway">
<el-input clearable v-model.trim="form.gateway" />
</el-form-item>
<el-form-item :label="$t('container.scope')" prop="scope">
<el-input clearable v-model.trim="form.scope" />
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelStr"
/>
</el-form-item>
<el-form ref="formRef" label-position="top" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.networkName')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.driver')" prop="driver">
<el-select v-model="form.driver">
<el-option label="bridge" value="bridge" />
<el-option label="ipvlan" value="ipvlan" />
<el-option label="macvlan" value="macvlan" />
<el-option label="overlay" value="overlay" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.optionStr"
/>
</el-form-item>
<el-form-item :label="$t('container.subnet')" prop="subnet">
<el-input clearable v-model.trim="form.subnet" />
</el-form-item>
<el-form-item :label="$t('container.gateway')" prop="gateway">
<el-input clearable v-model.trim="form.gateway" />
</el-form-item>
<el-form-item :label="$t('container.scope')" prop="scope">
<el-input clearable v-model.trim="form.scope" />
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelStr"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="createVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -65,7 +67,7 @@ import { createNetwork } from '@/api/modules/container';
const loading = ref(false);
const createVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
name: '',
labelStr: '',
@ -79,11 +81,14 @@ const form = reactive({
});
const acceptParams = (): void => {
createVisiable.value = true;
drawerVisiable.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
const rules = reactive({
name: [Rules.requiredInput, Rules.name],
driver: [Rules.requiredSelect],
@ -107,7 +112,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
createVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;

View File

@ -1,58 +1,68 @@
<template>
<el-drawer v-model="repoVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ title }}{{ $t('container.repo') }}</span>
</div>
<DrawerHeader :header="title + $t('container.repo')" :back="handleClose" />
</template>
<el-form ref="formRef" v-loading="loading" :model="dialogData.rowData" :rules="rules" label-width="120px">
<el-form-item :label="$t('container.name')" prop="name">
<el-input
clearable
:disabled="dialogData.title === 'edit'"
v-model.trim="dialogData.rowData!.name"
></el-input>
</el-form-item>
<el-form-item :label="$t('container.auth')" prop="auth">
<el-radio-group v-model="dialogData.rowData!.auth">
<el-radio :label="true">{{ $t('commons.true') }}</el-radio>
<el-radio :label="false">{{ $t('commons.false') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.username')" prop="username">
<el-input clearable v-model.trim="dialogData.rowData!.username"></el-input>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.password')" prop="password">
<el-input
clearable
type="password"
show-password
v-model.trim="dialogData.rowData!.password"
></el-input>
</el-form-item>
<el-form-item :label="$t('container.downloadUrl')" prop="downloadUrl">
<el-input
clearable
v-model.trim="dialogData.rowData!.downloadUrl"
:placeholder="'172.16.10.10:8081'"
></el-input>
<span v-if="dialogData.rowData!.downloadUrl" class="input-help">
docker pull {{ dialogData.rowData!.downloadUrl }}/nginx
</span>
</el-form-item>
<el-form-item :label="$t('container.protocol')" prop="protocol">
<el-radio-group v-model="dialogData.rowData!.protocol">
<el-radio label="http">http</el-radio>
<el-radio label="https">https</el-radio>
</el-radio-group>
<span v-if="dialogData.rowData!.protocol === 'http'" class="input-help">
{{ $t('container.httpRepo') }}
</span>
</el-form-item>
<el-form
ref="formRef"
label-position="top"
v-loading="loading"
:model="dialogData.rowData"
:rules="rules"
label-width="120px"
>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.name')" prop="name">
<el-input
clearable
:disabled="dialogData.title === 'edit'"
v-model.trim="dialogData.rowData!.name"
></el-input>
</el-form-item>
<el-form-item :label="$t('container.auth')" prop="auth">
<el-radio-group v-model="dialogData.rowData!.auth">
<el-radio :label="true">{{ $t('commons.true') }}</el-radio>
<el-radio :label="false">{{ $t('commons.false') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.username')" prop="username">
<el-input clearable v-model.trim="dialogData.rowData!.username"></el-input>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.password')" prop="password">
<el-input
clearable
type="password"
show-password
v-model.trim="dialogData.rowData!.password"
></el-input>
</el-form-item>
<el-form-item :label="$t('container.downloadUrl')" prop="downloadUrl">
<el-input
clearable
v-model.trim="dialogData.rowData!.downloadUrl"
:placeholder="'172.16.10.10:8081'"
></el-input>
<span v-if="dialogData.rowData!.downloadUrl" class="input-help">
docker pull {{ dialogData.rowData!.downloadUrl }}/nginx
</span>
</el-form-item>
<el-form-item :label="$t('container.protocol')" prop="protocol">
<el-radio-group v-model="dialogData.rowData!.protocol">
<el-radio label="http">http</el-radio>
<el-radio label="https">https</el-radio>
</el-radio-group>
<span v-if="dialogData.rowData!.protocol === 'http'" class="input-help">
{{ $t('container.httpRepo') }}
</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="repoVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -79,17 +89,20 @@ interface DialogProps {
getTableList?: () => Promise<any>;
}
const title = ref<string>('');
const repoVisiable = ref(false);
const drawerVisiable = ref(false);
const dialogData = ref<DialogProps>({
title: '',
});
const acceptParams = (params: DialogProps): void => {
dialogData.value = params;
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
repoVisiable.value = true;
drawerVisiable.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
const rules = reactive({
name: [Rules.requiredInput, Rules.name],
downloadUrl: [Rules.requiredInput],
@ -113,7 +126,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
repoVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;
@ -125,7 +138,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
repoVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;

View File

@ -1,37 +1,49 @@
<template>
<el-drawer v-model="templateVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ title }}{{ $t('container.composeTemplate') }}</span>
</div>
<DrawerHeader :header="title + $t('container.composeTemplate')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="formRef" :model="dialogData.rowData" :rules="rules" label-width="80px">
<el-form-item :label="$t('container.name')" prop="name">
<el-input :disabled="dialogData.title === 'edit'" v-model.trim="dialogData.rowData!.name"></el-input>
</el-form-item>
<el-form-item :label="$t('container.description')">
<el-input v-model="dialogData.rowData!.description"></el-input>
</el-form-item>
<el-form-item>
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 251px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="dialogData.rowData!.content"
:readOnly="true"
/>
</el-form-item>
<el-form
v-loading="loading"
label-position="top"
ref="formRef"
:model="dialogData.rowData"
:rules="rules"
label-width="80px"
>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.name')" prop="name">
<el-input
:disabled="dialogData.title === 'edit'"
v-model.trim="dialogData.rowData!.name"
></el-input>
</el-form-item>
<el-form-item :label="$t('container.description')">
<el-input v-model="dialogData.rowData!.description"></el-input>
</el-form-item>
<el-form-item>
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 351px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="dialogData.rowData!.content"
:readOnly="true"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="templateVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -62,17 +74,21 @@ interface DialogProps {
}
const extensions = [javascript(), oneDark];
const title = ref<string>('');
const templateVisiable = ref(false);
const drawerVisiable = ref(false);
const dialogData = ref<DialogProps>({
title: '',
});
const acceptParams = (params: DialogProps): void => {
dialogData.value = params;
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
templateVisiable.value = true;
drawerVisiable.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
const rules = reactive({
name: [Rules.requiredInput, Rules.name],
content: [Rules.requiredInput],
@ -92,7 +108,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
templateVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;
@ -104,7 +120,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
templateVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;

View File

@ -1,39 +1,48 @@
<template>
<el-drawer v-model="createVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.createVolume') }}</span>
</div>
<DrawerHeader :header="$t('container.createVolume')" :back="handleClose" />
</template>
<el-form ref="formRef" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-form-item :label="$t('container.volumeName')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.driver')" prop="driver">
<el-select v-model="form.driver">
<el-option label="local" value="local" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.optionStr"
/>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelStr"
/>
</el-form-item>
</el-form>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form
ref="formRef"
v-loading="loading"
label-position="top"
:model="form"
:rules="rules"
label-width="80px"
>
<el-form-item :label="$t('container.volumeName')" prop="name">
<el-input clearable v-model.trim="form.name" />
</el-form-item>
<el-form-item :label="$t('container.driver')" prop="driver">
<el-select v-model="form.driver">
<el-option label="local" value="local" />
</el-select>
</el-form-item>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.optionStr"
/>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.labelStr"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="createVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -53,7 +62,7 @@ import { createVolume } from '@/api/modules/container';
const loading = ref(false);
const createVisiable = ref(false);
const drawerVisiable = ref(false);
const form = reactive({
name: '',
driver: 'local',
@ -64,11 +73,14 @@ const form = reactive({
});
const acceptParams = (): void => {
createVisiable.value = true;
drawerVisiable.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
const rules = reactive({
name: [Rules.requiredInput, Rules.name],
driver: [Rules.requiredSelect],
@ -93,7 +105,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
createVisiable.value = false;
drawerVisiable.value = false;
})
.catch(() => {
loading.value = false;

View File

@ -1,9 +1,7 @@
<template>
<el-drawer v-model="cronjobVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ title }}{{ $t('cronjob.cronTask') }}</span>
</div>
<DrawerHeader :header="$t('cronjob.cronTask')" :back="handleClose" />
</template>
<el-form ref="formRef" :model="dialogData.rowData" label-position="left" :rules="rules" label-width="120px">
<el-form-item :label="$t('cronjob.taskType')" prop="type">
@ -132,7 +130,7 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cronjobVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
@ -161,26 +159,29 @@ interface DialogProps {
getTableList?: () => Promise<any>;
}
const title = ref<string>('');
const cronjobVisiable = ref(false);
const drawerVisiable = ref(false);
const dialogData = ref<DialogProps>({
title: '',
});
const acceptParams = (params: DialogProps): void => {
dialogData.value = params;
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
cronjobVisiable.value = true;
drawerVisiable.value = true;
checkMysqlInstalled();
loadBackups();
loadWebsites();
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
drawerVisiable.value = false;
};
const localDirID = ref();
const websiteOptions = ref();
const backupOptions = ref();
const emit = defineEmits<{ (e: 'search'): void }>();
const mysqlInfo = reactive({
isExist: false,
name: '',
@ -349,7 +350,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
cronjobVisiable.value = false;
drawerVisiable.value = false;
});
};

View File

@ -1,83 +1,89 @@
<template>
<div class="demo-collapse" v-show="onSetting">
<el-card style="margin-top: 5px" v-loading="loading">
<LayoutContent :header="'Mysql ' + $t('database.setting')" :back-name="'Mysql'" :reload="true">
<el-collapse v-model="activeName" @change="handleCollapse" accordion>
<el-collapse-item :title="$t('database.confChange')" name="1">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="mysqlConf"
:readOnly="true"
/>
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" style="margin-top: 10px" @click="onSaveConf">
{{ $t('commons.button.save') }}
</el-button>
<div v-show="onSetting">
<LayoutContent :title="$t('nginx.nginxConfig')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'status'" @click="changeTab('status')">
{{ $t('database.currentStatus') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'tuning'" @click="changeTab('tuning')">
{{ $t('database.performanceTuning') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'port'" @click="changeTab('port')">
{{ $t('database.portSetting') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'log'" @click="changeTab('log')">
{{ $t('database.log') }}
</el-button>
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
:plain="activeName !== 'slowLog'"
@click="changeTab('slowLog')"
>
{{ $t('database.slowLog') }}
</el-button>
</template>
<template #main>
<div v-if="activeName === 'conf'">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 360px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="mysqlConf"
:readOnly="true"
/>
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" style="margin-top: 10px" @click="onSaveConf">
{{ $t('commons.button.save') }}
</el-button>
<el-row>
<el-col :span="8">
<el-alert
v-if="useOld"
style="margin-top: 10px"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
></el-alert>
</el-col>
</el-row>
</div>
<Status v-if="activeName === 'status'" ref="statusRef" />
<Variables v-if="activeName === 'tuning'" ref="variablesRef" />
<div v-if="activeName === 'port'">
<el-form :model="baseInfo" ref="panelFormRef" label-width="120px">
<el-row>
<el-col :span="8">
<el-alert
v-if="useOld"
style="margin-top: 10px"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
></el-alert>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="baseInfo.port">
<template #append>
<el-button @click="onSavePort(panelFormRef)" icon="Collection">
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item
:disabled="mysqlStatus !== 'Running'"
:title="$t('database.currentStatus')"
name="2"
>
<Status ref="statusRef" />
</el-collapse-item>
<el-collapse-item
:disabled="mysqlStatus !== 'Running'"
:title="$t('database.performanceTuning')"
name="3"
>
<Variables ref="variablesRef" />
</el-collapse-item>
<el-collapse-item :title="$t('database.portSetting')" name="4">
<el-form :model="baseInfo" ref="panelFormRef" label-width="120px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="baseInfo.port">
<template #append>
<el-button @click="onSavePort(panelFormRef)" icon="Collection">
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-collapse-item>
<el-collapse-item :title="$t('database.log')" name="5">
<ContainerLog ref="dialogContainerLogRef" />
</el-collapse-item>
<el-collapse-item :disabled="mysqlStatus !== 'Running'" :title="$t('database.slowLog')" name="6">
<SlowLog ref="slowLogRef" />
</el-collapse-item>
</el-collapse>
</LayoutContent>
</el-card>
</el-form>
</div>
<ContainerLog v-if="activeName === 'log'" ref="dialogContainerLogRef" />
<SlowLog v-if="activeName === 'slowLog'" ref="slowLogRef" />
</template>
</LayoutContent>
<ConfirmDialog ref="confirmPortRef" @confirm="onSubmitChangePort"></ConfirmDialog>
<ConfirmDialog ref="confirmConfRef" @confirm="onSubmitChangeConf"></ConfirmDialog>
@ -106,7 +112,7 @@ import { loadBaseDir } from '@/api/modules/setting';
const loading = ref(false);
const extensions = [javascript(), oneDark];
const activeName = ref('1');
const activeName = ref('conf');
const baseInfo = reactive({
name: '',
@ -152,7 +158,8 @@ const onClose = (): void => {
onSetting.value = false;
};
const handleCollapse = async (val: string) => {
const changeTab = (val: string) => {
activeName.value = val;
if (val !== '5') {
dialogContainerLogRef.value!.onCloseLog();
}
@ -160,6 +167,7 @@ const handleCollapse = async (val: string) => {
slowLogRef.value!.onCloseLog();
}
};
const onSubmitChangePort = async () => {
let params = {
key: 'mysql',

View File

@ -14,34 +14,27 @@
inactive-value="OFF"
@change="handleSlowLogs"
/>
<div v-if="variables.slow_query_log === 'ON'" style="margin-left: 20px; float: left">
<div style="margin-left: 20px; float: left">
<el-checkbox border v-model="isWatch">{{ $t('commons.button.watch') }}</el-checkbox>
</div>
<el-button
v-if="variables.slow_query_log === 'ON'"
style="margin-left: 20px"
@click="onDownload"
icon="Download"
>
<el-button style="margin-left: 20px" @click="onDownload" icon="Download">
{{ $t('file.download') }}
</el-button>
<div v-if="variables.slow_query_log === 'ON'">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="slowLogs"
:readOnly="true"
/>
</div>
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 370px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="slowLogs"
:readOnly="true"
/>
<br />
<ConfirmDialog @cancle="onCancle" ref="confirmDialogRef" @confirm="onSave"></ConfirmDialog>

View File

@ -1,51 +1,49 @@
<template>
<div>
<el-row :gutter="20">
<el-col :span="1"><br /></el-col>
<el-col :span="6">
<table style="width: 100%" class="myTable">
<tr>
<td>{{ $t('database.runTime') }}</td>
<td>{{ mysqlStatus.run }}</td>
</tr>
<tr>
<td>{{ $t('database.connections') }}</td>
<td>{{ mysqlStatus.connections }}</td>
</tr>
<tr>
<td>{{ $t('database.bytesSent') }}</td>
<td>{{ mysqlStatus!.bytesSent }}</td>
</tr>
<tr>
<td>{{ $t('database.bytesReceived') }}</td>
<td>{{ mysqlStatus!.bytesReceived }}</td>
</tr>
</table>
<el-col :span="8">
<el-row style="margin-top: 20px">
<table style="width: 100%" class="myTable">
<tr>
<td>{{ $t('database.runTime') }}</td>
<td>{{ mysqlStatus.run }}</td>
</tr>
<tr>
<td>{{ $t('database.connections') }}</td>
<td>{{ mysqlStatus.connections }}</td>
</tr>
<tr>
<td>{{ $t('database.bytesSent') }}</td>
<td>{{ mysqlStatus!.bytesSent }}</td>
</tr>
<tr>
<td>{{ $t('database.bytesReceived') }}</td>
<td>{{ mysqlStatus!.bytesReceived }}</td>
</tr>
</table>
</el-row>
<el-row style="margin-top: 20px">
<table style="width: 100%" class="myTable">
<tr>
<td>{{ $t('database.queryPerSecond') }}</td>
<td>{{ mysqlStatus!.queryPerSecond }}</td>
</tr>
<tr>
<td>{{ $t('database.queryPerSecond') }}</td>
<td>{{ mysqlStatus!.txPerSecond }}</td>
</tr>
<tr>
<td>File</td>
<td>{{ mysqlStatus!.file }}</td>
</tr>
<tr>
<td>Position</td>
<td>{{ mysqlStatus!.position }}</td>
</tr>
</table>
</el-row>
</el-col>
<el-col :span="6">
<table style="width: 100%" class="myTable">
<tr>
<td>{{ $t('database.queryPerSecond') }}</td>
<td>{{ mysqlStatus!.queryPerSecond }}</td>
</tr>
<tr>
<td>{{ $t('database.queryPerSecond') }}</td>
<td>{{ mysqlStatus!.txPerSecond }}</td>
</tr>
<tr>
<td>File</td>
<td>{{ mysqlStatus!.file }}</td>
</tr>
<tr>
<td>Position</td>
<td>{{ mysqlStatus!.position }}</td>
</tr>
</table>
</el-col>
</el-row>
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="12">
<el-col :span="16">
<table style="margin-top: 20px; width: 100%" class="myTable">
<tr>
<td>{{ $t('database.queryPerSecond') }}</td>

View File

@ -1,116 +1,114 @@
<template>
<div>
<el-card v-loading="loading">
<el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-width="160px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item :label="$t('database.optimizationScheme')">
<el-select @change="changePlan" clearable v-model="plan">
<el-option
v-for="item in planOptions"
:key="item.id"
:label="item.title"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="key_buffer_size" prop="key_buffer_size">
<el-input clearable v-model.number="mysqlVariables.key_buffer_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.keyBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="join_buffer_size" prop="join_buffer_size">
<el-input clearable v-model.number="mysqlVariables.join_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.joinBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="tmp_table_size" prop="tmp_table_size">
<el-input clearable v-model.number="mysqlVariables.tmp_table_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.tmpTableSizeHelper') }}</span>
</el-form-item>
<el-form-item label="innodb_buffer_pool_size" prop="innodb_buffer_pool_size">
<el-input clearable v-model.number="mysqlVariables.innodb_buffer_pool_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.innodbBufferPoolSizeHelper') }}</span>
</el-form-item>
<el-form-item label="innodb_log_buffer_size" prop="innodb_log_buffer_size">
<el-input clearable v-model.number="mysqlVariables.innodb_log_buffer_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.innodbLogBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="sort_buffer_size" prop="sort_buffer_size">
<el-input clearable v-model.number="mysqlVariables.sort_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.sortBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="read_buffer_size" prop="read_buffer_size">
<el-input clearable v-model.number="mysqlVariables.read_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.readBufferSizeHelper') }}</span>
</el-form-item>
<el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-width="160px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item :label="$t('database.optimizationScheme')">
<el-select @change="changePlan" clearable v-model="plan">
<el-option
v-for="item in planOptions"
:key="item.id"
:label="item.title"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="key_buffer_size" prop="key_buffer_size">
<el-input clearable v-model.number="mysqlVariables.key_buffer_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.keyBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="join_buffer_size" prop="join_buffer_size">
<el-input clearable v-model.number="mysqlVariables.join_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.joinBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="tmp_table_size" prop="tmp_table_size">
<el-input clearable v-model.number="mysqlVariables.tmp_table_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.tmpTableSizeHelper') }}</span>
</el-form-item>
<el-form-item label="innodb_buffer_pool_size" prop="innodb_buffer_pool_size">
<el-input clearable v-model.number="mysqlVariables.innodb_buffer_pool_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.innodbBufferPoolSizeHelper') }}</span>
</el-form-item>
<el-form-item label="innodb_log_buffer_size" prop="innodb_log_buffer_size">
<el-input clearable v-model.number="mysqlVariables.innodb_log_buffer_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.innodbLogBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="sort_buffer_size" prop="sort_buffer_size">
<el-input clearable v-model.number="mysqlVariables.sort_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.sortBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="read_buffer_size" prop="read_buffer_size">
<el-input clearable v-model.number="mysqlVariables.read_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.readBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item>
<el-button :disabled="loading" @click="onSaveStart(variableFormRef)" type="primary">
{{ $t('commons.button.save') }}
</el-button>
</el-form-item>
</el-col>
<el-col :span="2"><br /></el-col>
<el-col :span="9">
<el-form-item label="read_rnd_buffer_size" prop="read_rnd_buffer_size">
<el-input clearable v-model.number="mysqlVariables.read_rnd_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.readRndBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item v-if="mysqlVersion === '5.7.39'" label="query_cache_size" prop="query_cache_size">
<el-input clearable v-model.number="mysqlVariables.query_cache_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.queryCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="thread_stack" prop="thread_stack">
<el-input clearable v-model.number="mysqlVariables.thread_stack">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.threadStackelper') }}</span>
</el-form-item>
<el-form-item label="binlog_cache_size" prop="binlog_cache_size">
<el-input clearable v-model.number="mysqlVariables.binlog_cache_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.binlogCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="thread_cache_size" prop="thread_cache_size">
<el-input clearable v-model.number="mysqlVariables.thread_cache_size" />
<span class="input-help">{{ $t('database.threadCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="table_open_cache" prop="table_open_cache">
<el-input clearable v-model.number="mysqlVariables.table_open_cache" />
<span class="input-help">{{ $t('database.tableOpenCacheHelper') }}</span>
</el-form-item>
<el-form-item label="max_connections" prop="max_connections">
<el-input clearable v-model.number="mysqlVariables.max_connections" />
<span class="input-help">{{ $t('database.maxConnectionsHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<el-form-item>
<el-button :disabled="loading" @click="onSaveStart(variableFormRef)" type="primary">
{{ $t('commons.button.save') }}
</el-button>
</el-form-item>
</el-col>
<el-col :span="2"><br /></el-col>
<el-col :span="9">
<el-form-item label="read_rnd_buffer_size" prop="read_rnd_buffer_size">
<el-input clearable v-model.number="mysqlVariables.read_rnd_buffer_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.readRndBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item v-if="mysqlVersion === '5.7.39'" label="query_cache_size" prop="query_cache_size">
<el-input clearable v-model.number="mysqlVariables.query_cache_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('database.queryCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="thread_stack" prop="thread_stack">
<el-input clearable v-model.number="mysqlVariables.thread_stack">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.threadStackelper') }}</span>
</el-form-item>
<el-form-item label="binlog_cache_size" prop="binlog_cache_size">
<el-input clearable v-model.number="mysqlVariables.binlog_cache_size">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('database.binlogCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="thread_cache_size" prop="thread_cache_size">
<el-input clearable v-model.number="mysqlVariables.thread_cache_size" />
<span class="input-help">{{ $t('database.threadCacheSizeHelper') }}</span>
</el-form-item>
<el-form-item label="table_open_cache" prop="table_open_cache">
<el-input clearable v-model.number="mysqlVariables.table_open_cache" />
<span class="input-help">{{ $t('database.tableOpenCacheHelper') }}</span>
</el-form-item>
<el-form-item label="max_connections" prop="max_connections">
<el-input clearable v-model.number="mysqlVariables.max_connections" />
<span class="input-help">{{ $t('database.maxConnectionsHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSaveVariables"></ConfirmDialog>
</div>

View File

@ -1,102 +1,119 @@
<template>
<div class="demo-collapse" v-show="settingShow">
<el-card style="margin-top: 5px" v-loading="loading">
<LayoutContent :header="'Redis ' + $t('database.setting')" back-name="Redis" :reload="true">
<el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('database.confChange')" name="1">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 280px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="redisConf"
:readOnly="true"
/>
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" @click="onSaveFile" style="margin-top: 10px">
{{ $t('commons.button.save') }}
</el-button>
<el-row>
<el-col :span="8">
<el-alert
v-if="useOld"
style="margin-top: 10px"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
></el-alert>
<div v-show="settingShow">
<LayoutContent :title="$t('nginx.nginxConfig')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }}
</el-button>
<el-button
type="primary"
:disabled="redisStatus !== 'Running'"
:plain="activeName !== 'status'"
@click="changeTab('status')"
>
{{ $t('database.status') }}
</el-button>
<el-button
type="primary"
:disabled="redisStatus !== 'Running'"
:plain="activeName !== 'tuning'"
@click="changeTab('tuning')"
>
{{ $t('database.performanceTuning') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'port'" @click="changeTab('port')">
{{ $t('database.portSetting') }}
</el-button>
<el-button
type="primary"
:disabled="redisStatus !== 'Running'"
:plain="activeName !== 'persistence'"
@click="changeTab('persistence')"
>
{{ $t('database.persistence') }}
</el-button>
</template>
<template #main>
<div v-if="activeName === 'conf'">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 370px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="redisConf"
:readOnly="true"
/>
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" @click="onSaveFile" style="margin-top: 10px">
{{ $t('commons.button.save') }}
</el-button>
<el-row>
<el-col :span="8">
<el-alert
v-if="useOld"
style="margin-top: 10px"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
></el-alert>
</el-col>
</el-row>
</div>
<Status v-show="activeName === 'status'" ref="statusRef" />
<div v-if="activeName === 'tuning'">
<el-form :model="form" ref="formRef" :rules="rules" label-width="120px">
<el-row style="margin-top: 20px">
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('database.timeout')" prop="timeout">
<el-input clearable type="number" v-model.number="form.timeout" />
<span class="input-help">{{ $t('database.timeoutHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('database.maxclients')" prop="maxclients">
<el-input clearable type="number" v-model.number="form.maxclients" />
</el-form-item>
<el-form-item :label="$t('database.maxmemory')" prop="maxmemory">
<el-input clearable type="number" v-model.number="form.maxmemory" />
<span class="input-help">{{ $t('database.maxmemoryHelper') }}</span>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmtiForm(formRef)">
{{ $t('commons.button.save') }}
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item :disabled="redisStatus !== 'Running'" :title="$t('database.status')" name="2">
<Status ref="statusRef" />
</el-collapse-item>
<el-collapse-item
:disabled="redisStatus !== 'Running'"
:title="$t('database.performanceTuning')"
name="3"
>
<el-form :model="form" ref="formRef" :rules="rules" label-width="120px">
<el-row style="margin-top: 20px">
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('database.timeout')" prop="timeout">
<el-input clearable type="number" v-model.number="form.timeout" />
<span class="input-help">{{ $t('database.timeoutHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('database.maxclients')" prop="maxclients">
<el-input clearable type="number" v-model.number="form.maxclients" />
</el-form-item>
<el-form-item :label="$t('database.maxmemory')" prop="maxmemory">
<el-input clearable type="number" v-model.number="form.maxmemory" />
<span class="input-help">{{ $t('database.maxmemoryHelper') }}</span>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmtiForm(formRef)">
{{ $t('commons.button.save') }}
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-collapse-item>
<el-collapse-item :title="$t('database.portSetting')" name="4">
<el-form :model="form" ref="portRef" label-width="120px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="form.port">
<template #append>
<el-button @click="onSavePort(portRef)" icon="Collection">
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-collapse-item>
<el-collapse-item
:disabled="redisStatus !== 'Running'"
:title="$t('database.persistence')"
name="5"
>
<Persistence ref="persistenceRef" />
</el-collapse-item>
</el-collapse>
</LayoutContent>
</el-card>
</el-form>
</div>
<div v-if="activeName === 'port'">
<el-form :model="form" ref="portRef" label-width="120px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="form.port">
<template #append>
<el-button @click="onSavePort(portRef)" icon="Collection">
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<Persistence v-show="activeName === 'persistence'" ref="persistenceRef" />
</template>
</LayoutContent>
<ConfirmDialog ref="confirmDialogRef" @confirm="submtiFile"></ConfirmDialog>
<ConfirmDialog ref="confirmFileRef" @confirm="submtiFile"></ConfirmDialog>
@ -140,7 +157,7 @@ const rules = reactive({
maxmemory: [Rules.number],
});
const activeName = ref('1');
const activeName = ref('conf');
const statusRef = ref();
const persistenceRef = ref();
@ -160,6 +177,11 @@ interface DialogProps {
status: string;
}
const changeTab = (val: string) => {
activeName.value = val;
console.log(activeName.value);
};
const acceptParams = (prop: DialogProps): void => {
redisStatus.value = prop.status;
redisName.value = prop.redisName;

View File

@ -1,79 +1,77 @@
<template>
<div v-if="statusShow">
<el-card style="margin-top: 5px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="12">
<table style="margin-top: 20px; width: 100%" class="myTable">
<tr>
<td>uptime_in_days</td>
<td>{{ redisStatus!.uptime_in_days }}</td>
<td>{{ $t('database.uptimeInDays') }}</td>
</tr>
<tr>
<td>tcp_port</td>
<td>{{ redisStatus!.tcp_port }}</td>
<td>{{ $t('database.tcpPort') }}</td>
</tr>
<tr>
<td>connected_clients</td>
<td>{{ redisStatus!.connected_clients }}</td>
<td>{{ $t('database.connectedClients') }}</td>
</tr>
<tr>
<td>used_memory_rss</td>
<td>{{ redisStatus!.used_memory_rss }}</td>
<td>{{ $t('database.usedMemoryRss') }}</td>
</tr>
<tr>
<td>used_memory</td>
<td>{{ redisStatus!.used_memory }}</td>
<td>{{ $t('database.usedMemory') }}</td>
</tr>
<tr>
<td>mem_fragmentation_ratio</td>
<td>{{ redisStatus!.mem_fragmentation_ratio }}</td>
<td>{{ $t('database.tmpTableToDBHelper') }}</td>
</tr>
<tr>
<td>total_connections_received</td>
<td>{{ redisStatus!.total_connections_received }}</td>
<td>{{ $t('database.totalConnectionsReceived') }}</td>
</tr>
<tr>
<td>total_commands_processed</td>
<td>{{ redisStatus!.total_commands_processed }}</td>
<td>{{ $t('database.totalCommandsProcessed') }}</td>
</tr>
<tr>
<td>instantaneous_ops_per_sec</td>
<td>{{ redisStatus!.instantaneous_ops_per_sec }}</td>
<td>{{ $t('database.instantaneousOpsPerSec') }}</td>
</tr>
<tr>
<td>keyspace_hits</td>
<td>{{ redisStatus!.keyspace_hits }}</td>
<td>{{ $t('database.keyspaceHits') }}</td>
</tr>
<tr>
<td>keyspace_misses</td>
<td>{{ redisStatus!.keyspace_misses }}</td>
<td>{{ $t('database.keyspaceMisses') }}</td>
</tr>
<tr>
<td>hit</td>
<td>{{ redisStatus!.hit }}</td>
<td>{{ $t('database.hit') }}</td>
</tr>
<tr>
<td>latest_fork_usec</td>
<td>{{ redisStatus!.latest_fork_usec }}</td>
<td>{{ $t('database.latestForkUsec') }}</td>
</tr>
</table>
</el-col>
</el-row>
</el-card>
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="12">
<table style="margin-top: 20px; width: 100%" class="myTable">
<tr>
<td>uptime_in_days</td>
<td>{{ redisStatus!.uptime_in_days }}</td>
<td>{{ $t('database.uptimeInDays') }}</td>
</tr>
<tr>
<td>tcp_port</td>
<td>{{ redisStatus!.tcp_port }}</td>
<td>{{ $t('database.tcpPort') }}</td>
</tr>
<tr>
<td>connected_clients</td>
<td>{{ redisStatus!.connected_clients }}</td>
<td>{{ $t('database.connectedClients') }}</td>
</tr>
<tr>
<td>used_memory_rss</td>
<td>{{ redisStatus!.used_memory_rss }}</td>
<td>{{ $t('database.usedMemoryRss') }}</td>
</tr>
<tr>
<td>used_memory</td>
<td>{{ redisStatus!.used_memory }}</td>
<td>{{ $t('database.usedMemory') }}</td>
</tr>
<tr>
<td>mem_fragmentation_ratio</td>
<td>{{ redisStatus!.mem_fragmentation_ratio }}</td>
<td>{{ $t('database.tmpTableToDBHelper') }}</td>
</tr>
<tr>
<td>total_connections_received</td>
<td>{{ redisStatus!.total_connections_received }}</td>
<td>{{ $t('database.totalConnectionsReceived') }}</td>
</tr>
<tr>
<td>total_commands_processed</td>
<td>{{ redisStatus!.total_commands_processed }}</td>
<td>{{ $t('database.totalCommandsProcessed') }}</td>
</tr>
<tr>
<td>instantaneous_ops_per_sec</td>
<td>{{ redisStatus!.instantaneous_ops_per_sec }}</td>
<td>{{ $t('database.instantaneousOpsPerSec') }}</td>
</tr>
<tr>
<td>keyspace_hits</td>
<td>{{ redisStatus!.keyspace_hits }}</td>
<td>{{ $t('database.keyspaceHits') }}</td>
</tr>
<tr>
<td>keyspace_misses</td>
<td>{{ redisStatus!.keyspace_misses }}</td>
<td>{{ $t('database.keyspaceMisses') }}</td>
</tr>
<tr>
<td>hit</td>
<td>{{ redisStatus!.hit }}</td>
<td>{{ $t('database.hit') }}</td>
</tr>
<tr>
<td>latest_fork_usec</td>
<td>{{ redisStatus!.latest_fork_usec }}</td>
<td>{{ $t('database.latestForkUsec') }}</td>
</tr>
</table>
</el-col>
</el-row>
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div v-show="terminalShow" style="height: 100%">
<div style="height: calc(100vh - 230px)" :id="'terminal-exec'"></div>
<div style="height: calc(100vh - 360px)" :id="'terminal-exec'"></div>
</div>
</template>

View File

@ -1,30 +1,58 @@
<template>
<div>
<el-card style="margin-top: 20px">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button type="primary" icon="Plus" @click="onCreate()">
{{ $t('commons.button.create') }}
</el-button>
<el-button type="danger" plain :disabled="selects.length === 0" @click="batchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" min-width="100" prop="name" fix />
<el-table-column :label="$t('terminal.command')" min-width="300" show-overflow-tooltip prop="command" />
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
</el-card>
<el-dialog v-model="cmdVisiable" :title="$t('commons.button.' + operate)" width="30%">
<el-form ref="commandInfoRef" label-width="100px" label-position="left" :model="commandInfo" :rules="rules">
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input clearable v-model="commandInfo.name" />
</el-form-item>
<el-form-item :label="$t('terminal.command')" prop="command">
<el-input type="textarea" clearable v-model="commandInfo.command" />
</el-form-item>
</el-form>
<LayoutContent v-loading="loading" :title="$t('terminal.quickCommand')">
<template #toolbar>
<el-button type="primary" @click="onCreate()">
{{ $t('commons.button.create') }}{{ $t('terminal.quickCommand') }}
</el-button>
<el-button plain :disabled="selects.length === 0" @click="batchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<template #main>
<ComplexTable
:pagination-config="paginationConfig"
v-model:selects="selects"
:data="data"
@search="search"
>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" min-width="100" prop="name" fix />
<el-table-column
:label="$t('terminal.command')"
min-width="300"
show-overflow-tooltip
prop="command"
/>
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
</template>
</LayoutContent>
<el-drawer v-model="cmdVisiable" size="50%">
<template #header>
<DrawerHeader
:header="$t('commons.button.' + operate) + $t('terminal.quickCommand')"
:back="handleClose"
/>
</template>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form
ref="commandInfoRef"
label-width="100px"
label-position="top"
:model="commandInfo"
:rules="rules"
>
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input clearable v-model="commandInfo.name" />
</el-form-item>
<el-form-item :label="$t('terminal.command')" prop="command">
<el-input type="textarea" clearable v-model="commandInfo.command" />
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button @click="cmdVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
@ -33,11 +61,12 @@
</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</div>
</template>
<script setup lang="ts">
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { Command } from '@/api/interface/command';
import { addCommand, editCommand, deleteCommand, getCommandPage } from '@/api/modules/command';
@ -48,6 +77,7 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElMessage } from 'element-plus';
const loading = ref();
const data = ref();
const selects = ref<any>([]);
const paginationConfig = reactive({
@ -83,6 +113,10 @@ const onCreate = async () => {
cmdVisiable.value = true;
};
const handleClose = () => {
cmdVisiable.value = false;
};
const submitAddCommand = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid) => {
@ -145,9 +179,16 @@ const search = async () => {
pageSize: paginationConfig.pageSize,
info: info.value,
};
const res = await getCommandPage(params);
data.value = res.data.items || [];
paginationConfig.total = res.data.total;
loading.value = true;
await getCommandPage(params)
.then((res) => {
loading.value = false;
data.value = res.data.items || [];
paginationConfig.total = res.data.total;
})
.catch(() => {
loading.value = false;
});
};
defineExpose({

View File

@ -1,18 +1,19 @@
<template>
<div>
<el-card class="topRouterCard">
<el-radio-group @change="handleChange" v-model="activeNames">
<el-radio-button class="topRouterButton" size="default" label="terminal">
<el-card class="router_card">
<el-radio-group v-model="activeNames" @change="handleChange">
<el-radio-button class="router_card_button" size="large" label="terminal">
{{ $t('menu.terminal') }}
</el-radio-button>
<el-radio-button class="topRouterButton" size="default" label="host">
<el-radio-button class="router_card_button" size="large" label="host">
{{ $t('menu.host') }}
</el-radio-button>
<el-radio-button class="topRouterButton" size="default" label="command">
<el-radio-button class="router_card_button" size="large" label="command">
{{ $t('terminal.quickCommand') }}
</el-radio-button>
</el-radio-group>
</el-card>
<div v-show="activeNames === 'terminal'">
<TerminalTab ref="terminalTabRef" />
</div>
@ -55,3 +56,35 @@ onUnmounted(() => {
terminalTabRef.value?.cleanTimer();
});
</script>
<style lang="scss">
.router_card {
--el-card-border-radius: 8px;
--el-card-padding: 0;
padding: 0px;
padding-bottom: 2px;
padding-top: 2px;
}
.router_card_button {
margin-left: 2px;
.el-radio-button__inner {
min-width: 100px;
height: 100%;
border: 0 !important;
}
.el-radio-button__original-radio:checked + .el-radio-button__inner {
border-radius: 3px;
color: $primary-color;
background-color: #ffffff;
box-shadow: 0 0 0 2px $primary-color !important;
}
.el-radio-button:first-child .el-radio-button__inner {
border-radius: 3px;
color: $primary-color;
background-color: #ffffff;
box-shadow: 0 0 0 2px $primary-color !important;
}
}
</style>

View File

@ -1,6 +1,9 @@
<template>
<div>
<el-dialog v-model="dialogVisiable" :title="$t('terminal.addHost')" width="30%">
<el-drawer v-model="dialogVisiable" size="50%">
<template #header>
<DrawerHeader :header="$t('terminal.addHost')" :back="handleClose" />
</template>
<el-alert
v-if="isLocal"
style="margin-bottom: 20px"
@ -9,35 +12,45 @@
:closable="false"
type="warning"
/>
<el-form ref="hostRef" label-width="100px" :model="hostInfo" :rules="rules">
<el-form-item :label="$t('terminal.ip')" prop="addr">
<el-input v-if="!isLocal" clearable v-model="hostInfo.addr" />
<span v-if="isLocal">{{ hostInfo.addr }}</span>
</el-form-item>
<el-form-item :label="$t('terminal.user')" prop="user">
<el-input clearable v-model="hostInfo.user" />
</el-form-item>
<el-form-item :label="$t('terminal.authMode')" prop="authMode">
<el-radio-group v-model="hostInfo.authMode">
<el-radio label="password">{{ $t('terminal.passwordMode') }}</el-radio>
<el-radio label="key">{{ $t('terminal.keyMode') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('terminal.password')" v-if="hostInfo.authMode === 'password'" prop="password">
<el-input clearable show-password type="password" v-model="hostInfo.password" />
</el-form-item>
<el-form-item :label="$t('terminal.key')" v-if="hostInfo.authMode === 'key'" prop="privateKey">
<el-input clearable type="textarea" v-model="hostInfo.privateKey" />
</el-form-item>
<el-form-item :label="$t('terminal.port')" prop="port">
<el-input clearable v-model.number="hostInfo.port" />
</el-form-item>
<el-form-item :label="$t('commons.table.title')" prop="name">
<el-input clearable v-model="hostInfo.name" />
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model="hostInfo.description" />
</el-form-item>
<el-form ref="hostRef" label-width="100px" label-position="top" :model="hostInfo" :rules="rules">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('terminal.ip')" prop="addr">
<el-input v-if="!isLocal" clearable v-model="hostInfo.addr" />
<div style="margin-left: 12px">
<span v-if="isLocal">{{ hostInfo.addr }}</span>
</div>
</el-form-item>
<el-form-item :label="$t('terminal.user')" prop="user">
<el-input clearable v-model="hostInfo.user" />
</el-form-item>
<el-form-item :label="$t('terminal.authMode')" prop="authMode">
<el-radio-group v-model="hostInfo.authMode">
<el-radio label="password">{{ $t('terminal.passwordMode') }}</el-radio>
<el-radio label="key">{{ $t('terminal.keyMode') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
:label="$t('terminal.password')"
v-if="hostInfo.authMode === 'password'"
prop="password"
>
<el-input clearable show-password type="password" v-model="hostInfo.password" />
</el-form-item>
<el-form-item :label="$t('terminal.key')" v-if="hostInfo.authMode === 'key'" prop="privateKey">
<el-input clearable type="textarea" v-model="hostInfo.privateKey" />
</el-form-item>
<el-form-item :label="$t('terminal.port')" prop="port">
<el-input clearable v-model.number="hostInfo.port" />
</el-form-item>
<el-form-item :label="$t('commons.table.title')" prop="name">
<el-input clearable v-model="hostInfo.name" />
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model="hostInfo.description" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -50,7 +63,7 @@
</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</div>
</template>
@ -101,6 +114,10 @@ const acceptParams = (props: DialogProps) => {
dialogVisiable.value = true;
};
const handleClose = () => {
dialogVisiable.value = false;
};
const emit = defineEmits(['on-conn-terminal', 'load-host-tree']);
const submitAddHost = (formEl: FormInstance | undefined, ops: string) => {

View File

@ -35,7 +35,7 @@
</span>
</template>
<Terminal
style="height: calc(100vh - 178px); background-color: #000"
style="height: calc(100vh - 227px); background-color: #000"
:ref="'t-' + item.index"
:key="item.Refresh"
></Terminal>
@ -109,7 +109,7 @@
</el-tab-pane>
<div v-if="terminalTabs.length === 0">
<el-empty
style="background-color: #000; height: calc(100vh - 150px)"
style="background-color: #000; height: calc(100vh - 200px)"
:description="$t('terminal.emptyTerminal')"
></el-empty>
</div>
@ -383,7 +383,7 @@ defineExpose({
.fullScreen {
position: absolute;
right: 50px;
top: 80px;
top: 90px;
font-weight: 600;
font-size: 14px;
}

View File

@ -35,7 +35,10 @@
</div>
</template>
</LayoutContent>
<el-drawer :key="refresh" v-model="drawerShow" size="50%">
<el-drawer :key="refresh" v-model="drawerVisiable" size="50%">
<template #header>
<DrawerHeader :header="$t('setting.upgrade')" :back="handleClose" />
</template>
<el-form label-width="120px">
<el-form-item :label="$t('setting.newVersion')">
<el-tag>{{ upgradeInfo.newVersion }}</el-tag>
@ -65,7 +68,7 @@ import i18n from '@/lang';
const version = ref();
const upgradeInfo = ref();
const drawerShow = ref();
const drawerVisiable = ref();
const refresh = ref();
const loading = ref();
@ -87,6 +90,10 @@ const toGithubStar = () => {
window.open('https://github.com/1Panel-dev/1Panel', '_blank');
};
const handleClose = () => {
drawerVisiable.value = false;
};
const onLoadUpgradeInfo = async () => {
const res = await loadUpgradeInfoByOSS();
if (!res.data) {
@ -94,7 +101,7 @@ const onLoadUpgradeInfo = async () => {
return;
}
upgradeInfo.value = res.data;
drawerShow.value = true;
drawerVisiable.value = true;
};
const onUpgrade = async () => {
ElMessageBox.confirm(i18n.global.t('setting.upgradeHelper', i18n.global.t('setting.upgrade')), {
@ -106,7 +113,7 @@ const onUpgrade = async () => {
upgrade(upgradeInfo.value.newVersion)
.then(() => {
loading.value = false;
drawerShow.value = false;
drawerVisiable.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
search();
})

View File

@ -1,9 +1,7 @@
<template>
<el-drawer v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ title }}{{ $t('setting.backupAccount') }}</span>
</div>
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" />
</template>
<el-form ref="formRef" v-loading="loading" :model="dialogData.rowData" label-width="120px">
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
@ -101,7 +99,7 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="dialogVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
@ -137,7 +135,7 @@ interface DialogProps {
getTableList?: () => Promise<any>;
}
const title = ref<string>('');
const dialogVisiable = ref(false);
const drawerVisiable = ref(false);
const dialogData = ref<DialogProps>({
title: '',
});
@ -151,7 +149,11 @@ const acceptParams = (params: DialogProps): void => {
}
}
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
dialogVisiable.value = true;
drawerVisiable.value = true;
};
const handleClose = () => {
drawerVisiable.value = false;
};
const loadDir = async (path: string) => {
@ -204,7 +206,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
dialogVisiable.value = false;
drawerVisiable.value = false;
});
};

View File

@ -68,7 +68,10 @@
</template>
</LayoutContent>
<RecoverStatus ref="recoverStatusRef"></RecoverStatus>
<el-drawer v-model="dialogVisiable" :title="$t('setting.createSnapshot')" size="50%">
<el-drawer v-model="drawerVisiable" size="50%">
<template #header>
<DrawerHeader :header="$t('setting.createSnapshot')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="snapRef" label-width="100px" :model="snapInfo" :rules="rules">
<el-form-item :label="$t('cronjob.target')" prop="from">
<el-select v-model="snapInfo.from" clearable>
@ -86,7 +89,7 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="dialogVisiable = false">
<el-button :disabled="loading" @click="drawerVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="submitAddSnapshot(snapRef)">
@ -137,11 +140,15 @@ let snapInfo = reactive<Setting.SnapshotCreate>({
description: '',
});
const dialogVisiable = ref<boolean>(false);
const drawerVisiable = ref<boolean>(false);
const onCreate = async () => {
restForm();
dialogVisiable.value = true;
drawerVisiable.value = true;
};
const handleClose = () => {
drawerVisiable.value = false;
};
const submitAddSnapshot = (formEl: FormInstance | undefined) => {
@ -152,7 +159,7 @@ const submitAddSnapshot = (formEl: FormInstance | undefined) => {
await snapshotCreate(snapInfo)
.then(() => {
loading.value = false;
dialogVisiable.value = false;
drawerVisiable.value = false;
search();
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})

View File

@ -1,6 +1,9 @@
<template>
<div v-loading="loading">
<el-drawer v-model="drawerVisiable" :title="$t('setting.recoverDetail')">
<el-drawer v-model="drawerVisiable">
<template #header>
<DrawerHeader :header="$t('setting.recoverDetail')" :back="handleClose" />
</template>
<el-form label-width="120px">
<el-card>
<template #header>
@ -195,6 +198,10 @@ const acceptParams = (params: DialogProps): void => {
drawerVisiable.value = true;
};
const handleClose = () => {
drawerVisiable.value = false;
};
const doRecover = async (isNew: boolean) => {
loading.value = true;
await snapshotRecover({ id: snapInfo.value.id, isNew: isNew, reDownload: reDownload.value })