Files
cn-rdms-web/src/components/custom/business-form-dialog.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>