| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- <script setup lang="ts">
- import {
- type EventType,
- type ButtonProps,
- type DialogOptions,
- closeDialog,
- dialogStore
- } from "./index";
- import { ref, computed } from "vue";
- import { isFunction } from "@pureadmin/utils";
- import Fullscreen from "~icons/ri/fullscreen-fill";
- import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
- defineOptions({
- name: "ReDialog"
- });
- const sureBtnMap = ref({});
- const fullscreen = ref(false);
- const footerButtons = computed(() => {
- return (options: DialogOptions) => {
- return options?.footerButtons?.length > 0
- ? options.footerButtons
- : ([
- {
- label: "取消",
- text: true,
- bg: true,
- btnClick: ({ dialog: { options, index } }) => {
- const done = () =>
- closeDialog(options, index, { command: "cancel" });
- if (options?.beforeCancel && isFunction(options?.beforeCancel)) {
- options.beforeCancel(done, { options, index });
- } else {
- done();
- }
- }
- },
- {
- label: "确定",
- type: "primary",
- text: true,
- bg: true,
- popconfirm: options?.popconfirm,
- btnClick: ({ dialog: { options, index } }) => {
- if (options?.sureBtnLoading) {
- sureBtnMap.value[index] = Object.assign(
- {},
- sureBtnMap.value[index],
- {
- loading: true
- }
- );
- }
- const closeLoading = () => {
- if (options?.sureBtnLoading) {
- sureBtnMap.value[index].loading = false;
- }
- };
- const done = () => {
- closeLoading();
- closeDialog(options, index, { command: "sure" });
- };
- if (options?.beforeSure && isFunction(options?.beforeSure)) {
- options.beforeSure(done, { options, index, closeLoading });
- } else {
- done();
- }
- }
- }
- ] as Array<ButtonProps>);
- };
- });
- const fullscreenClass = computed(() => {
- return [
- "el-icon",
- "el-dialog__close",
- "-translate-x-2",
- "cursor-pointer",
- "hover:text-[red]!"
- ];
- });
- function eventsCallBack(
- event: EventType,
- options: DialogOptions,
- index: number,
- isClickFullScreen = false
- ) {
- if (!isClickFullScreen) fullscreen.value = options?.fullscreen ?? false;
- if (options?.[event] && isFunction(options?.[event])) {
- return options?.[event]({ options, index });
- }
- }
- function handleClose(
- options: DialogOptions,
- index: number,
- args = { command: "close" }
- ) {
- closeDialog(options, index, args);
- eventsCallBack("close", options, index);
- }
- </script>
- <template>
- <el-dialog
- v-for="(options, index) in dialogStore"
- :key="index"
- v-bind="options"
- v-model="options.visible"
- class="pure-dialog"
- :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
- @closed="handleClose(options, index)"
- @opened="eventsCallBack('open', options, index)"
- @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
- @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
- >
- <!-- header -->
- <template
- v-if="options?.fullscreenIcon || options?.headerRenderer"
- #header="{ close, titleId, titleClass }"
- >
- <div
- v-if="options?.fullscreenIcon"
- class="flex items-center justify-between"
- >
- <span :id="titleId" :class="titleClass">{{ options?.title }}</span>
- <i
- v-if="!options?.fullscreen"
- :class="fullscreenClass"
- @click="
- () => {
- fullscreen = !fullscreen;
- eventsCallBack(
- 'fullscreenCallBack',
- { ...options, fullscreen },
- index,
- true
- );
- }
- "
- >
- <IconifyIconOffline
- class="pure-dialog-svg"
- :icon="
- options?.fullscreen
- ? ExitFullscreen
- : fullscreen
- ? ExitFullscreen
- : Fullscreen
- "
- />
- </i>
- </div>
- <component
- :is="options?.headerRenderer({ close, titleId, titleClass })"
- v-else
- />
- </template>
- <component
- v-bind="options?.props"
- :is="options.contentRenderer({ options, index })"
- @close="args => handleClose(options, index, args)"
- />
- <!-- footer -->
- <template v-if="!options?.hideFooter" #footer>
- <template v-if="options?.footerRenderer">
- <component :is="options?.footerRenderer({ options, index })" />
- </template>
- <span v-else>
- <template v-for="(btn, key) in footerButtons(options)" :key="key">
- <el-popconfirm
- v-if="btn.popconfirm"
- v-bind="btn.popconfirm"
- @confirm="
- btn.btnClick({
- dialog: { options, index },
- button: { btn, index: key }
- })
- "
- >
- <template #reference>
- <el-button v-bind="btn">{{ btn?.label }}</el-button>
- </template>
- </el-popconfirm>
- <el-button
- v-else
- v-bind="btn"
- :loading="key === 1 && sureBtnMap[index]?.loading"
- @click="
- btn.btnClick({
- dialog: { options, index },
- button: { btn, index: key }
- })
- "
- >
- {{ btn?.label }}
- </el-button>
- </template>
- </span>
- </template>
- </el-dialog>
- </template>
|