<template> <!-- #region modal --> <transition name="my-modal-fade"> <div class="my-modal-backdrop"> <div class="my-modal" @keydown.esc="close()" tabindex="1000" @keydown.enter.ctrl="save()" role="dialog" :class="modalSize" aria-labelledby="my-modalTitle" aria-describedby="my-modalDescription" style="border-radius: 10px; padding: 0 5px 10px 5px" :style="{ overflow: $attrs.overflow, width: $attrs.width, height: $attrs.height, }" > <!-- #region header --> <header class="my-modal-header text-dark p-3" id="my-modalTitle"> <div class="d-flex flex-grow-1 font-weight-semi-bold"> <!-- <slot name="header-title"></slot> --> <slot></slot> <div class="flex-grow-1 mx-3"> <button-component @click="loadFromVuexClipboard()" buttonText="بارگزاری از حافظه" v-tooltip="'بارگذاری آخرین مورد کپی شده'" classes="btn btn-primary" v-if="showLoadButton" > </button-component> <button-component @click="copyToVuexClipboard()" classes="btn btn-success mr-2" buttonText="ذخیره در حافظه" v-tooltip="'ذخیره در حافظه محلی'" v-if="showCopyButton" > </button-component> </div> <div v-if="showNextBtns" class="d-flex col-3 justify-content-end pl-0" > <div class="main-page_date-icon-right col-auto"> <span class="d-flex btn text-title-nextItem" title="قبلی" @click.prevent="prevItem()" > <svg class="icon icon-Component-358--1"> <use xlink:href="#icon-Component-358--1"></use> </svg> <span class="nextItem">قبلی</span> </span> </div> <div class="main-page_date-icon-left col-auto pl-0"> <span class="d-flex btn text-title-prevItem" title="بعدی" @click.prevent="nextItem()" > <span class="prevItem">بعدی</span> <svg class="icon icon-Component-359--1"> <use xlink:href="#icon-Component-359--1"></use> </svg> </span> </div> </div> <!-- <button type="button" class="btn-close" @click="close" aria-label="Close my-modal" > x </button> --> <button @click.prevent="close" type="button" class="close" data-dismiss="modal" aria-label="Close" > <span aria-hidden="true">×</span> </button> </div> </header> <!-- #endregion header --> <!-- #region section --> <section class="my-modal-body firefox-scrollbar m-2" id="my-modalDescription" :key="renderBody" :style="{ maxHeight: $attrs.maxHeight, minHeight: $attrs.minHeight }" > <slot name="body"> </slot> </section> <!-- #endregion section --> <!-- #region footer --> <footer v-if="hasFooter" class="my-modal-footer p-1 mx-3"> <!-- <slot name="footer"> This is the default footer! </slot> --> <div class="modal-footer"> <button v-if="showDeleteButton" @click.prevent="deleteEmit()" class="btn delete-btn btn-outline-danger" type="button" > حذف </button> <div class="w-100 d-flex justify-content-end align-items-center"> <button v-if="showCloseButton" @click.prevent="close()" type="button" class="btn btn-default" data-dismiss="modal" > بستن </button> <button v-if="showSaveButton" @click.prevent="save()" type="button" class="btn btn-primary" > ذخیره </button> </div> </div> <div v-if="footerDesc"> {{ footerDesc }} </div> <!-- <button type="button" class="btn-green" @click="close" aria-label="Close my-modal" > Close me! </button> --> </footer> <!-- #endregion footer --> </div> </div> </transition> <!-- #endregion modal --> </template> <script> import { mapState, mapActions } from "pinia"; import { useCommonStore } from "~/stores/commonStore"; import { useAuthStore } from "~/stores/authStore"; /** * @vue-prop {String} [modalSize="modal-xl"] - اندازه مودال * @vue-prop {Boolean} [hasFooter=true] - نشان میدهد که آیا مودال دارای فوتر باشد یا خیر * @vue-prop {String} [modalTitle=""] - عنوان مودال * @vue-prop {Boolean} [showSaveButton=true] - نشان میدهد که آیا دکمه ذخیره نمایش داده شود یا خیر * @vue-prop {Boolean} [showCloseButton=true] - نشان میدهد که آیا دکمه بستن نمایش داده شود یا خیر * * @vue-data {String} [sub_Title=""] - زیر عنوان * * @vue-computed {String} [getComponentName] - نام کامپوننت * * @vue-event {Function} SHOW_BASE_MODAL - نمایش مودال پایه */ export default { props: { modalSize: { default: "modal-xl", }, hasFooter: { default: true, }, modalTitle: { default: "", }, footerDesc: { default: "", }, showLoadButton: { default: false, }, showCopyButton: { default: false, }, showSaveButton: { default: true, }, showCloseButton: { default: true, }, showDeleteButton: { default: true, }, showNextBtns: { default: false, }, formData: { default() { return {}; }, }, entity: { default() { return undefined; }, }, currentEntityContent: { default() { return undefined; }, }, }, data() { return { sub_Title: "", renderBody: 1, }; }, computed: { ...mapState(useAuthStore, ["getComponentName"]), // ...mapState("common", ["lastRecordGetter"]), }, methods: { ...mapActions(useCommonStore, ["SHOW_BASE_MODAL"]), // ...mapActions("common", ["lastRecordSetter"]), prevItem() { this.$emit("prevItem"); }, nextItem() { this.$emit("nextItem"); }, loadFromVuexClipboard() { this.$emit("loadFromVuexClipboard"); // let lastObj = this.lastRecordGetter[this.qruleActiveTabGetter.key]; // if(lastObj.id) // delete lastObj.id; // this.formData = lastObj; // this.renderBody++; }, copyToVuexClipboard() { this.$emit("copyToVuexClipboard"); // this.lastRecordSetter({ // [this.qruleActiveTabGetter.key]: structuredClone(this.selectRuleObject), // }); }, /** * بستن مدال. * این متد مدال را بسته و رویداد بستن را از طریق امیت به والد ارسال میکند. */ close() { // this.SHOW_BASE_MODAL(false); this.$emit("close"); }, /** * ذخیره تغییرات و بستن مدال. * این متد تغییرات را ذخیره کرده، مدال را بسته و رویداد ذخیره را از طریق امیت به والد ارسال میکند. */ save() { // this.SHOW_BASE_MODAL(false); if (this.showSaveButton) this.$emit("save"); }, deleteEmit() { this.mySwalConfirm({ title: "هشدار!!!", html: `از حذف اطلاعات جاری اطمینان دارید؟ `, icon: "warning", }).then((result) => { if (result.isConfirmed) { this.$emit("delete"); } }); }, }, mounted() { // window.addEventListener("keydown", this.handleKeyDown); // this.$nextTick(() => { // this.$el?.focus(); // }); }, }; </script> <style lang="scss"> .my-modal-backdrop { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center; z-index: 99; } .my-modal { background: #ffffff; box-shadow: 2px 2px 20px 1px; overflow-x: auto; display: flex; flex-direction: column; &.modal-sm { width: 300px; } &.modal-lg { width: 800px; } &.modal-xl { width: 1140px; } &.modal-xxl { width: 1500px; } } .my-modal-header, .my-modal-footer { padding: 15px; display: flex; } .my-modal-header { position: relative; border-bottom: 1px solid #eeeeee; color: #4aae9b; justify-content: space-between; margin: 0 15px; } .my-modal-footer { /* border-top: 1px solid #eeeeee; */ flex-direction: column; .modal-footer { display: flex; justify-content: space-between; align-items: center; } } .my-modal-body { position: relative; padding: 10px 10px; overflow-y: auto; overflow-x: hidden; // width: 50em; height: 100%; min-height: auto; max-height: 30em; } .close { &:hover { color: #ef4444 !important; } } .btn-close { position: absolute; top: 0; left: 0; border: none; font-size: 20px; padding: 10px; cursor: pointer; font-weight: bold; color: #4aae9b; background: transparent; } .btn-green { color: white; background: #4aae9b; border: 1px solid #4aae9b; border-radius: 2px; } .my-modal-fade-enter, .my-modal-fade-leave-to { opacity: 0; } .my-modal-fade-enter-active, .my-modal-fade-leave-active { transition: opacity 0.5s ease; } </style>