You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.2 KiB
Vue
158 lines
4.2 KiB
Vue
11 months ago
|
<script setup lang="ts">
|
||
|
import {
|
||
|
closeDialog,
|
||
|
dialogStore,
|
||
|
type EventType,
|
||
|
type ButtonProps,
|
||
|
type DialogOptions
|
||
|
} from "./index";
|
||
|
import { ref, computed } from "vue";
|
||
|
import { isFunction } from "@pureadmin/utils";
|
||
|
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
|
||
|
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
|
||
|
|
||
|
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,
|
||
|
btnClick: ({ dialog: { options, index } }) => {
|
||
|
const done = () =>
|
||
|
closeDialog(options, index, { command: "sure" });
|
||
|
if (options?.beforeSure && isFunction(options?.beforeSure)) {
|
||
|
options.beforeSure(done, { options, index });
|
||
|
} 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
|
||
|
) {
|
||
|
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
|
||
|
class="pure-dialog"
|
||
|
v-for="(options, index) in dialogStore"
|
||
|
:key="index"
|
||
|
v-bind="options"
|
||
|
v-model="options.visible"
|
||
|
:fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
|
||
|
@close="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"
|
||
|
>
|
||
|
<IconifyIconOffline
|
||
|
class="pure-dialog-svg"
|
||
|
:icon="
|
||
|
options?.fullscreen
|
||
|
? ExitFullscreen
|
||
|
: fullscreen
|
||
|
? ExitFullscreen
|
||
|
: Fullscreen
|
||
|
"
|
||
|
/>
|
||
|
</i>
|
||
|
</div>
|
||
|
<component
|
||
|
v-else
|
||
|
:is="options?.headerRenderer({ close, titleId, titleClass })"
|
||
|
/>
|
||
|
</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>
|
||
|
<el-button
|
||
|
v-for="(btn, key) in footerButtons(options)"
|
||
|
:key="key"
|
||
|
v-bind="btn"
|
||
|
@click="
|
||
|
btn.btnClick({
|
||
|
dialog: { options, index },
|
||
|
button: { btn, index: key }
|
||
|
})
|
||
|
"
|
||
|
>
|
||
|
{{ btn?.label }}
|
||
|
</el-button>
|
||
|
</span>
|
||
|
</template>
|
||
|
</el-dialog>
|
||
|
</template>
|