2021-05-29 11:31:21 -07:00
|
|
|
<template>
|
2021-07-22 01:22:17 -07:00
|
|
|
<div>
|
|
|
|
<el-drawer
|
|
|
|
v-if="drawer"
|
|
|
|
:direction="drawerDirection"
|
|
|
|
:visible="visible && visibleDrawer"
|
|
|
|
:size="drawerWidth"
|
|
|
|
:before-close="closeDrawer"
|
|
|
|
>
|
|
|
|
<template v-slot:title>
|
|
|
|
<slot name="header" />
|
|
|
|
</template>
|
|
|
|
<template>
|
|
|
|
<slot name="content"/>
|
|
|
|
</template>
|
|
|
|
</el-drawer>
|
2021-05-29 11:31:21 -07:00
|
|
|
<el-dialog
|
2021-07-22 01:22:17 -07:00
|
|
|
v-else
|
2021-05-29 11:31:21 -07:00
|
|
|
:visible="dialogVisible"
|
|
|
|
:before-close="closeDialog"
|
|
|
|
:title="title"
|
|
|
|
:class="{ 'dialog-wrapper': true, [size]: true }"
|
|
|
|
:width="width"
|
2021-09-11 01:15:36 -07:00
|
|
|
:show-close="showClose"
|
|
|
|
:custom-class="getCustomClass()"
|
2021-05-29 11:31:21 -07:00
|
|
|
append-to-body
|
|
|
|
>
|
|
|
|
<template v-slot:title>
|
2021-09-11 01:15:36 -07:00
|
|
|
<slot name="header" v-if="!loading" />
|
2021-05-29 11:31:21 -07:00
|
|
|
</template>
|
|
|
|
<div class="modal-content" @keydown.stop @keydown.enter="handleEnter" @keydown.esc="closeDialog">
|
2021-09-11 01:15:36 -07:00
|
|
|
<slot v-if="!loading" name="content"/>
|
|
|
|
<div class="loader" v-else>
|
|
|
|
<n8n-spinner />
|
|
|
|
</div>
|
2021-05-29 11:31:21 -07:00
|
|
|
</div>
|
2021-09-11 01:15:36 -07:00
|
|
|
<el-row v-if="!loading" class="modal-footer">
|
2021-05-29 11:31:21 -07:00
|
|
|
<slot name="footer" :close="closeDialog" />
|
|
|
|
</el-row>
|
|
|
|
</el-dialog>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import Vue from "vue";
|
|
|
|
|
|
|
|
const sizeMap: {[size: string]: string} = {
|
|
|
|
xl: '80%',
|
2021-09-11 01:15:36 -07:00
|
|
|
lg: '70%',
|
2021-05-29 11:31:21 -07:00
|
|
|
m: '50%',
|
|
|
|
default: '50%',
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Vue.extend({
|
|
|
|
name: "Modal",
|
2021-09-11 01:15:36 -07:00
|
|
|
props: ['name', 'title', 'eventBus', 'size', 'drawer', 'drawerDirection', 'drawerWidth', 'visible', 'showClose', 'loading', 'classic', 'beforeClose', 'customClass'],
|
2021-07-22 01:22:17 -07:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
visibleDrawer: this.drawer,
|
|
|
|
};
|
|
|
|
},
|
2021-05-29 11:31:21 -07:00
|
|
|
mounted() {
|
|
|
|
window.addEventListener('keydown', this.onWindowKeydown);
|
|
|
|
|
|
|
|
if (this.$props.eventBus) {
|
|
|
|
this.$props.eventBus.$on('close', () => {
|
|
|
|
this.closeDialog();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const activeElement = document.activeElement as HTMLElement;
|
|
|
|
if (activeElement) {
|
|
|
|
activeElement.blur();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
beforeDestroy() {
|
|
|
|
window.removeEventListener('keydown', this.onWindowKeydown);
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onWindowKeydown(event: KeyboardEvent) {
|
|
|
|
if (!this.isActive) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event && event.keyCode === 13) {
|
|
|
|
this.handleEnter();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
handleEnter() {
|
|
|
|
if (this.isActive) {
|
|
|
|
this.$emit('enter');
|
|
|
|
}
|
|
|
|
},
|
2021-07-22 01:22:17 -07:00
|
|
|
closeDialog(callback?: () => void) {
|
2021-09-11 01:15:36 -07:00
|
|
|
if (this.beforeClose) {
|
|
|
|
this.beforeClose(() => {
|
|
|
|
this.$store.commit('ui/closeTopModal');
|
|
|
|
if (typeof callback === 'function') {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-29 11:31:21 -07:00
|
|
|
this.$store.commit('ui/closeTopModal');
|
2021-08-29 04:36:17 -07:00
|
|
|
if (typeof callback === 'function') {
|
2021-07-22 01:22:17 -07:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
closeDrawer() {
|
|
|
|
this.visibleDrawer = false;
|
|
|
|
setTimeout(() =>{
|
|
|
|
this.$store.commit('ui/closeTopModal');
|
|
|
|
this.visibleDrawer = true;
|
|
|
|
}, 300); // delayed for closing animation to take effect
|
2021-05-29 11:31:21 -07:00
|
|
|
},
|
2021-09-11 01:15:36 -07:00
|
|
|
getCustomClass() {
|
|
|
|
let classes = this.$props.customClass || '';
|
|
|
|
|
|
|
|
if (this.$props.classic) {
|
|
|
|
classes = `${classes} classic`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return classes;
|
|
|
|
},
|
2021-05-29 11:31:21 -07:00
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
width(): string {
|
|
|
|
return this.$props.size ? sizeMap[this.$props.size] : sizeMap.default;
|
|
|
|
},
|
|
|
|
isActive(): boolean {
|
|
|
|
return this.$store.getters['ui/isModalActive'](this.$props.name);
|
|
|
|
},
|
|
|
|
dialogVisible(): boolean {
|
|
|
|
return this.$store.getters['ui/isModalOpen'](this.$props.name);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
2021-07-22 01:22:17 -07:00
|
|
|
.el-drawer__header {
|
|
|
|
margin: 0;
|
|
|
|
padding: 30px 30px 0 30px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.el-drawer__body {
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
2021-09-11 01:15:36 -07:00
|
|
|
.el-dialog__body {
|
|
|
|
height: 100%;
|
|
|
|
}
|
2021-05-29 11:31:21 -07:00
|
|
|
|
2021-09-11 01:15:36 -07:00
|
|
|
.dialog-wrapper {
|
2021-05-29 11:31:21 -07:00
|
|
|
&.xl > div, &.md > div {
|
|
|
|
min-width: 620px;
|
|
|
|
}
|
|
|
|
|
2021-09-11 01:15:36 -07:00
|
|
|
&.lg > div {
|
|
|
|
height: 80%;
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
.modal-content {
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 11:31:21 -07:00
|
|
|
&.sm {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
> div {
|
2021-09-11 01:15:36 -07:00
|
|
|
max-width: 460px;
|
2021-05-29 11:31:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.modal-content > .el-row {
|
|
|
|
margin-bottom: 15px;
|
|
|
|
}
|
2021-09-11 01:15:36 -07:00
|
|
|
|
|
|
|
.loader {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
color: var(--color-primary-tint-1);
|
|
|
|
font-size: 30px;
|
|
|
|
height: 80%;
|
|
|
|
}
|
2021-08-21 05:11:32 -07:00
|
|
|
</style>
|