fix: 容器弹框改为抽屉,修改部分国际化

This commit is contained in:
ssongliu 2023-02-15 17:10:15 +08:00 committed by ssongliu
parent f85299d518
commit 38984a502d
37 changed files with 366 additions and 320 deletions

View file

@ -1,9 +1,7 @@
<template>
<el-dialog v-model="codeVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<el-drawer v-model="codeVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ header }}</span>
</div>
<DrawerHeader :header="header" :back="handleClose" />
</template>
<codemirror
ref="mymirror"
@ -11,7 +9,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px; min-height: 200px; width: 100%"
style="width: 100%; height: calc(100vh - 112px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
@ -20,7 +18,7 @@
v-model="detailInfo"
:readOnly="true"
/>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
@ -28,6 +26,7 @@ import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import DrawerHeader from '@/components/drawer-header/index.vue';
const mymirror = ref();
@ -47,6 +46,10 @@ const acceptParams = (props: DialogProps): void => {
codeVisiable.value = true;
};
const handleClose = () => {
codeVisiable.value = false;
};
defineExpose({
acceptParams,
});

View file

@ -34,7 +34,7 @@
import { logContainer } from '@/api/modules/container';
import i18n from '@/lang';
import { dateFormatForName } from '@/utils/util';
import { nextTick, reactive, ref, shallowRef } from 'vue';
import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
@ -75,12 +75,6 @@ const timeOptions = ref([
},
]);
const onCloseLog = async () => {
logSearch.isWatch = false;
clearInterval(Number(timer));
timer = null;
};
const searchLogs = async () => {
const res = await logContainer(logSearch);
logInfo.value = res.data;
@ -121,8 +115,12 @@ const acceptParams = (props: DialogProps): void => {
}, 1000 * 5);
};
onBeforeUnmount(() => {
clearInterval(Number(timer));
timer = null;
});
defineExpose({
acceptParams,
onCloseLog,
});
</script>

View file

@ -6,7 +6,7 @@ export default {
create: 'Create ',
add: 'Add ',
save: 'Save ',
set: 'Reset',
set: 'Setting',
sync: 'Sync ',
delete: 'Delete ',
edit: 'Edit',
@ -33,7 +33,8 @@ export default {
init: 'Init',
verify: 'Verify',
saveAndEnable: 'Save and enable',
import: 'import',
import: 'Import',
search: 'Search',
},
search: {
timeStart: 'Time start',
@ -63,7 +64,7 @@ export default {
title: 'Title',
tableSetting: 'Table setting',
autoRefresh: 'Auto refresh',
refreshRate: 'Refresh rate',
refreshRate: 'Rate',
},
loadingText: {
Upgrading: 'System upgrade, please wait...',
@ -152,17 +153,17 @@ export default {
serviceNotStarted: 'The {0} service is not currently started',
},
status: {
running: 'running',
stopped: 'stopped',
success: 'success',
failed: 'failed',
error: 'error',
created: 'created',
restarting: 'restarting',
uploading: 'uploading',
removing: 'removing',
paused: 'paused',
exited: 'exited',
running: 'Running',
stopped: 'Stopped',
success: 'Success',
failed: 'Failed',
error: 'Error',
created: 'Created',
restarting: 'Restarting',
uploading: 'Uploading',
removing: 'Removing',
paused: 'Paused',
exited: 'Exited',
enabled: 'Enabled',
disabled: 'Disabled',
},
@ -174,6 +175,7 @@ export default {
project: 'Project',
config: 'Config',
firewall: 'Firewall',
ssl: 'SSL',
database: 'Database',
container: 'Container',
cronjob: 'Cronjob',
@ -253,19 +255,20 @@ export default {
permissionForIP: 'IP',
permissionAll: 'All of them (unsafe)',
rootPassword: 'Root password',
backupList: 'Backup list',
backupList: 'Backup',
backList: 'Return',
loadBackup: 'Import the backup',
setting: 'MySQL Settings',
loadBackup: 'Import',
setting: 'Settings',
remoteAccess: 'Remote access',
changePassword: 'Password change',
remoteConnHelper:
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
changePassword: 'Password',
changePasswordHelper:
'The database has been associated with an application. Changing the password will change the database password of the application at the same time. The change takes effect after the application restarts.',
baseSetting: 'infrastructure',
remoteConnHelper:
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
confChange: 'Configuration change',
portSetting: 'Port setting',
portHelper:
'This port is the exposed port of the container. You need to save the modification separately and restart the container!',
@ -394,7 +397,7 @@ export default {
newName: 'New name',
custom: 'Custom',
emptyUser: 'When empty, you will log in with the default user of container',
emptyUser: 'When empty, you will log in as default',
containerTerminal: 'Container terminal',
port: 'Port',
@ -433,6 +436,7 @@ export default {
import: 'Import',
build: 'Build',
imageBuild: 'Image build',
pathSelect: 'Path',
label: 'Label',
push: 'Push',
fileName: 'FileName',
@ -572,6 +576,7 @@ export default {
yestoday: 'Yestoday',
lastNDay: 'Last {0} day',
memory: 'Memory',
cache: 'Cache',
disk: 'Disk',
network: 'Network',
up: 'Up',
@ -590,9 +595,10 @@ export default {
expand: 'Expand all',
fold: 'All contract',
batchInput: 'Batch input',
quickCommand: 'quick command',
quickCommand: 'Quick command',
groupDeleteHelper:
'After the group is removed, all connections in the group will be migrated to the default group. Confirm the information',
command: 'Command',
quickCmd: 'Quick command',
addHost: 'Add Host',
localhost: 'Localhost',
@ -607,7 +613,7 @@ export default {
key: 'Private Key',
emptyTerminal: 'No terminal is currently connected',
},
operations: {
logs: {
operation: 'Operation logs',
login: 'Login logs',
system: 'System logs',
@ -639,48 +645,48 @@ export default {
status: 'status',
},
file: {
dir: 'folder',
dir: 'Folder',
upload: 'Upload',
download: 'download',
fileName: 'file name',
download: 'Download',
fileName: 'File name',
search: 'Find',
mode: 'permission',
owner: 'owner',
file: 'file',
remoteFile: 'remote download',
mode: 'Permission',
owner: 'Owner',
file: 'File',
remoteFile: 'Remote download',
share: 'Share',
sync: 'data synchronization',
size: 'size',
updateTime: 'modification time',
sync: 'Data synchronization',
size: 'Size',
updateTime: 'Modification time',
open: 'Open',
rename: 'Rename',
role: 'permission',
info: 'attribute',
linkFile: 'soft link file',
terminal: 'terminal',
role: 'Permission',
info: 'Attribute',
linkFile: 'Soft link file',
terminal: 'Terminal',
shareList: 'Share list',
zip: 'compressed',
user: 'user',
group: 'user group',
path: 'path',
public: 'public',
zip: 'Compressed',
user: 'User',
group: 'User group',
path: 'Path',
public: 'Public',
setRole: 'Set permissions',
link: 'whether to link',
rRole: 'Read',
wRole: 'Write',
xRole: 'executable',
name: 'name',
compress: 'compression',
xRole: 'Executable',
name: 'Name',
compress: 'Compression',
deCompress: 'Decompression',
compressType: 'compression format',
compressDst: 'compression path',
compressType: 'Compression format',
compressDst: 'Compression path',
replace: 'Overwrite existing files',
compressSuccess: 'Compressed successfully',
deCompressSuccess: 'Decompression succeeded',
deCompressDst: 'Decompression path',
linkType: 'Link Type',
softLink: 'soft link',
hardLink: 'hard link',
softLink: 'Soft link',
hardLink: 'Hard link',
linkPath: 'Link Path',
selectFile: 'Select file',
downloadSuccess: 'Download succeeded',
@ -689,13 +695,15 @@ export default {
moveStart: 'Move successfully',
move: 'Move',
copy: 'Copy',
calculate: 'calculate',
calculate: 'Calculate',
canNotDeCompress: 'Cannot decompress this file',
uploadSuccess: 'Upload successful!',
downloadProcess: 'Download progress',
downloading: 'Downloading...',
infoDetail: 'File Properties',
type: 'Type',
list: 'File List',
sub: 'Include subdirectory',
},
setting: {
all: 'All',
@ -831,9 +839,9 @@ export default {
appName: 'Application Name',
status: 'status',
container: 'container',
restart: 'restart',
up: 'start',
down: 'stop',
restart: 'Restart',
up: 'Start',
down: 'Stop',
name: 'name',
description: 'Description',
delete: 'delete',
@ -859,7 +867,7 @@ export default {
checkTitle: 'Prompt',
website: 'website',
database: 'database',
defaultConfig: 'default configuration',
defaultConfig: 'Default configuration',
defaultConfigHelper: 'It has been restored to the default configuration, it will take effect after saving',
forceDelete: 'force delete',
forceDeleteHelper:

View file

@ -463,7 +463,6 @@ export default {
import: '导入',
imageBuild: '构建镜像',
build: '构建镜像',
edit: '编辑',
pathSelect: '路径选择',
label: '标签',
push: '推送',
@ -592,6 +591,7 @@ export default {
yestoday: '昨天',
lastNDay: ' {0} ',
memory: '内存',
cache: '缓存',
disk: '磁盘',
network: '网络',
up: '上行',

View file

@ -38,7 +38,7 @@ export const GlobalStore = defineStore({
setCsrfToken(token: string) {
this.csrfToken = token;
},
updateLanguage(language: string) {
updateLanguage(language: any) {
this.language = language;
},
setThemeConfig(themeConfig: ThemeConfigProp) {

View file

@ -1,9 +1,7 @@
<template>
<el-dialog v-model="composeVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<el-drawer v-model="composeVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.edit') }}</span>
</div>
<DrawerHeader :header="$t('commons.button.edit')" :back="handleClose" />
</template>
<div v-loading="loading">
<codemirror
@ -11,7 +9,7 @@
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px; width: 100%; min-height: 200px"
style="width: 100%; height: calc(100vh - 175px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
@ -31,7 +29,7 @@
</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
@ -41,6 +39,7 @@ import { ref } from 'vue';
import { composeUpdate } from '@/api/modules/container';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false);
const composeVisiable = ref(false);
@ -79,6 +78,9 @@ const acceptParams = (props: DialogProps): void => {
name.value = props.name;
content.value = props.content;
};
const handleClose = () => {
composeVisiable.value = false;
};
defineExpose({
acceptParams,

View file

@ -195,9 +195,6 @@ const buttons = [
click: (row: Container.ComposeInfo) => {
onEdit(row);
},
disabled: (row: any) => {
return row.createdBy !== '1Panel';
},
},
{
label: i18n.global.t('commons.button.delete'),

View file

@ -96,7 +96,7 @@
show-overflow-tooltip
/>
<fu-table-operations
width="220px"
width="370px"
:ellipsis="10"
:buttons="buttons"
:label="$t('commons.table.operate')"

View file

@ -1,15 +1,7 @@
<template>
<el-dialog
v-model="logVisiable"
@close="onCloseLog"
:destroy-on-close="true"
:close-on-click-modal="false"
width="70%"
>
<el-drawer v-model="logVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.log') }}</span>
</div>
<DrawerHeader :header="$t('commons.button.log')" :back="handleClose" />
</template>
<div>
<el-select @change="searchLogs" style="width: 10%; float: left" v-model="logSearch.mode">
@ -28,7 +20,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
style="margin-top: 20px; height: calc(100vh - 230px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
@ -43,7 +35,7 @@
<el-button @click="logVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
@ -54,6 +46,7 @@ import { nextTick, reactive, ref, shallowRef } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import DrawerHeader from '@/components/drawer-header/index.vue';
const extensions = [javascript(), oneDark];
@ -93,8 +86,10 @@ const timeOptions = ref([
},
]);
const onCloseLog = async () => {
const handleClose = async () => {
logVisiable.value = false;
clearInterval(Number(timer));
timer = null;
};
const searchLogs = async () => {

View file

@ -1,50 +1,33 @@
<template>
<el-dialog
v-model="monitorVisiable"
:destroy-on-close="true"
@close="onClose"
:close-on-click-modal="false"
width="70%"
>
<el-drawer v-model="monitorVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.monitor') }}</span>
</div>
<DrawerHeader :header="$t('container.monitor')" :back="handleClose" />
</template>
<span>{{ $t('container.refreshTime') }}</span>
<el-select style="margin-left: 10px" v-model="timeInterval" @change="changeTimer">
<el-option label="1s" :value="1" />
<el-option label="3s" :value="3" />
<el-option label="5s" :value="5" />
<el-option label="10s" :value="10" />
<el-option label="30s" :value="30" />
<el-option label="60s" :value="60" />
</el-select>
<el-row :gutter="20" style="margin-top: 10px">
<el-col :span="12">
<el-card style="overflow: inherit">
<div id="cpuChart" style="width: 100%; height: 230px"></div>
</el-card>
</el-col>
<el-col :span="12">
<el-card style="overflow: inherit">
<div id="memoryChart" style="width: 100%; height: 230px"></div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 10px">
<el-col :span="12">
<el-card style="overflow: inherit">
<div id="ioChart" style="width: 100%; height: 230px"></div>
</el-card>
</el-col>
<el-col :span="12">
<el-card style="overflow: inherit">
<div id="networkChart" style="width: 100%; height: 230px"></div>
</el-card>
</el-col>
</el-row>
</el-dialog>
<el-form label-position="top">
<el-form-item :label="$t('container.refreshTime')">
<el-select v-model="timeInterval" @change="changeTimer">
<el-option label="1s" :value="1" />
<el-option label="3s" :value="3" />
<el-option label="5s" :value="5" />
<el-option label="10s" :value="10" />
<el-option label="30s" :value="30" />
<el-option label="60s" :value="60" />
</el-select>
</el-form-item>
</el-form>
<el-card>
<div id="cpuChart" style="width: 100%; height: 200px"></div>
</el-card>
<el-card style="margin-top: 10px">
<div id="memoryChart" style="width: 100%; height: 200px"></div>
</el-card>
<el-card style="margin-top: 10px">
<div id="ioChart" style="width: 100%; height: 200px"></div>
</el-card>
<el-card style="margin-top: 10px">
<div id="networkChart" style="width: 100%; height: 200px"></div>
</el-card>
</el-drawer>
</template>
<script lang="ts" setup>
@ -53,6 +36,7 @@ import { ContainerStats } from '@/api/modules/container';
import { dateFormatForSecond } from '@/utils/util';
import * as echarts from 'echarts';
import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
const monitorVisiable = ref(false);
const timeInterval = ref();
@ -276,7 +260,8 @@ function freshChart(chartName: string, legendDatas: any, xDatas: any, yDatas: an
itemChart?.setOption(option, true);
}
const onClose = async () => {
const handleClose = async () => {
monitorVisiable.value = false;
clearInterval(Number(timer));
timer = null;
window.removeEventListener('resize', changeChartSize);

View file

@ -1,12 +1,16 @@
<template>
<el-drawer v-model="newNameVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
<el-drawer v-model="newNameVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader :header="$t('container.rename')" :back="handleClose" />
</template>
<el-form ref="newNameRef" v-loading="loading" :model="renameForm" label-position="top">
<el-form-item :label="$t('container.newName')" :rules="Rules.requiredInput" prop="newName">
<el-input v-model="renameForm.newName"></el-input>
</el-form-item>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.newName')" :rules="Rules.requiredInput" prop="newName">
<el-input v-model="renameForm.newName"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -28,6 +32,7 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { ElForm } from 'element-plus';
import { reactive, ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false);
@ -67,7 +72,6 @@ interface DialogProps {
}
const acceptParams = (props: DialogProps): void => {
console.log(props.container);
renameForm.name = props.container;
renameForm.newName = '';
newNameVisiable.value = true;

View file

@ -1,46 +1,47 @@
<template>
<el-dialog
v-model="terminalVisiable"
:destroy-on-close="true"
@close="onClose"
:close-on-click-modal="false"
width="70%"
>
<el-drawer v-model="terminalVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('container.containerTerminal') }}</span>
</div>
<DrawerHeader :header="$t('container.containerTerminal')" :back="handleClose" />
</template>
<el-form ref="formRef" :model="form" label-width="80px">
<el-form-item label="User" prop="user">
<el-input style="width: 30%" clearable v-model="form.user" />
<span class="input-help">{{ $t('container.emptyUser') }}</span>
</el-form-item>
<el-form-item :label="$t('container.custom')" prop="custom">
<el-switch v-model="form.isCustom" @change="onChangeCommand" />
</el-form-item>
<el-form-item v-if="form.isCustom" label="Command" prop="command" :rules="Rules.requiredInput">
<el-input style="width: 30%" clearable v-model="form.command" />
</el-form-item>
<el-form-item v-if="!form.isCustom" label="Command" prop="command" :rules="Rules.requiredSelect">
<el-select style="width: 30%" allow-create filterable clearable v-model="form.command">
<el-option value="/bin/ash" label="/bin/ash" />
<el-option value="/bin/bash" label="/bin/bash" />
<el-option value="/bin/sh" label="/bin/sh" />
</el-select>
</el-form-item>
<el-form-item>
<el-button v-if="!terminalOpen" @click="initTerm(formRef)">{{ $t('commons.button.conn') }}</el-button>
<el-button v-else @click="onClose()">{{ $t('commons.button.disconn') }}</el-button>
</el-form-item>
<el-form ref="formRef" :model="form" label-position="top">
<el-row :gutter="20" type="flex" justify="center">
<el-col :span="12">
<el-form-item label="User" prop="user">
<el-input clearable v-model="form.user" />
<span class="input-help">{{ $t('container.emptyUser') }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.isCustom" label="Command" prop="command" :rules="Rules.requiredInput">
<el-checkbox style="width: 100px" border v-model="form.isCustom" @change="onChangeCommand">
{{ $t('container.custom') }}
</el-checkbox>
<el-input style="width: calc(100% - 100px)" clearable v-model="form.command" />
</el-form-item>
<el-form-item v-if="!form.isCustom" label="Command" prop="command" :rules="Rules.requiredSelect">
<el-checkbox style="width: 100px" border v-model="form.isCustom" @change="onChangeCommand">
{{ $t('container.custom') }}
</el-checkbox>
<el-select style="width: calc(100% - 100px)" filterable clearable v-model="form.command">
<el-option value="/bin/ash" label="/bin/ash" />
<el-option value="/bin/bash" label="/bin/bash" />
<el-option value="/bin/sh" label="/bin/sh" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<div style="height: calc(100vh - 290px)" :id="'terminal-exec'"></div>
</el-form>
<div :id="'terminal-exec'"></div>
<template #footer>
<span class="dialog-footer">
<el-button @click="terminalVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" v-if="!terminalOpen" @click="initTerm(formRef)">
{{ $t('commons.button.conn') }}
</el-button>
<el-button type="primary" v-else @click="handleClose()">{{ $t('commons.button.disconn') }}</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
@ -53,6 +54,7 @@ import 'xterm/css/xterm.css';
import { FitAddon } from 'xterm-addon-fit';
import { Rules } from '@/global/form-rules';
import { isJson } from '@/utils/util';
import DrawerHeader from '@/components/drawer-header/index.vue';
const terminalVisiable = ref(false);
const terminalOpen = ref(false);
@ -178,7 +180,8 @@ const isWsOpen = () => {
return false;
};
function onClose() {
function handleClose() {
terminalVisiable.value = false;
terminalOpen.value = false;
window.removeEventListener('resize', changeTerminalSize);
if (isWsOpen()) {

View file

@ -17,7 +17,7 @@
</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="edit">{{ $t('commons.button.edit') }}</el-radio>
<el-radio label="path">{{ $t('container.pathSelect') }}</el-radio>
</el-radio-group>
</el-form-item>

View file

@ -19,7 +19,7 @@
{{ $t('container.importImage') }}
</el-button>
<el-button type="primary" plain @click="onOpenBuild">
{{ $t('container.build') }}
{{ $t('container.imageBuild') }}
</el-button>
</el-col>
<el-col :span="8">

View file

@ -1,16 +1,20 @@
<template>
<el-drawer v-model="loadVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
<el-drawer v-model="loadVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader :header="$t('container.importImage')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="formRef" :model="form" label-position="top">
<el-form-item :label="$t('container.path')" :rules="Rules.requiredSelect" prop="path">
<el-input v-model="form.path">
<template #prepend>
<FileList @choose="loadLoadDir" :dir="false"></FileList>
</template>
</el-input>
</el-form-item>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('container.path')" :rules="Rules.requiredSelect" prop="path">
<el-input v-model="form.path">
<template #prepend>
<FileList @choose="loadLoadDir" :dir="false"></FileList>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -33,6 +37,7 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { imageLoad } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false);

View file

@ -1,7 +1,7 @@
<template>
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<DrawerHeader :header="'Tag ' + $t('container.image')" :back="handleClose" />
<DrawerHeader :header="$t('container.image') + ' Tag'" :back="handleClose" />
</template>
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
<el-row type="flex" justify="center">

View file

@ -0,0 +1,51 @@
<template>
<el-drawer v-model="detailVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.view') }}</span>
</div>
</template>
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 160px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:readOnly="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click="detailVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-drawer>
</template>
<script lang="ts" setup>
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
const extensions = [javascript(), oneDark];
const detailVisiable = ref(false);
const detailInfo = ref();
interface DialogProps {
content: string;
}
const acceptParams = (params: DialogProps): void => {
detailInfo.value = params.content;
detailVisiable.value = true;
};
defineExpose({
acceptParams,
});
</script>

View file

@ -69,33 +69,7 @@
</template>
</LayoutContent>
<el-dialog v-model="detailVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.view') }}</span>
</div>
</template>
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:readOnly="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click="detailVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-dialog>
<DetailDialog ref="detailRef" />
<OperatorDialog @search="search" ref="dialogRef" />
</div>
</template>
@ -104,12 +78,10 @@
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { reactive, onMounted, ref } from 'vue';
import { dateFormatSimple } from '@/utils/util';
import { Container } from '@/api/interface/container';
import DetailDialog from '@/views/container/template/detail/index.vue';
import OperatorDialog from '@/views/container/template/operator/index.vue';
import { deleteComposeTemplate, loadDockerStatus, searchComposeTemplate } from '@/api/modules/container';
import { useDeleteData } from '@/hooks/use-delete-data';
@ -119,9 +91,6 @@ import router from '@/routers';
const loading = ref();
const data = ref();
const selects = ref<any>([]);
const detailVisiable = ref(false);
const detailInfo = ref();
const extensions = [javascript(), oneDark];
const paginationConfig = reactive({
currentPage: 1,
@ -130,6 +99,8 @@ const paginationConfig = reactive({
});
const searchName = ref();
const detailRef = ref();
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
@ -161,8 +132,7 @@ const search = async () => {
};
const onOpenDetail = async (row: Container.TemplateInfo) => {
detailInfo.value = row.content;
detailVisiable.value = true;
detailRef.value.acceptParams({ content: row.content });
};
const dialogRef = ref();

View file

@ -97,7 +97,7 @@
show-overflow-tooltip
/>
<fu-table-operations
width="300px"
width="370px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"

View file

@ -5,35 +5,44 @@
<DrawerHeader :header="$t('database.changePassword')" :back="handleClose" />
</template>
<el-form>
<el-form v-loading="loading" ref="changeFormRef" :model="changeForm" label-width="80px">
<div v-if="changeForm.operation === 'password'">
<el-form-item :label="$t('commons.login.username')" prop="userName">
<el-input disabled v-model="changeForm.userName"></el-input>
</el-form-item>
<el-form-item
:label="$t('commons.login.password')"
prop="password"
:rules="Rules.requiredInput"
>
<el-input type="password" clearable show-password v-model="changeForm.password"></el-input>
</el-form-item>
</div>
<div v-if="changeForm.operation === 'privilege'">
<el-form-item :label="$t('database.permission')" prop="privilege">
<el-select style="width: 100%" v-model="changeForm.privilege">
<el-option value="localhost" :label="$t('database.permissionLocal')" />
<el-option value="%" :label="$t('database.permissionAll')" />
<el-option value="ip" :label="$t('database.permissionForIP')" />
</el-select>
</el-form-item>
<el-form-item
v-if="changeForm.privilege === 'ip'"
prop="privilegeIPs"
:rules="Rules.requiredInput"
>
<el-input clearable v-model="changeForm.privilegeIPs" />
</el-form-item>
</div>
<el-form v-loading="loading" ref="changeFormRef" :model="changeForm" label-position="top">
<el-row type="flex" justify="center">
<el-col :span="22">
<div v-if="changeForm.operation === 'password'">
<el-form-item :label="$t('commons.login.username')" prop="userName">
<el-input disabled v-model="changeForm.userName"></el-input>
</el-form-item>
<el-form-item
:label="$t('commons.login.password')"
prop="password"
:rules="Rules.requiredInput"
>
<el-input
type="password"
clearable
show-password
v-model="changeForm.password"
></el-input>
</el-form-item>
</div>
<div v-if="changeForm.operation === 'privilege'">
<el-form-item :label="$t('database.permission')" prop="privilege">
<el-select style="width: 100%" v-model="changeForm.privilege">
<el-option value="localhost" :label="$t('database.permissionLocal')" />
<el-option value="%" :label="$t('database.permissionAll')" />
<el-option value="ip" :label="$t('database.permissionForIP')" />
</el-select>
</el-form-item>
<el-form-item
v-if="changeForm.privilege === 'ip'"
prop="privilegeIPs"
:rules="Rules.requiredInput"
>
<el-input clearable v-model="changeForm.privilegeIPs" />
</el-form-item>
</div>
</el-col>
</el-row>
</el-form>
</el-form>
<template #footer>
@ -95,7 +104,6 @@ const acceptParams = (params: DialogProps): void => {
changeForm.privilege = params.privilege;
changeForm.privilegeIPs = params.privilegeIPs;
changeForm.value = params.value;
console.log(changeForm.password);
changeVisiable.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();

View file

@ -1,12 +1,16 @@
<template>
<el-drawer v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
<el-drawer v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader :header="$t('database.rootPassword')" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="formRef" :model="form" label-position="top">
<el-form-item :label="$t('database.rootPassword')" :rules="Rules.requiredInput" prop="password">
<el-input type="password" show-password clearable v-model="form.password" />
</el-form-item>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('database.rootPassword')" :rules="Rules.requiredInput" prop="password">
<el-input type="password" show-password clearable v-model="form.password" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>

View file

@ -2,26 +2,41 @@
<div v-show="onSetting">
<LayoutContent :title="'MySQL ' + $t('database.setting')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
<el-button type="primary" :plain="activeName !== 'conf'" @click="activeName = 'conf'">
{{ $t('database.confChange') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'status'" @click="changeTab('status')">
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
:plain="activeName !== 'status'"
@click="activeName = 'status'"
>
{{ $t('database.currentStatus') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'tuning'" @click="changeTab('tuning')">
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
:plain="activeName !== 'tuning'"
@click="activeName = 'tuning'"
>
{{ $t('database.performanceTuning') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'port'" @click="changeTab('port')">
<el-button type="primary" :plain="activeName !== 'port'" @click="activeName = 'port'">
{{ $t('database.portSetting') }}
</el-button>
<el-button type="primary" :plain="activeName !== 'log'" @click="changeTab('log')">
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
:plain="activeName !== 'log'"
@click="activeName = 'log'"
>
{{ $t('database.log') }}
</el-button>
<el-button
type="primary"
:disabled="mysqlStatus !== 'Running'"
@click="activeName = 'slowLog'"
:plain="activeName !== 'slowLog'"
@click="changeTab('slowLog')"
>
{{ $t('database.slowLog') }}
</el-button>
@ -159,16 +174,6 @@ const onClose = (): void => {
onSetting.value = false;
};
const changeTab = (val: string) => {
activeName.value = val;
if (val !== '5') {
dialogContainerLogRef.value!.onCloseLog();
}
if (val !== '6') {
slowLogRef.value!.onCloseLog();
}
};
const onSubmitChangePort = async () => {
let params = {
key: 'mysql',

View file

@ -44,7 +44,7 @@
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { nextTick, reactive, ref, shallowRef } from 'vue';
import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
import { Database } from '@/api/interface/database';
import { LoadFile } from '@/api/modules/files';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
@ -151,14 +151,12 @@ const loadMysqlSlowlogs = async (path: string) => {
});
};
const onCloseLog = async () => {
isWatch.value = false;
onBeforeUnmount(() => {
clearInterval(Number(timer));
timer = null;
};
});
defineExpose({
acceptParams,
onCloseLog,
});
</script>

View file

@ -1,6 +1,6 @@
<template>
<div>
<el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-width="160px">
<el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-position="top">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">

View file

@ -69,7 +69,7 @@
</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-form :model="form" ref="formRef" :rules="rules" label-position="top">
<el-row style="margin-top: 20px">
<el-col :span="1"><br /></el-col>
<el-col :span="10">

View file

@ -5,21 +5,14 @@
:destroy-on-close="true"
:close-on-click-modal="false"
:before-close="handleClose"
size="40%"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('file.download')" :back="handleClose" />
</template>
<el-row>
<el-col :span="11" :offset="1">
<el-form
ref="fileForm"
label-position="top"
:model="addForm"
label-width="100px"
:rules="rules"
v-loading="loading"
>
<el-form ref="fileForm" label-position="top" :model="addForm" :rules="rules" v-loading="loading">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('file.compressType')" prop="type">
<el-select v-model="addForm.type">
<el-option v-for="item in options" :key="item" :label="item" :value="item" />
@ -30,9 +23,9 @@
<template #append>{{ extension }}</template>
</el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>

View file

@ -4,21 +4,14 @@
:destroy-on-close="true"
:close-on-click-modal="false"
:before-close="handleClose"
size="40%"
size="30%"
>
<template #header>
<DrawerHeader :header="title" :back="handleClose" />
</template>
<el-row>
<el-col :span="22" :offset="1">
<el-form
ref="fileForm"
label-position="top"
:model="addForm"
label-width="100px"
:rules="rules"
v-loading="loading"
>
<el-form ref="fileForm" label-position="top" :model="addForm" :rules="rules" v-loading="loading">
<el-form-item :label="$t('file.path')" prop="newPath">
<el-input v-model="addForm.newPath">
<template #prepend><FileList @choose="getPath" :dir="true"></FileList></template>

View file

@ -28,7 +28,7 @@
</ComplexTable>
</template>
</LayoutContent>
<el-drawer v-model="cmdVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
<el-drawer v-model="cmdVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader
:header="$t('commons.button.' + operate) + $t('terminal.quickCommand')"

View file

@ -52,8 +52,14 @@
{{ $t('logs.detail.' + row.source) }}
</template>
</el-table-column>
<el-table-column :label="$t('logs.operate')" min-width="150px" prop="detailZH" />
<el-table-column :label="$t('logs.status')" prop="status">
<el-table-column :label="$t('logs.operate')" min-width="150px" prop="detailZH">
<template #default="{ row }">
<span v-if="globalStore.language === 'zh'">{{ row.detailZH }}</span>
<span v-if="globalStore.language === 'en'">{{ row.detailEN }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-tag v-if="row.status === 'Success'" class="ml-2" type="success">
{{ $t('commons.status.success') }}
@ -97,6 +103,7 @@ import { cleanLogs, getOperationLogs } from '@/api/modules/log';
import { onMounted, reactive, ref } from '@vue/runtime-core';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { GlobalStore } from '@/store';
const loading = ref();
const data = ref();
@ -110,6 +117,8 @@ const searchName = ref<string>('');
const searchGroup = ref<string>('');
const searchStatus = ref<string>('');
const globalStore = GlobalStore();
const search = async () => {
let params = {
operation: searchName.value,

View file

@ -7,7 +7,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 180px)"
style="height: calc(100vh - 240px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"

View file

@ -28,7 +28,9 @@
</el-row>
</el-form>
<div style="margin-top: 20px"><span style="font-size: 14px; font-weight: 500">第三方账号</span></div>
<div style="margin-top: 20px">
<span style="font-size: 14px; font-weight: 500">{{ $t('setting.thirdParty') }}</span>
</div>
<el-row :gutter="20" style="margin-top: 5px">
<el-col :span="12">
<el-card style="height: 265px">

View file

@ -10,6 +10,7 @@
<el-input clearable v-model="form.userName">
<template #append>
<el-button
style="width: 85px"
@click="onSave(panelFormRef, 'UserName', form.userName)"
icon="Collection"
>
@ -22,7 +23,7 @@
<el-form-item :label="$t('setting.passwd')" :rules="Rules.requiredInput" prop="password">
<el-input type="password" clearable disabled v-model="form.password">
<template #append>
<el-button icon="Setting" @click="onChangePassword">
<el-button style="width: 85px" icon="Setting" @click="onChangePassword">
{{ $t('commons.button.set') }}
</el-button>
</template>
@ -49,6 +50,7 @@
<el-input clearable v-model="form.panelName">
<template #append>
<el-button
style="width: 85px"
@click="onSave(panelFormRef, 'PanelName', form.panelName)"
icon="Collection"
>
@ -77,6 +79,7 @@
<el-input v-model.number="form.sessionTimeout">
<template #append>
<el-button
style="width: 85px"
@click="onSave(panelFormRef, 'SessionTimeout', form.sessionTimeout)"
icon="Collection"
>
@ -94,7 +97,12 @@
<el-form-item :label="$t('setting.syncTime')">
<el-input disabled v-model="form.localTime">
<template #append>
<el-button v-show="!show" @click="onSyncTime" icon="Refresh">
<el-button
style="width: 85px"
v-show="!show"
@click="onSyncTime"
icon="Refresh"
>
{{ $t('commons.button.sync') }}
</el-button>
<span v-show="show">{{ count }} S</span>

View file

@ -58,6 +58,7 @@ import { FormInstance } from 'element-plus';
import { GlobalStore } from '@/store';
import { reactive, ref } from 'vue';
import { updatePassword } from '@/api/modules/setting';
import DrawerHeader from '@/components/drawer-header/index.vue';
const globalStore = GlobalStore();
const passFormRef = ref<FormInstance>();

View file

@ -2,7 +2,7 @@
<div>
<LayoutContent v-loading="loading" :title="$t('setting.safe')" :divider="true">
<template #main>
<el-form :model="form" ref="panelFormRef" v-loading="loading" label-position="left" label-width="160px">
<el-form :model="form" ref="panelFormRef" v-loading="loading" label-position="left" label-width="180px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
@ -10,6 +10,7 @@
<el-input clearable v-model.number="form.serverPort">
<template #append>
<el-button
style="width: 85px"
@click="onSavePort(panelFormRef, 'ServerPort', form.serverPort)"
icon="Collection"
>
@ -26,7 +27,7 @@
>
<el-input disabled v-model="form.expirationTime">
<template #append>
<el-button @click="onChangeExpirationTime" icon="Setting">
<el-button style="width: 85px" @click="onChangeExpirationTime" icon="Setting">
{{ $t('commons.button.set') }}
</el-button>
</template>

View file

@ -145,6 +145,7 @@
<script setup lang="ts">
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { snapshotCreate, searchSnapshotPage, snapshotDelete, updateSnapshotDescription } from '@/api/modules/setting';
import { onMounted, reactive, ref } from 'vue';
import { dateFormat } from '@/utils/util';

View file

@ -1,6 +1,6 @@
<template>
<div>
<el-form :model="form" :rules="variablesRules" ref="nginxFormRef" label-width="160px">
<el-form :model="form" :rules="variablesRules" ref="nginxFormRef" label-position="top">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
@ -24,6 +24,11 @@
<el-input clearable v-model.number="form.keepalive_timeout"></el-input>
<span class="input-help">{{ $t('nginx.keepaliveTimeoutHelper') }}</span>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit(nginxFormRef)" :loading="loading">
{{ $t('commons.button.save') }}
</el-button>
</el-form-item>
</el-col>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
@ -47,9 +52,6 @@
</el-col>
</el-row>
</el-form>
<el-button type="primary" @click="submit(nginxFormRef)" :loading="loading">
{{ $t('commons.button.save') }}
</el-button>
</div>
</template>
<script lang="ts" setup>

View file

@ -5,7 +5,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 700px"
style="width: 100%; height: calc(100vh - 375px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"