1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-14 01:34:47 +08:00

feat: 统一抽屉组件 (#5691)

This commit is contained in:
zhengkunwang 2024-07-05 16:48:38 +08:00 committed by zhengkunwang223
parent a1b1790935
commit ed2f5c42d0
154 changed files with 6464 additions and 8584 deletions

View File

@ -37,7 +37,7 @@
"codemirror": "^6.0.1", "codemirror": "^6.0.1",
"echarts": "^5.5.0", "echarts": "^5.5.0",
"element-plus": "^2.7.5", "element-plus": "^2.7.5",
"fit2cloud-ui-plus": "^1.1.4", "fit2cloud-ui-plus": "^1.1.5",
"highlight.js": "^11.9.0", "highlight.js": "^11.9.0",
"js-base64": "^3.7.7", "js-base64": "^3.7.7",
"md-editor-v3": "^2.11.3", "md-editor-v3": "^2.11.3",

View File

@ -1,22 +1,12 @@
<template> <template>
<div> <DrawerPro
<el-drawer v-model="backupVisible"
v-model="backupVisible" :header="$t('commons.button.backup')"
:destroy-on-close="true" :resource="detailName ? name + ' [' + detailName + ']' : name"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" size="large"
size="50%" >
> <template #content>
<template #header>
<DrawerHeader
v-if="detailName"
:header="$t('commons.button.backup')"
:resource="name + '(' + detailName + ')'"
:back="handleClose"
/>
<DrawerHeader v-else :header="$t('commons.button.backup')" :resource="name" :back="handleClose" />
</template>
<div class="mb-5" v-if="type === 'app'"> <div class="mb-5" v-if="type === 'app'">
<el-alert :closable="false" type="warning"> <el-alert :closable="false" type="warning">
<div class="mt-2 text-xs"> <div class="mt-2 text-xs">
@ -70,11 +60,9 @@
<fu-table-operations width="230px" :buttons="buttons" :label="$t('commons.table.operate')" fix /> <fu-table-operations width="230px" :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable> </ComplexTable>
</el-drawer> </template>
</DrawerPro>
<OpDialog ref="opRef" @search="search" /> <OpDialog ref="opRef" @search="search" />
</div>
<AppBackUp ref="backupRef" @close="search" /> <AppBackUp ref="backupRef" @close="search" />
<AppRecover ref="recoverRef" /> <AppRecover ref="recoverRef" />
</template> </template>
@ -84,7 +72,6 @@ import { reactive, ref } from 'vue';
import { computeSize, dateFormat, downloadFile } from '@/utils/util'; import { computeSize, dateFormat, downloadFile } from '@/utils/util';
import { getBackupList } from '@/api/modules/setting'; import { getBackupList } from '@/api/modules/setting';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/setting'; import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/setting';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import router from '@/routers'; import router from '@/routers';

View File

@ -3,7 +3,7 @@
<div class="complex-table__header" v-if="slots.header || header"> <div class="complex-table__header" v-if="slots.header || header">
<slot name="header">{{ header }}</slot> <slot name="header">{{ header }}</slot>
</div> </div>
<div v-if="slots.toolbar" class="bt-5"> <div v-if="slots.toolbar">
<slot name="toolbar"></slot> <slot name="toolbar"></slot>
</div> </div>
@ -48,7 +48,6 @@ const props = defineProps({
paginationConfig: { paginationConfig: {
type: Object, type: Object,
required: false, required: false,
default: () => {},
}, },
heightDiff: { heightDiff: {
type: Number, type: Number,
@ -126,6 +125,10 @@ onMounted(() => {
font-size: 18px; font-size: 18px;
} }
.complex-table__body {
margin-top: 10px;
}
.complex-table__toolbar { .complex-table__toolbar {
@include flex-row(space-between, center); @include flex-row(space-between, center);

View File

@ -37,7 +37,7 @@
<script setup lang="ts"> <script setup lang="ts">
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { onMounted, reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
defineOptions({ name: 'OpDialog' }); defineOptions({ name: 'OpDialog' });
@ -103,8 +103,6 @@ const handleClose = () => {
open.value = false; open.value = false;
}; };
onMounted(() => {});
defineExpose({ defineExpose({
acceptParams, acceptParams,
}); });

View File

@ -0,0 +1,122 @@
<template>
<el-drawer
v-model="localOpenPage"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
:size="size"
>
<template #header>
<el-page-header @back="handleBack">
<template #content>
<span>{{ header }}</span>
<span v-if="resource != ''">
-
<el-tooltip v-if="resource.length > 25" :content="resource" placement="bottom">
<el-text type="primary">{{ resource.substring(0, 23) + '...' }}</el-text>
</el-tooltip>
<el-text type="primary" v-else>{{ resource }}</el-text>
</span>
<el-divider v-if="slots.buttons" direction="vertical" />
<slot v-if="slots.buttons" name="buttons"></slot>
</template>
<template #extra>
<el-tooltip :content="loadTooltip()" placement="top" v-if="fullScreen">
<el-button @click="toggleFullscreen" link icon="FullScreen" plain class="mr-5"></el-button>
</el-tooltip>
<slot v-if="slots.extra" name="extra"></slot>
</template>
</el-page-header>
</template>
<div v-if="slots.content">
<slot name="content"></slot>
</div>
<el-row v-else>
<el-col :span="22" :offset="1">
<slot></slot>
</el-col>
</el-row>
<template #footer v-if="slots.footer">
<slot name="footer"></slot>
</template>
</el-drawer>
</template>
<script lang="ts" setup>
import { computed, useSlots } from 'vue';
defineOptions({ name: 'DrawerPro' });
import screenfull from 'screenfull';
import i18n from '@/lang';
const props = defineProps({
header: String,
back: Function,
resource: {
type: String,
default: '',
},
size: {
type: String,
default: 'normal',
},
modelValue: {
type: Boolean,
default: false,
},
fullScreen: {
type: Boolean,
default: false,
},
});
const slots = useSlots();
const emit = defineEmits(['update:modelValue']);
const size = computed(() => {
switch (props.size) {
case 'small':
return '30%';
case 'normal':
return '40%';
case 'large':
return '50%';
case 'full':
return '100%';
default:
return '50%';
}
});
const localOpenPage = computed({
get() {
return props.modelValue;
},
set(value: boolean) {
emit('update:modelValue', value);
},
});
const handleBack = () => {
if (props.back) {
props.back();
} else {
closePage();
}
};
const closePage = () => {
localOpenPage.value = false;
};
function toggleFullscreen() {
if (screenfull.isEnabled) {
screenfull.toggle();
}
}
const loadTooltip = () => {
return i18n.global.t('commons.button.' + (screenfull.isFullscreen ? 'quitFullscreen' : 'fullscreen'));
};
</script>

View File

@ -10,6 +10,7 @@ import Tooltip from '@/components/tooltip/index.vue';
import CopyButton from '@/components/copy-button/index.vue'; import CopyButton from '@/components/copy-button/index.vue';
import MsgInfo from '@/components/msg-info/index.vue'; import MsgInfo from '@/components/msg-info/index.vue';
import MainDiv from '@/components/main-div/index.vue'; import MainDiv from '@/components/main-div/index.vue';
import DrawerPro from '@/components/drawer-pro/index.vue';
export default { export default {
install(app: App) { install(app: App) {
app.component(LayoutContent.name, LayoutContent); app.component(LayoutContent.name, LayoutContent);
@ -23,5 +24,6 @@ export default {
app.component(TableSetting.name, TableSetting); app.component(TableSetting.name, TableSetting);
app.component(MsgInfo.name, MsgInfo); app.component(MsgInfo.name, MsgInfo);
app.component(MainDiv.name, MainDiv); app.component(MainDiv.name, MainDiv);
app.component(DrawerPro.name, DrawerPro);
}, },
}; };

View File

@ -19,23 +19,29 @@
</div> </div>
<div class="content-container__main" v-if="slots.main"> <div class="content-container__main" v-if="slots.main">
<el-card> <el-card>
<div class="content-container__title" v-if="slots.title || title"> <div class="content-container__title" v-if="title">
<slot name="title"> <slot name="title">
<back-button <div v-if="showBack">
:path="backPath" <div class="flex justify-between">
:name="backName" <back-button
:to="backTo" :path="backPath"
:header="title" :name="backName"
:reload="reload" :to="backTo"
v-if="showBack" :header="title"
> :reload="reload"
<template v-if="slots.leftToolBar" #buttons> >
<slot name="leftToolBar"></slot> <template v-if="slots.leftToolBar" #buttons>
</template> <slot name="leftToolBar" v-if="slots.leftToolBar"></slot>
<template v-else-if="slots.buttons" #buttons> </template>
<slot name="buttons"></slot> <!-- <template v-else-if="slots.buttons" #buttons>
</template> <slot name="buttons"></slot>
</back-button> </template> -->
</back-button>
<div>
<slot name="rightToolBar" v-if="slots.rightToolBar"></slot>
</div>
</div>
</div>
<div class="flex justify-between" v-else> <div class="flex justify-between" v-else>
<div> <div>
{{ title }} {{ title }}
@ -106,7 +112,7 @@ const showBack = computed(() => {
} }
.content-container__title { .content-container__title {
font-weight: 700; font-weight: 400;
font-size: 18px; font-size: 18px;
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<el-popover placement="bottom-start" :width="200" trigger="click"> <el-popover placement="bottom-start" :width="200" trigger="hover">
<template #reference> <template #reference>
<el-button class="timer-button" :icon="Refresh"></el-button> <el-button class="timer-button" :icon="Refresh"></el-button>
</template> </template>

View File

@ -1,97 +1,100 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="upVisible" v-model="upVisible"
:destroy-on-close="true" :header="$t('commons.button.import')"
:close-on-click-modal="false" :resource="title"
:close-on-press-escape="false" :back="handleClose"
size="50%" size="large"
> >
<template #header> <template #content>
<DrawerHeader :header="$t('commons.button.import')" :resource="title" :back="handleClose" /> <div v-loading="loading">
</template> <div class="mb-4" v-if="type === 'mysql' || type === 'mariadb'">
<div v-loading="loading"> <el-alert type="error" :title="$t('database.formatHelper', [remark])" />
<div class="mb-4" v-if="type === 'mysql' || type === 'mariadb'">
<el-alert type="error" :title="$t('database.formatHelper', [remark])" />
</div>
<div class="mb-4" v-if="type === 'website'">
<el-alert :closable="false" type="warning" :title="$t('website.websiteBackupWarn')"></el-alert>
</div>
<el-upload ref="uploadRef" drag :on-change="fileOnChange" class="upload-demo" :auto-upload="false">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
{{ $t('database.dropHelper') }}
<em>{{ $t('database.clickHelper') }}</em>
</div> </div>
<template #tip> <div class="mb-4" v-if="type === 'website'">
<el-progress <el-alert :closable="false" type="warning" :title="$t('website.websiteBackupWarn')"></el-alert>
v-if="isUpload" </div>
text-inside <el-upload ref="uploadRef" drag :on-change="fileOnChange" class="upload-demo" :auto-upload="false">
:stroke-width="12" <el-icon class="el-icon--upload"><upload-filled /></el-icon>
:percentage="uploadPercent" <div class="el-upload__text">
></el-progress> {{ $t('database.dropHelper') }}
<div <em>{{ $t('database.clickHelper') }}</em>
v-if="type === 'mysql' || type === 'mariadb' || type === 'postgresql'"
style="width: 80%"
class="el-upload__tip"
>
<span class="input-help">{{ $t('database.supportUpType') }}</span>
<span class="input-help">
{{ $t('database.zipFormat') }}
</span>
</div> </div>
<div v-else style="width: 80%" class="el-upload__tip"> <template #tip>
<span class="input-help">{{ $t('website.supportUpType') }}</span> <el-progress
<span class="input-help"> v-if="isUpload"
{{ $t('website.zipFormat', [type + '.json']) }} text-inside
</span> :stroke-width="12"
</div> :percentage="uploadPercent"
</template> ></el-progress>
</el-upload> <div
<el-button :disabled="isUpload" v-if="uploaderFiles.length === 1" icon="Upload" @click="onSubmit"> v-if="type === 'mysql' || type === 'mariadb' || type === 'postgresql'"
{{ $t('commons.button.upload') }} style="width: 80%"
</el-button> class="el-upload__tip"
>
<span class="input-help">{{ $t('database.supportUpType') }}</span>
<span class="input-help">
{{ $t('database.zipFormat') }}
</span>
</div>
<div v-else style="width: 80%" class="el-upload__tip">
<span class="input-help">{{ $t('website.supportUpType') }}</span>
<span class="input-help">
{{ $t('website.zipFormat', [type + '.json']) }}
</span>
</div>
</template>
</el-upload>
<el-button :disabled="isUpload" v-if="uploaderFiles.length === 1" icon="Upload" @click="onSubmit">
{{ $t('commons.button.upload') }}
</el-button>
<el-divider /> <el-divider />
<ComplexTable <ComplexTable
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@search="search" @search="search"
v-model:selects="selects" v-model:selects="selects"
:data="data" :data="data"
> >
<template #toolbar> <template #toolbar>
<el-button <el-button
style="margin-left: 10px" class="ml-2.5"
plain plain
:disabled="selects.length === 0" :disabled="selects.length === 0"
@click="onBatchDelete(null)" @click="onBatchDelete(null)"
>
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
<el-table-column :label="$t('file.size')" prop="size">
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
</el-table-column>
<el-table-column
show-overflow-tooltip
:label="$t('commons.table.createdAt')"
min-width="90"
fix
> >
{{ $t('commons.button.delete') }} <template #default="{ row }">
</el-button> {{ row.createdAt }}
</template> </template>
<el-table-column type="selection" fix /> </el-table-column>
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" /> <fu-table-operations
<el-table-column :label="$t('file.size')" prop="size"> width="150px"
<template #default="{ row }"> :buttons="buttons"
{{ computeSize(row.size) }} :ellipsis="10"
</template> :label="$t('commons.table.operate')"
</el-table-column> fix
<el-table-column show-overflow-tooltip :label="$t('commons.table.createdAt')" min-width="90" fix> />
<template #default="{ row }"> </ComplexTable>
{{ row.createdAt }} </div>
</template> </template>
</el-table-column> </DrawerPro>
<fu-table-operations
width="150px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</div>
</el-drawer>
<OpDialog ref="opRef" @search="search" /> <OpDialog ref="opRef" @search="search" />
</div> </div>
<AppRecover ref="recoverRef" /> <AppRecover ref="recoverRef" />
@ -103,7 +106,6 @@ import { computeSize } from '@/utils/util';
import i18n from '@/lang'; import i18n from '@/lang';
import { UploadFile, UploadFiles, UploadInstance } from 'element-plus'; import { UploadFile, UploadFiles, UploadInstance } from 'element-plus';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { BatchDeleteFile, CheckFile, ChunkUploadFileData, GetUploadList } from '@/api/modules/files'; import { BatchDeleteFile, CheckFile, ChunkUploadFileData, GetUploadList } from '@/api/modules/files';
import { loadBaseDir } from '@/api/modules/setting'; import { loadBaseDir } from '@/api/modules/setting';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';

View File

@ -1,79 +1,72 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('app.detail')" :back="handleClose" size="large">
v-model="open" <template #content>
:destroy-on-close="true" <div class="brief" v-loading="loadingApp">
:close-on-click-modal="false" <div class="detail flex">
:close-on-press-escape="false" <div class="w-12 h-12 rounded p-1 shadow-md icon">
size="50%" <img :src="app.icon" alt="App Icon" class="w-full h-full rounded" style="object-fit: contain" />
> </div>
<template #header> <div class="ml-4">
<DrawerHeader :header="$t('app.detail')" :back="handleClose" /> <div class="name mb-2">
</template> <span>{{ app.name }}</span>
<div class="brief" v-loading="loadingApp"> </div>
<div class="detail flex"> <div class="description mb-4">
<div class="w-12 h-12 rounded p-1 shadow-md icon"> <span>
<img :src="app.icon" alt="App Icon" class="w-full h-full rounded" style="object-fit: contain" /> {{ language == 'zh' || language == 'tw' ? app.shortDescZh : app.shortDescEn }}
</span>
</div>
<br />
<div v-if="!loadingDetail" class="mb-2">
<el-alert
v-if="!appDetail.enable"
:title="$t('app.limitHelper')"
type="warning"
show-icon
:closable="false"
/>
</div>
<el-button
round
v-if="appDetail.enable && operate === 'install'"
@click="openInstall"
type="primary"
class="brief-button"
>
{{ $t('app.install') }}
</el-button>
</div>
</div> </div>
<div class="ml-4"> <div class="divider"></div>
<div class="name mb-2"> <div class="descriptions">
<span>{{ app.name }}</span> <div>
</div> <el-descriptions direction="vertical">
<div class="description mb-4"> <el-descriptions-item>
<span> <div class="icons">
{{ language == 'zh' || language == 'tw' ? app.shortDescZh : app.shortDescEn }} <el-link @click="toLink(app.website)">
</span> <el-icon><OfficeBuilding /></el-icon>
</div> <span>{{ $t('app.appOfficeWebsite') }}</span>
<br /> </el-link>
<div v-if="!loadingDetail" class="mb-2"> </div>
<el-alert </el-descriptions-item>
v-if="!appDetail.enable" <el-descriptions-item>
:title="$t('app.limitHelper')" <el-link @click="toLink(app.document)">
type="warning" <el-icon><Document /></el-icon>
show-icon <span>{{ $t('app.document') }}</span>
:closable="false"
/>
</div>
<el-button
round
v-if="appDetail.enable && operate === 'install'"
@click="openInstall"
type="primary"
class="brief-button"
>
{{ $t('app.install') }}
</el-button>
</div>
</div>
<div class="divider"></div>
<div class="descriptions">
<div>
<el-descriptions direction="vertical">
<el-descriptions-item>
<div class="icons">
<el-link @click="toLink(app.website)">
<el-icon><OfficeBuilding /></el-icon>
<span>{{ $t('app.appOfficeWebsite') }}</span>
</el-link> </el-link>
</div> </el-descriptions-item>
</el-descriptions-item> <el-descriptions-item>
<el-descriptions-item> <el-link @click="toLink(app.github)">
<el-link @click="toLink(app.document)"> <el-icon><Link /></el-icon>
<el-icon><Document /></el-icon> <span>{{ $t('app.github') }}</span>
<span>{{ $t('app.document') }}</span> </el-link>
</el-link> </el-descriptions-item>
</el-descriptions-item> </el-descriptions>
<el-descriptions-item> </div>
<el-link @click="toLink(app.github)">
<el-icon><Link /></el-icon>
<span>{{ $t('app.github') }}</span>
</el-link>
</el-descriptions-item>
</el-descriptions>
</div> </div>
</div> </div>
</div> <MdEditor previewOnly v-model="app.readMe" :theme="isDarkTheme ? 'dark' : 'light'" />
<MdEditor previewOnly v-model="app.readMe" :theme="isDarkTheme ? 'dark' : 'light'" /> </template>
</el-drawer> </DrawerPro>
<Install ref="installRef"></Install> <Install ref="installRef"></Install>
</template> </template>

View File

@ -1,137 +1,114 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('app.install')" :back="handleClose" size="large">
:close-on-click-modal="false" <el-alert
:close-on-press-escape="false" :title="$t('app.appInstallWarn')"
v-model="open" class="common-prompt"
:title="$t('app.install')" :closable="false"
size="50%" type="error"
:before-close="handleClose" v-if="!isHostMode"
> />
<template #header> <el-alert :title="$t('app.hostModeHelper')" class="common-prompt" :closable="false" type="warning" v-else />
<Header :header="$t('app.install')" :back="handleClose"></Header> <el-form
</template> v-loading="loading"
<el-row v-loading="loading"> @submit.prevent
<el-col :span="22" :offset="1"> ref="paramForm"
<el-alert label-position="top"
:title="$t('app.appInstallWarn')" :model="req"
class="common-prompt" label-width="150px"
:closable="false" :rules="rules"
type="error" :validate-on-rule-change="false"
v-if="!isHostMode" >
/> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-alert <el-input v-model.trim="req.name"></el-input>
:title="$t('app.hostModeHelper')" </el-form-item>
class="common-prompt" <el-form-item :label="$t('app.version')" prop="version">
:closable="false" <el-select v-model="req.version" @change="getAppDetail(req.version)">
type="warning" <el-option
v-else v-for="(version, index) in appVersions"
/> :key="index"
<el-form :label="version"
@submit.prevent :value="version"
ref="paramForm" ></el-option>
label-position="top" </el-select>
:model="req" </el-form-item>
label-width="150px" <Params
:rules="rules" :key="paramKey"
:validate-on-rule-change="false" v-if="open"
v-model:form="req.params"
v-model:params="installData.params"
v-model:rules="rules.params"
:propStart="'params.'"
></Params>
<el-form-item prop="advanced">
<el-checkbox v-model="req.advanced" :label="$t('app.advanced')" size="large" />
</el-form-item>
<div v-if="req.advanced">
<el-form-item :label="$t('app.containerName')" prop="containerName">
<el-input v-model.trim="req.containerName" :placeholder="$t('app.containerNameHelper')"></el-input>
</el-form-item>
<el-form-item prop="allowPort" v-if="!isHostMode">
<el-checkbox v-model="req.allowPort" :label="$t('app.allowPort')" size="large" />
<span class="input-help">{{ $t('app.allowPortHelper') }}</span>
</el-form-item>
<el-form-item
:label="$t('container.cpuQuota')"
prop="cpuQuota"
:rules="checkNumberRange(0, limits.cpu)"
> >
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-input type="number" style="width: 40%" v-model.number="req.cpuQuota" maxlength="5">
<el-input v-model.trim="req.name"></el-input> <template #append>{{ $t('app.cpuCore') }}</template>
</el-form-item> </el-input>
<el-form-item :label="$t('app.version')" prop="version"> <span class="input-help">
<el-select v-model="req.version" @change="getAppDetail(req.version)"> {{ $t('container.limitHelper', [limits.cpu]) }}{{ $t('commons.units.core') }}
<el-option </span>
v-for="(version, index) in appVersions" </el-form-item>
:key="index" <el-form-item
:label="version" :label="$t('container.memoryLimit')"
:value="version" prop="memoryLimit"
></el-option> :rules="checkNumberRange(0, limits.memory)"
</el-select> >
</el-form-item> <el-input style="width: 40%" v-model.number="req.memoryLimit" maxlength="10">
<Params <template #append>
:key="paramKey" <el-select
v-if="open" v-model="req.memoryUnit"
v-model:form="req.params" placeholder="Select"
v-model:params="installData.params" style="width: 85px"
v-model:rules="rules.params" @change="changeUnit"
:propStart="'params.'" >
></Params> <el-option label="MB" value="M" />
<el-form-item prop="advanced"> <el-option label="GB" value="G" />
<el-checkbox v-model="req.advanced" :label="$t('app.advanced')" size="large" /> </el-select>
</el-form-item> </template>
<div v-if="req.advanced"> </el-input>
<el-form-item :label="$t('app.containerName')" prop="containerName"> <span class="input-help">
<el-input {{ $t('container.limitHelper', [limits.memory]) }}{{ req.memoryUnit }}B
v-model.trim="req.containerName" </span>
:placeholder="$t('app.containerNameHelper')" </el-form-item>
></el-input> <el-form-item prop="editCompose">
</el-form-item> <el-checkbox v-model="req.editCompose" :label="$t('app.editCompose')" size="large" />
<el-form-item prop="allowPort" v-if="!isHostMode"> <span class="input-help">{{ $t('app.editComposeHelper') }}</span>
<el-checkbox v-model="req.allowPort" :label="$t('app.allowPort')" size="large" /> </el-form-item>
<span class="input-help">{{ $t('app.allowPortHelper') }}</span> <el-form-item pro="pullImage">
</el-form-item> <el-checkbox v-model="req.pullImage" :label="$t('container.forcePull')" size="large" />
<el-form-item <span class="input-help">{{ $t('container.forcePullHelper') }}</span>
:label="$t('container.cpuQuota')" </el-form-item>
prop="cpuQuota" <div v-if="req.editCompose">
:rules="checkNumberRange(0, limits.cpu)" <codemirror
> :autofocus="true"
<el-input type="number" style="width: 40%" v-model.number="req.cpuQuota" maxlength="5"> placeholder=""
<template #append>{{ $t('app.cpuCore') }}</template> :indent-with-tab="true"
</el-input> :tabSize="4"
<span class="input-help"> style="height: 400px"
{{ $t('container.limitHelper', [limits.cpu]) }}{{ $t('commons.units.core') }} :lineWrapping="true"
</span> :matchBrackets="true"
</el-form-item> theme="cobalt"
<el-form-item :styleActiveLine="true"
:label="$t('container.memoryLimit')" :extensions="extensions"
prop="memoryLimit" v-model="req.dockerCompose"
:rules="checkNumberRange(0, limits.memory)" />
> </div>
<el-input style="width: 40%" v-model.number="req.memoryLimit" maxlength="10"> </div>
<template #append> </el-form>
<el-select
v-model="req.memoryUnit"
placeholder="Select"
style="width: 85px"
@change="changeUnit"
>
<el-option label="MB" value="M" />
<el-option label="GB" value="G" />
</el-select>
</template>
</el-input>
<span class="input-help">
{{ $t('container.limitHelper', [limits.memory]) }}{{ req.memoryUnit }}B
</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="req.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<el-form-item pro="pullImage">
<el-checkbox v-model="req.pullImage" :label="$t('container.forcePull')" size="large" />
<span class="input-help">{{ $t('container.forcePullHelper') }}</span>
</el-form-item>
<div v-if="req.editCompose">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="height: 400px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="req.dockerCompose"
/>
</div>
</div>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -140,7 +117,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup name="appInstall"> <script lang="ts" setup name="appInstall">
@ -151,7 +128,6 @@ import { FormInstance, FormRules } from 'element-plus';
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import Params from '../params/index.vue'; import Params from '../params/index.vue';
import Header from '@/components/drawer-header/index.vue';
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';

View File

@ -1,112 +1,98 @@
<template> <template>
<el-drawer :close-on-click-modal="false" :close-on-press-escape="false" v-model="open" size="40%"> <DrawerPro v-model="open" :header="$t('app.param')" :back="handleClose" size="normal">
<template #header> <template #buttons>
<Header :header="$t('app.param')" :back="handleClose"> <el-button type="primary" plain @click="editParam" :disabled="loading">
<template #buttons> {{ edit ? $t('app.detail') : $t('commons.button.edit') }}
<el-button type="primary" plain @click="editParam" :disabled="loading"> </el-button>
{{ edit ? $t('app.detail') : $t('commons.button.edit') }}
</el-button>
</template>
</Header>
</template> </template>
<el-row v-if="!edit"> <el-descriptions border :column="1" v-if="!edit">
<el-col :span="22" :offset="1"> <el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
<el-descriptions border :column="1"> <span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key"> </el-descriptions-item>
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span> </el-descriptions>
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
<el-row v-else v-loading="loading">
<el-col :span="22" :offset="1">
<el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" class="common-prompt" />
<el-form @submit.prevent ref="paramForm" :model="paramModel" label-position="top" :rules="rules">
<div v-for="(p, index) in params" :key="index">
<el-form-item :prop="p.key" :label="getLabel(p)">
<el-input
v-if="p.type == 'number'"
type="number"
v-model.number="paramModel.params[p.key]"
:disabled="!p.edit"
></el-input>
<el-select
v-model="paramModel.params[p.key]"
v-else-if="p.type == 'select'"
:multiple="p.multiple"
>
<el-option
v-for="value in p.values"
:key="value.label"
:value="value.value"
:label="value.label"
:disabled="!p.edit"
></el-option>
</el-select>
<el-input v-else v-model.trim="paramModel.params[p.key]" :disabled="!p.edit"></el-input>
</el-form-item>
</div>
<el-form-item prop="advanced">
<el-checkbox v-model="paramModel.advanced" :label="$t('app.advanced')" size="large" />
</el-form-item>
<div v-if="paramModel.advanced">
<el-form-item :label="$t('app.containerName')" prop="containerName">
<el-input
v-model.trim="paramModel.containerName"
:placeholder="$t('app.containerNameHelper')"
></el-input>
</el-form-item>
<el-form-item prop="allowPort" v-if="!paramModel.isHostMode">
<el-checkbox v-model="paramModel.allowPort" :label="$t('app.allowPort')" size="large" />
<span class="input-help">{{ $t('app.allowPortHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.cpuQuota')" prop="cpuQuota">
<el-input
type="number"
style="width: 40%"
v-model.number="paramModel.cpuQuota"
maxlength="5"
>
<template #append>{{ $t('app.cpuCore') }}</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.memoryLimit')" prop="memoryLimit">
<el-input style="width: 40%" v-model.number="paramModel.memoryLimit" maxlength="10">
<template #append>
<el-select v-model="paramModel.memoryUnit" placeholder="Select" style="width: 85px">
<el-option label="KB" value="K" />
<el-option label="MB" value="M" />
<el-option label="GB" value="G" />
</el-select>
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item prop="editCompose"> <div v-else v-loading="loading">
<el-checkbox v-model="paramModel.editCompose" :label="$t('app.editCompose')" size="large" /> <el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" class="common-prompt" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span> <el-form @submit.prevent ref="paramForm" :model="paramModel" label-position="top" :rules="rules">
</el-form-item> <div v-for="(p, index) in params" :key="index">
<div v-if="paramModel.editCompose"> <el-form-item :prop="p.key" :label="getLabel(p)">
<codemirror <el-input
:autofocus="true" v-if="p.type == 'number'"
placeholder="" type="number"
:indent-with-tab="true" v-model.number="paramModel.params[p.key]"
:tabSize="4" :disabled="!p.edit"
style="height: 400px" ></el-input>
:lineWrapping="true" <el-select
:matchBrackets="true" v-model="paramModel.params[p.key]"
theme="cobalt" v-else-if="p.type == 'select'"
:styleActiveLine="true" :multiple="p.multiple"
:extensions="extensions" >
v-model="paramModel.dockerCompose" <el-option
/> v-for="value in p.values"
</div> :key="value.label"
:value="value.value"
:label="value.label"
:disabled="!p.edit"
></el-option>
</el-select>
<el-input v-else v-model.trim="paramModel.params[p.key]" :disabled="!p.edit"></el-input>
</el-form-item>
</div>
<el-form-item prop="advanced">
<el-checkbox v-model="paramModel.advanced" :label="$t('app.advanced')" size="large" />
</el-form-item>
<div v-if="paramModel.advanced">
<el-form-item :label="$t('app.containerName')" prop="containerName">
<el-input
v-model.trim="paramModel.containerName"
:placeholder="$t('app.containerNameHelper')"
></el-input>
</el-form-item>
<el-form-item prop="allowPort" v-if="!paramModel.isHostMode">
<el-checkbox v-model="paramModel.allowPort" :label="$t('app.allowPort')" size="large" />
<span class="input-help">{{ $t('app.allowPortHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.cpuQuota')" prop="cpuQuota">
<el-input type="number" class="!w-2/5" v-model.number="paramModel.cpuQuota" maxlength="5">
<template #append>{{ $t('app.cpuCore') }}</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.memoryLimit')" prop="memoryLimit">
<el-input class="!w-2/5" v-model.number="paramModel.memoryLimit" maxlength="10">
<template #append>
<el-select v-model="paramModel.memoryUnit" placeholder="Select" style="width: 85px">
<el-option label="KB" value="K" />
<el-option label="MB" value="M" />
<el-option label="GB" value="G" />
</el-select>
</template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper') }}</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="paramModel.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<div v-if="paramModel.editCompose">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="height: 400px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="paramModel.dockerCompose"
/>
</div> </div>
</el-form> </div>
</el-col> </el-form>
</el-row> </div>
<template #footer v-if="edit"> <template #footer v-if="edit">
<span> <span>
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -115,13 +101,12 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
import { GetAppInstallParams, UpdateAppInstallParams } from '@/api/modules/app'; import { GetAppInstallParams, UpdateAppInstallParams } from '@/api/modules/app';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import Header from '@/components/drawer-header/index.vue';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { Rules, checkNumberRange } from '@/global/form-rules'; import { Rules, checkNumberRange } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,41 +1,39 @@
<template> <template>
<el-drawer :close-on-click-modal="false" :close-on-press-escape="false" v-model="open" size="30%"> <DrawerPro v-model="open" :header="$t('app.ignoreList')" :back="handleClose" size="small">
<template #header> <template #content>
<Header :header="$t('app.ignoreList')" :back="handleClose"></Header> <el-row :gutter="5">
<el-col v-for="(app, index) in apps" :key="index">
<el-card class="app-margin">
<el-row :gutter="20">
<el-col :span="6">
<el-avatar shape="square" :size="60" :src="'data:image/png;base64,' + app.icon" />
</el-col>
<el-col :span="12">
<span>{{ app.name }}</span>
<div class="app-margin">
<el-tag>{{ app.version }}</el-tag>
</div>
</el-col>
<el-col :span="6">
<el-button type="primary" link @click="cancelIgnore(app.detailID)">
{{ $t('app.cancelIgnore') }}
</el-button>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
</template> </template>
<el-row :gutter="5">
<el-col v-for="(app, index) in apps" :key="index">
<el-card class="app-margin">
<el-row :gutter="20">
<el-col :span="6">
<el-avatar shape="square" :size="60" :src="'data:image/png;base64,' + app.icon" />
</el-col>
<el-col :span="12">
<span>{{ app.name }}</span>
<div class="app-margin">
<el-tag>{{ app.version }}</el-tag>
</div>
</el-col>
<el-col :span="6">
<el-button type="primary" link @click="cancelIgnore(app.detailID)">
{{ $t('app.cancelIgnore') }}
</el-button>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { GetIgnoredApp, IgnoreUpgrade } from '@/api/modules/app'; import { GetIgnoredApp, IgnoreUpgrade } from '@/api/modules/app';
import { ref } from 'vue'; import { ref } from 'vue';
import Header from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import i18n from '@/lang'; import i18n from '@/lang';

View File

@ -1,94 +1,84 @@
<template> <template>
<el-drawer :close-on-click-modal="false" :close-on-press-escape="false" v-model="open" size="50%"> <DrawerPro
<template #header> v-model="open"
<Header :header="$t('commons.button.' + operateReq.operate)"
:header="$t('commons.button.' + operateReq.operate)" :resource="resourceName"
:resource="resourceName" :back="handleClose"
:back="handleClose" >
></Header> <el-descriptions direction="vertical">
</template> <el-descriptions-item>
<el-row :gutter="10"> <el-link @click="toLink(app.website)">
<el-col :span="22" :offset="1"> <el-icon><OfficeBuilding /></el-icon>
<div> <span>{{ $t('app.appOfficeWebsite') }}</span>
<el-descriptions direction="vertical"> </el-link>
<el-descriptions-item> </el-descriptions-item>
<el-link @click="toLink(app.website)"> <el-descriptions-item>
<el-icon><OfficeBuilding /></el-icon> <el-link @click="toLink(app.document)">
<span>{{ $t('app.appOfficeWebsite') }}</span> <el-icon><Document /></el-icon>
</el-link> <span>{{ $t('app.document') }}</span>
</el-descriptions-item> </el-link>
<el-descriptions-item> </el-descriptions-item>
<el-link @click="toLink(app.document)"> <el-descriptions-item>
<el-icon><Document /></el-icon> <el-link @click="toLink(app.github)">
<span>{{ $t('app.document') }}</span> <el-icon><Link /></el-icon>
</el-link> <span>{{ $t('app.github') }}</span>
</el-descriptions-item> </el-link>
<el-descriptions-item> </el-descriptions-item>
<el-link @click="toLink(app.github)"> </el-descriptions>
<el-icon><Link /></el-icon> <el-form
<span>{{ $t('app.github') }}</span> @submit.prevent
</el-link> ref="updateRef"
</el-descriptions-item> :rules="rules"
</el-descriptions> label-position="top"
</div> :model="operateReq"
</el-col> v-loading="loading"
<el-col :span="22" :offset="1"> >
<el-form <el-form-item :label="$t('app.versionSelect')" prop="detailId">
@submit.prevent <el-select v-model="operateReq.version" @change="getVersions(operateReq.version)">
ref="updateRef" <el-option
:rules="rules" v-for="(version, index) in versions"
label-position="top" :key="index"
:model="operateReq" :value="version.version"
v-loading="loading" :label="version.version"
> ></el-option>
<el-form-item :label="$t('app.versionSelect')" prop="detailId"> </el-select>
<el-select v-model="operateReq.version" @change="getVersions(operateReq.version)"> </el-form-item>
<el-option <el-form-item prop="backup" v-if="operateReq.operate === 'upgrade'">
v-for="(version, index) in versions" <el-checkbox v-model="operateReq.backup" :label="$t('app.backupApp')" />
:key="index" <span class="input-help">
:value="version.version" <el-text type="warning">{{ $t('app.backupAppHelper') }}</el-text>
:label="version.version" </span>
></el-option> </el-form-item>
</el-select> <el-form-item pro="pullImage" v-if="operateReq.operate === 'upgrade'">
</el-form-item> <el-checkbox v-model="operateReq.pullImage" :label="$t('container.forcePull')" size="large" />
<el-form-item prop="backup" v-if="operateReq.operate === 'upgrade'"> <span class="input-help">{{ $t('container.forcePullHelper') }}</span>
<el-checkbox v-model="operateReq.backup" :label="$t('app.backupApp')" /> </el-form-item>
<span class="input-help"> </el-form>
<el-text type="warning">{{ $t('app.backupAppHelper') }}</el-text>
</span>
</el-form-item>
<el-form-item pro="pullImage" v-if="operateReq.operate === 'upgrade'">
<el-checkbox v-model="operateReq.pullImage" :label="$t('container.forcePull')" size="large" />
<span class="input-help">{{ $t('container.forcePullHelper') }}</span>
</el-form-item>
</el-form>
</el-col>
<el-col :span="22" :offset="1" v-if="operateReq.operate === 'upgrade'"> <div v-if="operateReq.operate === 'upgrade'">
<el-text type="warning">{{ $t('app.upgradeWarn') }}</el-text> <el-text type="warning">{{ $t('app.upgradeWarn') }}</el-text>
<el-button class="ml-1.5" type="text" @click="openDiff()">{{ $t('app.showDiff') }}</el-button> <el-button class="ml-1.5" type="text" @click="openDiff()">{{ $t('app.showDiff') }}</el-button>
<div> <div>
<el-checkbox v-model="useNewCompose" :label="$t('app.useCustom')" size="large" /> <el-checkbox v-model="useNewCompose" :label="$t('app.useCustom')" size="large" />
</div> </div>
<div v-if="useNewCompose"> <div v-if="useNewCompose">
<el-text type="danger">{{ $t('app.useCustomHelper') }}</el-text> <el-text type="danger">{{ $t('app.useCustomHelper') }}</el-text>
</div> </div>
<codemirror <codemirror
v-if="useNewCompose" v-if="useNewCompose"
:autofocus="true" :autofocus="true"
placeholder="" placeholder=""
:indent-with-tab="true" :indent-with-tab="true"
:tabSize="4" :tabSize="4"
style="width: 100%; height: calc(100vh - 500px); margin-top: 10px" style="width: 100%; height: calc(100vh - 500px); margin-top: 10px"
:lineWrapping="true" :lineWrapping="true"
:matchBrackets="true" :matchBrackets="true"
theme="cobalt" theme="cobalt"
:styleActiveLine="true" :styleActiveLine="true"
:extensions="extensions" :extensions="extensions"
v-model="newCompose" v-model="newCompose"
/> />
</el-col> </div>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -98,7 +88,7 @@
</span> </span>
</template> </template>
<Diff ref="composeDiffRef" @confirm="getNewCompose" /> <Diff ref="composeDiffRef" @confirm="getNewCompose" />
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
@ -106,7 +96,6 @@ import { GetAppUpdateVersions, IgnoreUpgrade, InstalledOp } from '@/api/modules/
import i18n from '@/lang'; import i18n from '@/lang';
import { ElMessageBox, FormInstance } from 'element-plus'; import { ElMessageBox, FormInstance } from 'element-plus';
import { reactive, ref, onBeforeUnmount } from 'vue'; import { reactive, ref, onBeforeUnmount } from 'vue';
import Header from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import Diff from './diff/index.vue'; import Diff from './diff/index.vue';

View File

@ -1,95 +1,74 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.compose')" :back="handleClose" size="large">
v-model="drawerVisible" <el-form ref="formRef" @submit.prevent label-position="top" :model="form" :rules="rules" v-loading="loading">
@close="handleClose" <el-form-item :label="$t('container.from')">
:destroy-on-close="true" <el-radio-group v-model="form.from" @change="onEdit('form')">
:close-on-click-modal="false" <el-radio value="edit">{{ $t('commons.button.edit') }}</el-radio>
:close-on-press-escape="false" <el-radio value="path">{{ $t('container.pathSelect') }}</el-radio>
size="50%" <el-radio value="template">{{ $t('container.composeTemplate') }}</el-radio>
> </el-radio-group>
<template #header> </el-form-item>
<DrawerHeader :header="$t('container.compose')" :back="handleClose" /> <el-form-item v-if="form.from === 'path'" prop="path">
</template> <el-input
<div v-loading="loading"> @change="onEdit('')"
<el-row type="flex" justify="center"> :placeholder="$t('commons.example') + '/tmp/docker-compose.yml'"
<el-col :span="22"> v-model="form.path"
<el-form ref="formRef" @submit.prevent label-position="top" :model="form" :rules="rules"> >
<el-form-item :label="$t('container.from')"> <template #prepend>
<el-radio-group v-model="form.from" @change="onEdit('form')"> <FileList @choose="loadDir" :dir="false"></FileList>
<el-radio value="edit">{{ $t('commons.button.edit') }}</el-radio> </template>
<el-radio value="path">{{ $t('container.pathSelect') }}</el-radio> </el-input>
<el-radio value="template">{{ $t('container.composeTemplate') }}</el-radio> </el-form-item>
</el-radio-group> <el-form-item v-if="form.from === 'template'" prop="template">
</el-form-item> <el-select v-model="form.template" @change="onEdit('template')">
<el-form-item v-if="form.from === 'path'" prop="path"> <template #prefix>{{ $t('container.template') }}</template>
<el-input <el-option v-for="item in templateOptions" :key="item.id" :value="item.id" :label="item.name" />
@change="onEdit('')" </el-select>
:placeholder="$t('commons.example') + '/tmp/docker-compose.yml'" </el-form-item>
v-model="form.path" <el-form-item v-if="form.from === 'edit' || form.from === 'template'" prop="name">
> <el-input @input="changePath" @change="onEdit('')" v-model.trim="form.name">
<template #prepend> <template #prefix>
<FileList @choose="loadDir" :dir="false"></FileList> <span style="margin-right: 8px">{{ $t('file.dir') }}</span>
</template> </template>
</el-input> </el-input>
</el-form-item> <span class="input-help">
<el-form-item v-if="form.from === 'template'" prop="template"> {{ $t('container.composePathHelper', [composeFile]) }}
<el-select v-model="form.template" @change="onEdit('template')"> </span>
<template #prefix>{{ $t('container.template') }}</template> </el-form-item>
<el-option <el-form-item>
v-for="item in templateOptions" <div v-if="form.from === 'edit' || form.from === 'template'" style="width: 100%">
:key="item.id" <el-radio-group v-model="mode" size="small">
:value="item.id" <el-radio-button label="edit">{{ $t('commons.button.edit') }}</el-radio-button>
:label="item.name" <el-radio-button label="log">{{ $t('commons.button.log') }}</el-radio-button>
/> </el-radio-group>
</el-select> <codemirror
</el-form-item> @change="onEdit('')"
<el-form-item v-if="form.from === 'edit' || form.from === 'template'" prop="name"> v-if="mode === 'edit'"
<el-input @input="changePath" @change="onEdit('')" v-model.trim="form.name"> :autofocus="true"
<template #prefix> placeholder="#Define or paste the content of your docker-compose file here"
<span style="margin-right: 8px">{{ $t('file.dir') }}</span> :indent-with-tab="true"
</template> :tabSize="4"
</el-input> style="width: 100%; height: calc(100vh - 376px)"
<span class="input-help"> :lineWrapping="true"
{{ $t('container.composePathHelper', [composeFile]) }} :matchBrackets="true"
</span> theme="cobalt"
</el-form-item> :styleActiveLine="true"
<el-form-item> :extensions="extensions"
<div v-if="form.from === 'edit' || form.from === 'template'" style="width: 100%"> v-model="form.file"
<el-radio-group v-model="mode" size="small"> />
<el-radio-button label="edit">{{ $t('commons.button.edit') }}</el-radio-button> </div>
<el-radio-button label="log">{{ $t('commons.button.log') }}</el-radio-button> <div style="width: 100%">
</el-radio-group> <LogFile
<codemirror ref="logRef"
@change="onEdit('')" v-model:is-reading="isReading"
v-if="mode === 'edit'" :config="logConfig"
:autofocus="true" :default-button="false"
placeholder="#Define or paste the content of your docker-compose file here" v-if="mode === 'log' && showLog"
:indent-with-tab="true" :style="'height: calc(100vh - 370px);min-height: 200px'"
:tabSize="4" />
style="width: 100%; height: calc(100vh - 376px)" </div>
:lineWrapping="true" </el-form-item>
:matchBrackets="true" </el-form>
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.file"
/>
</div>
<div style="width: 100%">
<LogFile
ref="logRef"
v-model:is-reading="isReading"
:config="logConfig"
:default-button="false"
v-if="mode === 'log' && showLog"
:style="'height: calc(100vh - 370px);min-height: 200px'"
/>
</div>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false"> <el-button @click="drawerVisible = false">
@ -100,7 +79,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -110,8 +89,6 @@ import { Codemirror } from 'vue-codemirror';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm, ElMessageBox } from 'element-plus'; import { ElForm, ElMessageBox } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { listComposeTemplate, testCompose, upCompose } from '@/api/modules/container';
import { loadBaseDir } from '@/api/modules/setting'; import { loadBaseDir } from '@/api/modules/setting';
import { MsgError } from '@/utils/message'; import { MsgError } from '@/utils/message';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';

View File

@ -1,14 +1,11 @@
<template> <template>
<el-drawer <DrawerPro
v-model="composeVisible" v-model="composeVisible"
:destroy-on-close="true" :header="$t('commons.button.edit')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="name"
size="50%" size="large"
> >
<template #header>
<DrawerHeader :header="$t('commons.button.edit')" :resource="name" :back="handleClose" />
</template>
<div v-loading="loading"> <div v-loading="loading">
<codemirror <codemirror
:autofocus="true" :autofocus="true"
@ -34,7 +31,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
@ -44,7 +41,6 @@ import { ref } from 'vue';
import { composeUpdate } from '@/api/modules/container'; import { composeUpdate } from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false); const loading = ref(false);
const composeVisible = ref(false); const composeVisible = ref(false);

View File

@ -1,43 +1,36 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="$t('container.makeImage')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="form.containerName"
size="50%" size="large"
> >
<template #header> <el-form @submit.prevent ref="formRef" :model="form" label-position="top" v-loading="loading">
<DrawerHeader :header="$t('container.makeImage')" :resource="form.containerName" :back="handleClose" /> <el-form-item prop="newImageName" :rules="Rules.imageName">
</template> <template #label>
<el-row v-loading="loading"> {{ $t('container.newImageName') }}
<el-col :span="22" :offset="1"> </template>
<el-form @submit.prevent ref="formRef" :model="form" label-position="top"> <el-input v-model="form.newImageName" />
<el-form-item prop="newImageName" :rules="Rules.imageName"> </el-form-item>
<template #label> <el-form-item prop="comment">
{{ $t('container.newImageName') }} <template #label>
</template> {{ $t('container.commitMessage') }}
<el-input v-model="form.newImageName" /> </template>
</el-form-item> <el-input v-model="form.comment" />
<el-form-item prop="comment"> </el-form-item>
<template #label> <el-form-item prop="author">
{{ $t('container.commitMessage') }} <template #label>
</template> {{ $t('container.author') }}
<el-input v-model="form.comment" /> </template>
</el-form-item> <el-input v-model="form.author" />
<el-form-item prop="author"> </el-form-item>
<template #label> <el-form-item prop="pause">
{{ $t('container.author') }} <el-checkbox v-model="form.pause">
</template> {{ $t('container.ifPause') }}
<el-input v-model="form.author" /> </el-checkbox>
</el-form-item> </el-form-item>
<el-form-item prop="pause"> </el-form>
<el-checkbox v-model="form.pause">
{{ $t('container.ifPause') }}
</el-checkbox>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="drawerVisible = false"> <el-button :disabled="loading" @click="drawerVisible = false">
@ -48,12 +41,11 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';

View File

@ -59,6 +59,7 @@
trigger="hover" trigger="hover"
:title="$t('commons.table.selectColumn')" :title="$t('commons.table.selectColumn')"
popper-class="popper-class" popper-class="popper-class"
:only-icon="true"
/> />
</template> </template>
<template #main> <template #main>

View File

@ -1,69 +1,71 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="logVisible" v-model="logVisible"
:destroy-on-close="true" :header="$t('commons.button.log')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="logSearch.container"
:before-close="handleClose" :size="globalStore.isFullScreen ? 'full' : 'large'"
:size="globalStore.isFullScreen ? '100%' : '50%'"
> >
<template #header> <template #extra v-if="!mobile">
<DrawerHeader :header="$t('commons.button.log')" :resource="logSearch.container" :back="handleClose"> <el-tooltip :content="loadTooltip()" placement="top">
<template #extra v-if="!mobile"> <el-button @click="toggleFullscreen" class="fullScreen" icon="FullScreen" plain></el-button>
<el-tooltip :content="loadTooltip()" placement="top"> </el-tooltip>
<el-button @click="toggleFullscreen" class="fullScreen" icon="FullScreen" plain></el-button>
</el-tooltip>
</template>
</DrawerHeader>
</template> </template>
<div> <template #content>
<el-select @change="searchLogs" class="fetchClass" v-model="logSearch.mode"> <div>
<template #prefix>{{ $t('container.fetch') }}</template> <el-select @change="searchLogs" class="fetchClass" v-model="logSearch.mode">
<el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" /> <template #prefix>{{ $t('container.fetch') }}</template>
</el-select> <el-option
<el-select @change="searchLogs" class="tailClass" v-model.number="logSearch.tail"> v-for="item in timeOptions"
<template #prefix>{{ $t('container.lines') }}</template> :key="item.label"
<el-option :value="0" :label="$t('commons.table.all')" /> :value="item.value"
<el-option :value="100" :label="100" /> :label="item.label"
<el-option :value="200" :label="200" /> />
<el-option :value="500" :label="500" /> </el-select>
<el-option :value="1000" :label="1000" /> <el-select @change="searchLogs" class="tailClass" v-model.number="logSearch.tail">
</el-select> <template #prefix>{{ $t('container.lines') }}</template>
<div class="margin-button" style="float: left"> <el-option :value="0" :label="$t('commons.table.all')" />
<el-checkbox border @change="searchLogs" v-model="logSearch.isWatch"> <el-option :value="100" :label="100" />
{{ $t('commons.button.watch') }} <el-option :value="200" :label="200" />
</el-checkbox> <el-option :value="500" :label="500" />
<el-option :value="1000" :label="1000" />
</el-select>
<div class="margin-button" style="float: left">
<el-checkbox border @change="searchLogs" v-model="logSearch.isWatch">
{{ $t('commons.button.watch') }}
</el-checkbox>
</div>
<el-button class="margin-button" @click="onDownload" icon="Download">
{{ $t('file.download') }}
</el-button>
<el-button class="margin-button" @click="onClean" icon="Delete">
{{ $t('commons.button.clean') }}
</el-button>
</div> </div>
<el-button class="margin-button" @click="onDownload" icon="Download">
{{ $t('file.download') }}
</el-button>
<el-button class="margin-button" @click="onClean" icon="Delete">
{{ $t('commons.button.clean') }}
</el-button>
</div>
<codemirror <codemirror
:autofocus="true" :autofocus="true"
:placeholder="$t('commons.msg.noneData')" :placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true" :indent-with-tab="true"
:tabSize="4" :tabSize="4"
style="margin-top: 20px; height: calc(100vh - 230px)" style="margin-top: 20px; height: calc(100vh - 230px)"
:lineWrapping="true" :lineWrapping="true"
:matchBrackets="true" :matchBrackets="true"
theme="cobalt" theme="cobalt"
:styleActiveLine="true" :styleActiveLine="true"
:extensions="extensions" :extensions="extensions"
v-model="logInfo" v-model="logInfo"
@ready="handleReady" @ready="handleReady"
:disabled="true" :disabled="true"
/> />
</template>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</div> </div>
</template> </template>
@ -75,7 +77,6 @@ import { computed, onBeforeUnmount, reactive, ref, shallowRef, watch } from 'vue
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import screenfull from 'screenfull'; import screenfull from 'screenfull';

View File

@ -1,15 +1,11 @@
<template> <template>
<el-drawer <DrawerPro
v-model="monitorVisible" v-model="monitorVisible"
:destroy-on-close="true" :header="$t('container.monitor')"
@close="handleClose" :back="handleClose"
:close-on-click-modal="false" :resource="title"
:close-on-press-escape="false" size="large"
size="50%"
> >
<template #header>
<DrawerHeader :header="$t('container.monitor')" :resource="title" :back="handleClose" />
</template>
<el-form label-position="top" @submit.prevent> <el-form label-position="top" @submit.prevent>
<el-form-item :label="$t('container.refreshTime')"> <el-form-item :label="$t('container.refreshTime')">
<el-select v-model="timeInterval" @change="changeTimer"> <el-select v-model="timeInterval" @change="changeTimer">
@ -30,7 +26,7 @@
v-if="chartsOption['cpuChart']" v-if="chartsOption['cpuChart']"
/> />
</el-card> </el-card>
<el-card style="margin-top: 10px"> <el-card class="mt-2.5">
<v-charts <v-charts
height="200px" height="200px"
id="memoryChart" id="memoryChart"
@ -39,7 +35,7 @@
v-if="chartsOption['memoryChart']" v-if="chartsOption['memoryChart']"
/> />
</el-card> </el-card>
<el-card style="margin-top: 10px"> <el-card class="mt-2.5">
<v-charts <v-charts
height="200px" height="200px"
id="ioChart" id="ioChart"
@ -48,7 +44,7 @@
v-if="chartsOption['ioChart']" v-if="chartsOption['ioChart']"
/> />
</el-card> </el-card>
<el-card style="margin-top: 10px"> <el-card class="mt-2.5">
<v-charts <v-charts
height="200px" height="200px"
id="networkChart" id="networkChart"
@ -57,7 +53,7 @@
v-if="chartsOption['networkChart']" v-if="chartsOption['networkChart']"
/> />
</el-card> </el-card>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -66,7 +62,6 @@ import { containerStats } from '@/api/modules/container';
import { dateFormatForSecond } from '@/utils/util'; import { dateFormatForSecond } from '@/utils/util';
import VCharts from '@/components/v-charts/index.vue'; import VCharts from '@/components/v-charts/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
const title = ref(); const title = ref();
const monitorVisible = ref(false); const monitorVisible = ref(false);

View File

@ -1,20 +1,11 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
@close="handleClose" :header="title"
:destroy-on-close="true" :back="handleClose"
:close-on-click-modal="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
:close-on-press-escape="false" size="large"
size="50%"
> >
<template #header>
<DrawerHeader
:header="title"
:hideResource="dialogData.title === 'create'"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form <el-form
ref="formRef" ref="formRef"
label-position="top" label-position="top"
@ -23,263 +14,227 @@
:rules="rules" :rules="rules"
label-width="80px" label-width="80px"
> >
<el-row type="flex" justify="center"> <el-alert
<el-col :span="22"> v-if="dialogData.title === 'edit' && isFromApp(dialogData.rowData!)"
<el-alert :title="$t('container.containerFromAppHelper')"
v-if="dialogData.title === 'edit' && isFromApp(dialogData.rowData!)" :closable="false"
:title="$t('container.containerFromAppHelper')" type="error"
:closable="false" />
type="error" <el-form-item class="mt-5" :label="$t('commons.table.name')" prop="name">
/> <el-input
<el-form-item class="mt-5" :label="$t('commons.table.name')" prop="name"> :disabled="isFromApp(dialogData.rowData!)"
<el-input clearable
:disabled="isFromApp(dialogData.rowData!)" v-model.trim="dialogData.rowData!.name"
clearable />
v-model.trim="dialogData.rowData!.name" <div v-if="dialogData.title === 'edit' && isFromApp(dialogData.rowData!)">
/> <span class="input-help">
<div v-if="dialogData.title === 'edit' && isFromApp(dialogData.rowData!)"> {{ $t('container.containerFromAppHelper1') }}
<span class="input-help"> <el-button style="margin-left: -5px" size="small" text type="primary" @click="goRouter()">
{{ $t('container.containerFromAppHelper1') }} <el-icon><Position /></el-icon>
<el-button {{ $t('firewall.quickJump') }}
style="margin-left: -5px" </el-button>
size="small" </span>
text </div>
type="primary" </el-form-item>
@click="goRouter()" <el-form-item :label="$t('container.image')" prop="image">
> <el-checkbox v-model="dialogData.rowData!.imageInput" :label="$t('container.input')" />
<el-icon><Position /></el-icon> <el-select v-if="!dialogData.rowData!.imageInput" filterable v-model="dialogData.rowData!.image">
{{ $t('firewall.quickJump') }} <el-option v-for="(item, index) of images" :key="index" :value="item.option" :label="item.option" />
</el-button> </el-select>
</span> <el-input v-else v-model="dialogData.rowData!.image" />
</div> </el-form-item>
</el-form-item> <el-form-item prop="forcePull">
<el-form-item :label="$t('container.image')" prop="image"> <el-checkbox v-model="dialogData.rowData!.forcePull">
<el-checkbox v-model="dialogData.rowData!.imageInput" :label="$t('container.input')" /> {{ $t('container.forcePull') }}
<el-select </el-checkbox>
v-if="!dialogData.rowData!.imageInput" <span class="input-help">{{ $t('container.forcePullHelper') }}</span>
filterable </el-form-item>
v-model="dialogData.rowData!.image" <el-form-item :label="$t('commons.table.port')">
> <el-radio-group v-model="dialogData.rowData!.publishAllPorts" class="ml-4">
<el-option <el-radio :value="false">{{ $t('container.exposePort') }}</el-radio>
v-for="(item, index) of images" <el-radio :value="true">{{ $t('container.exposeAll') }}</el-radio>
:key="index" </el-radio-group>
:value="item.option" </el-form-item>
:label="item.option" <el-form-item v-if="!dialogData.rowData!.publishAllPorts">
/> <el-card class="widthClass">
</el-select> <el-table
<el-input v-else v-model="dialogData.rowData!.image" /> v-if="dialogData.rowData!.exposedPorts.length !== 0"
</el-form-item> :data="dialogData.rowData!.exposedPorts"
<el-form-item prop="forcePull"> >
<el-checkbox v-model="dialogData.rowData!.forcePull"> <el-table-column :label="$t('container.server')" min-width="150">
{{ $t('container.forcePull') }} <template #default="{ row }">
</el-checkbox> <el-input :placeholder="$t('container.serverExample')" v-model="row.host" />
<span class="input-help">{{ $t('container.forcePullHelper') }}</span> </template>
</el-form-item> </el-table-column>
<el-form-item :label="$t('commons.table.port')"> <el-table-column :label="$t('container.container')" min-width="80">
<el-radio-group v-model="dialogData.rowData!.publishAllPorts" class="ml-4"> <template #default="{ row }">
<el-radio :value="false">{{ $t('container.exposePort') }}</el-radio> <el-input :placeholder="$t('container.containerExample')" v-model="row.containerPort" />
<el-radio :value="true">{{ $t('container.exposeAll') }}</el-radio> </template>
</el-radio-group> </el-table-column>
</el-form-item> <el-table-column :label="$t('commons.table.protocol')" min-width="50">
<el-form-item v-if="!dialogData.rowData!.publishAllPorts"> <template #default="{ row }">
<el-card class="widthClass"> <el-select
<el-table v-model="row.protocol"
v-if="dialogData.rowData!.exposedPorts.length !== 0" style="width: 100%"
:data="dialogData.rowData!.exposedPorts" :placeholder="$t('container.serverExample')"
>
<el-table-column :label="$t('container.server')" min-width="150">
<template #default="{ row }">
<el-input :placeholder="$t('container.serverExample')" v-model="row.host" />
</template>
</el-table-column>
<el-table-column :label="$t('container.container')" min-width="80">
<template #default="{ row }">
<el-input
:placeholder="$t('container.containerExample')"
v-model="row.containerPort"
/>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.protocol')" min-width="50">
<template #default="{ row }">
<el-select
v-model="row.protocol"
style="width: 100%"
:placeholder="$t('container.serverExample')"
>
<el-option label="tcp" value="tcp" />
<el-option label="udp" value="udp" />
</el-select>
</template>
</el-table-column>
<el-table-column min-width="35">
<template #default="scope">
<el-button link type="primary" @click="handlePortsDelete(scope.$index)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="ml-3 mt-2" @click="handlePortsAdd()">
{{ $t('commons.button.add') }}
</el-button>
</el-card>
</el-form-item>
<el-form-item :label="$t('container.network')" prop="network">
<el-select v-model="dialogData.rowData!.network">
<el-option
v-for="(item, indexV) of networks"
:key="indexV"
:value="item.option"
:label="item.option"
/>
</el-select>
</el-form-item>
<el-form-item label="ipv4" prop="ipv4">
<el-input v-model="dialogData.rowData!.ipv4" :placeholder="$t('container.inputIpv4')" />
</el-form-item>
<el-form-item label="ipv6" prop="ipv6">
<el-input v-model="dialogData.rowData!.ipv6" :placeholder="$t('container.inputIpv6')" />
</el-form-item>
<el-form-item :label="$t('container.mount')">
<div v-for="(row, index) in dialogData.rowData!.volumes" :key="index" style="width: 100%">
<el-card class="mt-1">
<el-radio-group v-model="row.type">
<el-radio-button value="volume">{{ $t('container.volumeOption') }}</el-radio-button>
<el-radio-button value="bind">{{ $t('container.hostOption') }}</el-radio-button>
</el-radio-group>
<el-button
class="float-right mt-3"
link
type="primary"
@click="handleVolumesDelete(index)"
> >
<el-option label="tcp" value="tcp" />
<el-option label="udp" value="udp" />
</el-select>
</template>
</el-table-column>
<el-table-column min-width="35">
<template #default="scope">
<el-button link type="primary" @click="handlePortsDelete(scope.$index)">
{{ $t('commons.button.delete') }} {{ $t('commons.button.delete') }}
</el-button> </el-button>
<el-row class="mt-4" :gutter="5">
<el-col :span="10">
<el-form-item
v-if="row.type === 'volume'"
:label="$t('container.volumeOption')"
>
<el-select filterable v-model="row.sourceDir">
<div v-for="(item, indexV) of volumes" :key="indexV">
<el-tooltip :hide-after="20" :content="item.option" placement="top">
<el-option
:value="item.option"
:label="item.option.substring(0, 30)"
/>
</el-tooltip>
</div>
</el-select>
</el-form-item>
<el-form-item v-else :label="$t('container.hostOption')">
<el-input v-model="row.sourceDir" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item :label="$t('container.mode')">
<el-select class="widthClass" filterable v-model="row.mode">
<el-option value="rw" :label="$t('container.modeRW')" />
<el-option value="ro" :label="$t('container.modeR')" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('container.containerDir')">
<el-input v-model="row.containerDir" />
</el-form-item>
</el-col>
</el-row>
</el-card>
</div>
<el-button @click="handleVolumesAdd()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item>
<el-form-item label="Command" prop="cmdStr">
<el-input v-model="dialogData.rowData!.cmdStr" :placeholder="$t('container.cmdHelper')" />
</el-form-item>
<el-form-item label="Entrypoint" prop="entrypointStr">
<el-input
v-model="dialogData.rowData!.entrypointStr"
:placeholder="$t('container.entrypointHelper')"
/>
</el-form-item>
<el-form-item prop="autoRemove">
<el-checkbox v-model="dialogData.rowData!.autoRemove">
{{ $t('container.autoRemove') }}
</el-checkbox>
</el-form-item>
<el-form-item>
<el-checkbox v-model="dialogData.rowData!.privileged">
{{ $t('container.privileged') }}
</el-checkbox>
<span class="input-help">{{ $t('container.privilegedHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.console')">
<el-checkbox v-model="dialogData.rowData!.tty">{{ $t('container.tty') }}</el-checkbox>
<el-checkbox v-model="dialogData.rowData!.openStdin">
{{ $t('container.openStdin') }}
</el-checkbox>
</el-form-item>
<el-form-item :label="$t('container.restartPolicy')" prop="restartPolicy">
<el-radio-group v-model="dialogData.rowData!.restartPolicy">
<el-radio value="no">{{ $t('container.no') }}</el-radio>
<el-radio value="always">{{ $t('container.always') }}</el-radio>
<el-radio value="on-failure">{{ $t('container.onFailure') }}</el-radio>
<el-radio value="unless-stopped">{{ $t('container.unlessStopped') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('container.cpuShare')" prop="cpuShares">
<el-input class="mini-form-item" v-model.number="dialogData.rowData!.cpuShares" />
<span class="input-help">{{ $t('container.cpuShareHelper') }}</span>
</el-form-item>
<el-form-item
:label="$t('container.cpuQuota')"
prop="nanoCPUs"
:rules="checkFloatNumberRange(0, Number(limits.cpu))"
>
<el-input class="mini-form-item" v-model="dialogData.rowData!.nanoCPUs">
<template #append>
<div style="width: 35px">{{ $t('commons.units.core') }}</div>
</template> </template>
</el-input> </el-table-column>
<span class="input-help"> </el-table>
{{ $t('container.limitHelper', [limits.cpu]) }}{{ $t('commons.units.core') }}
</span> <el-button class="ml-3 mt-2" @click="handlePortsAdd()">
</el-form-item> {{ $t('commons.button.add') }}
<el-form-item </el-button>
:label="$t('container.memoryLimit')" </el-card>
prop="memory" </el-form-item>
:rules="checkFloatNumberRange(0, Number(limits.memory))" <el-form-item :label="$t('container.network')" prop="network">
> <el-select v-model="dialogData.rowData!.network">
<el-input class="mini-form-item" v-model="dialogData.rowData!.memory"> <el-option
<template #append><div style="width: 35px">MB</div></template> v-for="(item, indexV) of networks"
</el-input> :key="indexV"
<span class="input-help">{{ $t('container.limitHelper', [limits.memory]) }}MB</span> :value="item.option"
</el-form-item> :label="item.option"
<el-form-item :label="$t('container.tag')" prop="labelsStr"> />
<el-input </el-select>
type="textarea" </el-form-item>
:placeholder="$t('container.tagHelper')"
:rows="3" <el-form-item label="ipv4" prop="ipv4">
v-model="dialogData.rowData!.labelsStr" <el-input v-model="dialogData.rowData!.ipv4" :placeholder="$t('container.inputIpv4')" />
/> </el-form-item>
</el-form-item> <el-form-item label="ipv6" prop="ipv6">
<el-form-item :label="$t('container.env')" prop="envStr"> <el-input v-model="dialogData.rowData!.ipv6" :placeholder="$t('container.inputIpv6')" />
<el-input </el-form-item>
type="textarea"
:placeholder="$t('container.tagHelper')" <el-form-item :label="$t('container.mount')">
:rows="3" <div v-for="(row, index) in dialogData.rowData!.volumes" :key="index" style="width: 100%">
v-model="dialogData.rowData!.envStr" <el-card class="mt-1">
/> <el-radio-group v-model="row.type">
</el-form-item> <el-radio-button value="volume">{{ $t('container.volumeOption') }}</el-radio-button>
</el-col> <el-radio-button value="bind">{{ $t('container.hostOption') }}</el-radio-button>
</el-row> </el-radio-group>
<el-button class="float-right mt-3" link type="primary" @click="handleVolumesDelete(index)">
{{ $t('commons.button.delete') }}
</el-button>
<el-row class="mt-4" :gutter="5">
<el-col :span="10">
<el-form-item v-if="row.type === 'volume'" :label="$t('container.volumeOption')">
<el-select filterable v-model="row.sourceDir">
<div v-for="(item, indexV) of volumes" :key="indexV">
<el-tooltip :hide-after="20" :content="item.option" placement="top">
<el-option :value="item.option" :label="item.option.substring(0, 30)" />
</el-tooltip>
</div>
</el-select>
</el-form-item>
<el-form-item v-else :label="$t('container.hostOption')">
<el-input v-model="row.sourceDir" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item :label="$t('container.mode')">
<el-select class="widthClass" filterable v-model="row.mode">
<el-option value="rw" :label="$t('container.modeRW')" />
<el-option value="ro" :label="$t('container.modeR')" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('container.containerDir')">
<el-input v-model="row.containerDir" />
</el-form-item>
</el-col>
</el-row>
</el-card>
</div>
<el-button @click="handleVolumesAdd()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item>
<el-form-item label="Command" prop="cmdStr">
<el-input v-model="dialogData.rowData!.cmdStr" :placeholder="$t('container.cmdHelper')" />
</el-form-item>
<el-form-item label="Entrypoint" prop="entrypointStr">
<el-input v-model="dialogData.rowData!.entrypointStr" :placeholder="$t('container.entrypointHelper')" />
</el-form-item>
<el-form-item prop="autoRemove">
<el-checkbox v-model="dialogData.rowData!.autoRemove">
{{ $t('container.autoRemove') }}
</el-checkbox>
</el-form-item>
<el-form-item>
<el-checkbox v-model="dialogData.rowData!.privileged">
{{ $t('container.privileged') }}
</el-checkbox>
<span class="input-help">{{ $t('container.privilegedHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('container.console')">
<el-checkbox v-model="dialogData.rowData!.tty">{{ $t('container.tty') }}</el-checkbox>
<el-checkbox v-model="dialogData.rowData!.openStdin">
{{ $t('container.openStdin') }}
</el-checkbox>
</el-form-item>
<el-form-item :label="$t('container.restartPolicy')" prop="restartPolicy">
<el-radio-group v-model="dialogData.rowData!.restartPolicy">
<el-radio value="no">{{ $t('container.no') }}</el-radio>
<el-radio value="always">{{ $t('container.always') }}</el-radio>
<el-radio value="on-failure">{{ $t('container.onFailure') }}</el-radio>
<el-radio value="unless-stopped">{{ $t('container.unlessStopped') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('container.cpuShare')" prop="cpuShares">
<el-input class="mini-form-item" v-model.number="dialogData.rowData!.cpuShares" />
<span class="input-help">{{ $t('container.cpuShareHelper') }}</span>
</el-form-item>
<el-form-item
:label="$t('container.cpuQuota')"
prop="nanoCPUs"
:rules="checkFloatNumberRange(0, Number(limits.cpu))"
>
<el-input class="mini-form-item" v-model="dialogData.rowData!.nanoCPUs">
<template #append>
<div style="width: 35px">{{ $t('commons.units.core') }}</div>
</template>
</el-input>
<span class="input-help">
{{ $t('container.limitHelper', [limits.cpu]) }}{{ $t('commons.units.core') }}
</span>
</el-form-item>
<el-form-item
:label="$t('container.memoryLimit')"
prop="memory"
:rules="checkFloatNumberRange(0, Number(limits.memory))"
>
<el-input class="mini-form-item" v-model="dialogData.rowData!.memory">
<template #append><div style="width: 35px">MB</div></template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper', [limits.memory]) }}MB</span>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelsStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:rows="3"
v-model="dialogData.rowData!.labelsStr"
/>
</el-form-item>
<el-form-item :label="$t('container.env')" prop="envStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:rows="3"
v-model="dialogData.rowData!.envStr"
/>
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -291,7 +246,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -299,7 +254,6 @@ import { reactive, ref } from 'vue';
import { Rules, checkFloatNumberRange, checkNumberRange } from '@/global/form-rules'; import { Rules, checkFloatNumberRange, checkNumberRange } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm, ElMessageBox } from 'element-plus'; import { ElForm, ElMessageBox } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { import {
listImage, listImage,
listVolume, listVolume,

View File

@ -1,26 +1,19 @@
<template> <template>
<el-drawer <DrawerPro
v-model="newNameVisible" v-model="newNameVisible"
:destroy-on-close="true" :header="$t('container.rename')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="renameForm.name"
size="30%" size="small"
> >
<template #header>
<DrawerHeader :header="$t('container.rename')" :resource="renameForm.name" :back="handleClose" />
</template>
<el-form @submit.prevent ref="newNameRef" v-loading="loading" :model="renameForm" label-position="top"> <el-form @submit.prevent ref="newNameRef" v-loading="loading" :model="renameForm" label-position="top">
<el-row type="flex" justify="center"> <el-form-item
<el-col :span="22"> :label="$t('container.newName')"
<el-form-item :rules="[Rules.containerName, Rules.requiredInput]"
:label="$t('container.newName')" prop="newName"
:rules="[Rules.containerName, Rules.requiredInput]" >
prop="newName" <el-input v-model="renameForm.newName"></el-input>
> </el-form-item>
<el-input v-model="renameForm.newName"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -32,7 +25,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -42,7 +35,6 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false); const loading = ref(false);

View File

@ -1,57 +1,55 @@
<template> <template>
<el-drawer <DrawerPro
v-model="terminalVisible" v-model="terminalVisible"
@close="handleClose" :header="$t('container.containerTerminal')"
:destroy-on-close="true" :back="handleClose"
:close-on-click-modal="false" :resource="title"
:close-on-press-escape="false" size="large"
size="50%"
> >
<template #header> <template #content>
<DrawerHeader :header="$t('container.containerTerminal')" :resource="title" :back="handleClose" /> <el-form ref="formRef" :model="form" label-position="top">
</template> <el-form-item :label="$t('commons.table.user')" prop="user">
<el-form ref="formRef" :model="form" label-position="top"> <el-input placeholder="root" clearable v-model="form.user" />
<el-form-item :label="$t('commons.table.user')" prop="user"> </el-form-item>
<el-input placeholder="root" clearable v-model="form.user" /> <el-form-item
</el-form-item> v-if="form.isCustom"
<el-form-item :label="$t('container.command')"
v-if="form.isCustom" prop="command"
:label="$t('container.command')" :rules="Rules.requiredInput"
prop="command" >
:rules="Rules.requiredInput" <el-checkbox class="p-w-100" border v-model="form.isCustom" @change="onChangeCommand">
> {{ $t('container.custom') }}
<el-checkbox style="width: 100px" border v-model="form.isCustom" @change="onChangeCommand"> </el-checkbox>
{{ $t('container.custom') }} <el-input style="width: calc(100% - 100px)" clearable v-model="form.command" />
</el-checkbox> </el-form-item>
<el-input style="width: calc(100% - 100px)" clearable v-model="form.command" /> <el-form-item
</el-form-item> v-if="!form.isCustom"
<el-form-item :label="$t('container.command')"
v-if="!form.isCustom" prop="command"
:label="$t('container.command')" :rules="Rules.requiredSelect"
prop="command" >
:rules="Rules.requiredSelect" <el-checkbox class="p-w-100" border v-model="form.isCustom" @change="onChangeCommand">
> {{ $t('container.custom') }}
<el-checkbox style="width: 100px" border v-model="form.isCustom" @change="onChangeCommand"> </el-checkbox>
{{ $t('container.custom') }} <el-select style="width: calc(100% - 100px)" filterable clearable v-model="form.command">
</el-checkbox> <el-option value="/bin/ash" label="/bin/ash" />
<el-select style="width: calc(100% - 100px)" filterable clearable v-model="form.command"> <el-option value="/bin/bash" label="/bin/bash" />
<el-option value="/bin/ash" label="/bin/ash" /> <el-option value="/bin/sh" label="/bin/sh" />
<el-option value="/bin/bash" label="/bin/bash" /> </el-select>
<el-option value="/bin/sh" label="/bin/sh" /> </el-form-item>
</el-select>
</el-form-item>
<el-button v-if="!terminalOpen" @click="initTerm(formRef)"> <el-button v-if="!terminalOpen" @click="initTerm(formRef)">
{{ $t('commons.button.conn') }} {{ $t('commons.button.conn') }}
</el-button> </el-button>
<el-button v-else @click="onClose()">{{ $t('commons.button.disconn') }}</el-button> <el-button v-else @click="onClose()">{{ $t('commons.button.disconn') }}</el-button>
<Terminal <Terminal
style="height: calc(100vh - 302px); margin-top: 18px" style="height: calc(100vh - 302px); margin-top: 18px"
ref="terminalRef" ref="terminalRef"
v-if="terminalOpen" v-if="terminalOpen"
></Terminal> ></Terminal>
</el-form> </el-form>
</el-drawer> </template>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -59,7 +57,6 @@ import { reactive, ref, nextTick } from 'vue';
import { ElForm, FormInstance } from 'element-plus'; import { ElForm, FormInstance } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import Terminal from '@/components/terminal/index.vue'; import Terminal from '@/components/terminal/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
const title = ref(); const title = ref();
const terminalVisible = ref(false); const terminalVisible = ref(false);

View File

@ -1,54 +1,42 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="$t('commons.button.upgrade')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="form.containerName"
size="50%" size="large"
> >
<template #header> <el-alert
<DrawerHeader :header="$t('commons.button.upgrade')" :resource="form.containerName" :back="handleClose" /> :title="$t('container.appHelper')"
</template> v-if="form.fromApp"
class="common-prompt"
<el-row v-loading="loading"> :closable="false"
<el-col :span="22" :offset="1"> type="error"
<el-alert />
:title="$t('container.appHelper')" <el-form @submit.prevent ref="formRef" :model="form" label-position="top">
v-if="form.fromApp" <el-form-item :label="$t('container.oldImage')" prop="oldImage">
class="common-prompt" <el-tooltip placement="top-start" :content="form.oldImageName" v-if="form.oldImageName.length > 50">
:closable="false" <el-tag>{{ form.oldImageName.substring(0, 50) }}...</el-tag>
type="error" </el-tooltip>
/> <el-tag v-else>{{ form.oldImageName }}</el-tag>
<el-form @submit.prevent ref="formRef" :model="form" label-position="top"> </el-form-item>
<el-form-item :label="$t('container.oldImage')" prop="oldImage"> <el-form-item prop="newImageName" :rules="Rules.imageName">
<el-tooltip <template #label>
placement="top-start" {{ $t('container.targetImage') }}
:content="form.oldImageName" <span v-if="!form.hasName">
v-if="form.oldImageName.length > 50" {{ ' (' + $t('container.imageLoadErr') + ')' }}
> </span>
<el-tag>{{ form.oldImageName.substring(0, 50) }}...</el-tag> </template>
</el-tooltip> <el-input v-model="form.newImageName" />
<el-tag v-else>{{ form.oldImageName }}</el-tag> <span class="input-help">{{ $t('container.upgradeHelper') }}</span>
</el-form-item> </el-form-item>
<el-form-item prop="newImageName" :rules="Rules.imageName"> <el-form-item prop="forcePull">
<template #label> <el-checkbox v-model="form.forcePull">
{{ $t('container.targetImage') }} {{ $t('container.forcePull') }}
<span v-if="!form.hasName"> </el-checkbox>
{{ ' (' + $t('container.imageLoadErr') + ')' }} <span class="input-help">{{ $t('container.forcePullHelper') }}</span>
</span> </el-form-item>
</template> </el-form>
<el-input v-model="form.newImageName" />
<span class="input-help">{{ $t('container.upgradeHelper') }}</span>
</el-form-item>
<el-form-item prop="forcePull">
<el-checkbox v-model="form.forcePull">
{{ $t('container.forcePull') }}
</el-checkbox>
<span class="input-help">{{ $t('container.forcePullHelper') }}</span>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="drawerVisible = false"> <el-button :disabled="loading" @click="drawerVisible = false">
@ -59,7 +47,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -69,7 +57,6 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false); const loading = ref(false);

View File

@ -1,72 +1,58 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.imageBuild')" :back="handleClose" size="large">
v-model="drawerVisible" <el-form ref="formRef" label-position="top" :model="form" label-width="80px" :rules="rules">
:destroy-on-close="true" <el-form-item :label="$t('commons.table.name')" prop="name">
@close="handleClose" <el-input :placeholder="$t('container.imageNameHelper')" v-model.trim="form.name" clearable />
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Dockerfile" prop="from">
size="50%" <el-radio-group @change="onEdit()" v-model="form.from">
> <el-radio value="edit">{{ $t('commons.button.edit') }}</el-radio>
<template #header> <el-radio value="path">{{ $t('container.pathSelect') }}</el-radio>
<DrawerHeader :header="$t('container.imageBuild')" :back="handleClose" /> </el-radio-group>
</template> </el-form-item>
<el-row type="flex" justify="center"> <el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
<el-col :span="22"> <codemirror
<el-form ref="formRef" label-position="top" :model="form" label-width="80px" :rules="rules"> @change="onEdit()"
<el-form-item :label="$t('commons.table.name')" prop="name"> :autofocus="true"
<el-input :placeholder="$t('container.imageNameHelper')" v-model.trim="form.name" clearable /> placeholder="#Define or paste the content of your Dockerfile here"
</el-form-item> :indent-with-tab="true"
<el-form-item label="Dockerfile" prop="from"> :tabSize="4"
<el-radio-group @change="onEdit()" v-model="form.from"> style="width: 100%; height: calc(100vh - 520px)"
<el-radio value="edit">{{ $t('commons.button.edit') }}</el-radio> :lineWrapping="true"
<el-radio value="path">{{ $t('container.pathSelect') }}</el-radio> :matchBrackets="true"
</el-radio-group> theme="cobalt"
</el-form-item> :styleActiveLine="true"
<el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput"> :extensions="extensions"
<codemirror v-model="form.dockerfile"
@change="onEdit()" :readOnly="true"
: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 @change="onEdit()" clearable v-model="form.dockerfile">
<template #prepend>
<FileList @choose="loadBuildDir"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.tag')">
<el-input
@change="onEdit()"
:placeholder="$t('container.tagHelper')"
type="textarea"
:rows="3"
v-model="form.tagStr"
/>
</el-form-item>
</el-form>
<LogFile
ref="logRef"
:config="logConfig"
:default-button="false"
v-model:is-reading="isReading"
v-if="logVisible"
:style="'height: calc(100vh - 370px);min-height: 200px'"
/> />
</el-col> </el-form-item>
</el-row> <el-form-item v-else :rules="Rules.requiredSelect" prop="dockerfile">
<el-input @change="onEdit()" clearable v-model="form.dockerfile">
<template #prepend>
<FileList @choose="loadBuildDir"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('container.tag')">
<el-input
@change="onEdit()"
:placeholder="$t('container.tagHelper')"
type="textarea"
:rows="3"
v-model="form.tagStr"
/>
</el-form-item>
</el-form>
<LogFile
ref="logRef"
:config="logConfig"
:default-button="false"
v-model:is-reading="isReading"
v-if="logVisible"
:style="'height: calc(100vh - 370px);min-height: 200px'"
/>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -76,7 +62,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -89,7 +75,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm, ElMessage } from 'element-plus'; import { ElForm, ElMessage } from 'element-plus';
import { imageBuild } from '@/api/modules/container'; import { imageBuild } from '@/api/modules/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
const logVisible = ref<boolean>(false); const logVisible = ref<boolean>(false);
const extensions = [javascript(), oneDark]; const extensions = [javascript(), oneDark];

View File

@ -25,7 +25,7 @@
</el-button> </el-button>
</template> </template>
<template #rightToolBar> <template #rightToolBar>
<TableSearch @search="search()" v-model:searchName="searchName" class="mr-" /> <TableSearch @search="search()" v-model:searchName="searchName" class="mr-2.5" />
<TableSetting @search="search()" /> <TableSetting @search="search()" />
</template> </template>
<template #main> <template #main>

View File

@ -1,26 +1,13 @@
<template> <template>
<el-drawer <DrawerPro v-model="loadVisible" :header="$t('container.importImage')" :back="handleClose" size="small">
v-model="loadVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('container.importImage')" :back="handleClose" />
</template>
<el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top"> <el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top">
<el-row type="flex" justify="center"> <el-form-item :label="$t('container.path')" :rules="Rules.requiredInput" prop="path">
<el-col :span="22"> <el-input v-model="form.path">
<el-form-item :label="$t('container.path')" :rules="Rules.requiredInput" prop="path"> <template #prepend>
<el-input v-model="form.path"> <FileList @choose="loadLoadDir" :dir="false"></FileList>
<template #prepend> </template>
<FileList @choose="loadLoadDir" :dir="false"></FileList> </el-input>
</template> </el-form-item>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -32,7 +19,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -43,7 +30,6 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { imageLoad } from '@/api/modules/container'; import { imageLoad } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
const loading = ref(false); const loading = ref(false);

View File

@ -1,49 +1,35 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.imagePull')" :back="onCloseLog" size="large">
v-model="drawerVisible" <el-form ref="formRef" label-position="top" :model="form">
@close="onCloseLog" <el-form-item :label="$t('container.from')">
:destroy-on-close="true" <el-checkbox @change="onEdit()" v-model="form.fromRepo">
:close-on-click-modal="false" {{ $t('container.imageRepo') }}
:close-on-press-escape="false" </el-checkbox>
size="50%" </el-form-item>
> <el-form-item
<template #header> v-if="form.fromRepo"
<DrawerHeader :header="$t('container.imagePull')" :back="onCloseLog" /> :label="$t('container.repoName')"
</template> :rules="Rules.requiredSelect"
<el-row type="flex" justify="center"> prop="repoID"
<el-col :span="22"> >
<el-form ref="formRef" label-position="top" :model="form"> <el-select @change="onEdit()" clearable style="width: 100%" filterable v-model="form.repoID">
<el-form-item :label="$t('container.from')"> <el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" />
<el-checkbox @change="onEdit()" v-model="form.fromRepo"> </el-select>
{{ $t('container.imageRepo') }} </el-form-item>
</el-checkbox> <el-form-item :label="$t('container.imageName')" :rules="Rules.imageName" prop="imageName">
</el-form-item> <el-input @change="onEdit()" v-model.trim="form.imageName">
<el-form-item <template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
v-if="form.fromRepo" </el-input>
:label="$t('container.repoName')" </el-form-item>
:rules="Rules.requiredSelect" </el-form>
prop="repoID" <LogFile
> ref="logRef"
<el-select @change="onEdit()" clearable style="width: 100%" filterable v-model="form.repoID"> :config="logConfig"
<el-option v-for="item in repos" :key="item.id" :value="item.id" :label="item.name" /> :default-button="false"
</el-select> v-model:is-reading="isReading"
</el-form-item> v-if="showLog"
<el-form-item :label="$t('container.imageName')" :rules="Rules.imageName" prop="imageName"> :style="'height: calc(100vh - 397px);min-height: 200px'"
<el-input @change="onEdit()" v-model.trim="form.imageName"> />
<template v-if="form.fromRepo" #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<LogFile
ref="logRef"
:config="logConfig"
:default-button="false"
v-model:is-reading="isReading"
v-if="showLog"
:style="'height: calc(100vh - 397px);min-height: 200px'"
/>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false"> <el-button @click="drawerVisible = false">
@ -54,7 +40,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -64,7 +50,6 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { imagePull } from '@/api/modules/container'; import { imagePull } from '@/api/modules/container';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
const drawerVisible = ref(false); const drawerVisible = ref(false);

View File

@ -1,51 +1,32 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.imagePush')" :back="onCloseLog" size="large">
v-model="drawerVisible" <el-form ref="formRef" label-position="top" :model="form" label-width="80px">
:destroy-on-close="true" <el-form-item :label="$t('container.tag')" :rules="Rules.requiredSelect" prop="tagName">
@close="onCloseLog" <el-select @change="onEdit(true)" filterable v-model="form.tagName">
:close-on-click-modal="false" <el-option v-for="item in form.tags" :key="item" :value="item" :label="item" />
:close-on-press-escape="false" </el-select>
size="50%" </el-form-item>
> <el-form-item :label="$t('container.repoName')" :rules="Rules.requiredSelect" prop="repoID">
<template #header> <el-select @change="onEdit()" clearable style="width: 100%" filterable v-model="form.repoID">
<DrawerHeader :header="$t('container.imagePush')" :back="onCloseLog" /> <el-option v-for="item in dialogData.repos" :key="item.id" :value="item.id" :label="item.name" />
</template> </el-select>
<el-row type="flex" justify="center"> </el-form-item>
<el-col :span="22"> <el-form-item :label="$t('container.image')" :rules="Rules.imageName" prop="name">
<el-form ref="formRef" label-position="top" :model="form" label-width="80px"> <el-input @change="onEdit()" v-model.trim="form.name">
<el-form-item :label="$t('container.tag')" :rules="Rules.requiredSelect" prop="tagName"> <template #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
<el-select @change="onEdit(true)" filterable v-model="form.tagName"> </el-input>
<el-option v-for="item in form.tags" :key="item" :value="item" :label="item" /> </el-form-item>
</el-select> </el-form>
</el-form-item>
<el-form-item :label="$t('container.repoName')" :rules="Rules.requiredSelect" prop="repoID">
<el-select @change="onEdit()" clearable 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.image')" :rules="Rules.imageName" prop="name">
<el-input @change="onEdit()" v-model.trim="form.name">
<template #prepend>{{ loadDetailInfo(form.repoID) }}/</template>
</el-input>
</el-form-item>
</el-form>
<LogFile <LogFile
ref="logRef" ref="logRef"
:config="logConfig" :config="logConfig"
:default-button="false" :default-button="false"
v-model:is-reading="isReading" v-model:is-reading="isReading"
v-if="logVisible" v-if="logVisible"
:style="'height: calc(100vh - 370px);min-height: 200px'" :style="'height: calc(100vh - 370px);min-height: 200px'"
v-model:loading="loading" v-model:loading="loading"
/> />
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -57,7 +38,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -67,7 +48,6 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { imagePush } from '@/api/modules/container'; import { imagePush } from '@/api/modules/container';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
const drawerVisible = ref(false); const drawerVisible = ref(false);

View File

@ -1,50 +1,31 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.imageTag')" :back="handleClose" size="large">
v-model="drawerVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="50%"
>
<template #header>
<DrawerHeader :header="$t('container.imageTag')" :back="handleClose" />
</template>
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px"> <el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
<el-row type="flex" justify="center"> <el-form-item :label="$t('container.from')">
<el-col :span="22"> <el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox>
<el-form-item :label="$t('container.from')"> </el-form-item>
<el-checkbox v-model="form.fromRepo">{{ $t('container.imageRepo') }}</el-checkbox> <el-form-item
</el-form-item> v-if="form.fromRepo"
<el-form-item :label="$t('container.repoName')"
v-if="form.fromRepo" :rules="Rules.requiredSelect"
:label="$t('container.repoName')" prop="repo"
:rules="Rules.requiredSelect" >
prop="repo" <el-select clearable filterable v-model="form.repo" @change="changeRepo">
> <el-option v-for="item in repos" :key="item.id" :value="item.name" :label="item.name" />
<el-select style="width: 100%" clearable filterable v-model="form.repo" @change="changeRepo"> </el-select>
<el-option v-for="item in repos" :key="item.id" :value="item.name" :label="item.name" /> </el-form-item>
</el-select> <el-form-item :label="$t('container.imageTag')" :rules="Rules.imageName" prop="targetName">
</el-form-item> <el-input v-model="form.targetName" />
<el-form-item :label="$t('container.imageTag')" :rules="Rules.imageName" prop="targetName"> </el-form-item>
<el-input v-model="form.targetName" />
</el-form-item>
<el-form-item> <el-form-item>
<el-checkbox style="width: 100%" v-model="form.deleteTag"> <el-checkbox v-model="form.deleteTag">
{{ $t('container.imageTagDeleteHelper') }} {{ $t('container.imageTagDeleteHelper') }}
</el-checkbox> </el-checkbox>
<el-checkbox-group class="ml-5" v-if="form.deleteTag" v-model="form.deleteTags"> <el-checkbox-group class="ml-5" v-if="form.deleteTag" v-model="form.deleteTags">
<el-checkbox <el-checkbox v-for="item in tags" :key="item" :value="item" :label="item" />
style="width: 100%" </el-checkbox-group>
v-for="item in tags" </el-form-item>
:key="item"
:value="item"
:label="item"
/>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
@ -57,7 +38,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -67,7 +48,6 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { imageRemove, imageTag } from '@/api/modules/container'; import { imageRemove, imageTag } from '@/api/modules/container';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
const loading = ref(false); const loading = ref(false);

View File

@ -1,139 +1,116 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.createNetwork')" :back="handleClose" size="large">
v-model="drawerVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="50%"
>
<template #header>
<DrawerHeader :header="$t('container.createNetwork')" :back="handleClose" />
</template>
<el-form ref="formRef" label-position="top" v-loading="loading" :model="form" :rules="rules" label-width="80px"> <el-form ref="formRef" label-position="top" v-loading="loading" :model="form" :rules="rules" label-width="80px">
<el-row type="flex" justify="center"> <el-form-item :label="$t('container.networkName')" prop="name">
<el-col :span="22"> <el-input clearable v-model.trim="form.name" />
<el-form-item :label="$t('container.networkName')" prop="name"> </el-form-item>
<el-input clearable v-model.trim="form.name" /> <el-form-item :label="$t('container.driver')" prop="driver">
</el-form-item> <el-select v-model="form.driver">
<el-form-item :label="$t('container.driver')" prop="driver"> <el-option label="bridge" value="bridge" />
<el-select v-model="form.driver"> <el-option label="ipvlan" value="ipvlan" />
<el-option label="bridge" value="bridge" /> <el-option label="macvlan" value="macvlan" />
<el-option label="ipvlan" value="ipvlan" /> <el-option label="overlay" value="overlay" />
<el-option label="macvlan" value="macvlan" /> </el-select>
<el-option label="overlay" value="overlay" /> </el-form-item>
</el-select>
</el-form-item>
<el-checkbox v-model="form.ipv4">IPv4</el-checkbox> <el-checkbox v-model="form.ipv4">IPv4</el-checkbox>
<div v-if="form.ipv4"> <div v-if="form.ipv4">
<el-row type="flex" justify="center" :gutter="20"> <el-row type="flex" justify="center" :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item :label="$t('container.subnet')" prop="subnet"> <el-form-item :label="$t('container.subnet')" prop="subnet">
<el-input placeholder="172.16.10.0/24" clearable v-model.trim="form.subnet" /> <el-input placeholder="172.16.10.0/24" clearable v-model.trim="form.subnet" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('container.gateway')" prop="gateway">
<el-input placeholder="172.16.10.12" clearable v-model.trim="form.gateway" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('container.scope')" prop="scope">
<el-input placeholder="172.16.10.0/16" clearable v-model.trim="form.scope" />
</el-form-item>
</el-col>
<el-col :span="12"></el-col>
</el-row>
<el-form-item :label="$t('container.auxAddress')" prop="scopeV6">
<el-table :data="form.auxAddress" v-if="form.auxAddress.length !== 0">
<el-table-column :label="$t('container.label')" min-width="100">
<template #default="{ row }">
<el-input placeholder="my-router" v-model="row.key" />
</template>
</el-table-column>
<el-table-column label="IP" min-width="150">
<template #default="{ row }">
<el-input placeholder="172.16.10.13" v-model="row.value" />
</template>
</el-table-column>
<el-table-column min-width="40">
<template #default="scope">
<el-button link type="primary" @click="handleV4Delete(scope.$index)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-2" @click="handleV4Add()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item> </el-form-item>
</div> </el-col>
<el-col :span="12">
<el-checkbox class="mb-4" v-model="form.ipv6">IPv6</el-checkbox> <el-form-item :label="$t('container.gateway')" prop="gateway">
<div v-if="form.ipv6"> <el-input placeholder="172.16.10.12" clearable v-model.trim="form.gateway" />
<el-row type="flex" justify="center" :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('container.subnet')" prop="subnetV6">
<el-input placeholder="2408:400e::/48" clearable v-model.trim="form.subnetV6" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('container.gateway')" prop="gatewayV6">
<el-input placeholder="2408:400e::1" clearable v-model.trim="form.gatewayV6" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('container.scope')" prop="scopeV6">
<el-input placeholder="2408:400e::/64" clearable v-model.trim="form.scopeV6" />
</el-form-item>
</el-col>
<el-col :span="12"></el-col>
</el-row>
<el-form-item :label="$t('container.auxAddress')" prop="scopeV6">
<el-table :data="form.auxAddressV6" v-if="form.auxAddressV6.length !== 0">
<el-table-column :label="$t('container.label')" min-width="100">
<template #default="{ row }">
<el-input placeholder="my-router" v-model="row.key" />
</template>
</el-table-column>
<el-table-column label="IP" min-width="150">
<template #default="{ row }">
<el-input placeholder="2408:400e::3" v-model="row.value" />
</template>
</el-table-column>
<el-table-column min-width="40">
<template #default="scope">
<el-button link type="primary" @click="handleV6Delete(scope.$index)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-2" @click="handleV6Add()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item> </el-form-item>
</div> </el-col>
<el-col :span="12">
<el-form-item :label="$t('container.scope')" prop="scope">
<el-input placeholder="172.16.10.0/16" clearable v-model.trim="form.scope" />
</el-form-item>
</el-col>
<el-col :span="12"></el-col>
</el-row>
<el-form-item :label="$t('container.auxAddress')" prop="scopeV6">
<el-table :data="form.auxAddress" v-if="form.auxAddress.length !== 0">
<el-table-column :label="$t('container.label')" min-width="100">
<template #default="{ row }">
<el-input placeholder="my-router" v-model="row.key" />
</template>
</el-table-column>
<el-table-column label="IP" min-width="150">
<template #default="{ row }">
<el-input placeholder="172.16.10.13" v-model="row.value" />
</template>
</el-table-column>
<el-table-column min-width="40">
<template #default="scope">
<el-button link type="primary" @click="handleV4Delete(scope.$index)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-2" @click="handleV4Add()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item>
</div>
<el-form-item :label="$t('container.option')" prop="optionStr"> <el-checkbox class="mb-4" v-model="form.ipv6">IPv6</el-checkbox>
<el-input <div v-if="form.ipv6">
type="textarea" <el-row type="flex" justify="center" :gutter="20">
:placeholder="$t('container.tagHelper')" <el-col :span="12">
:rows="3" <el-form-item :label="$t('container.subnet')" prop="subnetV6">
v-model="form.optionStr" <el-input placeholder="2408:400e::/48" clearable v-model.trim="form.subnetV6" />
/> </el-form-item>
</el-form-item> </el-col>
<el-form-item :label="$t('container.tag')" prop="labelStr"> <el-col :span="12">
<el-input <el-form-item :label="$t('container.gateway')" prop="gatewayV6">
type="textarea" <el-input placeholder="2408:400e::1" clearable v-model.trim="form.gatewayV6" />
:placeholder="$t('container.tagHelper')" </el-form-item>
:rows="3" </el-col>
v-model="form.labelStr" <el-col :span="12">
/> <el-form-item :label="$t('container.scope')" prop="scopeV6">
</el-form-item> <el-input placeholder="2408:400e::/64" clearable v-model.trim="form.scopeV6" />
</el-col> </el-form-item>
</el-row> </el-col>
<el-col :span="12"></el-col>
</el-row>
<el-form-item :label="$t('container.auxAddress')" prop="scopeV6">
<el-table :data="form.auxAddressV6" v-if="form.auxAddressV6.length !== 0">
<el-table-column :label="$t('container.label')" min-width="100">
<template #default="{ row }">
<el-input placeholder="my-router" v-model="row.key" />
</template>
</el-table-column>
<el-table-column label="IP" min-width="150">
<template #default="{ row }">
<el-input placeholder="2408:400e::3" v-model="row.value" />
</template>
</el-table-column>
<el-table-column min-width="40">
<template #default="scope">
<el-button link type="primary" @click="handleV6Delete(scope.$index)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt-2" @click="handleV6Add()">
{{ $t('commons.button.add') }}
</el-button>
</el-form-item>
</div>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input type="textarea" :placeholder="$t('container.tagHelper')" :rows="3" v-model="form.optionStr" />
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input type="textarea" :placeholder="$t('container.tagHelper')" :rows="3" v-model="form.labelStr" />
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -145,7 +122,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -154,7 +131,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { createNetwork } from '@/api/modules/container'; import { createNetwork } from '@/api/modules/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { checkIp, checkIpV6 } from '@/utils/util'; import { checkIp, checkIpV6 } from '@/utils/util';

View File

@ -1,18 +1,11 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="title + $t('container.repo')"
:close-on-click-modal="false" :resource="dialogData.rowData?.name"
:close-on-press-escape="false" :back="handleClose"
size="30%" size="small"
> >
<template #header>
<DrawerHeader
:header="title + $t('container.repo')"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form <el-form
ref="formRef" ref="formRef"
label-position="top" label-position="top"
@ -21,53 +14,49 @@
:rules="rules" :rules="rules"
label-width="120px" label-width="120px"
> >
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input
<el-form-item :label="$t('commons.table.name')" prop="name"> clearable
<el-input :disabled="dialogData.title === 'edit'"
clearable v-model.trim="dialogData.rowData!.name"
:disabled="dialogData.title === 'edit'" ></el-input>
v-model.trim="dialogData.rowData!.name" </el-form-item>
></el-input> <el-form-item :label="$t('container.auth')" prop="auth">
</el-form-item> <el-radio-group v-model="dialogData.rowData!.auth">
<el-form-item :label="$t('container.auth')" prop="auth"> <el-radio :value="true">{{ $t('commons.true') }}</el-radio>
<el-radio-group v-model="dialogData.rowData!.auth"> <el-radio :value="false">{{ $t('commons.false') }}</el-radio>
<el-radio :value="true">{{ $t('commons.true') }}</el-radio> </el-radio-group>
<el-radio :value="false">{{ $t('commons.false') }}</el-radio> </el-form-item>
</el-radio-group> <el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.username')" prop="username">
</el-form-item> <el-input clearable v-model.trim="dialogData.rowData!.username"></el-input>
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.username')" prop="username"> </el-form-item>
<el-input clearable v-model.trim="dialogData.rowData!.username"></el-input> <el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input
<el-form-item v-if="dialogData.rowData!.auth" :label="$t('commons.login.password')" prop="password"> clearable
<el-input type="password"
clearable show-password
type="password" v-model.trim="dialogData.rowData!.password"
show-password ></el-input>
v-model.trim="dialogData.rowData!.password" </el-form-item>
></el-input> <el-form-item :label="$t('container.downloadUrl')" prop="downloadUrl">
</el-form-item> <el-input
<el-form-item :label="$t('container.downloadUrl')" prop="downloadUrl"> clearable
<el-input v-model.trim="dialogData.rowData!.downloadUrl"
clearable :placeholder="'172.16.10.10:8081'"
v-model.trim="dialogData.rowData!.downloadUrl" ></el-input>
:placeholder="'172.16.10.10:8081'" <span v-if="dialogData.rowData!.downloadUrl" class="input-help">
></el-input> docker pull {{ dialogData.rowData!.downloadUrl }}/nginx
<span v-if="dialogData.rowData!.downloadUrl" class="input-help"> </span>
docker pull {{ dialogData.rowData!.downloadUrl }}/nginx </el-form-item>
</span> <el-form-item :label="$t('commons.table.protocol')" prop="protocol">
</el-form-item> <el-radio-group v-model="dialogData.rowData!.protocol">
<el-form-item :label="$t('commons.table.protocol')" prop="protocol"> <el-radio label="http">http</el-radio>
<el-radio-group v-model="dialogData.rowData!.protocol"> <el-radio label="https">https</el-radio>
<el-radio label="http">http</el-radio> </el-radio-group>
<el-radio label="https">https</el-radio> <span v-if="dialogData.rowData!.protocol === 'http'" class="input-help">
</el-radio-group> {{ $t('container.httpRepo') }}
<span v-if="dialogData.rowData!.protocol === 'http'" class="input-help"> </span>
{{ $t('container.httpRepo') }} </el-form-item>
</span>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
@ -80,7 +69,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -89,7 +78,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { createImageRepo, updateImageRepo } from '@/api/modules/container'; import { createImageRepo, updateImageRepo } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,16 +1,5 @@
<template> <template>
<el-drawer <DrawerPro v-model="detailVisible" :header="$t('commons.button.view')" size="large">
v-model="detailVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="50%"
>
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.view') }}</span>
</div>
</template>
<codemirror <codemirror
:autofocus="true" :autofocus="true"
:placeholder="$t('commons.msg.noneData')" :placeholder="$t('commons.msg.noneData')"
@ -30,7 +19,7 @@
<el-button @click="detailVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="detailVisible = false">{{ $t('commons.button.cancel') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -1,19 +1,11 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="$t('container.composeTemplate')"
:close-on-click-modal="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
:close-on-press-escape="false" :back="handleClose"
size="50%" size="large"
> >
<template #header>
<DrawerHeader
:header="title + $t('container.composeTemplate')"
:hideResource="dialogData.title === 'create'"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form <el-form
v-loading="loading" v-loading="loading"
label-position="top" label-position="top"
@ -22,34 +14,27 @@
:rules="rules" :rules="rules"
label-width="80px" label-width="80px"
> >
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input :disabled="dialogData.title === 'edit'" v-model.trim="dialogData.rowData!.name"></el-input>
<el-form-item :label="$t('commons.table.name')" prop="name"> </el-form-item>
<el-input <el-form-item :label="$t('container.description')">
:disabled="dialogData.title === 'edit'" <el-input v-model="dialogData.rowData!.description"></el-input>
v-model.trim="dialogData.rowData!.name" </el-form-item>
></el-input> <el-form-item>
</el-form-item> <codemirror
<el-form-item :label="$t('container.description')"> :autofocus="true"
<el-input v-model="dialogData.rowData!.description"></el-input> placeholder="#Define or paste the content of your docker-compose file here"
</el-form-item> :indent-with-tab="true"
<el-form-item> :tabSize="4"
<codemirror style="width: 100%; height: calc(100vh - 351px)"
:autofocus="true" :lineWrapping="true"
placeholder="#Define or paste the content of your docker-compose file here" :matchBrackets="true"
:indent-with-tab="true" theme="cobalt"
:tabSize="4" :styleActiveLine="true"
style="width: 100%; height: calc(100vh - 351px)" :extensions="extensions"
:lineWrapping="true" v-model="dialogData.rowData!.content"
:matchBrackets="true" />
theme="cobalt" </el-form-item>
:styleActiveLine="true"
:extensions="extensions"
v-model="dialogData.rowData!.content"
/>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -61,7 +46,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -73,7 +58,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { createComposeTemplate, updateComposeTemplate } from '@/api/modules/container'; import { createComposeTemplate, updateComposeTemplate } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,78 +1,51 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="$t('container.createVolume')" :back="handleClose" size="small">
v-model="drawerVisible" <el-form
:destroy-on-close="true" ref="formRef"
:close-on-click-modal="false" v-loading="loading"
:close-on-press-escape="false" label-position="top"
size="30%" :model="form"
> :rules="rules"
<template #header> label-width="80px"
<DrawerHeader :header="$t('container.createVolume')" :back="handleClose" /> @submit.prevent
</template> >
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input clearable v-model.trim="form.name" />
<el-form </el-form-item>
ref="formRef" <el-form-item :label="$t('container.driver')" prop="driver">
v-loading="loading" <el-tag type="success">local</el-tag>
label-position="top" </el-form-item>
:model="form" <el-form-item :label="$t('container.nfsEnable')" prop="nfsStatus">
:rules="rules" <el-switch v-model="form.nfsStatus" active-value="enable" inactive-value="disable" />
label-width="80px" </el-form-item>
@submit.prevent <div v-if="form.nfsStatus === 'enable'">
> <el-form-item :label="$t('container.nfsAddress')" prop="nfsAddress">
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-input clearable v-model.trim="form.nfsAddress" :placeholder="$t('commons.rule.hostHelper')" />
<el-input clearable v-model.trim="form.name" /> </el-form-item>
</el-form-item> <el-form-item :label="$t('container.version')" prop="nfsVersion">
<el-form-item :label="$t('container.driver')" prop="driver"> <el-radio-group v-model="form.nfsVersion">
<el-tag type="success">local</el-tag> <el-radio value="v3">NFS</el-radio>
</el-form-item> <el-radio value="v4">NFS4</el-radio>
<el-form-item :label="$t('container.nfsEnable')" prop="nfsStatus"> </el-radio-group>
<el-switch v-model="form.nfsStatus" active-value="enable" inactive-value="disable" /> </el-form-item>
</el-form-item> <el-form-item :label="$t('container.mountpoint')" prop="nfsMount">
<div v-if="form.nfsStatus === 'enable'"> <el-input
<el-form-item :label="$t('container.nfsAddress')" prop="nfsAddress"> clearable
<el-input v-model.trim="form.nfsMount"
clearable :placeholder="$t('container.mountpointNFSHelper')"
v-model.trim="form.nfsAddress" />
:placeholder="$t('commons.rule.hostHelper')" </el-form-item>
/> <el-form-item :label="$t('container.options')" prop="nfsOption">
</el-form-item> <el-input clearable v-model.trim="form.nfsOption" />
<el-form-item :label="$t('container.version')" prop="nfsVersion"> </el-form-item>
<el-radio-group v-model="form.nfsVersion"> </div>
<el-radio value="v3">NFS</el-radio> <el-form-item :label="$t('container.option')" prop="optionStr">
<el-radio value="v4">NFS4</el-radio> <el-input type="textarea" :placeholder="$t('container.tagHelper')" :rows="3" v-model="form.optionStr" />
</el-radio-group> </el-form-item>
</el-form-item> <el-form-item :label="$t('container.tag')" prop="labelStr">
<el-form-item :label="$t('container.mountpoint')" prop="nfsMount"> <el-input type="textarea" :placeholder="$t('container.tagHelper')" :rows="3" v-model="form.labelStr" />
<el-input </el-form-item>
clearable </el-form>
v-model.trim="form.nfsMount"
:placeholder="$t('container.mountpointNFSHelper')"
/>
</el-form-item>
<el-form-item :label="$t('container.options')" prop="nfsOption">
<el-input clearable v-model.trim="form.nfsOption" />
</el-form-item>
</div>
<el-form-item :label="$t('container.option')" prop="optionStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:rows="3"
v-model="form.optionStr"
/>
</el-form-item>
<el-form-item :label="$t('container.tag')" prop="labelStr">
<el-input
type="textarea"
:placeholder="$t('container.tagHelper')"
:rows="3"
v-model="form.labelStr"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="drawerVisible = false"> <el-button :disabled="loading" @click="drawerVisible = false">
@ -83,7 +56,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -92,7 +65,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { createVolume } from '@/api/modules/container'; import { createVolume } from '@/api/modules/container';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
const loading = ref(false); const loading = ref(false);

View File

@ -1,21 +1,12 @@
<template> <template>
<div> <DrawerPro
<el-drawer v-model="backupVisible"
v-model="backupVisible" :header="$t('commons.button.backup')"
:destroy-on-close="true" :resource="cronjob"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" size="large"
size="50%" >
> <template #content>
<template #header>
<DrawerHeader
v-if="cronjob"
:header="$t('commons.button.backup')"
:resource="cronjob"
:back="handleClose"
/>
<DrawerHeader v-else :header="$t('commons.button.backup')" :resource="cronjob" :back="handleClose" />
</template>
<ComplexTable <ComplexTable
v-loading="loading" v-loading="loading"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@ -48,15 +39,14 @@
<fu-table-operations width="130px" :buttons="buttons" :label="$t('commons.table.operate')" fix /> <fu-table-operations width="130px" :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable> </ComplexTable>
</el-drawer> </template>
</div> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { computeSize, dateFormat, downloadFile } from '@/utils/util'; import { computeSize, dateFormat, downloadFile } from '@/utils/util';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/setting'; import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/setting';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';

View File

@ -1,353 +1,311 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
:close-on-press-escape="false" :back="handleClose"
size="50%" size="large"
> >
<template #header>
<DrawerHeader
:header="title"
:hideResource="dialogData.title === 'create'"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('cronjob.taskType')" prop="type">
<el-col :span="22"> <el-select
<el-form-item :label="$t('cronjob.taskType')" prop="type"> v-if="dialogData.title === 'create'"
<el-select class="selectClass"
v-if="dialogData.title === 'create'" @change="changeType"
class="selectClass" v-model="dialogData.rowData!.type"
@change="changeType" >
v-model="dialogData.rowData!.type" <el-option value="shell" :label="$t('cronjob.shell')" />
<el-option value="app" :label="$t('cronjob.app')" />
<el-option value="website" :label="$t('cronjob.website')" />
<el-option value="database" :label="$t('cronjob.database')" />
<el-option value="directory" :label="$t('cronjob.directory')" />
<el-option value="log" :label="$t('cronjob.log')" />
<el-option value="curl" :label="$t('cronjob.curl')" />
<el-option value="cutWebsiteLog" :label="$t('cronjob.cutWebsiteLog')" />
<el-option value="clean" :label="$t('setting.diskClean')" />
<el-option value="snapshot" :label="$t('cronjob.snapshot')" />
<el-option value="ntp" :label="$t('cronjob.ntp')" />
</el-select>
<div v-else class="w-full">
<el-tag>{{ $t('cronjob.' + dialogData.rowData!.type) }}</el-tag>
</div>
<div v-if="dialogData.rowData!.type === 'log'" class="logText">
<span class="input-help">
{{ $t('cronjob.logHelper1') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/system')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
<span class="input-help">
{{ $t('cronjob.logHelper2') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/ssh')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
<span class="input-help">
{{ $t('cronjob.logHelper3') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/website')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</div>
<div v-if="dialogData.rowData!.type === 'ntp'">
<span class="input-help">
{{ $t('cronjob.ntp_helper') }}
<el-link
style="font-size: 12px"
icon="Position"
@click="goRouter('/toolbox/device')"
type="primary"
> >
<el-option value="shell" :label="$t('cronjob.shell')" /> {{ $t('firewall.quickJump') }}
<el-option value="app" :label="$t('cronjob.app')" /> </el-link>
<el-option value="website" :label="$t('cronjob.website')" /> </span>
<el-option value="database" :label="$t('cronjob.database')" /> </div>
<el-option value="directory" :label="$t('cronjob.directory')" /> </el-form-item>
<el-option value="log" :label="$t('cronjob.log')" />
<el-option value="curl" :label="$t('cronjob.curl')" />
<el-option value="cutWebsiteLog" :label="$t('cronjob.cutWebsiteLog')" />
<el-option value="clean" :label="$t('setting.diskClean')" />
<el-option value="snapshot" :label="$t('cronjob.snapshot')" />
<el-option value="ntp" :label="$t('cronjob.ntp')" />
</el-select>
<div v-else style="width: 100%">
<el-tag>{{ $t('cronjob.' + dialogData.rowData!.type) }}</el-tag>
</div>
<div v-if="dialogData.rowData!.type === 'log'" class="logText">
<span class="input-help">
{{ $t('cronjob.logHelper1') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/system')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
<span class="input-help">
{{ $t('cronjob.logHelper2') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/ssh')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
<span class="input-help">
{{ $t('cronjob.logHelper3') }}
<el-link class="link" icon="Position" @click="goRouter('/logs/website')" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</div>
<div v-if="dialogData.rowData!.type === 'ntp'">
<span class="input-help">
{{ $t('cronjob.ntp_helper') }}
<el-link
style="font-size: 12px"
icon="Position"
@click="goRouter('/toolbox/device')"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</div>
</el-form-item>
<el-form-item :label="$t('cronjob.taskName')" prop="name"> <el-form-item :label="$t('cronjob.taskName')" prop="name">
<el-input <el-input :disabled="dialogData.title === 'edit'" clearable v-model.trim="dialogData.rowData!.name" />
:disabled="dialogData.title === 'edit'" </el-form-item>
clearable
v-model.trim="dialogData.rowData!.name" <el-form-item :label="$t('cronjob.cronSpec')" prop="spec">
<div v-for="(specObj, index) of dialogData.rowData.specObjs" :key="index" style="width: 100%">
<el-select class="specTypeClass" v-model="specObj.specType" @change="changeSpecType(index)">
<el-option
v-for="item in specOptions"
:key="item.label"
:value="item.value"
:label="item.label"
/> />
</el-form-item> </el-select>
<el-select v-if="specObj.specType === 'perWeek'" class="specClass" v-model="specObj.week">
<el-form-item :label="$t('cronjob.cronSpec')" prop="spec"> <el-option
<div v-for="(specObj, index) of dialogData.rowData.specObjs" :key="index" style="width: 100%"> v-for="item in weekOptions"
<el-select class="specTypeClass" v-model="specObj.specType" @change="changeSpecType(index)"> :key="item.label"
<el-option :value="item.value"
v-for="item in specOptions" :label="item.label"
:key="item.label" />
:value="item.value" </el-select>
:label="item.label" <el-input v-if="hasDay(specObj)" class="specClass" v-model.number="specObj.day">
/> <template #append>
</el-select> <div class="append">{{ $t('cronjob.day') }}</div>
<el-select v-if="specObj.specType === 'perWeek'" class="specClass" v-model="specObj.week"> </template>
<el-option </el-input>
v-for="item in weekOptions" <el-input v-if="hasHour(specObj)" class="specClass" v-model.number="specObj.hour">
:key="item.label" <template #append>
:value="item.value" <div class="append">{{ $t('commons.units.hour') }}</div>
:label="item.label" </template>
/> </el-input>
</el-select> <el-input
<el-input v-if="hasDay(specObj)" class="specClass" v-model.number="specObj.day"> v-if="specObj.specType !== 'perNSecond'"
<template #append> class="specClass"
<div class="append">{{ $t('cronjob.day') }}</div> v-model.number="specObj.minute"
</template> >
</el-input> <template #append>
<el-input v-if="hasHour(specObj)" class="specClass" v-model.number="specObj.hour"> <div class="append">{{ $t('commons.units.minute') }}</div>
<template #append> </template>
<div class="append">{{ $t('commons.units.hour') }}</div> </el-input>
</template> <el-input
</el-input> v-if="specObj.specType === 'perNSecond'"
<el-input class="specClass"
v-if="specObj.specType !== 'perNSecond'" v-model.number="specObj.second"
class="specClass" >
v-model.number="specObj.minute" <template #append>
> <div class="append">{{ $t('commons.units.second') }}</div>
<template #append> </template>
<div class="append">{{ $t('commons.units.minute') }}</div> </el-input>
</template> <el-button
</el-input> class="ml-2.5"
<el-input link
v-if="specObj.specType === 'perNSecond'" type="primary"
class="specClass" @click="handleSpecDelete(index)"
v-model.number="specObj.second" v-if="dialogData.rowData.specObjs.length > 1"
> >
<template #append> {{ $t('commons.button.delete') }}
<div class="append">{{ $t('commons.units.second') }}</div>
</template>
</el-input>
<el-button
link
type="primary"
style="float: right; margin-top: 5px"
@click="handleSpecDelete(index)"
v-if="dialogData.rowData.specObjs.length > 1"
>
{{ $t('commons.button.delete') }}
</el-button>
<el-divider v-if="dialogData.rowData.specObjs.length > 1" class="divider" />
</div>
</el-form-item>
<el-button class="mb-3" @click="handleSpecAdd()">
{{ $t('commons.button.add') }}
</el-button> </el-button>
<el-divider v-if="dialogData.rowData.specObjs.length > 1" class="divider" />
</div>
</el-form-item>
<el-button class="mb-3" @click="handleSpecAdd()">
{{ $t('commons.button.add') }}
</el-button>
<el-form-item v-if="hasScript()"> <el-form-item v-if="hasScript()">
<el-checkbox v-model="dialogData.rowData!.inContainer"> <el-checkbox v-model="dialogData.rowData!.inContainer">
{{ $t('cronjob.containerCheckBox') }} {{ $t('cronjob.containerCheckBox') }}
</el-checkbox> </el-checkbox>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="hasScript() && dialogData.rowData!.inContainer" v-if="hasScript() && dialogData.rowData!.inContainer"
:label="$t('cronjob.containerName')" :label="$t('cronjob.containerName')"
prop="containerName" prop="containerName"
> >
<el-select class="selectClass" v-model="dialogData.rowData!.containerName"> <el-select class="selectClass" v-model="dialogData.rowData!.containerName">
<el-option v-for="item in containerOptions" :key="item" :value="item" :label="item" /> <el-option v-for="item in containerOptions" :key="item" :value="item" :label="item" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="hasScript() && dialogData.rowData!.inContainer" v-if="hasScript() && dialogData.rowData!.inContainer"
:label="$t('container.command')" :label="$t('container.command')"
prop="command" prop="command"
:rules="Rules.requiredInput" :rules="Rules.requiredInput"
> >
<el-checkbox style="width: 100px" border v-model="dialogData.rowData!.isCustom"> <el-checkbox class="w-full" border v-model="dialogData.rowData!.isCustom">
{{ $t('container.custom') }} {{ $t('container.custom') }}
</el-checkbox> </el-checkbox>
<el-select <el-select style="width: calc(100% - 100px)" filterable clearable v-model="dialogData.rowData!.command">
style="width: calc(100% - 100px)" <el-option value="ash" label="/bin/ash" />
filterable <el-option value="bash" label="/bin/bash" />
clearable <el-option value="sh" label="/bin/sh" />
v-model="dialogData.rowData!.command" </el-select>
> </el-form-item>
<el-option value="ash" label="/bin/ash" />
<el-option value="bash" label="/bin/bash" />
<el-option value="sh" label="/bin/sh" />
</el-select>
</el-form-item>
<el-form-item v-if="hasScript()" :label="$t('cronjob.shellContent')" prop="script"> <el-form-item v-if="hasScript()" :label="$t('cronjob.shellContent')" prop="script">
<el-input clearable type="textarea" :rows="5" v-model="dialogData.rowData!.script" /> <el-input clearable type="textarea" :rows="5" v-model="dialogData.rowData!.script" />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'cutWebsiteLog'" v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'cutWebsiteLog'"
:label="dialogData.rowData!.type === 'website' ? $t('cronjob.website'):$t('website.website')" :label="dialogData.rowData!.type === 'website' ? $t('cronjob.website'):$t('website.website')"
prop="website" prop="website"
>
<el-select class="selectClass" v-model="dialogData.rowData!.website">
<el-option :disabled="websiteOptions.length === 0" :label="$t('commons.table.all')" value="all" />
<el-option
v-for="(item, index) in websiteOptions"
:key="index"
:value="item.id + ''"
:label="item.primaryDomain"
> >
<el-select class="selectClass" v-model="dialogData.rowData!.website"> <span>{{ item.primaryDomain }}</span>
<el-option <el-tag class="tagClass">
:disabled="websiteOptions.length === 0" {{ item.alias }}
:label="$t('commons.table.all')" </el-tag>
value="all" </el-option>
/> </el-select>
<el-option <span class="input-help" v-if="dialogData.rowData!.type === 'cutWebsiteLog'">
v-for="(item, index) in websiteOptions" {{ $t('cronjob.cutWebsiteLogHelper') }}
:key="index" </span>
:value="item.id + ''" </el-form-item>
:label="item.primaryDomain"
> <div v-if="dialogData.rowData!.type === 'app'">
<span>{{ item.primaryDomain }}</span> <el-form-item :label="$t('cronjob.app')" prop="appID">
<el-select class="selectClass" clearable v-model="dialogData.rowData!.appID">
<el-option :disabled="appOptions.length === 0" :label="$t('commons.table.all')" value="all" />
<div v-for="item in appOptions" :key="item.id">
<el-option :value="item.id + ''" :label="item.name">
<span>{{ item.name }}</span>
<el-tag class="tagClass"> <el-tag class="tagClass">
{{ item.alias }} {{ item.key }}
</el-tag> </el-tag>
</el-option> </el-option>
</el-select> </div>
<span class="input-help" v-if="dialogData.rowData!.type === 'cutWebsiteLog'"> </el-select>
{{ $t('cronjob.cutWebsiteLogHelper') }} </el-form-item>
</span> </div>
</el-form-item>
<div v-if="dialogData.rowData!.type === 'app'"> <div v-if="dialogData.rowData!.type === 'database'">
<el-form-item :label="$t('cronjob.app')" prop="appID"> <el-form-item :label="$t('cronjob.database')">
<el-select class="selectClass" clearable v-model="dialogData.rowData!.appID"> <el-radio-group v-model="dialogData.rowData!.dbType" @change="loadDatabases">
<el-option <el-radio value="mysql">MySQL</el-radio>
:disabled="appOptions.length === 0" <el-radio value="mariadb">Mariadb</el-radio>
:label="$t('commons.table.all')" <el-radio value="postgresql">PostgreSQL</el-radio>
value="all" </el-radio-group>
/> </el-form-item>
<div v-for="item in appOptions" :key="item.id"> <el-form-item :label="$t('cronjob.database')" prop="dbName">
<el-option :value="item.id + ''" :label="item.name"> <el-select class="selectClass" clearable v-model="dialogData.rowData!.dbName">
<span>{{ item.name }}</span> <el-option :disabled="dbInfo.dbs.length === 0" :label="$t('commons.table.all')" value="all" />
<el-tag class="tagClass"> <el-option v-for="item in dbInfo.dbs" :key="item.id" :value="item.id + ''" :label="item.name">
{{ item.key }} <span>{{ item.name }}</span>
</el-tag> <el-tag class="tagClass">
</el-option> {{ item.from === 'local' ? $t('database.local') : $t('database.remote') }}
</div> </el-tag>
</el-select> <el-tag class="tagClass">
</el-form-item> {{ item.database }}
</div> </el-tag>
</el-option>
</el-select>
</el-form-item>
</div>
<div v-if="dialogData.rowData!.type === 'database'"> <el-form-item
<el-form-item :label="$t('cronjob.database')"> v-if="dialogData.rowData!.type === 'directory'"
<el-radio-group v-model="dialogData.rowData!.dbType" @change="loadDatabases"> :label="$t('cronjob.sourceDir')"
<el-radio value="mysql">MySQL</el-radio> prop="sourceDir"
<el-radio value="mariadb">Mariadb</el-radio> >
<el-radio value="postgresql">PostgreSQL</el-radio> <el-input v-model="dialogData.rowData!.sourceDir">
</el-radio-group> <template #prepend>
</el-form-item> <FileList @choose="loadDir" :dir="true"></FileList>
<el-form-item :label="$t('cronjob.database')" prop="dbName"> </template>
<el-select class="selectClass" clearable v-model="dialogData.rowData!.dbName"> </el-input>
<el-option </el-form-item>
:disabled="dbInfo.dbs.length === 0"
:label="$t('commons.table.all')"
value="all"
/>
<el-option
v-for="item in dbInfo.dbs"
:key="item.id"
:value="item.id + ''"
:label="item.name"
>
<span>{{ item.name }}</span>
<el-tag class="tagClass">
{{ item.from === 'local' ? $t('database.local') : $t('database.remote') }}
</el-tag>
<el-tag class="tagClass">
{{ item.database }}
</el-tag>
</el-option>
</el-select>
</el-form-item>
</div>
<el-form-item <div v-if="isBackup()">
v-if="dialogData.rowData!.type === 'directory'" <el-form-item :label="$t('setting.backupAccount')" prop="backupAccountList">
:label="$t('cronjob.sourceDir')" <el-select
prop="sourceDir" multiple
class="selectClass"
v-model="dialogData.rowData!.backupAccountList"
@change="changeAccount"
> >
<el-input v-model="dialogData.rowData!.sourceDir"> <div v-for="item in backupOptions" :key="item.label">
<template #prepend> <el-option :value="item.value" :label="item.label" />
<FileList @choose="loadDir" :dir="true"></FileList> </div>
</template> </el-select>
</el-input> <span class="input-help">
</el-form-item> {{ $t('cronjob.targetHelper') }}
<el-link
<div v-if="isBackup()"> style="font-size: 12px"
<el-form-item :label="$t('setting.backupAccount')" prop="backupAccountList"> icon="Position"
<el-select @click="goRouter('/settings/backupaccount')"
multiple type="primary"
class="selectClass"
v-model="dialogData.rowData!.backupAccountList"
@change="changeAccount"
>
<div v-for="item in backupOptions" :key="item.label">
<el-option :value="item.value" :label="item.label" />
</div>
</el-select>
<span class="input-help">
{{ $t('cronjob.targetHelper') }}
<el-link
style="font-size: 12px"
icon="Position"
@click="goRouter('/settings/backupaccount')"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</el-form-item>
<el-form-item
:label="$t('setting.compressPassword')"
prop="secret"
v-if="isBackup() && dialogData.rowData!.type !== 'database'"
> >
<el-input v-model="dialogData.rowData!.secret" /> {{ $t('firewall.quickJump') }}
</el-form-item> </el-link>
<el-form-item :label="$t('cronjob.default_download_path')" prop="defaultDownload"> </span>
<el-select class="selectClass" v-model="dialogData.rowData!.defaultDownload"> </el-form-item>
<div v-for="item in accountOptions" :key="item.label"> <el-form-item
<el-option :value="item.value" :label="item.label" /> :label="$t('setting.compressPassword')"
</div> prop="secret"
</el-select> v-if="isBackup() && dialogData.rowData!.type !== 'database'"
</el-form-item> >
</div> <el-input v-model="dialogData.rowData!.secret" />
</el-form-item>
<el-form-item :label="$t('cronjob.default_download_path')" prop="defaultDownload">
<el-select class="selectClass" v-model="dialogData.rowData!.defaultDownload">
<div v-for="item in accountOptions" :key="item.label">
<el-option :value="item.value" :label="item.label" />
</div>
</el-select>
</el-form-item>
</div>
<el-form-item :label="$t('cronjob.retainCopies')" prop="retainCopies"> <el-form-item :label="$t('cronjob.retainCopies')" prop="retainCopies">
<el-input-number <el-input-number
style="width: 200px" style="width: 200px"
:min="1" :min="1"
step-strictly step-strictly
:step="1" :step="1"
v-model.number="dialogData.rowData!.retainCopies" v-model.number="dialogData.rowData!.retainCopies"
></el-input-number> ></el-input-number>
<span v-if="isBackup()" class="input-help">{{ $t('cronjob.retainCopiesHelper1') }}</span> <span v-if="isBackup()" class="input-help">{{ $t('cronjob.retainCopiesHelper1') }}</span>
<span v-else class="input-help">{{ $t('cronjob.retainCopiesHelper') }}</span> <span v-else class="input-help">{{ $t('cronjob.retainCopiesHelper') }}</span>
</el-form-item> </el-form-item>
<el-form-item v-if="dialogData.rowData!.type === 'curl'" :label="$t('cronjob.url')" prop="url"> <el-form-item v-if="dialogData.rowData!.type === 'curl'" :label="$t('cronjob.url')" prop="url">
<el-input clearable v-model.trim="dialogData.rowData!.url" /> <el-input clearable v-model.trim="dialogData.rowData!.url" />
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-if="hasExclusionRules()" :label="$t('cronjob.exclusionRules')" prop="exclusionRules">
v-if="hasExclusionRules()" <el-input
:label="$t('cronjob.exclusionRules')" type="textarea"
prop="exclusionRules" :placeholder="$t('cronjob.rulesHelper')"
> :rows="3"
<el-input clearable
type="textarea" v-model="dialogData.rowData!.exclusionRules"
:placeholder="$t('cronjob.rulesHelper')" />
:rows="3" <span class="input-help">{{ $t('cronjob.exclusionRulesHelper') }}</span>
clearable </el-form-item>
v-model="dialogData.rowData!.exclusionRules"
/>
<span class="input-help">{{ $t('cronjob.exclusionRulesHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -357,7 +315,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -371,7 +329,6 @@ import { Cronjob } from '@/api/interface/cronjob';
import { addCronjob, editCronjob } from '@/api/modules/cronjob'; import { addCronjob, editCronjob } from '@/api/modules/cronjob';
import { listDbItems } from '@/api/modules/database'; import { listDbItems } from '@/api/modules/database';
import { GetWebsiteOptions } from '@/api/modules/website'; import { GetWebsiteOptions } from '@/api/modules/website';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { listContainer } from '@/api/modules/container'; import { listContainer } from '@/api/modules/container';

View File

@ -58,30 +58,24 @@
</div> </div>
<LayoutContent :title="$t('cronjob.record')" :reload="true"> <LayoutContent :title="$t('cronjob.record')" :reload="true">
<template #search> <template #rightToolBar>
<el-row :gutter="20"> <el-date-picker
<el-col :span="8"> class="mr-2.5"
<el-date-picker @change="search()"
style="width: calc(100% - 20px)" v-model="timeRangeLoad"
@change="search()" type="datetimerange"
v-model="timeRangeLoad" :range-separator="$t('commons.search.timeRange')"
type="datetimerange" :start-placeholder="$t('commons.search.timeStart')"
:range-separator="$t('commons.search.timeRange')" :end-placeholder="$t('commons.search.timeEnd')"
:start-placeholder="$t('commons.search.timeStart')" :shortcuts="shortcuts"
:end-placeholder="$t('commons.search.timeEnd')" ></el-date-picker>
:shortcuts="shortcuts" <el-select @change="search()" v-model="searchInfo.status" class="p-w-200">
></el-date-picker> <template #prefix>{{ $t('commons.table.status') }}</template>
</el-col> <el-option :label="$t('commons.table.all')" value="" />
<el-col :span="16"> <el-option :label="$t('commons.status.success')" value="Success" />
<el-select @change="search()" v-model="searchInfo.status" class="p-w-200"> <el-option :label="$t('commons.status.waiting')" value="Waiting" />
<template #prefix>{{ $t('commons.table.status') }}</template> <el-option :label="$t('commons.status.failed')" value="Failed" />
<el-option :label="$t('commons.table.all')" value="" /> </el-select>
<el-option :label="$t('commons.status.success')" value="Success" />
<el-option :label="$t('commons.status.waiting')" value="Waiting" />
<el-option :label="$t('commons.status.failed')" value="Failed" />
</el-select>
</el-col>
</el-row>
</template> </template>
<template #main> <template #main>
<div class="mainClass"> <div class="mainClass">

View File

@ -1,41 +1,30 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="bindVisible" v-model="bindVisible"
:destroy-on-close="true" :header="$t('database.userBind')"
:close-on-click-modal="false" :resource="form.mysqlName"
:close-on-press-escape="false" :back="handleClose"
width="30%" size="small"
> >
<template #header>
<DrawerHeader :header="$t('database.userBind')" :resource="form.mysqlName" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top"> <el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top">
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.login.username')" prop="username">
<el-col :span="22"> <el-input v-model="form.username"></el-input>
<el-form-item :label="$t('commons.login.username')" prop="username"> </el-form-item>
<el-input v-model="form.username"></el-input> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input type="password" clearable show-password v-model="form.password"></el-input>
<el-form-item :label="$t('commons.login.password')" prop="password"> </el-form-item>
<el-input type="password" clearable show-password v-model="form.password"></el-input> <el-form-item :label="$t('database.permission')" prop="permission">
</el-form-item> <el-select v-model="form.permission">
<el-form-item :label="$t('database.permission')" prop="permission"> <el-option value="%" :label="$t('database.permissionAll')" />
<el-select v-model="form.permission"> <el-option v-if="form.from !== 'local'" value="localhost" :label="$t('terminal.localhost')" />
<el-option value="%" :label="$t('database.permissionAll')" /> <el-option value="ip" :label="$t('database.permissionForIP')" />
<el-option </el-select>
v-if="form.from !== 'local'" </el-form-item>
value="localhost" <el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
:label="$t('terminal.localhost')" <el-input clearable :rows="3" type="textarea" v-model="form.permissionIPs" />
/> <span class="input-help">{{ $t('database.remoteHelper') }}</span>
<el-option value="ip" :label="$t('database.permissionForIP')" /> </el-form-item>
</el-select>
</el-form-item>
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
<el-input clearable :rows="3" type="textarea" v-model="form.permissionIPs" />
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -47,8 +36,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
</div> </div>
</template> </template>
@ -57,7 +45,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { bindUser } from '@/api/modules/database'; import { bindUser } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { checkIp } from '@/utils/util'; import { checkIp } from '@/utils/util';

View File

@ -1,113 +1,89 @@
<template> <template>
<el-drawer <DrawerPro v-model="dialogVisible" :header="$t('database.databaseConnInfo')" :back="handleClose" size="small">
v-model="dialogVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('database.databaseConnInfo')" :back="handleClose" />
</template>
<el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top"> <el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top">
<el-row type="flex" justify="center"> <el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'">
<el-col :span="22"> <el-card class="mini-border-card">
<el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'"> <el-descriptions :column="1">
<el-card class="mini-border-card"> <el-descriptions-item :label="$t('database.connAddress')">
<el-descriptions :column="1"> <el-tooltip
<el-descriptions-item :label="$t('database.connAddress')"> v-if="loadMysqlInfo(true).length > 48"
<el-tooltip :content="loadMysqlInfo(true)"
v-if="loadMysqlInfo(true).length > 48" placement="top"
:content="loadMysqlInfo(true)" >
placement="top" {{ loadMysqlInfo(true).substring(0, 48) }}...
> </el-tooltip>
{{ loadMysqlInfo(true).substring(0, 48) }}... <span else>
</el-tooltip> {{ loadMysqlInfo(true) }}
<span else> </span>
{{ loadMysqlInfo(true) }} <CopyButton :content="loadMysqlInfo(true)" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadMysqlInfo(true)" type="icon" /> <el-descriptions-item :label="$t('database.connPort')">
</el-descriptions-item> 3306
<el-descriptions-item :label="$t('database.connPort')"> <CopyButton content="3306" type="icon" />
3306 </el-descriptions-item>
<CopyButton content="3306" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
</el-descriptions> <span class="input-help">
</el-card> {{ $t('database.containerConnHelper') }}
<span class="input-help"> </span>
{{ $t('database.containerConnHelper') }} </el-form-item>
</span> <el-form-item :label="$t('database.remoteConn')">
</el-form-item> <el-card class="mini-border-card">
<el-form-item :label="$t('database.remoteConn')"> <el-descriptions :column="1">
<el-card class="mini-border-card"> <el-descriptions-item :label="$t('database.connAddress')">
<el-descriptions :column="1"> <el-tooltip
<el-descriptions-item :label="$t('database.connAddress')"> v-if="loadMysqlInfo(false).length > 48"
<el-tooltip :content="loadMysqlInfo(false)"
v-if="loadMysqlInfo(false).length > 48" placement="top"
:content="loadMysqlInfo(false)" >
placement="top" {{ loadMysqlInfo(false).substring(0, 48) }}...
> </el-tooltip>
{{ loadMysqlInfo(false).substring(0, 48) }}... <span else>
</el-tooltip> {{ loadMysqlInfo(false) }}
<span else> </span>
{{ loadMysqlInfo(false) }} <CopyButton :content="loadMysqlInfo(false)" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadMysqlInfo(false)" type="icon" /> <el-descriptions-item :label="$t('database.connPort')">
</el-descriptions-item> {{ form.port }}
<el-descriptions-item :label="$t('database.connPort')"> <CopyButton :content="form.port + ''" type="icon" />
{{ form.port }} </el-descriptions-item>
<CopyButton :content="form.port + ''" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
</el-descriptions> <span v-if="form.from === 'local'" class="input-help">
</el-card> {{ $t('database.remoteConnHelper2') }}
<span v-if="form.from === 'local'" class="input-help"> </span>
{{ $t('database.remoteConnHelper2') }} </el-form-item>
</span> <el-divider border-style="dashed" />
</el-form-item>
<el-divider border-style="dashed" />
<div v-if="form.from === 'local'"> <div v-if="form.from === 'local'">
<el-form-item :label="$t('database.remoteAccess')" prop="privilege"> <el-form-item :label="$t('database.remoteAccess')" prop="privilege">
<el-switch <el-switch v-model="form.privilege" :disabled="form.status !== 'Running'" @change="onSaveAccess" />
v-model="form.privilege" <span class="input-help">{{ $t('database.remoteConnHelper') }}</span>
:disabled="form.status !== 'Running'" </el-form-item>
@change="onSaveAccess" <el-form-item :label="$t('database.rootPassword')" :rules="Rules.paramComplexity" prop="password">
/> <el-input type="password" show-password clearable v-model="form.password">
<span class="input-help">{{ $t('database.remoteConnHelper') }}</span> <template #append>
</el-form-item> <CopyButton :content="form.password" />
<el-form-item <el-button @click="random" class="p-ml-5">
:label="$t('database.rootPassword')" {{ $t('commons.button.random') }}
:rules="Rules.paramComplexity" </el-button>
prop="password" </template>
> </el-input>
<el-input type="password" show-password clearable v-model="form.password"> </el-form-item>
<template #append> </div>
<CopyButton :content="form.password" /> <div v-if="form.from !== 'local'">
<el-button @click="random" class="p-ml-5"> <el-form-item :label="$t('commons.login.username')">
{{ $t('commons.button.random') }} <el-tag>{{ form.username }}</el-tag>
</el-button> <CopyButton :content="form.username" type="icon" />
</template> </el-form-item>
</el-input> <el-form-item :label="$t('commons.login.password')">
</el-form-item> <el-tag>{{ form.password }}</el-tag>
</div> <CopyButton :content="form.password" type="icon" />
</el-form-item>
<div v-if="form.from !== 'local'"> </div>
<el-form-item :label="$t('commons.login.username')">
<el-tag>{{ form.username }}</el-tag>
<CopyButton :content="form.username" type="icon" />
</el-form-item>
<el-form-item :label="$t('commons.login.password')">
<el-tag>{{ form.password }}</el-tag>
<CopyButton :content="form.password" type="icon" />
</el-form-item>
</div>
</el-col>
</el-row>
</el-form> </el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" @cancel="loadPassword"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" @cancel="loadPassword"></ConfirmDialog>
<ConfirmDialog ref="confirmAccessDialogRef" @confirm="onSubmitAccess" @cancel="loadAccess"></ConfirmDialog> <ConfirmDialog ref="confirmAccessDialogRef" @confirm="onSubmitAccess" @cancel="loadAccess"></ConfirmDialog>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="dialogVisible = false"> <el-button :disabled="loading" @click="dialogVisible = false">
@ -118,7 +94,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -129,7 +105,6 @@ import { ElForm } from 'element-plus';
import { getDatabase, loadRemoteAccess, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database'; import { getDatabase, loadRemoteAccess, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database';
import ConfirmDialog from '@/components/confirm-dialog/index.vue'; import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { GetAppConnInfo } from '@/api/modules/app'; import { GetAppConnInfo } from '@/api/modules/app';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { getRandomStr } from '@/utils/util'; import { getRandomStr } from '@/utils/util';
import { getSettingInfo } from '@/api/modules/setting'; import { getSettingInfo } from '@/api/modules/setting';

View File

@ -1,69 +1,46 @@
<template> <template>
<el-drawer <DrawerPro v-model="createVisible" :header="$t('database.create')" :back="handleClose" size="normal">
v-model="createVisible" <el-form ref="formRef" label-position="top" :model="form" :rules="rules" v-loading="loading">
:destroy-on-close="true" <el-form-item :label="$t('commons.table.name')" prop="name">
:close-on-click-modal="false" <el-input clearable v-model.trim="form.name" @input="form.username = form.name">
:close-on-press-escape="false" <template #append>
size="30%" <el-select v-model="form.format" class="p-w-100">
> <el-option label="utf8mb4" value="utf8mb4" />
<template #header> <el-option label="utf-8" value="utf8" />
<DrawerHeader :header="$t('database.create')" :back="handleClose" /> <el-option label="gbk" value="gbk" />
</template> <el-option label="big5" value="big5" />
<div v-loading="loading"> </el-select>
<el-form ref="formRef" label-position="top" :model="form" :rules="rules"> </template>
<el-row type="flex" justify="center"> </el-input>
<el-col :span="22"> </el-form-item>
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-form-item :label="$t('commons.login.username')" prop="username">
<el-input clearable v-model.trim="form.name" @input="form.username = form.name"> <el-input clearable v-model.trim="form.username" />
<template #append> </el-form-item>
<el-select v-model="form.format" style="width: 120px"> <el-form-item :label="$t('commons.login.password')" prop="password">
<el-option label="utf8mb4" value="utf8mb4" /> <el-input type="password" clearable show-password v-model.trim="form.password">
<el-option label="utf-8" value="utf8" /> <template #append>
<el-option label="gbk" value="gbk" /> <el-button @click="random">{{ $t('commons.button.random') }}</el-button>
<el-option label="big5" value="big5" /> </template>
</el-select> </el-input>
</template> </el-form-item>
</el-input> <el-form-item :label="$t('database.permission')" prop="permission">
</el-form-item> <el-select v-model="form.permission">
<el-form-item :label="$t('commons.login.username')" prop="username"> <el-option value="%" :label="$t('database.permissionAll')" />
<el-input clearable v-model.trim="form.username" /> <el-option v-if="form.from !== 'local'" value="localhost" :label="$t('terminal.localhost')" />
</el-form-item> <el-option value="ip" :label="$t('database.permissionForIP')" />
<el-form-item :label="$t('commons.login.password')" prop="password"> </el-select>
<el-input type="password" clearable show-password v-model.trim="form.password"> </el-form-item>
<template #append> <el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
<el-button @click="random">{{ $t('commons.button.random') }}</el-button> <el-input clearable :rows="3" type="textarea" v-model="form.permissionIPs" />
</template> <span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-input> </el-form-item>
</el-form-item> <el-form-item :label="$t('commons.table.type')" prop="database">
<el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag>
<el-form-item :label="$t('database.permission')" prop="permission"> </el-form-item>
<el-select v-model="form.permission"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-option value="%" :label="$t('database.permissionAll')" /> <el-input type="textarea" clearable v-model="form.description" />
<el-option </el-form-item>
v-if="form.from !== 'local'" </el-form>
value="localhost"
:label="$t('terminal.localhost')"
/>
<el-option value="ip" :label="$t('database.permissionForIP')" />
</el-select>
</el-form-item>
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
<el-input clearable :rows="3" type="textarea" v-model="form.permissionIPs" />
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="database">
<el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input type="textarea" clearable v-model="form.description" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="createVisible = false"> <el-button :disabled="loading" @click="createVisible = false">
@ -74,7 +51,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -83,7 +60,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { addMysqlDB } from '@/api/modules/database'; import { addMysqlDB } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { checkIp, getRandomStr } from '@/utils/util'; import { checkIp, getRandomStr } from '@/utils/util';

View File

@ -257,10 +257,8 @@
<UploadDialog ref="uploadRef" /> <UploadDialog ref="uploadRef" />
<OperateDialog @search="search" ref="dialogRef" /> <OperateDialog @search="search" ref="dialogRef" />
<Backups ref="dialogBackupRef" /> <Backups ref="dialogBackupRef" />
<AppResources ref="checkRef"></AppResources> <AppResources ref="checkRef"></AppResources>
<DeleteDialog ref="deleteRef" @search="search" /> <DeleteDialog ref="deleteRef" @search="search" />
<PortJumpDialog ref="dialogPortJumpRef" /> <PortJumpDialog ref="dialogPortJumpRef" />
</div> </div>
</template> </template>

View File

@ -1,50 +1,38 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="changeVisible" v-model="changeVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :resource="changeForm.mysqlName"
:close-on-press-escape="false" :back="handleClose"
width="30%" size="small"
> >
<template #header>
<DrawerHeader :header="title" :resource="changeForm.mysqlName" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="changeFormRef" :model="changeForm" :rules="rules" label-position="top"> <el-form v-loading="loading" ref="changeFormRef" :model="changeForm" :rules="rules" label-position="top">
<el-row type="flex" justify="center"> <div v-if="changeForm.operation === 'password'">
<el-col :span="22"> <el-form-item :label="$t('commons.login.username')" prop="userName">
<div v-if="changeForm.operation === 'password'"> <el-input disabled v-model="changeForm.userName"></el-input>
<el-form-item :label="$t('commons.login.username')" prop="userName"> </el-form-item>
<el-input disabled v-model="changeForm.userName"></el-input> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input type="password" clearable show-password v-model="changeForm.password"></el-input>
<el-form-item :label="$t('commons.login.password')" prop="password"> </el-form-item>
<el-input </div>
type="password" <div v-if="changeForm.operation === 'privilege'">
clearable <el-form-item :label="$t('database.permission')" prop="privilege">
show-password <el-select style="width: 100%" v-model="changeForm.privilege">
v-model="changeForm.password" <el-option value="%" :label="$t('database.permissionAll')" />
></el-input> <el-option
</el-form-item> v-if="changeForm.from !== 'local'"
</div> value="localhost"
<div v-if="changeForm.operation === 'privilege'"> :label="$t('terminal.localhost')"
<el-form-item :label="$t('database.permission')" prop="privilege"> />
<el-select style="width: 100%" v-model="changeForm.privilege"> <el-option value="ip" :label="$t('database.permissionForIP')" />
<el-option value="%" :label="$t('database.permissionAll')" /> </el-select>
<el-option </el-form-item>
v-if="changeForm.from !== 'local'" <el-form-item v-if="changeForm.privilege === 'ip'" prop="privilegeIPs">
value="localhost" <el-input clearable :rows="3" type="textarea" v-model="changeForm.privilegeIPs" />
:label="$t('terminal.localhost')" <span class="input-help">{{ $t('database.remoteHelper') }}</span>
/> </el-form-item>
<el-option value="ip" :label="$t('database.permissionForIP')" /> </div>
</el-select>
</el-form-item>
<el-form-item v-if="changeForm.privilege === 'ip'" prop="privilegeIPs">
<el-input clearable :rows="3" type="textarea" v-model="changeForm.privilegeIPs" />
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-form-item>
</div>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -56,7 +44,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
</div> </div>
@ -66,7 +54,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { deleteCheckMysqlDB, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database'; import { deleteCheckMysqlDB, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { checkIp } from '@/utils/util'; import { checkIp } from '@/utils/util';

View File

@ -1,20 +1,13 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent> <LayoutContent backName="MySQL" :title="$t('database.remoteDB')">
<template #title> <template #leftToolBar>
<back-button name="MySQL" :header="$t('database.remoteDB')" /> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</template> </template>
<template #toolbar> <template #rightToolBar>
<el-row> <TableSearch @search="search()" v-model:searchName="searchName" />
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20">
<el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<TableSearch @search="search()" v-model:searchName="searchName" />
</el-col>
</el-row>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">

View File

@ -1,120 +1,95 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
size="50%" size="large"
> >
<template #header>
<DrawerHeader
:hideResource="dialogData.title === 'create'"
:header="title"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input v-if="dialogData.title === 'create'" clearable v-model.trim="dialogData.rowData!.name" />
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-tag v-else>{{ dialogData.rowData!.name }}</el-tag>
<el-input </el-form-item>
v-if="dialogData.title === 'create'" <el-form-item :label="$t('commons.table.type')" prop="type">
clearable <el-radio-group v-model="dialogData.rowData!.type" @change="changeType">
v-model.trim="dialogData.rowData!.name" <el-radio-button value="mysql">MySQL</el-radio-button>
/> <el-radio-button value="mariadb">MariaDB</el-radio-button>
<el-tag v-else>{{ dialogData.rowData!.name }}</el-tag> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="type"> <el-form-item :label="$t('database.version')" prop="version">
<el-radio-group v-model="dialogData.rowData!.type" @change="changeType"> <el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false">
<el-radio-button value="mysql">MySQL</el-radio-button> <div v-if="dialogData.rowData!.type === 'mysql'">
<el-radio-button value="mariadb">MariaDB</el-radio-button> <el-radio label="8.x" value="8.x" />
</el-radio-group> <el-radio label="5.7" value="5.7" />
</el-form-item> <el-radio label="5.6" value="5.6" />
<el-form-item :label="$t('database.version')" prop="version">
<el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false">
<div v-if="dialogData.rowData!.type === 'mysql'">
<el-radio label="8.x" value="8.x" />
<el-radio label="5.7" value="5.7" />
<el-radio label="5.6" value="5.6" />
</div>
<div v-else>
<el-radio label="10.x" value="10.x" />
<el-radio label="11.x" value="11.x" />
</div>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('database.address')" prop="address">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
</el-form-item>
<el-form-item :label="$t('commons.table.port')" prop="port">
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
</el-form-item>
<el-form-item :label="$t('commons.login.username')" prop="username">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.username" />
<span class="input-help">{{ $t('database.userHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="password">
<el-input
@change="isOK = false"
type="password"
clearable
show-password
v-model.trim="dialogData.rowData!.password"
/>
</el-form-item>
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.ssl"
:label="$t('database.ssl')"
/>
</el-form-item>
<div v-if="dialogData.rowData!.ssl">
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.hasCA"
:label="$t('database.hasCA')"
/>
</el-form-item>
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.skipVerify"
:label="$t('database.skipVerify')"
/>
</el-form-item>
<el-form-item :label="$t('database.clientKey')" prop="clientKey">
<el-input
type="textarea"
@change="isOK = false"
clearable
v-model="dialogData.rowData!.clientKey"
/>
</el-form-item>
<el-form-item :label="$t('database.clientCert')" prop="clientCert">
<el-input
type="textarea"
@change="isOK = false"
clearable
v-model="dialogData.rowData!.clientCert"
/>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.hasCA" :label="$t('database.caCert')" prop="rootCert">
<el-input
type="textarea"
@change="isOK = false"
clearable
v-model="dialogData.rowData!.rootCert"
/>
</el-form-item>
</div> </div>
<el-form-item :label="$t('commons.table.description')" prop="description"> <div v-else>
<el-input clearable v-model.trim="dialogData.rowData!.description" /> <el-radio label="10.x" value="10.x" />
</el-form-item> <el-radio label="11.x" value="11.x" />
</el-col> </div>
</el-row> </el-radio-group>
</el-form-item>
<el-form-item :label="$t('database.address')" prop="address">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
</el-form-item>
<el-form-item :label="$t('commons.table.port')" prop="port">
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
</el-form-item>
<el-form-item :label="$t('commons.login.username')" prop="username">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.username" />
<span class="input-help">{{ $t('database.userHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="password">
<el-input
@change="isOK = false"
type="password"
clearable
show-password
v-model.trim="dialogData.rowData!.password"
/>
</el-form-item>
<el-form-item>
<el-checkbox @change="isOK = false" v-model="dialogData.rowData!.ssl" :label="$t('database.ssl')" />
</el-form-item>
<div v-if="dialogData.rowData!.ssl">
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.hasCA"
:label="$t('database.hasCA')"
/>
</el-form-item>
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.skipVerify"
:label="$t('database.skipVerify')"
/>
</el-form-item>
<el-form-item :label="$t('database.clientKey')" prop="clientKey">
<el-input
type="textarea"
@change="isOK = false"
clearable
v-model="dialogData.rowData!.clientKey"
/>
</el-form-item>
<el-form-item :label="$t('database.clientCert')" prop="clientCert">
<el-input
type="textarea"
@change="isOK = false"
clearable
v-model="dialogData.rowData!.clientCert"
/>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.hasCA" :label="$t('database.caCert')" prop="rootCert">
<el-input type="textarea" @change="isOK = false" clearable v-model="dialogData.rowData!.rootCert" />
</el-form-item>
</div>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -127,7 +102,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -135,7 +110,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Database } from '@/api/interface/database'; import { Database } from '@/api/interface/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database'; import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';

View File

@ -1,49 +1,45 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent> <LayoutContent backName="MySQL" :title="props.database + ' ' + $t('commons.button.set')">
<template #title> <template #leftToolBar>
<back-button name="MySQL" :header="props.database + ' ' + $t('commons.button.set')"> <el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf">
<template #buttons> {{ $t('database.confChange') }}
<el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf"> </el-button>
{{ $t('database.confChange') }} <el-button
</el-button> type="primary"
<el-button :disabled="mysqlStatus !== 'Running'"
type="primary" :plain="activeName !== 'status'"
:disabled="mysqlStatus !== 'Running'" @click="activeName = 'status'"
:plain="activeName !== 'status'" >
@click="activeName = 'status'" {{ $t('database.currentStatus') }}
> </el-button>
{{ $t('database.currentStatus') }} <el-button
</el-button> type="primary"
<el-button :disabled="mysqlStatus !== 'Running'"
type="primary" :plain="activeName !== 'tuning'"
:disabled="mysqlStatus !== 'Running'" @click="activeName = 'tuning'"
:plain="activeName !== 'tuning'" >
@click="activeName = 'tuning'" {{ $t('database.performanceTuning') }}
> </el-button>
{{ $t('database.performanceTuning') }} <el-button type="primary" :plain="activeName !== 'port'" @click="activeName = 'port'">
</el-button> {{ $t('commons.table.port') }}
<el-button type="primary" :plain="activeName !== 'port'" @click="activeName = 'port'"> </el-button>
{{ $t('commons.table.port') }} <el-button
</el-button> type="primary"
<el-button :disabled="mysqlStatus !== 'Running'"
type="primary" :plain="activeName !== 'log'"
:disabled="mysqlStatus !== 'Running'" @click="activeName = 'log'"
:plain="activeName !== 'log'" >
@click="activeName = 'log'" {{ $t('database.log') }}
> </el-button>
{{ $t('database.log') }} <el-button
</el-button> type="primary"
<el-button :disabled="mysqlStatus !== 'Running'"
type="primary" @click="jumpToSlowlog"
:disabled="mysqlStatus !== 'Running'" :plain="activeName !== 'slowLog'"
@click="jumpToSlowlog" >
:plain="activeName !== 'slowLog'" {{ $t('database.slowLog') }}
> </el-button>
{{ $t('database.slowLog') }}
</el-button>
</template>
</back-button>
</template> </template>
<template #app> <template #app>
@ -65,17 +61,17 @@
:extensions="extensions" :extensions="extensions"
v-model="mysqlConf" v-model="mysqlConf"
/> />
<el-button style="margin-top: 10px" @click="getDefaultConfig()"> <el-button class="mt-2.5" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }} {{ $t('app.defaultConfig') }}
</el-button> </el-button>
<el-button type="primary" style="margin-top: 10px" @click="onSaveConf"> <el-button type="primary" class="mt-2.5" @click="onSaveConf">
{{ $t('commons.button.save') }} {{ $t('commons.button.save') }}
</el-button> </el-button>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-alert <el-alert
v-if="useOld" v-if="useOld"
style="margin-top: 10px" class="mt-2.5"
:title="$t('app.defaultConfigHelper')" :title="$t('app.defaultConfigHelper')"
type="info" type="info"
:closable="false" :closable="false"

View File

@ -1,30 +1,23 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="bindVisible" v-model="bindVisible"
:destroy-on-close="true" :header="$t('database.userBind')"
:close-on-click-modal="false" :resource="form.name"
:close-on-press-escape="false" :back="handleClose"
width="30%" size="small"
> >
<template #header>
<DrawerHeader :header="$t('database.userBind')" :resource="form.name" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top"> <el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top">
<el-row type="flex" justify="center"> <el-alert type="warning" :title="$t('database.pgBindHelper')" :closable="false" />
<el-col :span="22"> <el-form-item class="mt-5" :label="$t('database.userBind')" prop="username">
<el-alert type="warning" :title="$t('database.pgBindHelper')" :closable="false" /> <el-input v-model="form.username" />
<el-form-item class="mt-5" :label="$t('database.userBind')" prop="username"> </el-form-item>
<el-input v-model="form.username" /> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input type="password" clearable show-password v-model="form.password" />
<el-form-item :label="$t('commons.login.password')" prop="password"> </el-form-item>
<el-input type="password" clearable show-password v-model="form.password" /> <el-form-item :label="$t('database.permission')" prop="superUser">
</el-form-item> <el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
<el-form-item :label="$t('database.permission')" prop="superUser"> </el-form-item>
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -36,7 +29,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
</div> </div>
@ -46,7 +39,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { bindPostgresqlUser } from '@/api/modules/database'; import { bindPostgresqlUser } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,108 +1,87 @@
<template> <template>
<el-drawer <DrawerPro v-model="dialogVisible" :header="$t('database.databaseConnInfo')" :back="handleClose" size="small">
v-model="dialogVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('database.databaseConnInfo')" :back="handleClose" />
</template>
<el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top"> <el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top">
<el-row type="flex" justify="center"> <el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'">
<el-col :span="22"> <el-card class="mini-border-card">
<el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'"> <el-descriptions :column="1">
<el-card class="mini-border-card"> <el-descriptions-item :label="$t('database.connAddress')">
<el-descriptions :column="1"> <el-tooltip v-if="loadPgInfo(true).length > 48" :content="loadPgInfo(true)" placement="top">
<el-descriptions-item :label="$t('database.connAddress')"> {{ loadPgInfo(true).substring(0, 48) }}...
<el-tooltip </el-tooltip>
v-if="loadPgInfo(true).length > 48" <span else>
:content="loadPgInfo(true)" {{ loadPgInfo(true) }}
placement="top" </span>
> <CopyButton :content="loadPgInfo(true)" type="icon" />
{{ loadPgInfo(true).substring(0, 48) }}... </el-descriptions-item>
</el-tooltip> <el-descriptions-item :label="$t('database.connPort')">
<span else> {{ form.port }}
{{ loadPgInfo(true) }} <CopyButton :content="form.port + ''" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadPgInfo(true)" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
<el-descriptions-item :label="$t('database.connPort')"> <span class="input-help">
{{ form.port }} {{ $t('database.containerConnHelper') }}
<CopyButton :content="form.port + ''" type="icon" /> </span>
</el-descriptions-item> </el-form-item>
</el-descriptions> <el-form-item :label="$t('database.remoteConn')">
</el-card> <el-card class="mini-border-card">
<span class="input-help"> <el-descriptions :column="1">
{{ $t('database.containerConnHelper') }} <el-descriptions-item :label="$t('database.connAddress')">
</span> <el-tooltip
</el-form-item> v-if="loadPgInfo(false).length > 48"
<el-form-item :label="$t('database.remoteConn')"> :content="loadPgInfo(false)"
<el-card class="mini-border-card"> placement="top"
<el-descriptions :column="1"> >
<el-descriptions-item :label="$t('database.connAddress')"> {{ loadPgInfo(false).substring(0, 48) }}...
<el-tooltip </el-tooltip>
v-if="loadPgInfo(false).length > 48" <span else>
:content="loadPgInfo(false)" {{ loadPgInfo(false) }}
placement="top" </span>
> <CopyButton :content="loadPgInfo(false)" type="icon" />
{{ loadPgInfo(false).substring(0, 48) }}... </el-descriptions-item>
</el-tooltip> <el-descriptions-item :label="$t('database.connPort')">
<span else> {{ form.port }}
{{ loadPgInfo(false) }} <CopyButton :content="form.port + ''" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadPgInfo(false)" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
<el-descriptions-item :label="$t('database.connPort')"> <span v-if="form.from === 'local'" class="input-help">
{{ form.port }} {{ $t('database.remoteConnHelper2') }}
<CopyButton :content="form.port + ''" type="icon" /> </span>
</el-descriptions-item> </el-form-item>
</el-descriptions>
</el-card>
<span v-if="form.from === 'local'" class="input-help">
{{ $t('database.remoteConnHelper2') }}
</span>
</el-form-item>
<el-divider border-style="dashed" /> <el-divider border-style="dashed" />
<div v-if="form.from === 'local'"> <div v-if="form.from === 'local'">
<el-form-item :label="$t('commons.login.username')" prop="username"> <el-form-item :label="$t('commons.login.username')" prop="username">
<el-input type="text" readonly disabled v-model="form.username"> <el-input type="text" readonly disabled v-model="form.username">
<template #append> <template #append>
<el-button-group> <el-button-group>
<CopyButton :content="form.username" /> <CopyButton :content="form.username" />
</el-button-group> </el-button-group>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item :label="$t('commons.login.password')" :rules="Rules.paramComplexity" prop="password">
:label="$t('commons.login.password')" <el-input type="password" show-password clearable v-model="form.password">
:rules="Rules.paramComplexity" <template #append>
prop="password" <CopyButton :content="form.password" />
> <el-button @click="random" class="p-ml-5">
<el-input type="password" show-password clearable v-model="form.password"> {{ $t('commons.button.random') }}
<template #append> </el-button>
<CopyButton :content="form.password" /> </template>
<el-button @click="random" class="p-ml-5"> </el-input>
{{ $t('commons.button.random') }} </el-form-item>
</el-button> </div>
</template> <div v-if="form.from !== 'local'">
</el-input> <el-form-item :label="$t('commons.login.username')">
</el-form-item> <el-tag>{{ form.username }}</el-tag>
</div> <CopyButton :content="form.username" type="icon" />
<div v-if="form.from !== 'local'"> </el-form-item>
<el-form-item :label="$t('commons.login.username')"> <el-form-item :label="$t('commons.login.password')">
<el-tag>{{ form.username }}</el-tag> <el-tag>{{ form.password }}</el-tag>
<CopyButton :content="form.username" type="icon" /> <CopyButton :content="form.password" type="icon" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.login.password')"> </div>
<el-tag>{{ form.password }}</el-tag>
<CopyButton :content="form.password" type="icon" />
</el-form-item>
</div>
</el-col>
</el-row>
</el-form> </el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" @cancel="loadPassword"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" @cancel="loadPassword"></ConfirmDialog>
@ -117,7 +96,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -128,7 +107,6 @@ import { ElForm } from 'element-plus';
import { getDatabase, updatePostgresqlPassword } from '@/api/modules/database'; import { getDatabase, updatePostgresqlPassword } from '@/api/modules/database';
import ConfirmDialog from '@/components/confirm-dialog/index.vue'; import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { GetAppConnInfo } from '@/api/modules/app'; import { GetAppConnInfo } from '@/api/modules/app';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { getRandomStr } from '@/utils/util'; import { getRandomStr } from '@/utils/util';
import { getSettingInfo } from '@/api/modules/setting'; import { getSettingInfo } from '@/api/modules/setting';

View File

@ -1,47 +1,33 @@
<template> <template>
<el-drawer <DrawerPro v-model="createVisible" :header="$t('database.create')" :back="handleClose" size="small">
v-model="createVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('database.create')" :back="handleClose" />
</template>
<div v-loading="loading"> <div v-loading="loading">
<el-form ref="formRef" label-position="top" :model="form" :rules="rules"> <el-form ref="formRef" label-position="top" :model="form" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input clearable v-model.trim="form.name" @input="form.username = form.name"></el-input>
<el-form-item :label="$t('commons.table.name')" prop="name"> </el-form-item>
<el-input clearable v-model.trim="form.name" @input="form.username = form.name"></el-input> <el-form-item :label="$t('commons.login.username')" prop="username">
</el-form-item> <el-input clearable v-model.trim="form.username" />
<el-form-item :label="$t('commons.login.username')" prop="username"> </el-form-item>
<el-input clearable v-model.trim="form.username" /> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input type="password" clearable show-password v-model.trim="form.password">
<el-form-item :label="$t('commons.login.password')" prop="password"> <template #append>
<el-input type="password" clearable show-password v-model.trim="form.password"> <el-button @click="random">{{ $t('commons.button.random') }}</el-button>
<template #append> </template>
<el-button @click="random">{{ $t('commons.button.random') }}</el-button> </el-input>
</template> </el-form-item>
</el-input> <el-form-item :label="$t('database.permission')" prop="superUser">
</el-form-item> <el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
<el-form-item :label="$t('database.permission')" prop="superUser"> </el-form-item>
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="database"> <el-form-item :label="$t('commons.table.type')" prop="database">
<el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag> <el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag>
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-input type="textarea" clearable v-model="form.description" /> <el-input type="textarea" clearable v-model="form.description" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
</div> </div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button :disabled="loading" @click="createVisible = false"> <el-button :disabled="loading" @click="createVisible = false">
@ -52,7 +38,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -61,7 +47,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { addPostgresqlDB } from '@/api/modules/database'; import { addPostgresqlDB } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { getRandomStr } from '@/utils/util'; import { getRandomStr } from '@/utils/util';

View File

@ -1,33 +1,21 @@
<template> <template>
<div> <div>
<el-drawer <DrawerPro
v-model="changeVisible" v-model="changeVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :resource="changeForm.postgresqlName"
:close-on-press-escape="false" :back="handleClose"
width="30%" size="small"
> >
<template #header>
<DrawerHeader :header="title" :resource="changeForm.postgresqlName" :back="handleClose" />
</template>
<el-form v-loading="loading" ref="changeFormRef" :rules="rules" :model="changeForm" label-position="top"> <el-form v-loading="loading" ref="changeFormRef" :rules="rules" :model="changeForm" label-position="top">
<el-row type="flex" justify="center"> <div v-if="changeForm.operation === 'password'">
<el-col :span="22"> <el-form-item :label="$t('commons.login.username')" prop="username">
<div v-if="changeForm.operation === 'password'"> <el-input disabled v-model="changeForm.username"></el-input>
<el-form-item :label="$t('commons.login.username')" prop="username"> </el-form-item>
<el-input disabled v-model="changeForm.username"></el-input> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input type="password" clearable show-password v-model="changeForm.password"></el-input>
<el-form-item :label="$t('commons.login.password')" prop="password"> </el-form-item>
<el-input </div>
type="password"
clearable
show-password
v-model="changeForm.password"
></el-input>
</el-form-item>
</div>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -39,7 +27,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
</div> </div>
@ -49,7 +37,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { deleteCheckPostgresqlDB, updatePostgresqlPassword } from '@/api/modules/database'; import { deleteCheckPostgresqlDB, updatePostgresqlPassword } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';

View File

@ -1,20 +1,13 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent> <LayoutContent :title="$t('database.remoteDB')" backName="PostgreSQL">
<template #title> <template #leftToolBar>
<back-button name="PostgreSQL" :header="$t('database.remoteDB')" /> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</template> </template>
<template #toolbar> <template #rightToolBar>
<el-row> <TableSearch @search="search()" v-model:searchName="searchName" />
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20">
<el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<TableSearch @search="search()" v-model:searchName="searchName" />
</el-col>
</el-row>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">

View File

@ -1,62 +1,46 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
size="50%" size="large"
> >
<template #header>
<DrawerHeader
:hideResource="dialogData.title === 'create'"
:header="title"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input v-if="dialogData.title === 'create'" clearable v-model.trim="dialogData.rowData!.name" />
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-tag v-else>{{ dialogData.rowData!.name }}</el-tag>
<el-input </el-form-item>
v-if="dialogData.title === 'create'" <el-form-item :label="$t('database.version')" prop="version">
clearable <el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false">
v-model.trim="dialogData.rowData!.name" <el-radio label="16.x" value="16.x" />
/> <el-radio label="15.x" value="15.x" />
<el-tag v-else>{{ dialogData.rowData!.name }}</el-tag> <el-radio label="14.x" value="14.x" />
</el-form-item> </el-radio-group>
<el-form-item :label="$t('database.version')" prop="version"> </el-form-item>
<el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false"> <el-form-item :label="$t('database.address')" prop="address">
<el-radio label="16.x" value="16.x" /> <el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
<el-radio label="15.x" value="15.x" /> </el-form-item>
<el-radio label="14.x" value="14.x" /> <el-form-item :label="$t('commons.table.port')" prop="port">
</el-radio-group> <el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('database.address')" prop="address"> <el-form-item :label="$t('commons.login.username')" prop="username">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" /> <el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.username" />
</el-form-item> <span class="input-help">{{ $t('database.pgUserHelper') }}</span>
<el-form-item :label="$t('commons.table.port')" prop="port"> </el-form-item>
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" /> <el-form-item :label="$t('commons.login.password')" prop="password">
</el-form-item> <el-input
<el-form-item :label="$t('commons.login.username')" prop="username"> @change="isOK = false"
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.username" /> type="password"
<span class="input-help">{{ $t('database.pgUserHelper') }}</span> clearable
</el-form-item> show-password
<el-form-item :label="$t('commons.login.password')" prop="password"> v-model.trim="dialogData.rowData!.password"
<el-input />
@change="isOK = false" </el-form-item>
type="password"
clearable
show-password
v-model.trim="dialogData.rowData!.password"
/>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" /> <el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -69,7 +53,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -77,7 +61,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Database } from '@/api/interface/database'; import { Database } from '@/api/interface/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database'; import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';

View File

@ -1,25 +1,21 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent> <LayoutContent :title="props.database + ' ' + $t('commons.button.set')" backName="PostgreSQL">
<template #title> <template #leftToolBar>
<back-button name="PostgreSQL" :header="props.database + ' ' + $t('commons.button.set')"> <el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf">
<template #buttons> {{ $t('database.confChange') }}
<el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf"> </el-button>
{{ $t('database.confChange') }} <el-button type="primary" :plain="activeName !== 'port'" @click="activeName = 'port'">
</el-button> {{ $t('commons.table.port') }}
<el-button type="primary" :plain="activeName !== 'port'" @click="activeName = 'port'"> </el-button>
{{ $t('commons.table.port') }} <el-button
</el-button> type="primary"
<el-button :disabled="postgresqlStatus !== 'Running'"
type="primary" :plain="activeName !== 'log'"
:disabled="postgresqlStatus !== 'Running'" @click="activeName = 'log'"
:plain="activeName !== 'log'" >
@click="activeName = 'log'" {{ $t('database.log') }}
> </el-button>
{{ $t('database.log') }}
</el-button>
</template>
</back-button>
</template> </template>
<template #app> <template #app>

View File

@ -1,16 +1,6 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('database.redisQuickCmd')" :back="handleClose" size="large">
<el-drawer <template #content>
v-model="drawerVisible"
:destroy-on-close="true"
@close="handleClose"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="50%"
>
<template #header>
<DrawerHeader :header="$t('database.redisQuickCmd')" :back="handleClose" />
</template>
<el-button type="primary" @click="handleCmdAdd()"> <el-button type="primary" @click="handleCmdAdd()">
{{ $t('commons.button.add') }} {{ $t('commons.button.add') }}
</el-button> </el-button>
@ -66,15 +56,14 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<template #footer> </template>
<span class="dialog-footer"> <template #footer>
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <span class="dialog-footer">
</span> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
</template> </span>
</el-drawer> </template>
</DrawerPro>
<OpDialog ref="opRef" @search="search" /> <OpDialog ref="opRef" @search="search" />
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -82,7 +71,6 @@ import { Command } from '@/api/interface/command';
import { saveRedisCommand, deleteRedisCommand, getRedisCommandPage } from '@/api/modules/host'; import { saveRedisCommand, deleteRedisCommand, getRedisCommandPage } from '@/api/modules/host';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
const drawerVisible = ref(); const drawerVisible = ref();

View File

@ -1,90 +1,77 @@
<template> <template>
<el-drawer <DrawerPro v-model="dialogVisible" :header="$t('database.databaseConnInfo')" :back="handleClose" size="small">
v-model="dialogVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('database.databaseConnInfo')" :back="handleClose" />
</template>
<el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top" :rules="rules"> <el-form @submit.prevent v-loading="loading" ref="formRef" :model="form" label-position="top" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'">
<el-col :span="22"> <el-card class="mini-border-card">
<el-form-item :label="$t('database.containerConn')" v-if="form.from === 'local'"> <el-descriptions :column="1">
<el-card class="mini-border-card"> <el-descriptions-item :label="$t('database.connAddress')">
<el-descriptions :column="1"> <el-tooltip
<el-descriptions-item :label="$t('database.connAddress')"> v-if="loadRedisInfo(true).length > 48"
<el-tooltip :content="loadRedisInfo(true)"
v-if="loadRedisInfo(true).length > 48" placement="top"
:content="loadRedisInfo(true)" >
placement="top" {{ loadRedisInfo(true).substring(0, 48) }}...
> </el-tooltip>
{{ loadRedisInfo(true).substring(0, 48) }}... <span else>
</el-tooltip> {{ loadRedisInfo(true) }}
<span else> </span>
{{ loadRedisInfo(true) }} <CopyButton :content="loadRedisInfo(true)" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadRedisInfo(true)" type="icon" /> <el-descriptions-item :label="$t('database.connPort')">
</el-descriptions-item> 6379
<el-descriptions-item :label="$t('database.connPort')"> <CopyButton content="6379" type="icon" />
6379 </el-descriptions-item>
<CopyButton content="6379" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
</el-descriptions> <span class="input-help">
</el-card> {{ $t('database.containerConnHelper') }}
<span class="input-help"> </span>
{{ $t('database.containerConnHelper') }} </el-form-item>
</span> <el-form-item :label="$t('database.remoteConn')">
</el-form-item> <el-card class="mini-border-card">
<el-form-item :label="$t('database.remoteConn')"> <el-descriptions :column="1">
<el-card class="mini-border-card"> <el-descriptions-item :label="$t('database.connAddress')">
<el-descriptions :column="1"> <el-tooltip
<el-descriptions-item :label="$t('database.connAddress')"> v-if="loadRedisInfo(false).length > 48"
<el-tooltip :content="loadRedisInfo(false)"
v-if="loadRedisInfo(false).length > 48" placement="top"
:content="loadRedisInfo(false)" >
placement="top" {{ loadRedisInfo(false).substring(0, 48) }}...
> </el-tooltip>
{{ loadRedisInfo(false).substring(0, 48) }}... <span else>
</el-tooltip> {{ loadRedisInfo(false) }}
<span else> </span>
{{ loadRedisInfo(false) }} <CopyButton :content="loadRedisInfo(false)" type="icon" />
</span> </el-descriptions-item>
<CopyButton :content="loadRedisInfo(false)" type="icon" /> <el-descriptions-item :label="$t('database.connPort')">
</el-descriptions-item> {{ form.port }}
<el-descriptions-item :label="$t('database.connPort')"> <CopyButton :content="form.port + ''" type="icon" />
{{ form.port }} </el-descriptions-item>
<CopyButton :content="form.port + ''" type="icon" /> </el-descriptions>
</el-descriptions-item> </el-card>
</el-descriptions> <span class="input-help">
</el-card> {{ $t('database.remoteConnHelper2') }}
<span class="input-help"> </span>
{{ $t('database.remoteConnHelper2') }} </el-form-item>
</span>
</el-form-item>
<el-divider border-style="dashed" /> <el-divider border-style="dashed" />
<el-form-item :label="$t('commons.login.password')" v-if="form.from === 'local'" prop="password"> <el-form-item :label="$t('commons.login.password')" v-if="form.from === 'local'" prop="password">
<el-input type="password" show-password clearable v-model="form.password"> <el-input type="password" show-password clearable v-model="form.password">
<template #append> <template #append>
<CopyButton :content="form.password" /> <CopyButton :content="form.password" />
<el-button @click="random" class="p-ml-5"> <el-button @click="random" class="p-ml-5">
{{ $t('commons.button.random') }} {{ $t('commons.button.random') }}
</el-button> </el-button>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<div v-if="form.from !== 'local'"> <div v-if="form.from !== 'local'">
<el-form-item :label="$t('commons.login.password')"> <el-form-item :label="$t('commons.login.password')">
<el-tag>{{ form.password }}</el-tag> <el-tag>{{ form.password }}</el-tag>
<CopyButton :content="form.password" type="icon" /> <CopyButton :content="form.password" type="icon" />
</el-form-item> </el-form-item>
</div> </div>
</el-col>
</el-row>
</el-form> </el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
@ -99,7 +86,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -110,7 +97,6 @@ import { changeRedisPassword, getDatabase } from '@/api/modules/database';
import ConfirmDialog from '@/components/confirm-dialog/index.vue'; import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { GetAppConnInfo } from '@/api/modules/app'; import { GetAppConnInfo } from '@/api/modules/app';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { getRandomStr } from '@/utils/util'; import { getRandomStr } from '@/utils/util';
import { getSettingInfo } from '@/api/modules/setting'; import { getSettingInfo } from '@/api/modules/setting';

View File

@ -8,7 +8,7 @@
</div> </div>
</el-card> </el-card>
</div> </div>
<LayoutContent> <LayoutContent title="Redis">
<template #app v-if="currentDB?.from === 'local'"> <template #app v-if="currentDB?.from === 'local'">
<AppStatus <AppStatus
:app-key="'redis'" :app-key="'redis'"
@ -19,96 +19,100 @@
@setting="onSetting" @setting="onSetting"
></AppStatus> ></AppStatus>
</template> </template>
<template #search v-if="!isOnSetting"> <template #leftToolBar v-if="!isOnSetting">
<div class="flex"> <el-button v-if="currentDB" type="primary" plain @click="onLoadConn">
<div> {{ $t('database.databaseConnInfo') }}
<el-button v-if="currentDB" type="primary" plain @click="onLoadConn"> </el-button>
{{ $t('database.databaseConnInfo') }} <el-button @click="goRemoteDB" type="primary" plain>
{{ $t('database.remoteDB') }}
</el-button>
</template>
<template #rightToolBar v-if="!isOnSetting">
<el-select v-model="currentDBName" @change="changeDatabase()" class="p-w-200 ml-5" v-if="currentDB">
<template #prefix>{{ $t('commons.table.type') }}</template>
<el-option-group :label="$t('database.local')">
<div v-for="(item, index) in dbOptionsLocal" :key="index">
<el-option v-if="item.from === 'local'" :value="item.database" class="optionClass">
<span v-if="item.database.length < 25">{{ item.database }}</span>
<el-tooltip v-else :content="item.database" placement="top">
<span>{{ item.database.substring(0, 25) }}...</span>
</el-tooltip>
</el-option>
</div>
<el-button link type="primary" class="jumpAdd" @click="goRouter('app')" icon="Position">
{{ $t('database.goInstall') }}
</el-button> </el-button>
<el-button @click="goRemoteDB" type="primary" plain> </el-option-group>
{{ $t('database.remoteDB') }} <el-option-group :label="$t('database.remote')">
<div v-for="(item, index) in dbOptionsRemote" :key="index">
<el-option v-if="item.from === 'remote'" :value="item.database" class="optionClass">
<span v-if="item.database.length < 25">{{ item.database }}</span>
<el-tooltip v-else :content="item.database" placement="top">
<span>{{ item.database.substring(0, 25) }}...</span>
</el-tooltip>
</el-option>
</div>
<el-button link type="primary" class="jumpAdd" @click="goRouter('remote')" icon="Position">
{{ $t('database.createRemoteDB') }}
</el-button>
</el-option-group>
</el-select>
</template>
<template #main v-if="!isOnSetting">
<div v-if="currentDB && !isOnSetting" class="mt-5">
<Terminal
:style="{ height: `calc(100vh - ${loadHeight()})` }"
:key="isRefresh"
ref="terminalRef"
v-show="redisStatus === 'Running' && terminalShow"
/>
<el-empty
v-if="redisStatus !== 'Running' || (currentDB.from === 'remote' && !redisCliExist)"
:image-size="80"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'background-color': '#000' }"
:description="loadErrMsg()"
>
<el-button v-if="currentDB.from === 'remote'" type="primary" @click="installCli">
{{ $t('commons.button.enable') }}
</el-button>
</el-empty>
<div>
<el-select v-model="quickCmd" clearable filterable @change="quickInput" style="width: 90%">
<template #prefix>{{ $t('terminal.quickCommand') }}</template>
<el-option
v-for="cmd in quickCmdList"
:key="cmd.id"
:label="cmd.name"
:value="cmd.command"
/>
</el-select>
<el-button @click="onSetQuickCmd" icon="Setting" style="width: 10%">
{{ $t('commons.button.set') }}
</el-button> </el-button>
</div> </div>
<el-select v-model="currentDBName" @change="changeDatabase()" class="p-w-200 ml-5" v-if="currentDB"> </div>
<template #prefix>{{ $t('commons.table.type') }}</template>
<el-option-group :label="$t('database.local')"> <div v-if="dbOptionsLocal.length === 0 && dbOptionsRemote.length === 0">
<div v-for="(item, index) in dbOptionsLocal" :key="index"> <LayoutContent :title="'Redis ' + $t('menu.database')" :divider="true">
<el-option v-if="item.from === 'local'" :value="item.database" class="optionClass"> <template #main>
<span v-if="item.database.length < 25">{{ item.database }}</span> <div class="app-warn">
<el-tooltip v-else :content="item.database" placement="top"> <div>
<span>{{ item.database.substring(0, 25) }}...</span> <span>{{ $t('app.checkInstalledWarn', ['Redis']) }}</span>
</el-tooltip> <span @click="goRouter('app')">
</el-option> <el-icon class="ml-2"><Position /></el-icon>
{{ $t('database.goInstall') }}
</span>
<div>
<img src="@/assets/images/no_app.svg" />
</div>
</div>
</div> </div>
<el-button link type="primary" class="jumpAdd" @click="goRouter('app')" icon="Position"> </template>
{{ $t('database.goInstall') }} </LayoutContent>
</el-button>
</el-option-group>
<el-option-group :label="$t('database.remote')">
<div v-for="(item, index) in dbOptionsRemote" :key="index">
<el-option v-if="item.from === 'remote'" :value="item.database" class="optionClass">
<span v-if="item.database.length < 25">{{ item.database }}</span>
<el-tooltip v-else :content="item.database" placement="top">
<span>{{ item.database.substring(0, 25) }}...</span>
</el-tooltip>
</el-option>
</div>
<el-button link type="primary" class="jumpAdd" @click="goRouter('remote')" icon="Position">
{{ $t('database.createRemoteDB') }}
</el-button>
</el-option-group>
</el-select>
</div> </div>
</template> </template>
</LayoutContent> </LayoutContent>
<div v-if="currentDB && !isOnSetting" class="mt-5">
<Terminal
:style="{ height: `calc(100vh - ${loadHeight()})` }"
:key="isRefresh"
ref="terminalRef"
v-show="redisStatus === 'Running' && terminalShow"
/>
<el-empty
v-if="redisStatus !== 'Running' || (currentDB.from === 'remote' && !redisCliExist)"
:image-size="80"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'background-color': '#000' }"
:description="loadErrMsg()"
>
<el-button v-if="currentDB.from === 'remote'" type="primary" @click="installCli">
{{ $t('commons.button.enable') }}
</el-button>
</el-empty>
<div>
<el-select v-model="quickCmd" clearable filterable @change="quickInput" style="width: 90%">
<template #prefix>{{ $t('terminal.quickCommand') }}</template>
<el-option v-for="cmd in quickCmdList" :key="cmd.id" :label="cmd.name" :value="cmd.command" />
</el-select>
<el-button @click="onSetQuickCmd" icon="Setting" style="width: 10%">
{{ $t('commons.button.set') }}
</el-button>
</div>
</div>
<div v-if="dbOptionsLocal.length === 0 && dbOptionsRemote.length === 0">
<LayoutContent :title="'Redis ' + $t('menu.database')" :divider="true">
<template #main>
<div class="app-warn">
<div>
<span>{{ $t('app.checkInstalledWarn', ['Redis']) }}</span>
<span @click="goRouter('app')">
<el-icon class="ml-2"><Position /></el-icon>
{{ $t('database.goInstall') }}
</span>
<div>
<img src="@/assets/images/no_app.svg" />
</div>
</div>
</div>
</template>
</LayoutContent>
</div>
<Setting ref="settingRef" style="margin-top: 30px" /> <Setting ref="settingRef" style="margin-top: 30px" />
<Conn ref="connRef" @check-exist="reOpenTerminal" @close-terminal="closeTerminal(true)" /> <Conn ref="connRef" @check-exist="reOpenTerminal" @close-terminal="closeTerminal(true)" />
<el-dialog <el-dialog

View File

@ -1,20 +1,13 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent> <LayoutContent :title="$t('database.remoteDB')" backName="Redis">
<template #title> <template #leftToolBar>
<back-button name="Redis" :header="$t('database.remoteDB')" /> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</template> </template>
<template #toolbar> <template #rightToolBar>
<el-row> <TableSearch @search="search()" v-model:searchName="searchName" />
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20">
<el-button type="primary" @click="onOpenDialog('create')">
{{ $t('database.createRemoteDB') }}
</el-button>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<TableSearch @search="search()" v-model:searchName="searchName" />
</el-col>
</el-row>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">

View File

@ -1,56 +1,40 @@
<template> <template>
<el-drawer <DrawerPro
v-model="drawerVisible" v-model="drawerVisible"
:destroy-on-close="true" :header="title"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" :resource="dialogData.title === 'create' ? '' : dialogData.rowData?.name"
size="50%" size="large"
> >
<template #header>
<DrawerHeader
:hideResource="dialogData.title === 'create'"
:header="title"
:resource="dialogData.rowData?.name"
:back="handleClose"
/>
</template>
<el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center"> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-col :span="22"> <el-input v-if="dialogData.title === 'create'" clearable v-model.trim="dialogData.rowData!.name" />
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-tag v-else>{{ dialogData.rowData!.name }}</el-tag>
<el-input </el-form-item>
v-if="dialogData.title === 'create'" <el-form-item :label="$t('database.version')" prop="version">
clearable <el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false">
v-model.trim="dialogData.rowData!.name" <el-radio label="6.x" value="6.x" />
/> <el-radio label="7.x" value="7.x" />
<el-tag v-else>{{ dialogData.rowData!.name }}</el-tag> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item :label="$t('database.version')" prop="version"> <el-form-item :label="$t('database.address')" prop="address">
<el-radio-group v-model="dialogData.rowData!.version" @change="isOK = false"> <el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
<el-radio label="6.x" value="6.x" /> </el-form-item>
<el-radio label="7.x" value="7.x" /> <el-form-item :label="$t('commons.table.port')" prop="port">
</el-radio-group> <el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('database.address')" prop="address"> <el-form-item :label="$t('commons.login.password')" prop="password">
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" /> <el-input
</el-form-item> @change="isOK = false"
<el-form-item :label="$t('commons.table.port')" prop="port"> type="password"
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" /> clearable
</el-form-item> show-password
<el-form-item :label="$t('commons.login.password')" prop="password"> v-model.trim="dialogData.rowData!.password"
<el-input />
@change="isOK = false" </el-form-item>
type="password" <el-form-item :label="$t('commons.table.description')" prop="description">
clearable <el-input clearable v-model.trim="dialogData.rowData!.description" />
show-password </el-form-item>
v-model.trim="dialogData.rowData!.password"
/>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -63,7 +47,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -71,7 +55,6 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Database } from '@/api/interface/database'; import { Database } from '@/api/interface/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database'; import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';

View File

@ -1,7 +1,7 @@
<template> <template>
<div v-show="settingShow" v-loading="loading"> <div v-show="settingShow" v-loading="loading">
<LayoutContent :title="database + ' ' + $t('commons.button.set')" :reload="true"> <LayoutContent :title="database + ' ' + $t('commons.button.set')" :reload="true">
<template #buttons> <template #leftToolBar>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')"> <el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }} {{ $t('database.confChange') }}
</el-button> </el-button>

View File

@ -1,42 +1,29 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.setRole')" :back="handleClose" size="large">
v-model="open" <div v-loading="loading">
:before-close="handleClose" <FileRole :mode="mode" @get-mode="getMode" :key="open.toString()"></FileRole>
:close-on-click-modal="false" <el-form ref="fileForm" label-position="left" :model="addForm" label-width="100px" :rules="rules">
:close-on-press-escape="false" <el-form-item :label="$t('commons.table.user')" prop="user">
size="50%" <el-input v-model.trim="addForm.user" />
> </el-form-item>
<template #header> <el-form-item :label="$t('file.group')" prop="group">
<DrawerHeader :header="$t('file.setRole')" :back="handleClose" /> <el-input v-model.trim="addForm.group" />
</template> </el-form-item>
<el-form-item>
<el-row> <el-checkbox v-model="addForm.sub">{{ $t('file.containSub') }}</el-checkbox>
<el-col :span="22" :offset="1" v-loading="loading"> </el-form-item>
<FileRole :mode="mode" @get-mode="getMode" :key="open.toString()"></FileRole> </el-form>
<el-form ref="fileForm" label-position="left" :model="addForm" label-width="100px" :rules="rules"> </div>
<el-form-item :label="$t('commons.table.user')" prop="user">
<el-input v-model.trim="addForm.user" />
</el-form-item>
<el-form-item :label="$t('file.group')" prop="group">
<el-input v-model.trim="addForm.group" />
</el-form-item>
<el-form-item>
<el-checkbox v-model="addForm.sub">{{ $t('file.containSub') }}</el-checkbox>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit()">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit()">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import DrawerHeader from '@/components/drawer-header/index.vue';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import { BatchChangeRole } from '@/api/modules/files'; import { BatchChangeRole } from '@/api/modules/files';

View File

@ -1,34 +1,19 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.setRole')" :back="handleClose" :resource="name" size="large">
v-model="open" <FileRole v-loading="loading" :mode="mode" @get-mode="getMode" :key="open.toString()"></FileRole>
:before-close="handleClose" <el-form-item v-if="form.isDir">
:close-on-click-modal="false" <el-checkbox v-model="form.sub">{{ $t('file.containSub') }}</el-checkbox>
:close-on-press-escape="false" </el-form-item>
size="50%"
>
<template #header>
<DrawerHeader :header="$t('file.setRole')" :resource="name" :back="handleClose" />
</template>
<el-row>
<el-col :span="22" :offset="1">
<FileRole v-loading="loading" :mode="mode" @get-mode="getMode" :key="open.toString()"></FileRole>
<el-form-item v-if="form.isDir">
<el-checkbox v-model="form.sub">{{ $t('file.containSub') }}</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit()">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit()">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import DrawerHeader from '@/components/drawer-header/index.vue';
import { ref } from 'vue'; import { ref } from 'vue';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import { ChangeFileMode } from '@/api/modules/files'; import { ChangeFileMode } from '@/api/modules/files';

View File

@ -1,38 +1,31 @@
<template> <template>
<el-drawer v-model="open" size="40%" :close-on-click-modal="false" :close-on-press-escape="false"> <DrawerPro v-model="open" :header="$t('file.setRole')" :back="handleClose" :resource="name" size="normal">
<template #header> <el-alert :title="$t('file.ownerHelper')" type="info" :closable="false" class="common-prompt" />
<DrawerHeader :header="$t('file.changeOwner')" :resource="name" :back="handleClose" /> <el-form
</template> ref="fileForm"
<el-row> label-position="top"
<el-col :span="22" :offset="1"> :model="addForm"
<el-alert :title="$t('file.ownerHelper')" type="info" :closable="false" class="common-prompt" /> label-width="100px"
<el-form :rules="rules"
ref="fileForm" v-loading="loading"
label-position="top" >
:model="addForm" <el-form-item :label="$t('commons.table.user')" prop="user">
label-width="100px" <el-input v-model.trim="addForm.user" />
:rules="rules" </el-form-item>
v-loading="loading" <el-form-item :label="$t('file.group')" prop="group">
> <el-input v-model.trim="addForm.group" />
<el-form-item :label="$t('commons.table.user')" prop="user"> </el-form-item>
<el-input v-model.trim="addForm.user" /> <el-form-item v-if="isDir">
</el-form-item> <el-checkbox v-model="addForm.sub">{{ $t('file.containSub') }}</el-checkbox>
<el-form-item :label="$t('file.group')" prop="group"> </el-form-item>
<el-input v-model.trim="addForm.group" /> </el-form>
</el-form-item>
<el-form-item v-if="isDir">
<el-checkbox v-model="addForm.sub">{{ $t('file.containSub') }}</el-checkbox>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -42,7 +35,6 @@ import { FormInstance, FormRules } from 'element-plus';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
interface OwnerProps { interface OwnerProps {
path: string; path: string;

View File

@ -1,58 +1,44 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="title" :back="handleClose" size="large">
v-model="open" <el-form
:destroy-on-close="true" ref="fileForm"
:close-on-click-modal="false" label-position="top"
:close-on-press-escape="false" :model="form"
:before-close="handleClose" label-width="100px"
size="50%" :rules="rules"
> v-loading="loading"
<template #header> >
<DrawerHeader :header="title" :back="handleClose" /> <el-form-item :label="$t('file.compressType')" prop="type">
</template> <el-select v-model="form.type">
<el-row> <el-option v-for="item in options" :key="item" :label="item" :value="item" />
<el-col :span="22" :offset="1"> </el-select>
<el-form </el-form-item>
ref="fileForm" <el-form-item :label="$t('commons.table.name')" prop="name">
label-position="top" <el-input v-model="form.name">
:model="form" <template #append>{{ extension }}</template>
label-width="100px" </el-input>
:rules="rules" </el-form-item>
v-loading="loading" <el-form-item :label="$t('file.compressDst')" prop="dst">
> <el-input v-model="form.dst">
<el-form-item :label="$t('file.compressType')" prop="type"> <template #prepend>
<el-select v-model="form.type"> <FileList :path="form.dst" @choose="getLinkPath" :dir="true"></FileList>
<el-option v-for="item in options" :key="item" :label="item" :value="item" /> </template>
</el-select> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-form-item :label="$t('setting.compressPassword')" prop="secret" v-if="form.type === 'tar.gz'">
<el-input v-model="form.name"> <el-input v-model="form.secret"></el-input>
<template #append>{{ extension }}</template> </el-form-item>
</el-input> <el-form-item>
</el-form-item> <el-checkbox v-model="form.replace" :label="$t('file.replace')"></el-checkbox>
<el-form-item :label="$t('file.compressDst')" prop="dst"> </el-form-item>
<el-input v-model="form.dst"> </el-form>
<template #prepend>
<FileList :path="form.dst" @choose="getLinkPath" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.compressPassword')" prop="secret" v-if="form.type === 'tar.gz'">
<el-input v-model="form.secret"></el-input>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.replace" :label="$t('file.replace')"></el-checkbox>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -64,7 +50,6 @@ import { Rules } from '@/global/form-rules';
import { CompressExtension, CompressType } from '@/enums/files'; import { CompressExtension, CompressType } from '@/enums/files';
import { CompressFile } from '@/api/modules/files'; import { CompressFile } from '@/api/modules/files';
import FileList from '@/components/file-list/index.vue'; import FileList from '@/components/file-list/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
interface CompressProps { interface CompressProps {

View File

@ -1,65 +1,48 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('commons.button.create')" :back="handleClose" size="normal">
v-model="open" <el-form
:before-close="handleClose" ref="fileForm"
:destroy-on-close="true" label-position="top"
:close-on-click-modal="false" :model="addForm"
:close-on-press-escape="false" label-width="100px"
size="40%" :rules="rules"
> v-loading="loading"
<template #header> @submit.enter.prevent
<DrawerHeader :header="$t('commons.button.create')" :back="handleClose" /> >
</template> <el-form-item :label="$t('commons.table.name')" prop="name">
<el-input v-model.trim="addForm.name" />
<el-row> </el-form-item>
<el-col :span="22" :offset="1"> <el-form-item v-if="!addForm.isDir">
<el-form <el-checkbox v-model="addForm.isLink" :label="$t('file.link')"></el-checkbox>
ref="fileForm" </el-form-item>
label-position="top" <el-form-item :label="$t('file.linkType')" v-if="addForm.isLink" prop="linkType">
:model="addForm" <el-radio-group v-model="addForm.isSymlink">
label-width="100px" <el-radio :value="true">{{ $t('file.softLink') }}</el-radio>
:rules="rules" <el-radio :value="false">{{ $t('file.hardLink') }}</el-radio>
v-loading="loading" </el-radio-group>
@submit.enter.prevent </el-form-item>
> <el-form-item v-if="addForm.isLink" :label="$t('file.linkPath')" prop="linkPath">
<el-form-item :label="$t('commons.table.name')" prop="name"> <el-input v-model="addForm.linkPath">
<el-input v-model.trim="addForm.name" /> <template #prepend>
</el-form-item> <FileList @choose="getLinkPath"></FileList>
<el-form-item v-if="!addForm.isDir"> </template>
<el-checkbox v-model="addForm.isLink" :label="$t('file.link')"></el-checkbox> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('file.linkType')" v-if="addForm.isLink" prop="linkType"> <el-form-item>
<el-radio-group v-model="addForm.isSymlink"> <el-checkbox v-if="addForm.isDir" v-model="setRole" :label="$t('file.setRole')"></el-checkbox>
<el-radio :value="true">{{ $t('file.softLink') }}</el-radio> </el-form-item>
<el-radio :value="false">{{ $t('file.hardLink') }}</el-radio> </el-form>
</el-radio-group> <FileRole v-if="setRole" :mode="'0755'" @get-mode="getMode" :key="open.toString()"></FileRole>
</el-form-item>
<el-form-item v-if="addForm.isLink" :label="$t('file.linkPath')" prop="linkPath">
<el-input v-model="addForm.linkPath">
<template #prepend>
<FileList @choose="getLinkPath"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-checkbox v-if="addForm.isDir" v-model="setRole" :label="$t('file.setRole')"></el-checkbox>
</el-form-item>
</el-form>
<FileRole v-if="setRole" :mode="'0755'" @get-mode="getMode" :key="open.toString()"></FileRole>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import DrawerHeader from '@/components/drawer-header/index.vue';
import { ref, reactive, computed } from 'vue'; import { ref, reactive, computed } from 'vue';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import { FormInstance, FormRules } from 'element-plus'; import { FormInstance, FormRules } from 'element-plus';

View File

@ -1,48 +1,34 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.deCompress')" :resource="name" :back="handleClose" size="normal">
v-model="open" <el-form
:destroy-on-close="true" ref="fileForm"
:close-on-click-modal="false" label-position="top"
:close-on-press-escape="false" :model="form"
:before-close="handleClose" label-width="100px"
size="40%" :rules="rules"
> v-loading="loading"
<template #header> >
<DrawerHeader :header="$t('file.deCompress')" :resource="name" :back="handleClose" /> <el-form-item :label="$t('commons.table.name')">
</template> <el-input v-model="name" disabled></el-input>
<el-row> </el-form-item>
<el-col :span="22" :offset="1"> <el-form-item :label="$t('file.deCompressDst')" prop="dst">
<el-form <el-input v-model="form.dst">
ref="fileForm" <template #prepend>
label-position="top" <FileList :path="form.dst" @choose="getLinkPath" :dir="true"></FileList>
:model="form" </template>
label-width="100px" </el-input>
:rules="rules" </el-form-item>
v-loading="loading" <el-form-item :label="$t('setting.compressPassword')" prop="secret" v-if="name.includes('tar.gz')">
> <el-input v-model="form.secret"></el-input>
<el-form-item :label="$t('commons.table.name')"> </el-form-item>
<el-input v-model="name" disabled></el-input> </el-form>
</el-form-item>
<el-form-item :label="$t('file.deCompressDst')" prop="dst">
<el-input v-model="form.dst">
<template #prepend>
<FileList :path="form.dst" @choose="getLinkPath" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.compressPassword')" prop="secret" v-if="name.includes('tar.gz')">
<el-input v-model="form.secret"></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -54,7 +40,6 @@ import { Rules } from '@/global/form-rules';
import { DeCompressFile } from '@/api/modules/files'; import { DeCompressFile } from '@/api/modules/files';
import { Mimetypes } from '@/global/mimetype'; import { Mimetypes } from '@/global/mimetype';
import FileList from '@/components/file-list/index.vue'; import FileList from '@/components/file-list/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
interface CompressProps { interface CompressProps {

View File

@ -1,35 +1,28 @@
<template> <template>
<el-drawer v-model="open" width="30%" :close-on-click-modal="false" :close-on-press-escape="false"> <DrawerPro v-model="open" :header="$t('file.info')" :back="handleClose" size="large">
<template #header> <el-descriptions :column="1" border>
<DrawerHeader :header="$t('file.info')" :back="handleClose" /> <el-descriptions-item :label="$t('file.fileName')">{{ data.name }}</el-descriptions-item>
</template> <el-descriptions-item :label="$t('commons.table.type')">{{ data.type }}</el-descriptions-item>
<el-row> <el-descriptions-item :label="$t('file.path')">{{ data.path }}</el-descriptions-item>
<el-col> <el-descriptions-item :label="$t('file.size')">
<el-descriptions :column="1" border> <span v-if="data.isDir">
<el-descriptions-item :label="$t('file.fileName')">{{ data.name }}</el-descriptions-item> <el-button type="primary" link small @click="getDirSize(data)">
<el-descriptions-item :label="$t('commons.table.type')">{{ data.type }}</el-descriptions-item> <span v-if="data.dirSize == undefined">
<el-descriptions-item :label="$t('file.path')">{{ data.path }}</el-descriptions-item> {{ $t('file.calculate') }}
<el-descriptions-item :label="$t('file.size')">
<span v-if="data.isDir">
<el-button type="primary" link small @click="getDirSize(data)" :loading="loading">
<span v-if="data.dirSize == undefined">
{{ $t('file.calculate') }}
</span>
<span v-else>{{ computeSize(data.dirSize) }}</span>
</el-button>
</span> </span>
<span v-else>{{ computeSize(data.size) }}</span> <span v-else>{{ computeSize(data.dirSize) }}</span>
</el-descriptions-item> </el-button>
<el-descriptions-item :label="$t('file.role')">{{ data.mode }}</el-descriptions-item> </span>
<el-descriptions-item :label="$t('commons.table.user')">{{ data.user }}</el-descriptions-item> <span v-else>{{ computeSize(data.size) }}</span>
<el-descriptions-item :label="$t('file.group')">{{ data.group }}</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item :label="$t('commons.table.updatedAt')"> <el-descriptions-item :label="$t('file.role')">{{ data.mode }}</el-descriptions-item>
{{ dateFormatSimple(data.modTime) }} <el-descriptions-item :label="$t('commons.table.user')">{{ data.user }}</el-descriptions-item>
</el-descriptions-item> <el-descriptions-item :label="$t('file.group')">{{ data.group }}</el-descriptions-item>
</el-descriptions> <el-descriptions-item :label="$t('commons.table.updatedAt')">
</el-col> {{ dateFormatSimple(data.modTime) }}
</el-row> </el-descriptions-item>
</el-drawer> </el-descriptions>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -37,7 +30,6 @@ import { ComputeDirSize, GetFileContent } from '@/api/modules/files';
import { computeSize } from '@/utils/util'; import { computeSize } from '@/utils/util';
import { ref } from 'vue'; import { ref } from 'vue';
import { dateFormatSimple } from '@/utils/util'; import { dateFormatSimple } from '@/utils/util';
import DrawerHeader from '@/components/drawer-header/index.vue';
interface InfoProps { interface InfoProps {
path: string; path: string;

View File

@ -1,31 +1,16 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.download')" :back="handleClose" size="normal">
v-model="open"
:title="$t('file.download')"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleClose"
size="40%"
>
<template #header>
<DrawerHeader :header="$t('file.download')" :back="handleClose" />
</template>
<el-form ref="fileForm" label-position="top" :model="addForm" :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-form-item :label="$t('file.compressType')" prop="type">
<el-col :span="22"> <el-select v-model="addForm.type">
<el-form-item :label="$t('file.compressType')" prop="type"> <el-option v-for="item in options" :key="item" :label="item" :value="item" />
<el-select v-model="addForm.type"> </el-select>
<el-option v-for="item in options" :key="item" :label="item" :value="item" /> </el-form-item>
</el-select> <el-form-item :label="$t('commons.table.name')" prop="name">
</el-form-item> <el-input v-model="addForm.name">
<el-form-item :label="$t('commons.table.name')" prop="name"> <template #append>{{ extension }}</template>
<el-input v-model="addForm.name"> </el-input>
<template #append>{{ extension }}</template> </el-form-item>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -33,7 +18,7 @@
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -43,7 +28,6 @@ import { computed, reactive, ref } from 'vue';
import { DownloadFile } from '@/api/modules/files'; import { DownloadFile } from '@/api/modules/files';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import DrawerHeader from '@/components/drawer-header/index.vue';
interface DownloadProps { interface DownloadProps {
paths: Array<string>; paths: Array<string>;

View File

@ -1,19 +1,12 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.favorite')" :back="handleClose" size="large">
v-model="open" <template #content>
:before-close="handleClose" <ComplexTable :pagination-config="paginationConfig" :data="data" @search="search">
:close-on-click-modal="false" <el-table-column :label="$t('file.path')" show-overflow-tooltip prop="path"></el-table-column>
:close-on-press-escape="false" <fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
size="50%" </ComplexTable>
>
<template #header>
<DrawerHeader :header="$t('file.favorite')" :back="handleClose" />
</template> </template>
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search"> </DrawerPro>
<el-table-column :label="$t('file.path')" show-overflow-tooltip prop="path"></el-table-column>
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
</el-drawer>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -138,7 +138,7 @@
</el-table> </el-table>
</div> </div>
</el-popover> </el-popover>
<el-button class="btn mr-5" @click="openRecycleBin"> <el-button class="btn mr-2.5" @click="openRecycleBin">
{{ $t('file.recycleBin') }} {{ $t('file.recycleBin') }}
</el-button> </el-button>
<div class="w-96"> <div class="w-96">

View File

@ -1,41 +1,28 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="title" :back="handleClose" size="normal">
v-model="open" <el-form
:destroy-on-close="true" @submit.prevent
:close-on-click-modal="false" ref="fileForm"
:close-on-press-escape="false" label-position="top"
size="40%" :model="addForm"
> :rules="rules"
<template #header> v-loading="loading"
<DrawerHeader :header="title" :back="handleClose" /> >
</template> <el-form-item :label="$t('file.path')" prop="newPath">
<el-row> <el-input v-model="addForm.newPath">
<el-col :span="22" :offset="1"> <template #prepend><FileList @choose="getPath" :dir="true"></FileList></template>
<el-form </el-input>
@submit.prevent </el-form-item>
ref="fileForm" <div v-if="changeName">
label-position="top" <el-form-item :label="$t('commons.table.name')" prop="name">
:model="addForm" <el-input v-model="addForm.name" :disabled="addForm.cover"></el-input>
:rules="rules" </el-form-item>
v-loading="loading" <el-radio-group v-model="addForm.cover" @change="changeType">
> <el-radio :value="true" size="large">{{ $t('file.replace') }}</el-radio>
<el-form-item :label="$t('file.path')" prop="newPath"> <el-radio :value="false" size="large">{{ $t('file.rename') }}</el-radio>
<el-input v-model="addForm.newPath"> </el-radio-group>
<template #prepend><FileList @choose="getPath" :dir="true"></FileList></template> </div>
</el-input> </el-form>
</el-form-item>
<div v-if="changeName">
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input v-model="addForm.name" :disabled="addForm.cover"></el-input>
</el-form-item>
<el-radio-group v-model="addForm.cover" @change="changeType">
<el-radio :value="true" size="large">{{ $t('file.replace') }}</el-radio>
<el-radio :value="false" size="large">{{ $t('file.rename') }}</el-radio>
</el-radio-group>
</div>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose(false)" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose(false)" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -44,7 +31,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -54,7 +41,6 @@ import i18n from '@/lang';
import { FormInstance, FormRules } from 'element-plus'; import { FormInstance, FormRules } from 'element-plus';
import { ref, reactive, computed } from 'vue'; import { ref, reactive, computed } from 'vue';
import FileList from '@/components/file-list/index.vue'; import FileList from '@/components/file-list/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { getDateStr } from '@/utils/util'; import { getDateStr } from '@/utils/util';

View File

@ -1,63 +1,60 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.recycleBin')" :back="handleClose" size="large">
v-model="open" <template #content>
:before-close="handleClose" <div class="flex space-x-4">
:close-on-click-modal="false" <el-button @click="clear" type="primary" :disabled="data == null || data.length == 0">
:close-on-press-escape="false" {{ $t('file.clearRecycleBin') }}
size="50%" </el-button>
> <el-button @click="patchDelete" :disabled="data == null || selects.length == 0">
<template #header> {{ $t('commons.button.delete') }}
<DrawerHeader :header="$t('file.recycleBin')" :back="handleClose" /> </el-button>
</template> <el-button @click="patchReduce" :disabled="data == null || selects.length == 0">
<div class="flex space-x-4"> {{ $t('file.reduce') }}
<el-button @click="clear" type="primary" :disabled="data == null || data.length == 0"> </el-button>
{{ $t('file.clearRecycleBin') }} <el-form-item :label="$t('file.fileRecycleBin')">
</el-button> <el-switch v-model="status" active-value="enable" inactive-value="disable" @change="changeStatus" />
<el-button @click="patchDelete" :disabled="data == null || selects.length == 0"> </el-form-item>
{{ $t('commons.button.delete') }} </div>
</el-button> <ComplexTable
<el-button @click="patchReduce" :disabled="data == null || selects.length == 0"> :pagination-config="paginationConfig"
{{ $t('file.reduce') }} v-model:selects="selects"
</el-button> :data="data"
<el-form-item :label="$t('file.fileRecycleBin')"> @search="search"
<el-switch v-model="status" active-value="enable" inactive-value="disable" @change="changeStatus" /> class="mt-5"
</el-form-item> >
</div> <el-table-column type="selection" fix />
<ComplexTable <el-table-column prop="name" :label="$t('commons.table.name')" show-overflow-tooltip>
:pagination-config="paginationConfig" <template #default="{ row }">
v-model:selects="selects" <span class="text-ellipsis" type="primary">
:data="data" <svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
@search="search" <svg-icon v-else className="table-icon" iconName="p-file-normal"></svg-icon>
class="mt-5" {{ row.name }}
> </span>
<el-table-column type="selection" fix /> </template>
<el-table-column prop="name" :label="$t('commons.table.name')" show-overflow-tooltip> </el-table-column>
<template #default="{ row }">
<span class="text-ellipsis" type="primary">
<svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
<svg-icon v-else className="table-icon" iconName="p-file-normal"></svg-icon>
{{ row.name }}
</span>
</template>
</el-table-column>
<el-table-column :label="$t('file.sourcePath')" show-overflow-tooltip prop="sourcePath"></el-table-column> <el-table-column
<el-table-column :label="$t('file.size')" prop="size" max-width="50"> :label="$t('file.sourcePath')"
<template #default="{ row }"> show-overflow-tooltip
{{ getFileSize(row.size) }} prop="sourcePath"
</template> ></el-table-column>
</el-table-column> <el-table-column :label="$t('file.size')" prop="size" max-width="50">
<el-table-column <template #default="{ row }">
:label="$t('file.deleteTime')" {{ getFileSize(row.size) }}
prop="deleteTime" </template>
:formatter="dateFormat" </el-table-column>
show-overflow-tooltip <el-table-column
></el-table-column> :label="$t('file.deleteTime')"
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix /> prop="deleteTime"
</ComplexTable> :formatter="dateFormat"
<Delete ref="deleteRef" @close="search" /> show-overflow-tooltip
<Reduce ref="reduceRef" @close="search" /> ></el-table-column>
</el-drawer> <fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
<Delete ref="deleteRef" @close="search" />
<Reduce ref="reduceRef" @close="search" />
</template>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -1,34 +1,27 @@
<template> <template>
<el-drawer v-model="open" size="40%" :close-on-click-modal="false" :close-on-press-escape="false"> <DrawerPro v-model="open" :header="$t('file.rename')" :resource="oldName" :back="handleClose" size="normal">
<template #header> <el-form
<DrawerHeader :header="$t('file.rename')" :resource="oldName" :back="handleClose" /> ref="fileForm"
</template> label-position="top"
<el-row> :model="addForm"
<el-col :span="22" :offset="1"> label-width="100px"
<el-form :rules="rules"
ref="fileForm" v-loading="loading"
label-position="top" >
:model="addForm" <el-form-item :label="$t('file.path')" prop="path">
label-width="100px" <el-input v-model="addForm.path" disabled />
:rules="rules" </el-form-item>
v-loading="loading" <el-form-item :label="$t('commons.table.name')" prop="newName">
> <el-input v-model.trim="addForm.newName" />
<el-form-item :label="$t('file.path')" prop="path"> </el-form-item>
<el-input v-model="addForm.path" disabled /> </el-form>
</el-form-item>
<el-form-item :label="$t('commons.table.name')" prop="newName">
<el-input v-model.trim="addForm.newName" />
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button> <el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -39,7 +32,6 @@ import { reactive, ref } from 'vue';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DrawerHeader from '@/components/drawer-header/index.vue';
interface RenameProps { interface RenameProps {
path: string; path: string;

View File

@ -1,82 +1,87 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.upload')" :back="handleClose" size="normal">
v-model="open" <template #content>
:before-close="handleClose" <div class="button-container">
size="40%" <div>
:destroy-on-close="true" <el-button type="primary" @click="upload('file')">
:close-on-click-modal="false" {{ $t('file.upload') }}{{ $t('file.file') }}
:close-on-press-escape="false" </el-button>
> <el-button type="primary" @click="upload('dir')">
<template #header> {{ $t('file.upload') }}{{ $t('file.dir') }}
<DrawerHeader :header="$t('file.upload')" :back="handleClose" /> </el-button>
</template> </div>
<div class="button-container"> <el-button @click="clearFiles">{{ $t('file.clearList') }}</el-button>
<div>
<el-button type="primary" @click="upload('file')">
{{ $t('file.upload') }}{{ $t('file.file') }}
</el-button>
<el-button type="primary" @click="upload('dir')">{{ $t('file.upload') }}{{ $t('file.dir') }}</el-button>
</div> </div>
<el-button @click="clearFiles">{{ $t('file.clearList') }}</el-button>
</div>
<div> <div>
<div class="el-upload-dragger" @dragover="handleDragover" @drop="handleDrop" @dragleave="handleDragleave"> <div
<div class="flex items-center justify-center h-52"> class="el-upload-dragger"
<div> @dragover="handleDragover"
<el-icon class="el-icon--upload"><upload-filled /></el-icon> @drop="handleDrop"
<div class="el-upload__text"> @dragleave="handleDragleave"
{{ $t('file.dropHelper') }} >
<div class="flex items-center justify-center h-52">
<div>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
{{ $t('file.dropHelper') }}
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<el-upload <el-upload
action="#" action="#"
:auto-upload="false" :auto-upload="false"
ref="uploadRef" ref="uploadRef"
:on-change="fileOnChange" :on-change="fileOnChange"
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-success="handleSuccess" :on-success="handleSuccess"
:show-file-list="false" :show-file-list="false"
multiple multiple
v-model:file-list="uploaderFiles" v-model:file-list="uploaderFiles"
:limit="1000" :limit="1000"
>
<template #tip>
<el-text>{{ uploadHelper }}</el-text>
<el-progress v-if="loading" text-inside :stroke-width="20" :percentage="uploadPercent"></el-progress>
</template>
</el-upload>
<div>
<p
v-for="(item, index) in uploaderFiles"
:key="index"
class="file-item"
@mouseover="hoverIndex = index"
@mouseout="hoverIndex = null"
> >
<el-icon class="file-icon"><Document /></el-icon> <template #tip>
<span v-if="item.raw.webkitRelativePath != ''">{{ item.raw.webkitRelativePath }}</span> <el-text>{{ uploadHelper }}</el-text>
<span v-else>{{ item.name }}</span> <el-progress
<span v-if="item.status === 'success'" class="success-icon"> v-if="loading"
<el-icon><Select /></el-icon> text-inside
</span> :stroke-width="20"
<span v-else> :percentage="uploadPercent"
<el-button ></el-progress>
class="delete-button" </template>
type="primary" </el-upload>
link
@click="removeFile(index)" <div>
:disabled="loading" <p
:icon="Close" v-for="(item, index) in uploaderFiles"
></el-button> :key="index"
</span> class="file-item"
</p> @mouseover="hoverIndex = index"
</div> @mouseout="hoverIndex = null"
>
<el-icon class="file-icon"><Document /></el-icon>
<span v-if="item.raw.webkitRelativePath != ''">{{ item.raw.webkitRelativePath }}</span>
<span v-else>{{ item.name }}</span>
<span v-if="item.status === 'success'" class="success-icon">
<el-icon><Select /></el-icon>
</span>
<span v-else>
<el-button
class="delete-button"
type="primary"
link
@click="removeFile(index)"
:disabled="loading"
:icon="Close"
></el-button>
</span>
</p>
</div>
</template>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -85,7 +90,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -93,7 +98,6 @@ import { nextTick, reactive, ref } from 'vue';
import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus'; import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
import { ChunkUploadFileData, UploadFileData } from '@/api/modules/files'; import { ChunkUploadFileData, UploadFileData } from '@/api/modules/files';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess, MsgWarning } from '@/utils/message'; import { MsgError, MsgSuccess, MsgWarning } from '@/utils/message';
import { Close, Document, UploadFilled } from '@element-plus/icons-vue'; import { Close, Document, UploadFilled } from '@element-plus/icons-vue';
import { TimeoutEnum } from '@/enums/http-enum'; import { TimeoutEnum } from '@/enums/http-enum';

View File

@ -1,45 +1,31 @@
<template> <template>
<el-drawer <DrawerPro v-model="open" :header="$t('file.download')" :back="handleClose" size="large">
v-model="open" <el-form
:destroy-on-close="true" ref="fileForm"
:before-close="handleClose" label-position="top"
size="50%" :model="addForm"
:close-on-click-modal="false" label-width="100px"
:close-on-press-escape="false" :rules="rules"
> v-loading="loading"
<template #header> >
<DrawerHeader :header="$t('file.download')" :back="handleClose" /> <el-form-item :label="$t('file.downloadUrl')" prop="url">
</template> <el-input v-model="addForm.url" @input="getFileName" />
<el-row> </el-form-item>
<el-col :span="22" :offset="1"> <el-form-item :label="$t('file.path')" prop="path">
<el-form <el-input v-model="addForm.path">
ref="fileForm" <template #prepend><FileList :path="addForm.path" @choose="getPath"></FileList></template>
label-position="top" </el-input>
:model="addForm" </el-form-item>
label-width="100px" <el-form-item :label="$t('commons.table.name')" prop="name">
:rules="rules" <el-input v-model="addForm.name"></el-input>
v-loading="loading" </el-form-item>
> <el-form-item>
<el-form-item :label="$t('file.downloadUrl')" prop="url"> <el-checkbox v-model="addForm.ignoreCertificate">
<el-input v-model="addForm.url" @input="getFileName" /> {{ $t('file.ignoreCertificate') }}
</el-form-item> </el-checkbox>
<el-form-item :label="$t('file.path')" prop="path"> <span class="input-help">{{ $t('file.ignoreCertificateHelper') }}</span>
<el-input v-model="addForm.path"> </el-form-item>
<template #prepend><FileList :path="addForm.path" @choose="getPath"></FileList></template> </el-form>
</el-input>
</el-form-item>
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input v-model="addForm.name"></el-input>
</el-form-item>
<el-form-item>
<el-checkbox v-model="addForm.ignoreCertificate">
{{ $t('file.ignoreCertificate') }}
</el-checkbox>
<span class="input-help">{{ $t('file.ignoreCertificateHelper') }}</span>
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleClose()" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="handleClose()" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -48,7 +34,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -58,7 +44,6 @@ import i18n from '@/lang';
import { FormInstance, FormRules } from 'element-plus'; import { FormInstance, FormRules } from 'element-plus';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import FileList from '@/components/file-list/index.vue'; import FileList from '@/components/file-list/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
interface WgetProps { interface WgetProps {

View File

@ -1,44 +1,29 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="title" :back="handleClose" size="large">
v-model="drawerVisible" <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules" v-loading="loading">
:destroy-on-close="true" <el-form-item :label="$t('commons.table.protocol')" prop="protocol">
:close-on-click-modal="false" <el-select class="w-full" v-model="dialogData.rowData!.protocol">
:close-on-press-escape="false" <el-option value="tcp" label="tcp" />
size="50%" <el-option value="udp" label="udp" />
> <el-option value="tcp/udp" label="tcp/udp" />
<template #header> </el-select>
<DrawerHeader :header="title" :back="handleClose" /> </el-form-item>
</template>
<div v-loading="loading">
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('commons.table.protocol')" prop="protocol">
<el-select style="width: 100%" v-model="dialogData.rowData!.protocol">
<el-option value="tcp" label="tcp" />
<el-option value="udp" label="udp" />
<el-option value="tcp/udp" label="tcp/udp" />
</el-select>
</el-form-item>
<el-form-item :label="$t('firewall.sourcePort')" prop="port"> <el-form-item :label="$t('firewall.sourcePort')" prop="port">
<el-input clearable v-model.trim="dialogData.rowData!.port" /> <el-input clearable v-model.trim="dialogData.rowData!.port" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('firewall.targetIP')" prop="targetIP"> <el-form-item :label="$t('firewall.targetIP')" prop="targetIP">
<el-input v-model.trim="dialogData.rowData!.targetIP" /> <el-input v-model.trim="dialogData.rowData!.targetIP" />
<span class="input-help">{{ $t('firewall.forwardHelper1') }}</span> <span class="input-help">{{ $t('firewall.forwardHelper1') }}</span>
<span class="input-help">{{ $t('firewall.forwardHelper2') }}</span> <span class="input-help">{{ $t('firewall.forwardHelper2') }}</span>
<span class="input-help">{{ $t('firewall.forwardHelper3') }}</span> <span class="input-help">{{ $t('firewall.forwardHelper3') }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="$t('firewall.targetPort')" prop="targetPort"> <el-form-item :label="$t('firewall.targetPort')" prop="targetPort">
<el-input clearable v-model.trim="dialogData.rowData!.targetPort" /> <el-input clearable v-model.trim="dialogData.rowData!.targetPort" />
</el-form-item> </el-form-item>
</el-col> </el-form>
</el-row>
</el-form>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
@ -47,7 +32,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -1,42 +1,34 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="title" :back="handleClose" size="large">
v-model="drawerVisible" <el-form
:destroy-on-close="true" ref="formRef"
:close-on-click-modal="false" label-position="top"
:close-on-press-escape="false" @submit.prevent
size="50%" :model="dialogData.rowData"
> :rules="rules"
<template #header> v-loading="loading"
<DrawerHeader :header="title" :back="handleClose" /> >
</template> <el-form-item :label="$t('firewall.address')" prop="address">
<div v-loading="loading"> <el-input
<el-form ref="formRef" label-position="top" @submit.prevent :model="dialogData.rowData" :rules="rules"> :disabled="dialogData.title === 'edit'"
<el-row type="flex" justify="center"> :rows="3"
<el-col :span="22"> type="textarea"
<el-form-item :label="$t('firewall.address')" prop="address"> clearable
<el-input v-model.trim="dialogData.rowData!.address"
:disabled="dialogData.title === 'edit'" />
:rows="3" <span class="input-help">{{ $t('firewall.addressHelper1') }}</span>
type="textarea" <span class="input-help">{{ $t('firewall.addressHelper2') }}</span>
clearable </el-form-item>
v-model.trim="dialogData.rowData!.address" <el-form-item :label="$t('firewall.strategy')" prop="strategy">
/> <el-radio-group v-model="dialogData.rowData!.strategy">
<span class="input-help">{{ $t('firewall.addressHelper1') }}</span> <el-radio value="accept">{{ $t('firewall.allow') }}</el-radio>
<span class="input-help">{{ $t('firewall.addressHelper2') }}</span> <el-radio value="drop">{{ $t('firewall.deny') }}</el-radio>
</el-form-item> </el-radio-group>
<el-form-item :label="$t('firewall.strategy')" prop="strategy"> </el-form-item>
<el-radio-group v-model="dialogData.rowData!.strategy"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-radio value="accept">{{ $t('firewall.allow') }}</el-radio> <el-input clearable v-model.trim="dialogData.rowData!.description" />
<el-radio value="drop">{{ $t('firewall.deny') }}</el-radio> </el-form-item>
</el-radio-group> </el-form>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
@ -45,14 +37,13 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { Host } from '@/api/interface/host'; import { Host } from '@/api/interface/host';
import { operateIPRule, updateAddrRule } from '@/api/modules/host'; import { operateIPRule, updateAddrRule } from '@/api/modules/host';

View File

@ -1,66 +1,47 @@
<template> <template>
<el-drawer <DrawerPro v-model="drawerVisible" :header="title" :back="handleClose" size="large">
v-model="drawerVisible" <el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules" v-loading="loading">
:destroy-on-close="true" <el-form-item :label="$t('commons.table.protocol')" prop="protocol">
:close-on-click-modal="false" <el-select class="w-full" v-model="dialogData.rowData!.protocol">
:close-on-press-escape="false" <el-option value="tcp" label="tcp" />
size="50%" <el-option value="udp" label="udp" />
> <el-option value="tcp/udp" label="tcp/udp" />
<template #header> </el-select>
<DrawerHeader :header="title" :back="handleClose" /> </el-form-item>
</template>
<div v-loading="loading">
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('commons.table.protocol')" prop="protocol">
<el-select style="width: 100%" v-model="dialogData.rowData!.protocol">
<el-option value="tcp" label="tcp" />
<el-option value="udp" label="udp" />
<el-option value="tcp/udp" label="tcp/udp" />
</el-select>
</el-form-item>
<el-form-item :label="$t('commons.table.port')" prop="port"> <el-form-item :label="$t('commons.table.port')" prop="port">
<el-input <el-input :disabled="dialogData.title === 'edit'" clearable v-model.trim="dialogData.rowData!.port" />
:disabled="dialogData.title === 'edit'" <span class="input-help">{{ $t('firewall.portHelper1') }}</span>
clearable <span class="input-help">{{ $t('firewall.portHelper2') }}</span>
v-model.trim="dialogData.rowData!.port" </el-form-item>
/>
<span class="input-help">{{ $t('firewall.portHelper1') }}</span>
<span class="input-help">{{ $t('firewall.portHelper2') }}</span>
</el-form-item>
<el-form-item :label="$t('firewall.source')" prop="source"> <el-form-item :label="$t('firewall.source')" prop="source">
<el-radio-group v-model="dialogData.rowData!.source"> <el-radio-group v-model="dialogData.rowData!.source">
<el-radio value="anyWhere">{{ $t('firewall.anyWhere') }}</el-radio> <el-radio value="anyWhere">{{ $t('firewall.anyWhere') }}</el-radio>
<el-radio value="address">{{ $t('firewall.address') }}</el-radio> <el-radio value="address">{{ $t('firewall.address') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
:label="$t('firewall.address')" :label="$t('firewall.address')"
v-if="dialogData.rowData!.source === 'address'" v-if="dialogData.rowData!.source === 'address'"
prop="address" prop="address"
> >
<el-input v-model.trim="dialogData.rowData!.address" /> <el-input v-model.trim="dialogData.rowData!.address" />
<span class="input-help">{{ $t('firewall.addressHelper1') }}</span> <span class="input-help">{{ $t('firewall.addressHelper1') }}</span>
<span class="input-help">{{ $t('firewall.addressHelper2') }}</span> <span class="input-help">{{ $t('firewall.addressHelper2') }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="$t('firewall.strategy')" prop="strategy"> <el-form-item :label="$t('firewall.strategy')" prop="strategy">
<el-radio-group v-model="dialogData.rowData!.strategy"> <el-radio-group v-model="dialogData.rowData!.strategy">
<el-radio value="accept">{{ $t('firewall.accept') }}</el-radio> <el-radio value="accept">{{ $t('firewall.accept') }}</el-radio>
<el-radio value="drop">{{ $t('firewall.drop') }}</el-radio> <el-radio value="drop">{{ $t('firewall.drop') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" /> <el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item> </el-form-item>
</el-col> </el-form>
</el-row>
</el-form>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
@ -69,7 +50,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -77,7 +58,6 @@ import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { Host } from '@/api/interface/host'; import { Host } from '@/api/interface/host';
import { operatePortRule, updatePortRule } from '@/api/modules/host'; import { operatePortRule, updatePortRule } from '@/api/modules/host';

View File

@ -1,39 +1,19 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('monitor.storeDays')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('monitor.storeDays')" :rules="[Rules.integerNumber]" prop="monitorStoreDays">
:destroy-on-close="true" <el-input clearable v-model.number="form.monitorStoreDays" />
@close="handleClose" </el-form-item>
:close-on-click-modal="false" </el-form>
:close-on-press-escape="false" <template #footer>
size="30%" <span class="dialog-footer">
> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<template #header> <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
<DrawerHeader :header="$t('monitor.storeDays')" :back="handleClose" /> {{ $t('commons.button.confirm') }}
</template> </el-button>
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> </span>
<el-row type="flex" justify="center"> </template>
<el-col :span="22"> </DrawerPro>
<el-form-item
:label="$t('monitor.storeDays')"
:rules="[Rules.integerNumber]"
prop="monitorStoreDays"
>
<el-input clearable v-model.number="form.monitorStoreDays" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
@ -42,7 +22,6 @@ import { MsgSuccess } from '@/utils/message';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { updateSetting } from '@/api/modules/setting'; import { updateSetting } from '@/api/modules/setting';
import DrawerHeader from '@/components/drawer-header/index.vue';
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();

View File

@ -1,39 +1,23 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('monitor.interval')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item
:destroy-on-close="true" :label="$t('monitor.interval')"
@close="handleClose" :rules="[Rules.integerNumber, checkNumberRange(1, 60)]"
:close-on-click-modal="false" prop="monitorInterval"
:close-on-press-escape="false" >
size="30%" <el-input clearable v-model.number="form.monitorInterval" />
> </el-form-item>
<template #header> </el-form>
<DrawerHeader :header="$t('monitor.interval')" :back="handleClose" /> <template #footer>
</template> <span class="dialog-footer">
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-row type="flex" justify="center"> <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
<el-col :span="22"> {{ $t('commons.button.confirm') }}
<el-form-item </el-button>
:label="$t('monitor.interval')" </span>
:rules="[Rules.integerNumber, checkNumberRange(1, 60)]" </template>
prop="monitorInterval" </DrawerPro>
>
<el-input clearable v-model.number="form.monitorInterval" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
@ -42,7 +26,6 @@ import { MsgSuccess } from '@/utils/message';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { Rules, checkNumberRange } from '@/global/form-rules'; import { Rules, checkNumberRange } from '@/global/form-rules';
import { updateSetting } from '@/api/modules/setting'; import { updateSetting } from '@/api/modules/setting';
import DrawerHeader from '@/components/drawer-header/index.vue';
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();

View File

@ -1,100 +1,94 @@
<template> <template>
<el-drawer v-model="open" size="40%" :close-on-click-modal="false" :close-on-press-escape="false"> <DrawerPro v-model="open" :header="$t('app.detail')" :resource="resourceName" :back="handleClose" size="large">
<template #header> <template #content>
<DrawerHeader :header="$t('app.detail')" :back="handleClose" :resource="resourceName" /> <el-tabs v-model="activeName" type="card">
<el-tab-pane :label="$t('process.basic')" name="basic">
<el-descriptions :column="2" border>
<el-descriptions-item :label="$t('commons.table.name')" min-width="100px">
{{ data.name }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.status')">{{ data.status }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.pid')">{{ data.PID }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.ppid')">{{ data.PPID }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.numThreads')">
{{ data.numThreads }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.numConnections')">
{{ data.numConnections }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.diskRead')">
{{ data.diskRead }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.diskWrite')">
{{ data.diskWrite }}
</el-descriptions-item>
<el-descriptions-item :label="$t('commons.table.user')">
{{ data.username }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.startTime')">
{{ data.startTime }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.cmdLine')">
{{ data.cmdLine }}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane :label="$t('process.mem')" name="mem">
<el-descriptions :column="2" border>
<el-descriptions-item :label="'rss'">{{ data.rss }}</el-descriptions-item>
<el-descriptions-item :label="'swap'">{{ data.swap }}</el-descriptions-item>
<el-descriptions-item :label="'vms'">{{ data.vms }}</el-descriptions-item>
<el-descriptions-item :label="'hwm'">{{ data.hwm }}</el-descriptions-item>
<el-descriptions-item :label="'data'">{{ data.data }}</el-descriptions-item>
<el-descriptions-item :label="'stack'">{{ data.stack }}</el-descriptions-item>
<el-descriptions-item :label="'locked'">{{ data.locked }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane :label="$t('process.openFiles')" name="openFiles">
<el-table :data="data.openFiles" border style="width: 100%">
<el-table-column prop="path" :label="$t('process.file')" />
<el-table-column prop="fd" label="fd" width="100px" />
</el-table>
</el-tab-pane>
<el-tab-pane :label="$t('process.env')" name="env">
<codemirror
:autofocus="true"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 200px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="envStr"
:disabled="true"
/>
</el-tab-pane>
<el-tab-pane :label="$t('process.net')" name="net">
<el-table :data="data.connects" border style="width: 100%">
<el-table-column prop="localaddr" :label="$t('process.laddr')">
<template #default="{ row }">
<span>{{ row.localaddr.ip }}</span>
<span v-if="row.localaddr.port > 0">:{{ row.localaddr.port }}</span>
</template>
</el-table-column>
<el-table-column prop="remoteaddr" :label="$t('process.raddr')">
<template #default="{ row }">
<span>{{ row.remoteaddr.ip }}</span>
<span v-if="row.remoteaddr.port > 0">:{{ row.remoteaddr.port }}</span>
</template>
</el-table-column>
<el-table-column prop="status" :label="$t('app.status')" />
</el-table>
</el-tab-pane>
</el-tabs>
</template> </template>
<el-row> </DrawerPro>
<el-col>
<el-tabs v-model="activeName" type="card">
<el-tab-pane :label="$t('process.basic')" name="basic">
<el-descriptions :column="2" border>
<el-descriptions-item :label="$t('commons.table.name')" min-width="100px">
{{ data.name }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.status')">{{ data.status }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.pid')">{{ data.PID }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.ppid')">{{ data.PPID }}</el-descriptions-item>
<el-descriptions-item :label="$t('process.numThreads')">
{{ data.numThreads }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.numConnections')">
{{ data.numConnections }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.diskRead')">
{{ data.diskRead }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.diskWrite')">
{{ data.diskWrite }}
</el-descriptions-item>
<el-descriptions-item :label="$t('commons.table.user')">
{{ data.username }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.startTime')">
{{ data.startTime }}
</el-descriptions-item>
<el-descriptions-item :label="$t('process.cmdLine')">
{{ data.cmdLine }}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane :label="$t('process.mem')" name="mem">
<el-descriptions :column="2" border>
<el-descriptions-item :label="'rss'">{{ data.rss }}</el-descriptions-item>
<el-descriptions-item :label="'swap'">{{ data.swap }}</el-descriptions-item>
<el-descriptions-item :label="'vms'">{{ data.vms }}</el-descriptions-item>
<el-descriptions-item :label="'hwm'">{{ data.hwm }}</el-descriptions-item>
<el-descriptions-item :label="'data'">{{ data.data }}</el-descriptions-item>
<el-descriptions-item :label="'stack'">{{ data.stack }}</el-descriptions-item>
<el-descriptions-item :label="'locked'">{{ data.locked }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane :label="$t('process.openFiles')" name="openFiles">
<el-table :data="data.openFiles" border style="width: 100%">
<el-table-column prop="path" :label="$t('process.file')" />
<el-table-column prop="fd" label="fd" width="100px" />
</el-table>
</el-tab-pane>
<el-tab-pane :label="$t('process.env')" name="env">
<codemirror
:autofocus="true"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 200px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="envStr"
:disabled="true"
/>
</el-tab-pane>
<el-tab-pane :label="$t('process.net')" name="net">
<el-table :data="data.connects" border style="width: 100%">
<el-table-column prop="localaddr" :label="$t('process.laddr')">
<template #default="{ row }">
<span>{{ row.localaddr.ip }}</span>
<span v-if="row.localaddr.port > 0">:{{ row.localaddr.port }}</span>
</template>
</el-table-column>
<el-table-column prop="remoteaddr" :label="$t('process.raddr')">
<template #default="{ row }">
<span>{{ row.remoteaddr.ip }}</span>
<span v-if="row.remoteaddr.port > 0">:{{ row.remoteaddr.port }}</span>
</template>
</el-table-column>
<el-table-column prop="status" :label="$t('app.status')" />
</el-table>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</el-drawer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';

View File

@ -1,64 +1,41 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('ssh.listenAddress')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :rules="rules" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-alert class="common-prompt" :closable="false" type="error">
:destroy-on-close="true" <template #default>
@close="handleClose" <span>
:close-on-click-modal="false" {{ $t('ssh.listenHelper', [form.port]) }}
:close-on-press-escape="false" </span>
size="30%" </template>
> </el-alert>
<template #header> <el-form-item label="IPv4" prop="listenAddressV4">
<DrawerHeader :header="$t('ssh.listenAddress')" :back="handleClose" /> <el-checkbox
</template> v-model="form.ipv4All"
<el-form @change="form.listenAddressV4 = form.ipv4All ? '0.0.0.0' : form.listenAddressV4"
ref="formRef" >
label-position="top" {{ $t('setting.bindAll') }}
:rules="rules" </el-checkbox>
:model="form" <el-input :disabled="form.ipv4All" clearable v-model="form.listenAddressV4"></el-input>
@submit.prevent </el-form-item>
v-loading="loading" <el-form-item label="IPv6" prop="listenAddressV6">
> <el-checkbox
<el-row type="flex" justify="center"> v-model="form.ipv6All"
<el-col :span="22"> @change="form.listenAddressV6 = form.ipv6All ? '::' : form.listenAddressV6"
<el-alert class="common-prompt" :closable="false" type="error"> >
<template #default> {{ $t('setting.bindAll') }}
<span> </el-checkbox>
{{ $t('ssh.listenHelper', [form.port]) }} <el-input :disabled="form.ipv6All" clearable v-model="form.listenAddressV6"></el-input>
</span> </el-form-item>
</template> </el-form>
</el-alert> <template #footer>
<el-form-item label="IPv4" prop="listenAddressV4"> <span class="dialog-footer">
<el-checkbox <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
v-model="form.ipv4All" <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
@change="form.listenAddressV4 = form.ipv4All ? '0.0.0.0' : form.listenAddressV4" {{ $t('commons.button.confirm') }}
> </el-button>
{{ $t('setting.bindAll') }} </span>
</el-checkbox> </template>
<el-input :disabled="form.ipv4All" clearable v-model="form.listenAddressV4"></el-input> </DrawerPro>
</el-form-item>
<el-form-item label="IPv6" prop="listenAddressV6">
<el-checkbox
v-model="form.ipv6All"
@change="form.listenAddressV6 = form.ipv6All ? '::' : form.listenAddressV6"
>
{{ $t('setting.bindAll') }}
</el-checkbox>
<el-input :disabled="form.ipv6All" clearable v-model="form.listenAddressV6"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
@ -66,7 +43,6 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElMessageBox, FormInstance } from 'element-plus'; import { ElMessageBox, FormInstance } from 'element-plus';
import { updateSSH } from '@/api/modules/host'; import { updateSSH } from '@/api/modules/host';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { checkIp, checkIpV6 } from '@/utils/util'; import { checkIp, checkIpV6 } from '@/utils/util';
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();

View File

@ -1,42 +1,25 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('commons.table.port')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.port')" prop="port" :rules="Rules.port">
:destroy-on-close="true" <el-input clearable v-model.number="form.port" />
@close="handleClose" </el-form-item>
:close-on-click-modal="false" </el-form>
:close-on-press-escape="false" <template #footer>
size="30%" <span class="dialog-footer">
> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<template #header> <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
<DrawerHeader :header="$t('commons.table.port')" :back="handleClose" /> {{ $t('commons.button.confirm') }}
</template> </el-button>
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> </span>
<el-row type="flex" justify="center"> </template>
<el-col :span="22"> </DrawerPro>
<el-form-item :label="$t('commons.table.port')" prop="port" :rules="Rules.port">
<el-input clearable v-model.number="form.port" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElMessageBox, FormInstance } from 'element-plus'; import { ElMessageBox, FormInstance } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { updateSSH } from '@/api/modules/host'; import { updateSSH } from '@/api/modules/host';

View File

@ -1,65 +1,49 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('ssh.pubkey')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :rules="rules" :model="form" v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('ssh.encryptionMode')" prop="encryptionMode">
:destroy-on-close="true" <el-select v-model="form.encryptionMode" @change="onLoadSecret">
@close="handleClose" <el-option label="ED25519" value="ed25519" />
:close-on-click-modal="false" <el-option label="ECDSA" value="ecdsa" />
:close-on-press-escape="false" <el-option label="RSA" value="rsa" />
size="30%" <el-option label="DSA" value="dsa" />
> </el-select>
<template #header> </el-form-item>
<DrawerHeader :header="$t('ssh.pubkey')" :back="handleClose" /> <el-form-item :label="$t('commons.login.password')" prop="password">
</template> <el-input v-model="form.password" type="password" show-password>
<el-form ref="formRef" label-position="top" :rules="rules" :model="form" v-loading="loading"> <template #append>
<el-row type="flex" justify="center"> <el-button @click="onCopy(form.password)">
<el-col :span="22"> {{ $t('commons.button.copy') }}
<el-form-item :label="$t('ssh.encryptionMode')" prop="encryptionMode"> </el-button>
<el-select v-model="form.encryptionMode" @change="onLoadSecret"> <el-divider direction="vertical" />
<el-option label="ED25519" value="ed25519" /> <el-button @click="random">
<el-option label="ECDSA" value="ecdsa" /> {{ $t('commons.button.random') }}
<el-option label="RSA" value="rsa" /> </el-button>
<el-option label="DSA" value="dsa" /> </template>
</el-select> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="password">
<el-input v-model="form.password" type="password" show-password>
<template #append>
<el-button @click="onCopy(form.password)">
{{ $t('commons.button.copy') }}
</el-button>
<el-divider direction="vertical" />
<el-button @click="random">
{{ $t('commons.button.random') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('ssh.key')" prop="primaryKey" v-if="form.encryptionMode"> <el-form-item :label="$t('ssh.key')" prop="primaryKey" v-if="form.encryptionMode">
<el-input v-model="form.primaryKey" :rows="5" type="textarea" /> <el-input v-model="form.primaryKey" :rows="5" type="textarea" />
<div v-if="form.primaryKey"> <div v-if="form.primaryKey">
<el-button icon="CopyDocument" class="marginTop" @click="onCopy(form.primaryKey)"> <el-button icon="CopyDocument" class="marginTop" @click="onCopy(form.primaryKey)">
{{ $t('file.copy') }} {{ $t('file.copy') }}
</el-button>
<el-button icon="Download" class="marginTop" @click="onDownload">
{{ $t('commons.button.download') }}
</el-button>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="onGenerate(formRef)" type="primary">
{{ $t('ssh.generate') }}
</el-button> </el-button>
</span> <el-button icon="Download" class="marginTop" @click="onDownload">
</template> {{ $t('commons.button.download') }}
</el-drawer> </el-button>
</div> </div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="onGenerate(formRef)" type="primary">
{{ $t('ssh.generate') }}
</el-button>
</span>
</template>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { generateSecret, loadSecret } from '@/api/modules/host'; import { generateSecret, loadSecret } from '@/api/modules/host';
@ -68,7 +52,6 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { copyText, dateFormatForName, getRandomStr } from '@/utils/util'; import { copyText, dateFormatForName, getRandomStr } from '@/utils/util';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
const loading = ref(); const loading = ref();

View File

@ -1,40 +1,24 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('ssh.permitRootLogin')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('ssh.permitRootLogin')" prop="permitRootLogin">
:destroy-on-close="true" <el-select v-model="form.permitRootLogin" style="width: 100%">
@close="handleClose" <el-option :label="$t('ssh.rootHelper1')" value="yes" />
:close-on-click-modal="false" <el-option :label="$t('ssh.rootHelper2')" value="no" />
:close-on-press-escape="false" <el-option :label="$t('ssh.rootHelper3')" value="without-password" />
size="30%" <el-option :label="$t('ssh.rootHelper4')" value="forced-commands-only" />
> </el-select>
<template #header> </el-form-item>
<DrawerHeader :header="$t('ssh.permitRootLogin')" :back="handleClose" /> </el-form>
</template> <template #footer>
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> <span class="dialog-footer">
<el-row type="flex" justify="center"> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-col :span="22"> <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
<el-form-item :label="$t('ssh.permitRootLogin')" prop="permitRootLogin"> {{ $t('commons.button.confirm') }}
<el-select v-model="form.permitRootLogin" style="width: 100%"> </el-button>
<el-option :label="$t('ssh.rootHelper1')" value="yes" /> </span>
<el-option :label="$t('ssh.rootHelper2')" value="no" /> </template>
<el-option :label="$t('ssh.rootHelper3')" value="without-password" /> </DrawerPro>
<el-option :label="$t('ssh.rootHelper4')" value="forced-commands-only" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
@ -42,7 +26,6 @@ import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElMessageBox, FormInstance } from 'element-plus'; import { ElMessageBox, FormInstance } from 'element-plus';
import { updateSSH } from '@/api/modules/host'; import { updateSSH } from '@/api/modules/host';
import DrawerHeader from '@/components/drawer-header/index.vue';
const emit = defineEmits<{ (e: 'search'): void }>(); const emit = defineEmits<{ (e: 'search'): void }>();

View File

@ -61,45 +61,34 @@
</ComplexTable> </ComplexTable>
</template> </template>
</LayoutContent> </LayoutContent>
<el-drawer <DrawerPro
v-model="cmdVisible" v-model="cmdVisible"
:destroy-on-close="true" :header="$t('commons.button.' + operate) + $t('terminal.quickCommand')"
:close-on-click-modal="false" :back="handleClose"
:close-on-press-escape="false" size="small"
size="30%"
> >
<template #header> <el-form
<DrawerHeader @submit.prevent
:header="$t('commons.button.' + operate) + $t('terminal.quickCommand')" ref="commandInfoRef"
:back="handleClose" label-width="100px"
/> label-position="top"
</template> :model="commandInfo"
<el-row type="flex" justify="center"> :rules="rules"
<el-col :span="22"> >
<el-form <el-form-item :label="$t('commons.table.name')" prop="name">
@submit.prevent <el-input clearable v-model="commandInfo.name" />
ref="commandInfoRef" </el-form-item>
label-width="100px" <el-form-item :label="$t('commons.table.group')" prop="name">
label-position="top" <el-select filterable v-model="commandInfo.groupID" clearable style="width: 100%">
:model="commandInfo" <div v-for="item in groupList" :key="item.id">
:rules="rules" <el-option :label="item.name" :value="item.id" />
> </div>
<el-form-item :label="$t('commons.table.name')" prop="name"> </el-select>
<el-input clearable v-model="commandInfo.name" /> </el-form-item>
</el-form-item> <el-form-item :label="$t('terminal.command')" prop="command">
<el-form-item :label="$t('commons.table.group')" prop="name"> <el-input type="textarea" clearable v-model="commandInfo.command" />
<el-select filterable v-model="commandInfo.groupID" clearable style="width: 100%"> </el-form-item>
<div v-for="item in groupList" :key="item.id"> </el-form>
<el-option :label="item.name" :value="item.id" />
</div>
</el-select>
</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> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="cmdVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="cmdVisible = false">{{ $t('commons.button.cancel') }}</el-button>
@ -108,7 +97,7 @@
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
<OpDialog ref="opRef" @search="search" /> <OpDialog ref="opRef" @search="search" />
<GroupDialog @search="loadGroups" ref="dialogGroupRef" /> <GroupDialog @search="loadGroups" ref="dialogGroupRef" />
@ -125,7 +114,6 @@ import { reactive, ref } from 'vue';
import type { ElForm } from 'element-plus'; import type { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { GetGroupList } from '@/api/modules/group'; import { GetGroupList } from '@/api/modules/group';

View File

@ -1,38 +1,30 @@
<template> <template>
<div v-loading="loading"> <DrawerPro v-model="drawerVisible" :header="$t('terminal.groupChange')" :back="handleClose" size="small">
<el-drawer <el-form
v-model="drawerVisible" @submit.prevent
:destroy-on-close="true" ref="hostInfoRef"
:close-on-click-modal="false" label-position="top"
:close-on-press-escape="false" :model="dialogData"
size="30%" :rules="rules"
v-loading="loading"
> >
<template #header> <el-form-item :label="$t('commons.table.group')" prop="group">
<DrawerHeader :header="$t('terminal.groupChange')" :back="handleClose" /> <el-select filterable v-model="dialogData.groupID" clearable class="w-full">
</template> <div v-for="item in groupList" :key="item.id">
<el-row type="flex" justify="center"> <el-option :label="item.name" :value="item.id" />
<el-col :span="22"> </div>
<el-form @submit.prevent ref="hostInfoRef" label-position="top" :model="dialogData" :rules="rules"> </el-select>
<el-form-item :label="$t('commons.table.group')" prop="group"> </el-form-item>
<el-select filterable v-model="dialogData.groupID" clearable style="width: 100%"> </el-form>
<div v-for="item in groupList" :key="item.id"> <template #footer>
<el-option :label="item.name" :value="item.id" /> <span class="dialog-footer">
</div> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
</el-select> <el-button type="primary" @click="onSubmit(hostInfoRef)">
</el-form-item> {{ $t('commons.button.confirm') }}
</el-form> </el-button>
</el-col> </span>
</el-row> </template>
<template #footer> </DrawerPro>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="onSubmit(hostInfoRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -41,7 +33,6 @@ import type { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { editHostGroup } from '@/api/modules/host'; import { editHostGroup } from '@/api/modules/host';
import { GetGroupList } from '@/api/modules/group'; import { GetGroupList } from '@/api/modules/group';
import DrawerHeader from '@/components/drawer-header/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,109 +1,80 @@
<template> <template>
<div v-loading="loading"> <DrawerPro v-model="drawerVisible" :header="$t('terminal.host')" :back="handleClose" size="large">
<el-drawer <el-form ref="hostInfoRef" label-position="top" :model="dialogData.rowData" :rules="rules" v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('terminal.ip')" prop="addr">
:destroy-on-close="true" <el-tag v-if="dialogData.rowData!.addr === '127.0.0.1' && dialogData.title === 'edit'">
:close-on-click-modal="false" {{ dialogData.rowData!.addr }}
:close-on-press-escape="false" </el-tag>
size="50%" <el-input @change="isOK = false" v-else clearable v-model.trim="dialogData.rowData!.addr" />
> </el-form-item>
<template #header> <el-form-item :label="$t('commons.login.username')" prop="user">
<DrawerHeader :header="$t('terminal.host')" :back="handleClose" /> <el-input @change="isOK = false" clearable v-model="dialogData.rowData!.user" />
</template> </el-form-item>
<el-row type="flex" justify="center"> <el-form-item :label="$t('terminal.authMode')" prop="authMode">
<el-col :span="22"> <el-radio-group @change="isOK = false" v-model="dialogData.rowData!.authMode">
<el-form ref="hostInfoRef" label-position="top" :model="dialogData.rowData" :rules="rules"> <el-radio value="password">{{ $t('terminal.passwordMode') }}</el-radio>
<el-form-item :label="$t('terminal.ip')" prop="addr"> <el-radio value="key">{{ $t('terminal.keyMode') }}</el-radio>
<el-tag v-if="dialogData.rowData!.addr === '127.0.0.1' && dialogData.title === 'edit'"> </el-radio-group>
{{ dialogData.rowData!.addr }} </el-form-item>
</el-tag> <el-form-item
<el-input @change="isOK = false" v-else clearable v-model.trim="dialogData.rowData!.addr" /> :label="$t('commons.login.password')"
</el-form-item> v-if="dialogData.rowData!.authMode === 'password'"
<el-form-item :label="$t('commons.login.username')" prop="user"> prop="password"
<el-input @change="isOK = false" clearable v-model="dialogData.rowData!.user" /> >
</el-form-item> <el-input
<el-form-item :label="$t('terminal.authMode')" prop="authMode"> @change="isOK = false"
<el-radio-group @change="isOK = false" v-model="dialogData.rowData!.authMode"> clearable
<el-radio value="password">{{ $t('terminal.passwordMode') }}</el-radio> show-password
<el-radio value="key">{{ $t('terminal.keyMode') }}</el-radio> type="password"
</el-radio-group> v-model="dialogData.rowData!.password"
</el-form-item> />
<el-form-item </el-form-item>
:label="$t('commons.login.password')" <el-form-item :label="$t('terminal.key')" v-if="dialogData.rowData!.authMode === 'key'" prop="privateKey">
v-if="dialogData.rowData!.authMode === 'password'" <el-input @change="isOK = false" clearable type="textarea" v-model="dialogData.rowData!.privateKey" />
prop="password" </el-form-item>
> <el-form-item
<el-input :label="$t('terminal.keyPassword')"
@change="isOK = false" v-if="dialogData.rowData!.authMode === 'key'"
clearable prop="passPhrase"
show-password >
type="password" <el-input
v-model="dialogData.rowData!.password" @change="isOK = false"
/> type="password"
</el-form-item> show-password
<el-form-item clearable
:label="$t('terminal.key')" v-model="dialogData.rowData!.passPhrase"
v-if="dialogData.rowData!.authMode === 'key'" />
prop="privateKey" </el-form-item>
> <el-checkbox clearable v-model.number="dialogData.rowData!.rememberPassword">
<el-input {{ $t('terminal.rememberPassword') }}
@change="isOK = false" </el-checkbox>
clearable <el-form-item style="margin-top: 10px" :label="$t('commons.table.port')" prop="port">
type="textarea" <el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
v-model="dialogData.rowData!.privateKey" </el-form-item>
/> <el-form-item :label="$t('commons.table.group')" prop="groupID">
</el-form-item> <el-select filterable v-model="dialogData.rowData!.groupID" clearable style="width: 100%">
<el-form-item <el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.id" />
:label="$t('terminal.keyPassword')" </el-select>
v-if="dialogData.rowData!.authMode === 'key'" </el-form-item>
prop="passPhrase" <el-form-item :label="$t('commons.table.title')" prop="name">
> <el-input clearable v-model="dialogData.rowData!.name" />
<el-input </el-form-item>
@change="isOK = false" <el-form-item :label="$t('commons.table.description')" prop="description">
type="password" <el-input clearable type="textarea" v-model="dialogData.rowData!.description" />
show-password </el-form-item>
clearable </el-form>
v-model="dialogData.rowData!.passPhrase" <template #footer>
/> <span class="dialog-footer">
</el-form-item> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-checkbox clearable v-model.number="dialogData.rowData!.rememberPassword"> <el-button @click="submitAddHost(hostInfoRef, 'testconn')">
{{ $t('terminal.rememberPassword') }} {{ $t('terminal.testConn') }}
</el-checkbox> </el-button>
<el-form-item style="margin-top: 10px" :label="$t('commons.table.port')" prop="port"> <el-button type="primary" :disabled="!isOK" @click="submitAddHost(hostInfoRef, dialogData.title)">
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" /> {{ $t('commons.button.confirm') }}
</el-form-item> </el-button>
<el-form-item :label="$t('commons.table.group')" prop="groupID"> </span>
<el-select filterable v-model="dialogData.rowData!.groupID" clearable style="width: 100%"> </template>
<el-option </DrawerPro>
v-for="item in groupList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('commons.table.title')" prop="name">
<el-input clearable v-model="dialogData.rowData!.name" />
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable type="textarea" v-model="dialogData.rowData!.description" />
</el-form-item>
</el-form>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="submitAddHost(hostInfoRef, 'testconn')">
{{ $t('terminal.testConn') }}
</el-button>
<el-button type="primary" :disabled="!isOK" @click="submitAddHost(hostInfoRef, dialogData.title)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -111,7 +82,6 @@ import { ref, reactive } from 'vue';
import type { ElForm } from 'element-plus'; import type { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { addHost, editHost, testByInfo } from '@/api/modules/host'; import { addHost, editHost, testByInfo } from '@/api/modules/host';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { GetGroupList } from '@/api/modules/group'; import { GetGroupList } from '@/api/modules/group';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';

View File

@ -1,96 +1,67 @@
<template> <template>
<div> <DrawerPro v-model="dialogVisible" :header="$t('terminal.addHost')" :back="handleClose" size="large">
<el-drawer <el-form ref="hostRef" label-width="100px" label-position="top" :model="hostInfo" :rules="rules">
v-model="dialogVisible" <el-alert
:destroy-on-close="true" v-if="isLocal"
:close-on-click-modal="false" class="common-prompt"
:close-on-press-escape="false" center
size="50%" :title="$t('terminal.connLocalErr')"
> :closable="false"
<template #header> type="warning"
<DrawerHeader :header="$t('terminal.addHost')" :back="handleClose" /> />
</template> <el-form-item :label="$t('terminal.ip')" prop="addr">
<el-form ref="hostRef" label-width="100px" label-position="top" :model="hostInfo" :rules="rules"> <el-input @change="isOK = false" v-if="!isLocal" clearable v-model.trim="hostInfo.addr" />
<el-row type="flex" justify="center"> <el-tag v-if="isLocal">{{ hostInfo.addr }}</el-tag>
<el-col :span="22"> </el-form-item>
<el-alert <el-form-item :label="$t('commons.login.username')" prop="user">
v-if="isLocal" <el-input @change="isOK = false" clearable v-model="hostInfo.user" />
class="common-prompt" </el-form-item>
center <el-form-item :label="$t('terminal.authMode')" prop="authMode">
:title="$t('terminal.connLocalErr')" <el-radio-group @change="isOK = false" v-model="hostInfo.authMode">
:closable="false" <el-radio value="password">{{ $t('terminal.passwordMode') }}</el-radio>
type="warning" <el-radio value="key">{{ $t('terminal.keyMode') }}</el-radio>
/> </el-radio-group>
<el-form-item :label="$t('terminal.ip')" prop="addr"> </el-form-item>
<el-input @change="isOK = false" v-if="!isLocal" clearable v-model.trim="hostInfo.addr" /> <el-form-item :label="$t('commons.login.password')" v-if="hostInfo.authMode === 'password'" prop="password">
<el-tag v-if="isLocal">{{ hostInfo.addr }}</el-tag> <el-input @change="isOK = false" clearable show-password type="password" v-model="hostInfo.password" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.login.username')" prop="user"> <el-form-item :label="$t('terminal.key')" v-if="hostInfo.authMode === 'key'" prop="privateKey">
<el-input @change="isOK = false" clearable v-model="hostInfo.user" /> <el-input @change="isOK = false" clearable type="textarea" v-model="hostInfo.privateKey" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('terminal.authMode')" prop="authMode"> <el-form-item :label="$t('terminal.keyPassword')" v-if="hostInfo.authMode === 'key'" prop="passPhrase">
<el-radio-group @change="isOK = false" v-model="hostInfo.authMode"> <el-input
<el-radio value="password">{{ $t('terminal.passwordMode') }}</el-radio> @change="isOK = false"
<el-radio value="key">{{ $t('terminal.keyMode') }}</el-radio> type="password"
</el-radio-group> show-password
</el-form-item> clearable
<el-form-item v-model="hostInfo.passPhrase"
:label="$t('commons.login.password')" />
v-if="hostInfo.authMode === 'password'" </el-form-item>
prop="password" <el-checkbox clearable v-model.number="hostInfo.rememberPassword">
> {{ $t('terminal.rememberPassword') }}
<el-input </el-checkbox>
@change="isOK = false" <el-form-item class="mt-2.5" :label="$t('commons.table.port')" prop="port">
clearable <el-input @change="isOK = false" clearable v-model.number="hostInfo.port" />
show-password </el-form-item>
type="password" <el-form-item :label="$t('commons.table.title')" prop="name">
v-model="hostInfo.password" <el-input clearable v-model="hostInfo.name" />
/> </el-form-item>
</el-form-item> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-form-item :label="$t('terminal.key')" v-if="hostInfo.authMode === 'key'" prop="privateKey"> <el-input clearable v-model="hostInfo.description" />
<el-input @change="isOK = false" clearable type="textarea" v-model="hostInfo.privateKey" /> </el-form-item>
</el-form-item> </el-form>
<el-form-item <template #footer>
:label="$t('terminal.keyPassword')" <span class="dialog-footer">
v-if="hostInfo.authMode === 'key'" <el-button @click="dialogVisible = false">{{ $t('commons.button.cancel') }}</el-button>
prop="passPhrase" <el-button @click="submitAddHost(hostRef, 'testConn')">
> {{ $t('terminal.testConn') }}
<el-input </el-button>
@change="isOK = false" <el-button type="primary" :disabled="!isOK" @click="submitAddHost(hostRef, 'saveAndConn')">
type="password" {{ $t('terminal.saveAndConn') }}
show-password </el-button>
clearable </span>
v-model="hostInfo.passPhrase" </template>
/> </DrawerPro>
</el-form-item>
<el-checkbox clearable v-model.number="hostInfo.rememberPassword">
{{ $t('terminal.rememberPassword') }}
</el-checkbox>
<el-form-item style="margin-top: 10px" :label="$t('commons.table.port')" prop="port">
<el-input @change="isOK = false" 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">
<el-button @click="dialogVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="submitAddHost(hostRef, 'testConn')">
{{ $t('terminal.testConn') }}
</el-button>
<el-button type="primary" :disabled="!isOK" @click="submitAddHost(hostRef, 'saveAndConn')">
{{ $t('terminal.saveAndConn') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -98,7 +69,6 @@ import { ElForm } from 'element-plus';
import { Host } from '@/api/interface/host'; import { Host } from '@/api/interface/host';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { addHost, testByInfo } from '@/api/modules/host'; import { addHost, testByInfo } from '@/api/modules/host';
import DrawerHeader from '@/components/drawer-header/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';

View File

@ -1,109 +1,74 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="cosData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + cosData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
size="50%" <el-input v-model.trim="cosData.rowData!.accessKey" />
> </el-form-item>
<template #header> <el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input show-password clearable v-model.trim="cosData.rowData!.credential" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="cosData.rowData"> <el-form-item label="Region" prop="varsJson.region" :rules="Rules.requiredInput">
<el-row type="flex" justify="center"> <el-checkbox v-model="regionInput" :label="$t('container.input')" />
<el-col :span="22"> <el-select v-if="!regionInput" v-model="cosData.rowData!.varsJson['region']" filterable clearable>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-option v-for="item in cities" :key="item.value" :label="item.label" :value="item.value">
<el-tag>{{ $t('setting.' + cosData.rowData!.type) }}</el-tag> <span class="float-left">{{ item.label }}</span>
</el-form-item> <span class="option-help">
<el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput"> {{ item.value }}
<el-input v-model.trim="cosData.rowData!.accessKey" /> </span>
</el-form-item> </el-option>
<el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput"> </el-select>
<el-input show-password clearable v-model.trim="cosData.rowData!.credential" /> <el-input v-else v-model.trim="cosData.rowData!.varsJson['region']" />
</el-form-item> </el-form-item>
<el-form-item label="Region" prop="varsJson.region" :rules="Rules.requiredInput"> <el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput">
<el-checkbox v-model="regionInput" :label="$t('container.input')" /> <el-input v-model.trim="cosData.rowData!.varsJson['endpointItem']">
<el-select <template #prepend>
v-if="!regionInput" <el-select v-model.trim="endpointProto" class="p-w-100">
v-model="cosData.rowData!.varsJson['region']" <el-option label="http" value="http" />
filterable <el-option label="https" value="https" />
clearable </el-select>
> </template>
<el-option </el-input>
v-for="item in cities" </el-form-item>
:key="item.value" <el-form-item label="Bucket" prop="bucket">
:label="item.label" <el-select @change="errBuckets = false" class="!w-4/5" v-model="cosData.rowData!.bucket">
:value="item.value" <el-option v-for="item in buckets" :key="item" :value="item" />
> </el-select>
<span style="float: left">{{ item.label }}</span> <el-button class="!w-1/5" plain @click="getBuckets(formRef)">
<span class="option-help"> {{ $t('setting.loadBucket') }}
{{ item.value }} </el-button>
</span> <span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-option> </el-form-item>
</el-select> <el-form-item :label="$t('setting.scType')" prop="varsJson.scType" :rules="[Rules.requiredSelect]">
<el-input v-else v-model.trim="cosData.rowData!.varsJson['region']" /> <el-select v-model="cosData.rowData!.varsJson['scType']">
</el-form-item> <el-option value="Standard" :label="$t('setting.scStandard')" />
<el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput"> <el-option value="Standard_IA" :label="$t('setting.scStandard_IA')" />
<el-input v-model.trim="cosData.rowData!.varsJson['endpointItem']"> <el-option value="Archive" :label="$t('setting.scArchive')" />
<template #prepend> <el-option value="Deep_Archive" :label="$t('setting.scDeep_Archive')" />
<el-select v-model.trim="endpointProto" style="width: 100px"> </el-select>
<el-option label="http" value="http" /> <el-alert
<el-option label="https" value="https" /> v-if="cosData.rowData!.varsJson['scType'] === 'Archive' || cosData.rowData!.varsJson['scType'] === 'Deep_Archive'"
</el-select> class="mt-2.5"
</template> :closable="false"
</el-input> type="warning"
</el-form-item> :title="$t('setting.archiveHelper')"
<el-form-item label="Bucket" prop="bucket"> />
<el-select </el-form-item>
@change="errBuckets = false" <el-form-item :label="$t('setting.backupDir')" prop="backupPath">
style="width: 80%" <el-input clearable v-model.trim="cosData.rowData!.backupPath" placeholder="/1panel" />
v-model="cosData.rowData!.bucket" </el-form-item>
> </el-form>
<el-option v-for="item in buckets" :key="item" :value="item" /> <template #footer>
</el-select> <el-button :disabled="loading" @click="handleClose">
<el-button style="width: 20%" plain @click="getBuckets(formRef)"> {{ $t('commons.button.cancel') }}
{{ $t('setting.loadBucket') }} </el-button>
</el-button> <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span> {{ $t('commons.button.confirm') }}
</el-form-item> </el-button>
<el-form-item </template>
:label="$t('setting.scType')" </DrawerPro>
prop="varsJson.scType"
:rules="[Rules.requiredSelect]"
>
<el-select v-model="cosData.rowData!.varsJson['scType']">
<el-option value="Standard" :label="$t('setting.scStandard')" />
<el-option value="Standard_IA" :label="$t('setting.scStandard_IA')" />
<el-option value="Archive" :label="$t('setting.scArchive')" />
<el-option value="Deep_Archive" :label="$t('setting.scDeep_Archive')" />
</el-select>
<el-alert
v-if="cosData.rowData!.varsJson['scType'] === 'Archive' || cosData.rowData!.varsJson['scType'] === 'Deep_Archive'"
style="margin-top: 10px"
:closable="false"
type="warning"
:title="$t('setting.archiveHelper')"
/>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="cosData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -112,7 +77,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, listBucket } from '@/api/modules/setting'; import { addBackup, editBackup, listBucket } from '@/api/modules/setting';
import { deepCopy, spliceHttp, splitHttp } from '@/utils/util'; import { deepCopy, spliceHttp, splitHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,83 +1,56 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="kodoData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + kodoData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
size="50%" <el-input v-model.trim="kodoData.rowData!.accessKey" />
> </el-form-item>
<template #header> <el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input show-password clearable v-model.trim="kodoData.rowData!.credential" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="kodoData.rowData"> <el-form-item :label="$t('setting.domain')" prop="varsJson.domainItem" :rules="Rules.requiredInput">
<el-row type="flex" justify="center"> <el-input v-model="kodoData.rowData!.varsJson['domainItem']">
<el-col :span="22"> <template #prepend>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-select v-model.trim="domainProto" class="p-w-100">
<el-tag>{{ $t('setting.' + kodoData.rowData!.type) }}</el-tag> <el-option label="http" value="http" />
</el-form-item> <el-option label="https" value="https" />
<el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput"> </el-select>
<el-input v-model.trim="kodoData.rowData!.accessKey" /> </template>
</el-form-item> </el-input>
<el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput"> </el-form-item>
<el-input show-password clearable v-model.trim="kodoData.rowData!.credential" /> <el-form-item label="Bucket" prop="bucket">
</el-form-item> <el-select @change="errBuckets = false" class="!w-4/5" v-model="kodoData.rowData!.bucket">
<el-form-item <el-option v-for="item in buckets" :key="item" :value="item" />
:label="$t('setting.domain')" </el-select>
prop="varsJson.domainItem" <el-button class="!w-1/5" plain @click="getBuckets(formRef)">
:rules="Rules.requiredInput" {{ $t('setting.loadBucket') }}
> </el-button>
<el-input v-model="kodoData.rowData!.varsJson['domainItem']"> <span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
<template #prepend> </el-form-item>
<el-select v-model.trim="domainProto" style="width: 100px"> <el-form-item :label="$t('cronjob.requestExpirationTime')" prop="varsJson.timeout">
<el-option label="http" value="http" /> <el-input-number
<el-option label="https" value="https" /> style="width: 200px"
</el-select> :min="1"
</template> step-strictly
</el-input> :step="1"
</el-form-item> v-model.number="kodoData.rowData!.varsJson['timeout']"
<el-form-item label="Bucket" prop="bucket"> ></el-input-number>
<el-select </el-form-item>
@change="errBuckets = false" <el-form-item :label="$t('setting.backupDir')" prop="backupPath">
style="width: 80%" <el-input clearable v-model.trim="kodoData.rowData!.backupPath" placeholder="/1panel" />
v-model="kodoData.rowData!.bucket" </el-form-item>
> </el-form>
<el-option v-for="item in buckets" :key="item" :value="item" /> <template #footer>
</el-select> <el-button :disabled="loading" @click="handleClose">
<el-button style="width: 20%" plain @click="getBuckets(formRef)"> {{ $t('commons.button.cancel') }}
{{ $t('setting.loadBucket') }} </el-button>
</el-button> <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span> {{ $t('commons.button.confirm') }}
</el-form-item> </el-button>
</template>
<el-form-item :label="$t('cronjob.requestExpirationTime')" prop="varsJson.timeout"> </DrawerPro>
<el-input-number
style="width: 200px"
:min="1"
step-strictly
:step="1"
v-model.number="kodoData.rowData!.varsJson['timeout']"
></el-input-number>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="kodoData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -86,7 +59,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, listBucket } from '@/api/modules/setting'; import { addBackup, editBackup, listBucket } from '@/api/modules/setting';
import { deepCopy, spliceHttp, splitHttp } from '@/utils/util'; import { deepCopy, spliceHttp, splitHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,47 +1,26 @@
<template> <template>
<div v-loading="loading"> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + dialogData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item :label="$t('setting.backupDir')" prop="varsJson['dir']" :rules="Rules.requiredInput">
size="50%" <el-input v-model="dialogData.rowData!.varsJson['dir']">
> <template #prepend>
<template #header> <FileList @choose="loadDir" :dir="true"></FileList>
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> </template>
</template> </el-input>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData"> </el-form-item>
<el-row type="flex" justify="center"> </el-form>
<el-col :span="22"> <template #footer>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-button :disabled="loading" @click="handleClose">
<el-tag>{{ $t('setting.' + dialogData.rowData!.type) }}</el-tag> {{ $t('commons.button.cancel') }}
</el-form-item> </el-button>
<el-form-item <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
:label="$t('setting.backupDir')" {{ $t('commons.button.confirm') }}
prop="varsJson['dir']" </el-button>
:rules="Rules.requiredInput" </template>
> </DrawerPro>
<el-input v-model="dialogData.rowData!.varsJson['dir']">
<template #prepend>
<FileList @choose="loadDir" :dir="true"></FileList>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -51,7 +30,6 @@ import FileList from '@/components/file-list/index.vue';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup } from '@/api/modules/setting'; import { addBackup, editBackup } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,68 +1,47 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="minioData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + minioData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
size="50%" <el-input v-model.trim="minioData.rowData!.accessKey" />
> </el-form-item>
<template #header> <el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input show-password clearable v-model.trim="minioData.rowData!.credential" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="minioData.rowData"> <el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput">
<el-row type="flex" justify="center"> <el-input v-model="minioData.rowData!.varsJson['endpointItem']">
<el-col :span="22"> <template #prepend>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-select v-model.trim="endpointProto" style="width: 100px">
<el-tag>{{ $t('setting.' + minioData.rowData!.type) }}</el-tag> <el-option label="http" value="http" />
</el-form-item> <el-option label="https" value="https" />
<el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput"> </el-select>
<el-input v-model.trim="minioData.rowData!.accessKey" /> </template>
</el-form-item> </el-input>
<el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput"> </el-form-item>
<el-input show-password clearable v-model.trim="minioData.rowData!.credential" /> <el-form-item label="Bucket" prop="bucket">
</el-form-item> <el-select class="!w-4/5" @change="errBuckets = false" v-model="minioData.rowData!.bucket">
<el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput"> <el-option v-for="item in buckets" :key="item" :value="item" />
<el-input v-model="minioData.rowData!.varsJson['endpointItem']"> </el-select>
<template #prepend> <el-button class="!w-1/5" plain @click="getBuckets(formRef)">
<el-select v-model.trim="endpointProto" style="width: 100px"> {{ $t('setting.loadBucket') }}
<el-option label="http" value="http" /> </el-button>
<el-option label="https" value="https" /> <span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-select> </el-form-item>
</template> <el-form-item :label="$t('setting.backupDir')" prop="backupPath">
</el-input> <el-input clearable v-model.trim="minioData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item> </el-form-item>
<el-form-item label="Bucket" prop="bucket"> </el-form>
<el-select <template #footer>
style="width: 80%" <el-button :disabled="loading" @click="handleClose">
@change="errBuckets = false" {{ $t('commons.button.cancel') }}
v-model="minioData.rowData!.bucket" </el-button>
> <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
<el-option v-for="item in buckets" :key="item" :value="item" /> {{ $t('commons.button.confirm') }}
</el-select> </el-button>
<el-button style="width: 20%" plain @click="getBuckets(formRef)"> </template>
{{ $t('setting.loadBucket') }} </DrawerPro>
</el-button>
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="minioData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -71,7 +50,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, listBucket } from '@/api/modules/setting'; import { addBackup, editBackup, listBucket } from '@/api/modules/setting';
import { deepCopy, splitHttp, spliceHttp } from '@/utils/util'; import { deepCopy, splitHttp, spliceHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,108 +1,77 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="oneDriveData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + oneDriveData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item>
size="50%" <el-radio-group v-model="oneDriveData.rowData!.varsJson['isCN']" @change="changeFrom">
> <el-radio-button :value="false">{{ $t('setting.isNotCN') }}</el-radio-button>
<template #header> <el-radio-button :value="true">{{ $t('setting.isCN') }}</el-radio-button>
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> </el-radio-group>
</template> <span class="input-help">
<el-form {{ $t('setting.onedrive_helper') }}
@submit.prevent <el-link
ref="formRef" style="font-size: 12px; margin-left: 5px"
v-loading="loading" icon="Position"
label-position="top" @click="toDoc(true)"
:model="oneDriveData.rowData" type="primary"
> >
<el-row type="flex" justify="center"> {{ $t('firewall.quickJump') }}
<el-col :span="22"> </el-link>
<el-form-item :label="$t('commons.table.type')" prop="type">
<el-tag>{{ $t('setting.' + oneDriveData.rowData!.type) }}</el-tag>
</el-form-item>
<el-form-item>
<el-radio-group v-model="oneDriveData.rowData!.varsJson['isCN']" @change="changeFrom">
<el-radio-button :value="false">{{ $t('setting.isNotCN') }}</el-radio-button>
<el-radio-button :value="true">{{ $t('setting.isCN') }}</el-radio-button>
</el-radio-group>
<span class="input-help">
{{ $t('setting.onedrive_helper') }}
<el-link
style="font-size: 12px; margin-left: 5px"
icon="Position"
@click="toDoc(true)"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</el-form-item>
<el-form-item
:label="$t('setting.client_id')"
prop="varsJson.client_id"
:rules="Rules.requiredInput"
>
<el-input v-model.trim="oneDriveData.rowData!.varsJson['client_id']" />
</el-form-item>
<el-form-item
:label="$t('setting.client_secret')"
prop="varsJson.client_secret"
:rules="Rules.requiredInput"
>
<el-input v-model.trim="oneDriveData.rowData!.varsJson['client_secret']" />
</el-form-item>
<el-form-item
:label="$t('setting.redirect_uri')"
prop="varsJson.redirect_uri"
:rules="Rules.requiredInput"
>
<el-input v-model.trim="oneDriveData.rowData!.varsJson['redirect_uri']" />
</el-form-item>
<el-form-item :label="$t('setting.code')" prop="varsJson.code" :rules="rules.driveCode">
<div style="width: 100%">
<el-input
style="width: calc(100% - 80px)"
:rows="3"
type="textarea"
clearable
v-model.trim="oneDriveData.rowData!.varsJson['code']"
/>
<el-button class="append-button" @click="jumpAzure(formRef)">
{{ $t('setting.loadCode') }}
</el-button>
</div>
<span class="input-help">
{{ $t('setting.codeHelper') }}
<el-link
style="font-size: 12px; margin-left: 5px"
icon="Position"
@click="toDoc(false)"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="oneDriveData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span> </span>
</template> </el-form-item>
</el-drawer> <el-form-item :label="$t('setting.client_id')" prop="varsJson.client_id" :rules="Rules.requiredInput">
</div> <el-input v-model.trim="oneDriveData.rowData!.varsJson['client_id']" />
</el-form-item>
<el-form-item
:label="$t('setting.client_secret')"
prop="varsJson.client_secret"
:rules="Rules.requiredInput"
>
<el-input v-model.trim="oneDriveData.rowData!.varsJson['client_secret']" />
</el-form-item>
<el-form-item :label="$t('setting.redirect_uri')" prop="varsJson.redirect_uri" :rules="Rules.requiredInput">
<el-input v-model.trim="oneDriveData.rowData!.varsJson['redirect_uri']" />
</el-form-item>
<el-form-item :label="$t('setting.code')" prop="varsJson.code" :rules="rules.driveCode">
<div class="!w-full">
<el-input
style="width: calc(100% - 80px)"
:rows="3"
type="textarea"
clearable
v-model.trim="oneDriveData.rowData!.varsJson['code']"
/>
<el-button class="append-button" @click="jumpAzure(formRef)">
{{ $t('setting.loadCode') }}
</el-button>
</div>
<span class="input-help">
{{ $t('setting.codeHelper') }}
<el-link
style="font-size: 12px; margin-left: 5px"
icon="Position"
@click="toDoc(false)"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="oneDriveData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-form>
<template #footer>
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</template>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -111,7 +80,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, getOneDriveInfo } from '@/api/modules/setting'; import { addBackup, editBackup, getOneDriveInfo } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,87 +1,62 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="ossData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + ossData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
size="50%" <el-input v-model.trim="ossData.rowData!.accessKey" />
> </el-form-item>
<template #header> <el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input show-password clearable v-model.trim="ossData.rowData!.credential" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="ossData.rowData"> <el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput">
<el-row type="flex" justify="center"> <el-input v-model="ossData.rowData!.varsJson['endpointItem']">
<el-col :span="22"> <template #prepend>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-select v-model.trim="endpointProto" class="!w-full">
<el-tag>{{ $t('setting.' + ossData.rowData!.type) }}</el-tag> <el-option label="http" value="http" />
</el-form-item> <el-option label="https" value="https" />
<el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput"> </el-select>
<el-input v-model.trim="ossData.rowData!.accessKey" /> </template>
</el-form-item> </el-input>
<el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput"> </el-form-item>
<el-input show-password clearable v-model.trim="ossData.rowData!.credential" /> <el-form-item label="Bucket" prop="bucket">
</el-form-item> <el-select @change="errBuckets = false" class="!w-4/5" v-model="ossData.rowData!.bucket">
<el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput"> <el-option v-for="item in buckets" :key="item" :value="item" />
<el-input v-model="ossData.rowData!.varsJson['endpointItem']"> </el-select>
<template #prepend> <el-button class="!w-1/5" plain @click="getBuckets(formRef)">
<el-select v-model.trim="endpointProto" style="width: 100px"> {{ $t('setting.loadBucket') }}
<el-option label="http" value="http" /> </el-button>
<el-option label="https" value="https" /> <span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-select> </el-form-item>
</template> <el-form-item :label="$t('setting.scType')" prop="varsJson.scType" :rules="[Rules.requiredSelect]">
</el-input> <el-select v-model="ossData.rowData!.varsJson['scType']">
</el-form-item> <el-option value="Standard" :label="$t('setting.scStandard')" />
<el-form-item label="Bucket" prop="bucket"> <el-option value="IA" :label="$t('setting.scStandard_IA')" />
<el-select <el-option value="Archive" :label="$t('setting.scArchive')" />
@change="errBuckets = false" <el-option value="ColdArchive" :label="$t('setting.scDeep_Archive')" />
style="width: 80%" </el-select>
v-model="ossData.rowData!.bucket" <el-alert
> v-if="ossData.rowData!.varsJson['scType'] === 'Archive' || ossData.rowData!.varsJson['scType'] === 'ColdArchive'"
<el-option v-for="item in buckets" :key="item" :value="item" /> class="mt-2.5"
</el-select> :closable="false"
<el-button style="width: 20%" plain @click="getBuckets(formRef)"> type="warning"
{{ $t('setting.loadBucket') }} :title="$t('setting.archiveHelper')"
</el-button> />
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span> </el-form-item>
</el-form-item> <el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-form-item <el-input clearable v-model.trim="ossData.rowData!.backupPath" placeholder="/1panel" />
:label="$t('setting.scType')" </el-form-item>
prop="varsJson.scType" </el-form>
:rules="[Rules.requiredSelect]" <template #footer>
> <el-button :disabled="loading" @click="handleClose">
<el-select v-model="ossData.rowData!.varsJson['scType']"> {{ $t('commons.button.cancel') }}
<el-option value="Standard" :label="$t('setting.scStandard')" /> </el-button>
<el-option value="IA" :label="$t('setting.scStandard_IA')" /> <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
<el-option value="Archive" :label="$t('setting.scArchive')" /> {{ $t('commons.button.confirm') }}
<el-option value="ColdArchive" :label="$t('setting.scDeep_Archive')" /> </el-button>
</el-select> </template>
<el-alert </DrawerPro>
v-if="ossData.rowData!.varsJson['scType'] === 'Archive' || ossData.rowData!.varsJson['scType'] === 'ColdArchive'"
style="margin-top: 10px"
:closable="false"
type="warning"
:title="$t('setting.archiveHelper')"
/>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="ossData.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -90,7 +65,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, listBucket } from '@/api/modules/setting'; import { addBackup, editBackup, listBucket } from '@/api/modules/setting';
import { deepCopy, spliceHttp, splitHttp } from '@/utils/util'; import { deepCopy, spliceHttp, splitHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,86 +1,65 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="s3Data.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + s3Data.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
size="50%" <el-input v-model.trim="s3Data.rowData!.accessKey" />
> </el-form-item>
<template #header> <el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input show-password clearable v-model.trim="s3Data.rowData!.credential" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="s3Data.rowData"> <el-form-item label="Region" prop="varsJson.region" :rules="Rules.requiredInput">
<el-row type="flex" justify="center"> <el-input pro v-model.trim="s3Data.rowData!.varsJson['region']" />
<el-col :span="22"> </el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput">
<el-tag>{{ $t('setting.' + s3Data.rowData!.type) }}</el-tag> <el-input v-model="s3Data.rowData!.varsJson['endpointItem']">
</el-form-item> <template #prepend>
<el-form-item label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput"> <el-select v-model.trim="endpointProto" class="p-w-100">
<el-input v-model.trim="s3Data.rowData!.accessKey" /> <el-option label="http" value="http" />
</el-form-item> <el-option label="https" value="https" />
<el-form-item label="Secret Key" prop="credential" :rules="Rules.requiredInput"> </el-select>
<el-input show-password clearable v-model.trim="s3Data.rowData!.credential" /> </template>
</el-form-item> </el-input>
<el-form-item label="Region" prop="varsJson.region" :rules="Rules.requiredInput"> </el-form-item>
<el-input pro v-model.trim="s3Data.rowData!.varsJson['region']" /> <el-form-item label="Bucket" prop="bucket">
</el-form-item> <el-select @change="errBuckets = false" class="!w-4/5" v-model="s3Data.rowData!.bucket">
<el-form-item label="Endpoint" prop="varsJson.endpointItem" :rules="Rules.requiredInput"> <el-option v-for="item in buckets" :key="item" :value="item" />
<el-input v-model="s3Data.rowData!.varsJson['endpointItem']"> </el-select>
<template #prepend> <el-button class="!w-1/5" plain @click="getBuckets(formRef)">
<el-select v-model.trim="endpointProto" style="width: 100px"> {{ $t('setting.loadBucket') }}
<el-option label="http" value="http" /> </el-button>
<el-option label="https" value="https" /> <span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-select> </el-form-item>
</template> <el-form-item :label="$t('setting.scType')" prop="varsJson.scType" :rules="[Rules.requiredSelect]">
</el-input> <el-select v-model="s3Data.rowData!.varsJson['scType']">
</el-form-item> <el-option value="STANDARD" :label="$t('setting.scStandard')" />
<el-form-item label="Bucket" prop="bucket"> <el-option value="STANDARD_IA" :label="$t('setting.scStandard_IA')" />
<el-select @change="errBuckets = false" style="width: 80%" v-model="s3Data.rowData!.bucket"> <el-option value="GLACIER" :label="$t('setting.scArchive')" />
<el-option v-for="item in buckets" :key="item" :value="item" /> <el-option value="DEEP_ARCHIVE" :label="$t('setting.scDeep_Archive')" />
</el-select> </el-select>
<el-button style="width: 20%" plain @click="getBuckets(formRef)"> <el-alert
{{ $t('setting.loadBucket') }} v-if="s3Data.rowData!.varsJson['scType'] === 'Archive' || s3Data.rowData!.varsJson['scType'] === 'ColdArchive'"
</el-button> class="mt-2.5"
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span> :closable="false"
</el-form-item> type="warning"
<el-form-item :title="$t('setting.archiveHelper')"
:label="$t('setting.scType')" />
prop="varsJson.scType" </el-form-item>
:rules="[Rules.requiredSelect]" <el-form-item :label="$t('setting.backupDir')" prop="backupPath">
> <el-input clearable v-model.trim="s3Data.rowData!.backupPath" placeholder="/1panel" />
<el-select v-model="s3Data.rowData!.varsJson['scType']"> </el-form-item>
<el-option value="STANDARD" :label="$t('setting.scStandard')" /> </el-form>
<el-option value="STANDARD_IA" :label="$t('setting.scStandard_IA')" /> <template #footer>
<el-option value="GLACIER" :label="$t('setting.scArchive')" /> <el-button :disabled="loading" @click="handleClose">
<el-option value="DEEP_ARCHIVE" :label="$t('setting.scDeep_Archive')" /> {{ $t('commons.button.cancel') }}
</el-select> </el-button>
<el-alert <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
v-if="s3Data.rowData!.varsJson['scType'] === 'Archive' || s3Data.rowData!.varsJson['scType'] === 'ColdArchive'" {{ $t('commons.button.confirm') }}
style="margin-top: 10px" </el-button>
:closable="false" </template>
type="warning" </DrawerPro>
:title="$t('setting.archiveHelper')"
/>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="backupPath">
<el-input clearable v-model.trim="s3Data.rowData!.backupPath" placeholder="/1panel" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -89,7 +68,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup, listBucket } from '@/api/modules/setting'; import { addBackup, editBackup, listBucket } from '@/api/modules/setting';
import { deepCopy, spliceHttp, splitHttp } from '@/utils/util'; import { deepCopy, spliceHttp, splitHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,68 +1,34 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="sftpData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + sftpData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item :label="$t('setting.address')" prop="varsJson.address" :rules="Rules.host">
size="50%" <el-input v-model.trim="sftpData.rowData!.varsJson['address']" />
> </el-form-item>
<template #header> <el-form-item :label="$t('commons.table.port')" prop="varsJson.port" :rules="[Rules.port]">
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-input-number :min="0" :max="65535" v-model.number="sftpData.rowData!.varsJson['port']" />
</template> </el-form-item>
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="sftpData.rowData"> <el-form-item :label="$t('commons.login.username')" prop="accessKey" :rules="[Rules.requiredInput]">
<el-row type="flex" justify="center"> <el-input v-model.trim="sftpData.rowData!.accessKey" />
<el-col :span="22"> </el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect"> <el-form-item :label="$t('commons.login.password')" prop="credential" :rules="[Rules.requiredInput]">
<el-tag>{{ $t('setting.' + sftpData.rowData!.type) }}</el-tag> <el-input type="password" clearable show-password v-model.trim="sftpData.rowData!.credential" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('setting.address')" prop="varsJson.address" :rules="Rules.host"> <el-form-item :label="$t('setting.backupDir')" prop="bucket" :rules="[Rules.requiredInput]">
<el-input v-model.trim="sftpData.rowData!.varsJson['address']" /> <el-input v-model.trim="sftpData.rowData!.bucket" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('commons.table.port')" prop="varsJson.port" :rules="[Rules.port]"> </el-form>
<el-input-number <template #footer>
:min="0" <el-button :disabled="loading" @click="handleClose">
:max="65535" {{ $t('commons.button.cancel') }}
v-model.number="sftpData.rowData!.varsJson['port']" </el-button>
/> <el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
</el-form-item> {{ $t('commons.button.confirm') }}
<el-form-item </el-button>
:label="$t('commons.login.username')" </template>
prop="accessKey" </DrawerPro>
:rules="[Rules.requiredInput]"
>
<el-input v-model.trim="sftpData.rowData!.accessKey" />
</el-form-item>
<el-form-item
:label="$t('commons.login.password')"
prop="credential"
:rules="[Rules.requiredInput]"
>
<el-input
type="password"
clearable
show-password
v-model.trim="sftpData.rowData!.credential"
/>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="bucket" :rules="[Rules.requiredInput]">
<el-input v-model.trim="sftpData.rowData!.bucket" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -71,7 +37,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup } from '@/api/modules/setting'; import { addBackup, editBackup } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,76 +1,37 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="title + $t('setting.backupAccount')" :back="handleClose" size="large">
<el-drawer <el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="webdavData.rowData">
v-model="drawerVisible" <el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-tag>{{ $t('setting.' + webdavData.rowData!.type) }}</el-tag>
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" <el-form-item :label="$t('setting.address')" prop="varsJson.address" :rules="Rules.requiredInput">
size="50%" <el-input v-model="webdavData.rowData!.varsJson['address']" />
> <span class="input-help">
<template #header> {{ $t('setting.WebDAVAlist') }}
<DrawerHeader :header="title + $t('setting.backupAccount')" :back="handleClose" /> <el-link style="font-size: 12px; margin-left: 5px" icon="Position" @click="toDoc()" type="primary">
</template> {{ $t('firewall.quickJump') }}
<el-form @submit.prevent ref="formRef" v-loading="loading" label-position="top" :model="webdavData.rowData"> </el-link>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('commons.table.type')" prop="type" :rules="Rules.requiredSelect">
<el-tag>{{ $t('setting.' + webdavData.rowData!.type) }}</el-tag>
</el-form-item>
<el-form-item
:label="$t('setting.address')"
prop="varsJson.address"
:rules="Rules.requiredInput"
>
<el-input v-model="webdavData.rowData!.varsJson['address']" />
<span class="input-help">
{{ $t('setting.WebDAVAlist') }}
<el-link
style="font-size: 12px; margin-left: 5px"
icon="Position"
@click="toDoc()"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</el-form-item>
<el-form-item
:label="$t('commons.login.username')"
prop="accessKey"
:rules="[Rules.requiredInput]"
>
<el-input v-model.trim="webdavData.rowData!.accessKey" />
</el-form-item>
<el-form-item
:label="$t('commons.login.password')"
prop="credential"
:rules="[Rules.requiredInput]"
>
<el-input
type="password"
clearable
show-password
v-model.trim="webdavData.rowData!.credential"
/>
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="bucket" :rules="[Rules.requiredInput]">
<el-input v-model.trim="webdavData.rowData!.bucket" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span> </span>
</template> </el-form-item>
</el-drawer> <el-form-item :label="$t('commons.login.username')" prop="accessKey" :rules="[Rules.requiredInput]">
</div> <el-input v-model.trim="webdavData.rowData!.accessKey" />
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="credential" :rules="[Rules.requiredInput]">
<el-input type="password" clearable show-password v-model.trim="webdavData.rowData!.credential" />
</el-form-item>
<el-form-item :label="$t('setting.backupDir')" prop="bucket" :rules="[Rules.requiredInput]">
<el-input v-model.trim="webdavData.rowData!.bucket" />
</el-form-item>
</el-form>
<template #footer>
<el-button :disabled="loading" @click="handleClose">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</template>
</DrawerPro>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -79,7 +40,6 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup'; import { Backup } from '@/api/interface/backup';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { addBackup, editBackup } from '@/api/modules/setting'; import { addBackup, editBackup } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';

View File

@ -1,45 +1,26 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('setting.defaultNetwork')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('setting.defaultNetwork')" prop="defaultNetwork" :rules="Rules.requiredSelect">
:destroy-on-close="true" <el-select v-model="form.defaultNetwork" filterable>
:close-on-click-modal="false" <el-option
:close-on-press-escape="false" v-for="item in netOptions"
size="30%" :key="item"
> :label="item == 'all' ? $t('commons.table.all') : item"
<template #header> :value="item"
<DrawerHeader :header="$t('setting.defaultNetwork')" :back="handleClose" /> />
</template> </el-select>
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> </el-form-item>
<el-row type="flex" justify="center"> </el-form>
<el-col :span="22"> <template #footer>
<el-form-item <span class="dialog-footer">
:label="$t('setting.defaultNetwork')" <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
prop="defaultNetwork" <el-button :disabled="loading" type="primary" @click="onSave(formRef)">
:rules="Rules.requiredSelect" {{ $t('commons.button.confirm') }}
> </el-button>
<el-select v-model="form.defaultNetwork" filterable> </span>
<el-option </template>
v-for="item in netOptions" </DrawerPro>
:key="item"
:label="item == 'all' ? $t('commons.table.all') : item"
:value="item"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
@ -48,7 +29,6 @@ import { MsgSuccess } from '@/utils/message';
import { updateSetting } from '@/api/modules/setting'; import { updateSetting } from '@/api/modules/setting';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { getNetworkOptions } from '@/api/modules/host'; import { getNetworkOptions } from '@/api/modules/host';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
const globalStore = GlobalStore(); const globalStore = GlobalStore();

View File

@ -1,20 +1,10 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('setting.advancedMenuHide')" :back="handleClose" size="small">
<el-drawer <template #content>
v-model="drawerVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('setting.advancedMenuHide')" :back="handleClose" />
</template>
<ComplexTable <ComplexTable
class="mb-5 w-full"
:data="treeData.hideMenu" :data="treeData.hideMenu"
:show-header="false" :show-header="false"
style="width: 100%; margin-bottom: 20px"
row-key="id" row-key="id"
default-expand-all default-expand-all
> >
@ -29,22 +19,20 @@
</template> </template>
</el-table-column> </el-table-column>
</ComplexTable> </ComplexTable>
</template>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="saveHideMenus"> <el-button :disabled="loading" type="primary" @click="saveHideMenus">
{{ $t('commons.button.confirm') }} {{ $t('commons.button.confirm') }}
</el-button> </el-button>
</span> </span>
</template> </template>
</el-drawer> </DrawerPro>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import i18n from '@/lang'; import i18n from '@/lang';
import { updateMenu } from '@/api/modules/setting'; import { updateMenu } from '@/api/modules/setting';

View File

@ -1,41 +1,17 @@
<template> <template>
<div> <DrawerPro v-model="drawerVisible" :header="$t('setting.title')" :back="handleClose" size="small">
<el-drawer <el-form ref="formRef" label-position="top" :model="form" :rules="rules" @submit.prevent v-loading="loading">
v-model="drawerVisible" <el-form-item :label="$t('setting.title')" prop="panelName">
:destroy-on-close="true" <el-input clearable v-model="form.panelName" />
:close-on-click-modal="false" </el-form-item>
:close-on-press-escape="false" </el-form>
size="30%" <template #footer>
> <el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<template #header> <el-button :disabled="loading" type="primary" @click="onSavePanelName(formRef)">
<DrawerHeader :header="$t('setting.title')" :back="handleClose" /> {{ $t('commons.button.confirm') }}
</template> </el-button>
<el-form </template>
ref="formRef" </DrawerPro>
label-position="top"
:model="form"
:rules="rules"
@submit.prevent
v-loading="loading"
>
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('setting.title')" prop="panelName">
<el-input clearable v-model="form.panelName" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button :disabled="loading" type="primary" @click="onSavePanelName(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, reactive, ref } from 'vue'; import { computed, reactive, ref } from 'vue';
@ -44,7 +20,6 @@ import { MsgSuccess } from '@/utils/message';
import { updateSetting } from '@/api/modules/setting'; import { updateSetting } from '@/api/modules/setting';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import DrawerHeader from '@/components/drawer-header/index.vue';
const globalStore = GlobalStore(); const globalStore = GlobalStore();
const themeConfig = computed(() => globalStore.themeConfig); const themeConfig = computed(() => globalStore.themeConfig);

Some files were not shown because too many files have changed in this diff Show More