119 lines
2.7 KiB
Vue
119 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { $t } from '@/locales';
|
|
|
|
defineOptions({
|
|
name: 'BusinessFormDialog',
|
|
inheritAttrs: false
|
|
});
|
|
|
|
type DialogPreset = 'sm' | 'md' | 'lg';
|
|
|
|
interface Props {
|
|
title: string;
|
|
preset?: DialogPreset;
|
|
width?: string | number;
|
|
loading?: boolean;
|
|
confirmLoading?: boolean;
|
|
confirmDisabled?: boolean;
|
|
showFooter?: boolean;
|
|
scrollbar?: boolean;
|
|
maxBodyHeight?: string | number;
|
|
cancelText?: string;
|
|
confirmText?: string;
|
|
}
|
|
|
|
interface Emits {
|
|
(e: 'cancel'): void;
|
|
(e: 'confirm'): void;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
preset: 'md',
|
|
width: undefined,
|
|
loading: false,
|
|
confirmLoading: false,
|
|
confirmDisabled: false,
|
|
showFooter: true,
|
|
scrollbar: true,
|
|
maxBodyHeight: '70vh',
|
|
cancelText: '',
|
|
confirmText: ''
|
|
});
|
|
|
|
const emit = defineEmits<Emits>();
|
|
|
|
const visible = defineModel<boolean>({
|
|
default: false
|
|
});
|
|
|
|
const DIALOG_WIDTH_MAP: Record<DialogPreset, string> = {
|
|
sm: '520px',
|
|
md: '720px',
|
|
lg: '960px'
|
|
};
|
|
|
|
const dialogWidth = computed(() => props.width ?? DIALOG_WIDTH_MAP[props.preset]);
|
|
|
|
const resolvedCancelText = computed(() => props.cancelText || $t('common.cancel'));
|
|
const resolvedConfirmText = computed(() => props.confirmText || $t('common.confirm'));
|
|
|
|
function handleCancel() {
|
|
visible.value = false;
|
|
emit('cancel');
|
|
}
|
|
|
|
function handleConfirm() {
|
|
emit('confirm');
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<ElDialog
|
|
v-model="visible"
|
|
class="business-form-dialog"
|
|
:title="props.title"
|
|
:width="dialogWidth"
|
|
:close-on-click-modal="false"
|
|
destroy-on-close
|
|
align-center
|
|
header-class="business-form-dialog__header"
|
|
body-class="business-form-dialog__body"
|
|
footer-class="business-form-dialog__footer"
|
|
v-bind="$attrs"
|
|
>
|
|
<ElScrollbar
|
|
v-if="props.scrollbar"
|
|
:max-height="props.maxBodyHeight"
|
|
class="business-form-dialog__scrollbar"
|
|
view-class="business-form-dialog__scrollbar-view"
|
|
>
|
|
<div v-loading="props.loading" class="business-form-dialog__content">
|
|
<slot />
|
|
</div>
|
|
</ElScrollbar>
|
|
|
|
<div v-else v-loading="props.loading" class="business-form-dialog__content">
|
|
<slot />
|
|
</div>
|
|
|
|
<template v-if="props.showFooter" #footer>
|
|
<slot name="footer" :close="handleCancel">
|
|
<ElSpace :size="16">
|
|
<ElButton @click="handleCancel">{{ resolvedCancelText }}</ElButton>
|
|
<ElButton
|
|
type="primary"
|
|
:loading="props.confirmLoading"
|
|
:disabled="props.confirmDisabled"
|
|
@click="handleConfirm"
|
|
>
|
|
{{ resolvedConfirmText }}
|
|
</ElButton>
|
|
</ElSpace>
|
|
</slot>
|
|
</template>
|
|
</ElDialog>
|
|
</template>
|
|
|
|
<style scoped></style>
|