mirror of
https://github.com/frappe/books.git
synced 2025-02-13 17:39:09 +00:00
121 lines
2.6 KiB
Vue
121 lines
2.6 KiB
Vue
<template>
|
|
<div
|
|
class="
|
|
text-gray-900
|
|
shadow-lg
|
|
px-3
|
|
py-2
|
|
flex
|
|
items-center
|
|
mb-3
|
|
w-96
|
|
z-10
|
|
bg-white
|
|
rounded-lg
|
|
"
|
|
style="transition: opacity 150ms ease-in"
|
|
:style="{ opacity }"
|
|
v-if="show"
|
|
>
|
|
<FeatherIcon :name="iconName" class="w-6 h-6 mr-3" :class="iconColor" />
|
|
<div @click="actionClicked" :class="actionText ? 'cursor-pointer' : ''">
|
|
<p class="text-base">{{ message }}</p>
|
|
<button
|
|
v-if="actionText"
|
|
class="text-sm text-gray-700 hover:text-gray-800"
|
|
>
|
|
{{ actionText }}
|
|
</button>
|
|
</div>
|
|
<feather-icon
|
|
name="x"
|
|
class="w-4 h-4 ml-auto text-gray-600 cursor-pointer hover:text-gray-800"
|
|
@click="closeToast"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import { getColorClass } from '../colors';
|
|
import FeatherIcon from './FeatherIcon.vue';
|
|
|
|
export default {
|
|
components: {
|
|
FeatherIcon,
|
|
},
|
|
data() {
|
|
return {
|
|
opacity: 0,
|
|
show: true,
|
|
opacityTimeoutId: -1,
|
|
cleanupTimeoutId: -1,
|
|
};
|
|
},
|
|
props: {
|
|
message: { type: String, required: true },
|
|
action: { type: Function, default: () => {} },
|
|
actionText: { type: String, default: '' },
|
|
type: { type: String, default: 'info' },
|
|
duration: { type: Number, default: 5000 },
|
|
},
|
|
computed: {
|
|
iconName() {
|
|
switch (this.type) {
|
|
case 'warning':
|
|
return 'alert-triangle';
|
|
case 'success':
|
|
return 'check-circle';
|
|
default:
|
|
return 'alert-circle';
|
|
}
|
|
},
|
|
color() {
|
|
return {
|
|
info: 'blue',
|
|
warning: 'orange',
|
|
error: 'red',
|
|
success: 'green',
|
|
}[this.type];
|
|
},
|
|
iconColor() {
|
|
return getColorClass(this.color, 'text', 400);
|
|
},
|
|
},
|
|
mounted() {
|
|
setTimeout(() => {
|
|
this.opacity = 1;
|
|
}, 50);
|
|
|
|
this.opacityTimeoutId = setTimeout(() => {
|
|
this.opacity = 0;
|
|
}, this.duration);
|
|
|
|
this.cleanupTimeoutId = setTimeout(() => {
|
|
this.show = false;
|
|
this.cleanup();
|
|
}, this.duration + 300);
|
|
},
|
|
methods: {
|
|
actionClicked() {
|
|
this.action();
|
|
this.closeToast();
|
|
},
|
|
closeToast() {
|
|
clearTimeout(this.opacityTimeoutId);
|
|
clearTimeout(this.cleanupTimeoutId);
|
|
|
|
this.opacity = 0;
|
|
setTimeout(() => {
|
|
this.show = false;
|
|
this.cleanup();
|
|
}, 300);
|
|
},
|
|
cleanup() {
|
|
Array.from(this.$el.parentElement?.children ?? [])
|
|
.filter((el) => !el.innerHTML)
|
|
.splice(1)
|
|
.forEach((el) => el.remove());
|
|
},
|
|
},
|
|
};
|
|
</script>
|