mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-28 16:00:18 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f91db55daa |
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="submitVisible" :title="header" size="mini">
|
||||
<DialogPro v-model="submitVisible" :title="header">
|
||||
<div>
|
||||
<span v-if="operationInfo" class="operation-info">{{ operationInfo }}</span>
|
||||
<slot />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<component
|
||||
:is="drawer ? DrawerPro : DialogPro"
|
||||
v-model="open"
|
||||
v-bind="drawer ? { header: form.title, size: 'large' } : { title: form.title, size: 'small' }"
|
||||
v-bind="drawer ? { header: form.title, size: 'large' } : { title: form.title }"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div v-loading="loading" class="del-dialog-body">
|
||||
@@ -56,8 +56,8 @@ const form = reactive({
|
||||
api: null as Function,
|
||||
params: {},
|
||||
});
|
||||
const loading = ref();
|
||||
const open = ref();
|
||||
const loading = ref(false);
|
||||
const open = ref(false);
|
||||
const successMsg = ref('');
|
||||
const noMsg = ref(false);
|
||||
|
||||
@@ -68,8 +68,8 @@ interface DialogProps {
|
||||
|
||||
api: Function;
|
||||
params: object;
|
||||
successMsg: string;
|
||||
noMsg: boolean;
|
||||
successMsg?: string;
|
||||
noMsg?: boolean;
|
||||
}
|
||||
const acceptParams = (props: DialogProps): void => {
|
||||
form.title = props.title;
|
||||
@@ -78,34 +78,32 @@ const acceptParams = (props: DialogProps): void => {
|
||||
form.api = props.api;
|
||||
form.params = props.params;
|
||||
successMsg.value = props.successMsg;
|
||||
if (props.noMsg) {
|
||||
noMsg.value = props.noMsg;
|
||||
}
|
||||
noMsg.value = props.noMsg ?? false;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const emit = defineEmits(['search', 'cancel', 'submit']);
|
||||
|
||||
const onConfirm = async () => {
|
||||
if (loading.value) return;
|
||||
if (form.api === null) {
|
||||
emit('submit');
|
||||
open.value = false;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
await form
|
||||
.api(form.params)
|
||||
.then(() => {
|
||||
try {
|
||||
await form.api(form.params);
|
||||
emit('search');
|
||||
if (!noMsg.value) {
|
||||
MsgSuccess(successMsg.value ?? i18n.global.t('commons.msg.deleteSuccess'));
|
||||
}
|
||||
open.value = false;
|
||||
} catch {
|
||||
// API errors are reported by the request interceptor; keep the dialog open for retry.
|
||||
} finally {
|
||||
loading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:show-close="showClose"
|
||||
:width="size"
|
||||
:width="width"
|
||||
:class="{ 'dialog-full-width': props.size === 'full', 'dialog-sized': !!props.size && props.size !== 'full' }"
|
||||
append-to-body
|
||||
draggable
|
||||
:open="open"
|
||||
@open="open"
|
||||
@opened="opened"
|
||||
:before-close="handleBeforeClose"
|
||||
>
|
||||
@@ -46,7 +47,7 @@ const props = defineProps({
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'normal',
|
||||
default: '',
|
||||
},
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
@@ -54,33 +55,23 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
// Explicit sizes preserve layouts such as imports; unspecified dialogs use the shared width.
|
||||
const widths: Record<string, string> = {
|
||||
mini: '20%',
|
||||
small: '30%',
|
||||
normal: '40%',
|
||||
large: '50%',
|
||||
full: '100%',
|
||||
'w-60': '60%',
|
||||
'w-70': '70%',
|
||||
'w-90': '90%',
|
||||
};
|
||||
const width = computed(() => (props.size ? (widths[props.size] ?? '50%') : undefined));
|
||||
|
||||
const slots = useSlots();
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'close', 'open', 'opened']);
|
||||
|
||||
const size = computed(() => {
|
||||
switch (props.size) {
|
||||
case 'mini':
|
||||
return '20%';
|
||||
case 'small':
|
||||
return '30%';
|
||||
case 'normal':
|
||||
return '40%';
|
||||
case 'large':
|
||||
return '50%';
|
||||
case 'full':
|
||||
return '100%';
|
||||
case 'w-60':
|
||||
return '60%';
|
||||
case 'w-70':
|
||||
return '70%';
|
||||
case 'w-90':
|
||||
return '90%';
|
||||
default:
|
||||
return '50%';
|
||||
}
|
||||
});
|
||||
|
||||
const dialogVisible = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.msg.infoTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.msg.infoTitle')">
|
||||
<el-form ref="formRef" label-position="top" @submit.prevent>
|
||||
<el-form-item :label="$t('xpack.node.syncProxyHelper')">
|
||||
<el-radio-group v-model="restart">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" size="small">
|
||||
<DialogPro v-model="open">
|
||||
<el-form ref="formRef" label-position="top" @submit.prevent>
|
||||
<el-form-item :label="title">
|
||||
<el-radio-group v-model="restart">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<DialogPro v-model="dialogVisible" :title="$t('file.existFileTitle')" size="normal">
|
||||
<DialogPro v-model="dialogVisible" :title="$t('file.existFileTitle')">
|
||||
<el-alert :show-icon="true" type="warning" :closable="false">
|
||||
<div class="whitespace-break-spaces">
|
||||
<span>{{ $t('file.existFileHelper') }}</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro :title="$t('file.list')" size="w-60" v-model="open" @close="handleClose">
|
||||
<DialogPro :title="$t('file.list')" v-model="open" @close="handleClose">
|
||||
<div>
|
||||
<div
|
||||
v-show="!searchableStatus"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<DialogPro v-model="open" class="level-up-pro" @close="handleClose">
|
||||
<DialogPro size="normal" v-model="open" class="level-up-pro" @close="handleClose">
|
||||
<div style="text-align: center" v-loading="loading">
|
||||
<span class="text-3xl font-medium title">
|
||||
{{ $t('license.importLicense') }}
|
||||
|
||||
@@ -32,12 +32,7 @@
|
||||
<div class="log-container" :style="styleVars">
|
||||
<div class="xterm-log-viewer" ref="terminalElement"></div>
|
||||
</div>
|
||||
<DialogPro
|
||||
v-model="downloadDialogVisible"
|
||||
:title="$t('commons.button.download')"
|
||||
size="small"
|
||||
:close-on-click-modal="true"
|
||||
>
|
||||
<DialogPro v-model="downloadDialogVisible" :title="$t('commons.button.download')" :close-on-click-modal="true">
|
||||
<el-form label-position="top">
|
||||
<el-form-item :label="$t('container.fetch')">
|
||||
<el-select v-model="downloadForm.mode" class="w-full">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<el-alert :closable="false" :title="$t('setting.systemIPWarning')" type="info">
|
||||
<el-link icon="Position" @click="jumpToPath(router, '/settings/panel')" type="primary">
|
||||
{{ $t('firewall.quickJump') }}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
v-if="isAdmin"
|
||||
v-model="open"
|
||||
:title="$t('menu.terminal')"
|
||||
size="w-70"
|
||||
:show-close="false"
|
||||
:modal="false"
|
||||
modal-penetrable
|
||||
|
||||
@@ -205,12 +205,7 @@
|
||||
</template>
|
||||
</DialogPro>
|
||||
|
||||
<DialogPro
|
||||
v-model="passkeyPrereqDialogOpen"
|
||||
:title="$t('setting.passkey')"
|
||||
size="small"
|
||||
@close="handlePasskeyPrereqDialogClose"
|
||||
>
|
||||
<DialogPro v-model="passkeyPrereqDialogOpen" :title="$t('setting.passkey')" @close="handlePasskeyPrereqDialogClose">
|
||||
<div class="passkey-prereq-dialog">
|
||||
<div class="passkey-prereq-title">{{ $t('setting.passkeyPrereqTitle') }}</div>
|
||||
<div class="passkey-prereq-list">
|
||||
|
||||
@@ -413,3 +413,11 @@ html {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Standard dialogs share one width; explicitly sized dialogs keep their layout.
|
||||
.el-dialog:not(.is-fullscreen):not(.dialog-full-width):not(.dialog-sized),
|
||||
.el-message-box {
|
||||
width: 60vw !important;
|
||||
min-width: 0;
|
||||
max-width: 60vw;
|
||||
}
|
||||
|
||||
@@ -84,9 +84,12 @@
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
.el-dialog.dialog-sized:not(.is-fullscreen) {
|
||||
min-width: min(420px, calc(100vw - 24px));
|
||||
max-width: calc(100vw - 24px);
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
max-height: calc(100vh - 24px);
|
||||
max-height: calc(100dvh - 24px);
|
||||
display: flex;
|
||||
@@ -133,10 +136,13 @@
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
.el-dialog.dialog-sized:not(.is-fullscreen) {
|
||||
width: calc(100vw - 24px) !important;
|
||||
min-width: 0;
|
||||
max-width: calc(100vw - 24px);
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin: 12px auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ElMessageBox, type ElMessageBoxOptions } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
|
||||
// Keep cancellation as a rejection and leave the business operation to the caller.
|
||||
export const confirmAction = (message: string, title: string, options: ElMessageBoxOptions = {}) => {
|
||||
return ElMessageBox.confirm(message, title, {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
...options,
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
// Wait for every request, keeping at most four deletions in flight. Return only
|
||||
// failed items so a retry cannot delete an already-removed item a second time.
|
||||
export async function deleteFilesWithLimit<T>(
|
||||
items: readonly T[],
|
||||
remove: (item: T) => Promise<unknown>,
|
||||
): Promise<T[]> {
|
||||
let next = 0;
|
||||
const failed = new Set<number>();
|
||||
const worker = async () => {
|
||||
while (next < items.length) {
|
||||
const index = next++;
|
||||
try {
|
||||
await remove(items[index]);
|
||||
} catch {
|
||||
failed.add(index);
|
||||
}
|
||||
}
|
||||
};
|
||||
await Promise.all(Array.from({ length: Math.min(4, items.length) }, worker));
|
||||
return items.filter((_, index) => failed.has(index));
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="header" size="w-60" @close="handleClose">
|
||||
<DialogPro v-model="open" :title="header" @close="handleClose">
|
||||
<div v-loading="loading" class="agent-file-drawer">
|
||||
<el-alert v-if="!agentId || !workspace" :title="$t('commons.msg.noneData')" type="info" :closable="false" />
|
||||
<template v-else>
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:title="$t('commons.button.delete') + ' - ' + agentName"
|
||||
size="small"
|
||||
@close="handleClose"
|
||||
>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + agentName" @close="handleClose">
|
||||
<el-form ref="deleteForm" label-position="left" v-loading="loading">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('website.forceDelete')" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="submitVisible">
|
||||
<DialogPro size="normal" v-model="submitVisible">
|
||||
<template #header>
|
||||
{{ $t('aiTools.mcp.importMcpJson') }}
|
||||
</template>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import type { FormInstance } from 'element-plus';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { confirmAction } from '@/utils/confirm';
|
||||
import {
|
||||
createAgentAccountModel,
|
||||
deleteAgentAccountModel,
|
||||
@@ -180,13 +180,9 @@ const submit = async () => {
|
||||
};
|
||||
|
||||
const onDelete = async (row: AI.AgentAccountModel) => {
|
||||
await ElMessageBox.confirm(
|
||||
await confirmAction(
|
||||
i18n.global.t('commons.msg.delete', [row.name || row.id]),
|
||||
i18n.global.t('commons.button.delete'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
},
|
||||
);
|
||||
await deleteAgentAccountModel({
|
||||
accountId: account.id,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('app.composeDiff')" @close="handleClose" size="w-90">
|
||||
<DialogPro v-model="open" :title="$t('app.composeDiff')" @close="handleClose">
|
||||
<div>
|
||||
<el-text type="warning">{{ $t('app.diffHelper') }}</el-text>
|
||||
<div ref="container" class="compose-diff"></div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + composeName" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + composeName">
|
||||
<el-form ref="deleteForm" v-loading="loading">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteFile" :label="$t('container.deleteFile')" />
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
</template>
|
||||
</DrawerPro>
|
||||
<FileUpload ref="uploadRef" @close="loadContainerFiles" />
|
||||
<DialogPro v-model="previewVisible" :title="previewTitle" size="w-70" :close-on-click-modal="true">
|
||||
<DialogPro v-model="previewVisible" :title="previewTitle" :close-on-click-modal="true">
|
||||
<el-alert
|
||||
v-if="previewTruncated"
|
||||
:title="$t('file.previewTruncated')"
|
||||
|
||||
@@ -407,11 +407,7 @@
|
||||
</ComplexTable>
|
||||
</template>
|
||||
|
||||
<DialogPro
|
||||
v-model="portsDialogVisible"
|
||||
:title="`${$t('commons.table.port')} - ${portsDialogContainer}`"
|
||||
size="small"
|
||||
>
|
||||
<DialogPro v-model="portsDialogVisible" :title="`${$t('commons.table.port')} - ${portsDialogContainer}`">
|
||||
<template #content>
|
||||
<div class="container-port-dialog-filters">
|
||||
<el-input v-model="portFilter" clearable :placeholder="$t('commons.button.search')" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.edit')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.edit')">
|
||||
<div v-if="isFromApp" class="leading-6">
|
||||
<div>
|
||||
<span>{{ $t('container.updateHelper1') }}</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('container.containerPrune')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('container.containerPrune')">
|
||||
<div>
|
||||
<ul class="help-ul">
|
||||
<li class="lineClass" style="color: red">{{ $t('container.containerPruneHelper1') }}</li>
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('container.iptablesDisable')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('container.iptablesDisable')">
|
||||
<div class="mt-2.5">
|
||||
<span class="text-rose-500">{{ $t('container.iptablesHelper2') }}</span>
|
||||
<div class="mt-2.5">
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('commons.button.clean')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.clean')">
|
||||
<el-form ref="deleteForm" label-position="left" v-loading="delLoading">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
|
||||
|
||||
+11
-13
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('database.unBindRemoteDB') + ' - ' + deleteReq.database" size="small">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<DialogPro v-model="open" :title="$t('database.unBindRemoteDB') + ' - ' + deleteReq.database">
|
||||
<el-form v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
@@ -21,7 +21,7 @@
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
<el-button type="primary" @click="submit" :loading="loading" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@@ -30,7 +30,6 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { deleteDatabase } from '@/api/modules/database';
|
||||
@@ -45,8 +44,6 @@ const deleteReq = ref({
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
const deleteForm = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
database: string;
|
||||
@@ -54,7 +51,7 @@ interface DialogProps {
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
const acceptParams = (prop: DialogProps) => {
|
||||
deleteReq.value = {
|
||||
id: prop.id,
|
||||
database: prop.database,
|
||||
@@ -65,17 +62,18 @@ const acceptParams = async (prop: DialogProps) => {
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
deleteDatabase(deleteReq.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
try {
|
||||
await deleteDatabase(deleteReq.value);
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
} catch {
|
||||
// The request interceptor reports failures; allow retry without losing the selection.
|
||||
} finally {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
</template>
|
||||
</DrawerPro>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<div class="flex justify-center items-center gap-2 flex-wrap">
|
||||
{{ $t('app.checkInstalledWarn', [dashboardName]) }}
|
||||
<el-link icon="Position" type="primary" @click="getAppDetail">
|
||||
|
||||
@@ -81,7 +81,7 @@ import { toRef, onMounted, reactive, ref } from 'vue';
|
||||
import { deleteCheckDatabase, searchDatabases } from '@/api/modules/database';
|
||||
import AppResources from '@/views/database/postgresql/check/index.vue';
|
||||
import OperateDialog from '@/views/database/mongodb/remote/operate/index.vue';
|
||||
import DeleteDialog from '@/views/database/mongodb/remote/delete/index.vue';
|
||||
import DeleteDialog from '@/views/database/components/remote-delete/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { Database } from '@/api/interface/database';
|
||||
|
||||
|
||||
@@ -60,12 +60,7 @@
|
||||
</template>
|
||||
</DialogPro>
|
||||
|
||||
<DialogPro
|
||||
v-if="!props.viewOnly"
|
||||
v-model="addDialogVisible"
|
||||
:title="$t('database.addUserAuthorization')"
|
||||
size="small"
|
||||
>
|
||||
<DialogPro v-if="!props.viewOnly" v-model="addDialogVisible" :title="$t('database.addUserAuthorization')">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" v-loading="loading">
|
||||
<el-form-item :label="$t('commons.table.type')" prop="mode">
|
||||
<el-radio-group v-model="form.mode" @change="changeMode">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
</span>
|
||||
</el-card>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<div class="flex justify-center items-center gap-2 flex-wrap">
|
||||
{{ $t('app.checkInstalledWarn', [dashboardName]) }}
|
||||
<el-link icon="Position" @click="getAppDetail" type="primary">
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('database.unBindRemoteDB') + ' - ' + deleteMysqlReq.database" size="small">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteMysqlReq.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.unBindForceHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteMysqlReq.deleteBackup" :label="$t('app.deleteBackup')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.deleteBackupHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<span style="font-size: 12px">{{ $t('database.unBindRemoteHelper') }}</span>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</DialogPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { deleteDatabase } from '@/api/modules/database';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
let deleteMysqlReq = ref({
|
||||
id: 0,
|
||||
database: '',
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
});
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
|
||||
const deleteForm = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
database: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
deleteMysqlReq.value = {
|
||||
id: prop.id,
|
||||
database: prop.database,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
};
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
deleteDatabase(deleteMysqlReq.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
@@ -80,7 +80,7 @@ import { toRef, onMounted, reactive, ref } from 'vue';
|
||||
import { deleteCheckDatabase, searchDatabases } from '@/api/modules/database';
|
||||
import AppResources from '@/views/database/mysql/check/index.vue';
|
||||
import OperateDialog from '@/views/database/mysql/remote/operate/index.vue';
|
||||
import DeleteDialog from '@/views/database/mysql/remote/delete/index.vue';
|
||||
import DeleteDialog from '@/views/database/components/remote-delete/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { Database } from '@/api/interface/database';
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<el-alert :closable="false" :title="$t('database.confNotFound')" type="info">
|
||||
<el-link icon="Position" @click="goUpgrade()" type="primary">
|
||||
{{ $t('database.goUpgrade') }}
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
</ComplexTable>
|
||||
</DrawerPro>
|
||||
|
||||
<DialogPro v-model="userDialogVisible" :title="userDialogTitle" size="small">
|
||||
<DialogPro v-model="userDialogVisible" :title="userDialogTitle">
|
||||
<el-form ref="userFormRef" :model="userForm" :rules="userRules" label-position="top" v-loading="loading">
|
||||
<el-form-item :label="$t('commons.login.username')" prop="username">
|
||||
<el-input v-model.trim="userForm.username" :disabled="userDialogMode === 'edit'" />
|
||||
@@ -133,7 +133,7 @@
|
||||
</template>
|
||||
</DialogPro>
|
||||
|
||||
<DialogPro v-model="supplementDialogVisible" :title="$t('database.supplementPassword')" size="small">
|
||||
<DialogPro v-model="supplementDialogVisible" :title="$t('database.supplementPassword')">
|
||||
<el-form
|
||||
ref="supplementFormRef"
|
||||
:model="supplementForm"
|
||||
@@ -159,11 +159,7 @@
|
||||
</template>
|
||||
</DialogPro>
|
||||
|
||||
<DialogPro
|
||||
v-model="deleteDialogVisible"
|
||||
:title="$t('commons.button.delete') + ' - ' + deleteUserIdentity"
|
||||
size="small"
|
||||
>
|
||||
<DialogPro v-model="deleteDialogVisible" :title="$t('commons.button.delete') + ' - ' + deleteUserIdentity">
|
||||
<div v-loading="loading">
|
||||
<div class="delete-user-title">{{ deleteUserIdentity }} {{ $t('database.userBoundDatabases') }}</div>
|
||||
<div class="delete-user-section">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName" size="small">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + dbName">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
|
||||
|
||||
@@ -210,7 +210,7 @@
|
||||
<span>{{ $t('commons.service.serviceNotStarted', ['PostgreSQL']) }}</span>
|
||||
</el-card>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<div class="flex justify-center items-center gap-2 flex-wrap">
|
||||
{{ $t('app.checkInstalledWarn', [dashboardName]) }}
|
||||
<el-link icon="Position" @click="getAppDetail" type="primary">
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('database.unBindRemoteDB') + ' - ' + deleteReq.database" size="small">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.unBindForceHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('app.deleteBackup')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.deleteBackupHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<span style="font-size: 12px">{{ $t('database.unBindRemoteHelper') }}</span>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</DialogPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { deleteDatabase } from '@/api/modules/database';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
let deleteReq = ref({
|
||||
id: 0,
|
||||
database: '',
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
});
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
|
||||
const deleteForm = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
database: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
deleteReq.value = {
|
||||
id: prop.id,
|
||||
database: prop.database,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
};
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
deleteDatabase(deleteReq.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
@@ -80,7 +80,7 @@ import { toRef, onMounted, reactive, ref } from 'vue';
|
||||
import { deleteCheckDatabase, searchDatabases } from '@/api/modules/database';
|
||||
import AppResources from '@/views/database/postgresql/check/index.vue';
|
||||
import OperateDialog from '@/views/database/postgresql/remote/operate/index.vue';
|
||||
import DeleteDialog from '@/views/database/postgresql/remote/delete/index.vue';
|
||||
import DeleteDialog from '@/views/database/components/remote-delete/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { Database } from '@/api/interface/database';
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<el-alert :closable="false" :title="$t('database.confNotFound')" type="info">
|
||||
<el-link icon="Position" @click="goUpgrade()" type="primary">
|
||||
{{ $t('database.goUpgrade') }}
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<Setting ref="settingRef" style="margin-top: 30px" />
|
||||
<Conn ref="connRef" @check-exist="reOpenTerminal" @close-terminal="closeTerminal(true)" />
|
||||
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('app.checkTitle')">
|
||||
<div class="flex justify-center items-center gap-2 flex-wrap">
|
||||
{{ $t('app.checkInstalledWarn', ['Redis-Commander']) }}
|
||||
<el-link icon="Position" @click="getAppDetail('redis-commander')" type="primary">
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('database.unBindRemoteDB') + ' - ' + deleteMysqlReq.database" size="small">
|
||||
<el-form ref="deleteForm" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteMysqlReq.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.unBindForceHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteMysqlReq.deleteBackup" :label="$t('app.deleteBackup')" />
|
||||
<span class="input-help">
|
||||
{{ $t('database.deleteBackupHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<span style="font-size: 12px">{{ $t('database.unBindRemoteHelper') }}</span>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</DialogPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { deleteDatabase } from '@/api/modules/database';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
let deleteMysqlReq = ref({
|
||||
id: 0,
|
||||
database: '',
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
});
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
|
||||
const deleteForm = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
database: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
deleteMysqlReq.value = {
|
||||
id: prop.id,
|
||||
database: prop.database,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
};
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
deleteDatabase(deleteMysqlReq.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
@@ -79,7 +79,7 @@ import { toRef, onMounted, reactive, ref } from 'vue';
|
||||
import { deleteCheckDatabase, searchDatabases } from '@/api/modules/database';
|
||||
import AppResources from '@/views/database/redis/check/index.vue';
|
||||
import OperateDialog from '@/views/database/redis/remote/operate/index.vue';
|
||||
import DeleteDialog from '@/views/database/redis/remote/delete/index.vue';
|
||||
import DeleteDialog from '@/views/database/components/remote-delete/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { Database } from '@/api/interface/database';
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@
|
||||
|
||||
<QuickJump @search="onLoadBaseInfo(false, 'all')" ref="quickJumpRef" />
|
||||
|
||||
<DialogPro v-model="welcomeOpen" size="w-70" id="welcomeDialog">
|
||||
<DialogPro v-model="welcomeOpen" id="welcomeDialog">
|
||||
<div ref="shadowContainer" />
|
||||
</DialogPro>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:size="isMobile ? 'full' : 'w-70'"
|
||||
:size="isMobile ? 'full' : undefined"
|
||||
class="code-dialog !p-0"
|
||||
@opened="onOpen"
|
||||
:show-close="false"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="delete-file-list">
|
||||
<div class="flx-align-center mb-1" v-for="(file, index) in files" :key="index">
|
||||
<svg-icon
|
||||
className="table-icon mr-1"
|
||||
:iconName="file.isDir ? 'p-file-folder' : getIcon(file.extension || '')"
|
||||
/>
|
||||
<span class="sle">{{ file.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIcon } from '@/utils/file';
|
||||
|
||||
defineProps<{ files: { name: string; isDir: boolean; extension?: string }[] }>();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.delete-file-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete')" size="small">
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:title="$t('commons.button.delete')"
|
||||
:show-close="!loading"
|
||||
:close-on-press-escape="!loading"
|
||||
>
|
||||
<div v-loading="loading">
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
@@ -20,23 +25,7 @@
|
||||
</el-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="file-list">
|
||||
<div class="flx-align-center mb-1" v-for="(row, index) in files" :key="index">
|
||||
<div>
|
||||
<svg-icon
|
||||
v-if="row.isDir"
|
||||
className="table-icon mr-1 "
|
||||
iconName="p-file-folder"
|
||||
></svg-icon>
|
||||
<svg-icon
|
||||
v-else
|
||||
className="table-icon mr-1"
|
||||
:iconName="getIconName(row.extension)"
|
||||
></svg-icon>
|
||||
</div>
|
||||
<span class="sle">{{ row.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<DeleteFileList :files="files" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@@ -57,26 +46,27 @@
|
||||
import i18n from '@/lang';
|
||||
import { ref } from 'vue';
|
||||
import { File } from '@/api/interface/file';
|
||||
import { getIcon } from '@/utils/file';
|
||||
import DeleteFileList from '../components/delete-file-list.vue';
|
||||
import { deleteFilesWithLimit } from '@/utils/file-delete';
|
||||
import { deleteFile, deleteFileByNode, getRecycleStatus, getRecycleStatusByNode } from '@/api/modules/files';
|
||||
import { MsgSuccess, MsgWarning } from '@/utils/message';
|
||||
import { loadBaseDir } from '@/api/modules/setting';
|
||||
|
||||
const open = ref(false);
|
||||
const files = ref();
|
||||
const files = ref<File.File[]>([]);
|
||||
const loading = ref(false);
|
||||
const em = defineEmits(['close']);
|
||||
const forceDelete = ref(false);
|
||||
const recycleStatus = ref('Enable');
|
||||
const reqNode = ref('');
|
||||
|
||||
const acceptParams = (props: File.File[], node: string) => {
|
||||
const acceptParams = (props: File.File[], node = '') => {
|
||||
reqNode.value = '';
|
||||
if (node != '') {
|
||||
reqNode.value = node;
|
||||
}
|
||||
getStatus();
|
||||
files.value = props;
|
||||
files.value = [...props];
|
||||
open.value = true;
|
||||
forceDelete.value = false;
|
||||
};
|
||||
@@ -101,67 +91,51 @@ const getStatus = async () => {
|
||||
};
|
||||
|
||||
const onConfirm = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
const selected = [...files.value];
|
||||
const node = reqNode.value;
|
||||
const force = forceDelete.value;
|
||||
try {
|
||||
const pros = [];
|
||||
let baseDir = '';
|
||||
if (files.value.some((item) => item['isDir'])) {
|
||||
if (selected.some((item) => item.isDir)) {
|
||||
const pathRes = await loadBaseDir();
|
||||
baseDir = pathRes.data;
|
||||
}
|
||||
for (const s of files.value) {
|
||||
if (s['isDir']) {
|
||||
if (s['path'].indexOf('.1panel_clash') > -1) {
|
||||
// Validate the entire selection before starting any deletion request.
|
||||
for (const file of selected) {
|
||||
if (!file.isDir) continue;
|
||||
if (file.path.includes('.1panel_clash')) {
|
||||
MsgWarning(i18n.global.t('file.clashDeleteAlert'));
|
||||
return;
|
||||
}
|
||||
if (s['path'] === baseDir) {
|
||||
if (file.path === baseDir) {
|
||||
MsgWarning(i18n.global.t('file.panelInstallDir'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (reqNode.value != '') {
|
||||
pros.push(
|
||||
deleteFileByNode(
|
||||
{ path: s['path'], isDir: s['isDir'], forceDelete: forceDelete.value },
|
||||
reqNode.value,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
pros.push(deleteFile({ path: s['path'], isDir: s['isDir'], forceDelete: forceDelete.value }));
|
||||
}
|
||||
}
|
||||
await Promise.all(pros);
|
||||
files.value = await deleteFilesWithLimit(selected, (file) => {
|
||||
const params = { path: file.path, isDir: file.isDir, forceDelete: force };
|
||||
return node ? deleteFileByNode(params, node) : deleteFile(params);
|
||||
});
|
||||
if (files.value.length === 0) {
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
em('close');
|
||||
}
|
||||
if (files.value.length < selected.length) em('close');
|
||||
} catch {
|
||||
// The request interceptor reports errors such as a failed base-directory lookup.
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const getIconName = (extension: string) => {
|
||||
return getIcon(extension);
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.resource {
|
||||
margin-top: 10px;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.file-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.delete-warn {
|
||||
line-height: 20px;
|
||||
word-wrap: break-word;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('file.downloadProcess')" size="small" @close="handleClose">
|
||||
<DialogPro v-model="open" :title="$t('file.downloadProcess')" @close="handleClose">
|
||||
<template #content>
|
||||
<div v-loading="loading" class="space-y-4 p-4 min-h-[160px]">
|
||||
<div
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete')" size="small">
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:title="$t('commons.button.delete')"
|
||||
:show-close="!loading"
|
||||
:close-on-press-escape="!loading"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-alert :title="$t('file.deleteRecycleHelper')" show-icon type="error" :closable="false"></el-alert>
|
||||
<div class="flx-align-center mb-1 mt-1" v-for="(row, index) in files" :key="index">
|
||||
<div>
|
||||
<svg-icon v-if="row.isDir" className="table-icon mr-1 " iconName="p-file-folder"></svg-icon>
|
||||
<svg-icon v-else className="table-icon mr-1" :iconName="getIconName(row.extension)"></svg-icon>
|
||||
</div>
|
||||
<span class="sle">{{ row.name }}</span>
|
||||
</div>
|
||||
<DeleteFileList :files="files" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -18,7 +17,7 @@
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="onConfirm" v-loading="loading">
|
||||
<el-button type="primary" @click="onConfirm" :loading="loading" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@@ -29,52 +28,40 @@
|
||||
import i18n from '@/lang';
|
||||
import { ref } from 'vue';
|
||||
import { File } from '@/api/interface/file';
|
||||
import { getIcon } from '@/utils/file';
|
||||
import DeleteFileList from '../../components/delete-file-list.vue';
|
||||
import { deleteFilesWithLimit } from '@/utils/file-delete';
|
||||
import { deleteFile } from '@/api/modules/files';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const open = ref(false);
|
||||
const files = ref();
|
||||
const files = ref<File.RecycleBin[]>([]);
|
||||
const loading = ref(false);
|
||||
const em = defineEmits(['close']);
|
||||
const forceDelete = ref(false);
|
||||
|
||||
const acceptParams = (props: File.RecycleBin[]) => {
|
||||
files.value = props;
|
||||
files.value = [...props];
|
||||
open.value = true;
|
||||
forceDelete.value = false;
|
||||
};
|
||||
|
||||
const onConfirm = () => {
|
||||
const pros = [];
|
||||
for (const s of files.value) {
|
||||
pros.push(deleteFile({ path: s.from + '/' + s.rName, isDir: s.isDir, forceDelete: true }));
|
||||
}
|
||||
const onConfirm = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
Promise.all(pros)
|
||||
.then(() => {
|
||||
const selected = [...files.value];
|
||||
try {
|
||||
files.value = await deleteFilesWithLimit(selected, (file) =>
|
||||
deleteFile({ path: file.from + '/' + file.rName, isDir: file.isDir, forceDelete: true }),
|
||||
);
|
||||
if (files.value.length === 0) {
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
em('close');
|
||||
})
|
||||
.finally(() => {
|
||||
}
|
||||
if (files.value.length < selected.length) em('close');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const getIconName = (extension: string) => {
|
||||
return getIcon(extension);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.resource {
|
||||
margin-top: 10px;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('file.reduce')" size="small">
|
||||
<DialogPro v-model="open" :title="$t('file.reduce')">
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-alert :title="$t('file.confirmReduce')" show-icon type="error" :closable="false"></el-alert>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</span>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
<DialogPro v-model="qrDialogOpen" :title="$t('file.shareQrDialogTitle')" size="small">
|
||||
<DialogPro v-model="qrDialogOpen" :title="$t('file.shareQrDialogTitle')">
|
||||
<div class="share-qr-dialog">
|
||||
<div class="share-qr-title">{{ $t('file.shareQrDialogTitle') }}</div>
|
||||
<img v-if="qrCodeUrl" class="share-qr-image" :src="qrCodeUrl" :alt="$t('file.shareQrCode')" />
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DialogPro v-model="open" :title="$t('commons.button.export')" size="mini">
|
||||
<DialogPro v-model="open" :title="$t('commons.button.export')">
|
||||
<el-form class="mt-5" ref="backupForm" @submit.prevent v-loading="loading">
|
||||
<el-form-item :label="$t('commons.table.status')">
|
||||
<el-select v-model="exportConfig.status" class="w-full">
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</template>
|
||||
</DrawerPro>
|
||||
|
||||
<DialogPro v-model="connOpen" :title="$t('ssh.pubkey')" size="small" :showClose="false">
|
||||
<DialogPro v-model="connOpen" :title="$t('ssh.pubkey')" :showClose="false">
|
||||
<el-descriptions class="margin-top" :column="1" border>
|
||||
<el-descriptions-item align="center" :label="$t('ssh.password')">
|
||||
<div>
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:title="$t('commons.button.delete') + ' - ' + resourceName"
|
||||
size="small"
|
||||
@close="handleClose"
|
||||
>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete') + ' - ' + resourceName" @close="handleClose">
|
||||
<div :key="key" :loading="loading">
|
||||
<el-form ref="deleteForm" label-position="left">
|
||||
<el-form-item>
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<DialogPro
|
||||
v-model="open"
|
||||
:title="$t('commons.button.' + operate) + $t('php.extensions')"
|
||||
size="small"
|
||||
@close="handleClose"
|
||||
>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.' + operate) + $t('php.extensions')" @close="handleClose">
|
||||
<el-row v-loading="loading">
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-form @submit.prevent ref="extensionsForm" label-position="top" :model="extensions" :rules="rules">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('ssl.apply')" size="small" @close="handleClose">
|
||||
<DialogPro v-model="open" :title="$t('ssl.apply')" @close="handleClose">
|
||||
<div class="text-center" v-loading="loading">
|
||||
<div v-if="ssl.websites && ssl.websites.length > 0">
|
||||
<span>{{ $t('ssl.renewWebsite') }}</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('website.delete') + ' - ' + websiteName" size="small" @close="handleClose">
|
||||
<DialogPro v-model="open" :title="$t('website.delete') + ' - ' + websiteName" @close="handleClose">
|
||||
<div :key="key" v-loading="loading">
|
||||
<el-form ref="deleteForm" label-position="left">
|
||||
<el-form-item>
|
||||
|
||||
Reference in New Issue
Block a user