Files
asco_admin/src/views/apps/email/Email.vue
T
2021-01-09 20:53:13 +03:30

291 lines
12 KiB
Vue

<!-- =========================================================================================
File Name: Email.vue
Description: Email Application (Inbox)
----------------------------------------------------------------------------------------
Item Name: Vuexy - Vuejs, HTML & Laravel Admin Dashboard Template
Author: Pixinvent
Author URL: http://www.themeforest.net/user/pixinvent
========================================================================================== -->
<template>
<div id="email-app" class="border border-solid d-theme-border-grey-light rounded relative overflow-hidden">
<vs-sidebar class="items-no-padding" parent="#email-app" :click-not-close="clickNotClose" :hidden-background="clickNotClose" v-model="isEmailSidebarActive">
<email-sidebar :emailTags="emailTags" @closeSidebar="toggleEmailSidebar" :mailFilter="mailFilter" />
</vs-sidebar>
<div :class="{'sidebar-spacer': clickNotClose}" class="no-scroll-content border border-solid d-theme-border-grey-light border-r-0 border-t-0 border-b-0">
<!-- SEARCH BAR -->
<div class="flex border d-theme-dark-bg items-center">
<feather-icon class="md:inline-flex lg:hidden ml-4 mr-4 cursor-pointer" icon="MenuIcon" @click.stop="toggleEmailSidebar(true)"/>
<vs-input icon-no-border icon="icon-search" size="large" icon-pack="feather" placeholder="Search Mail" v-model="searchQuery" class="vs-input-no-border vs-input-no-shdow-focus w-full" />
</div>
<!-- EMAIL ACTION BAR -->
<div class="email__actions flex items-center flex-wrap justify-between p-4 border border-r-0 border-l-0 border-solid d-theme-border-grey-light">
<div class="flex items-center">
<vs-checkbox v-model="selectAllCheckBox" icon-pack="feather" :icon="selectAllIcon" class="select-all-chexkbox ml-0">Select All</vs-checkbox>
</div>
<div class="flex">
<vs-dropdown vs-custom-content vs-trigger-click class="cursor-pointer" v-if="mailFilter != 'sent'">
<feather-icon icon="FolderIcon" class="cursor-pointer" svg-classes="h-6 w-6"></feather-icon>
<vs-dropdown-menu>
<vs-dropdown-item @click="moveTo('inbox')" v-if="mailFilter != 'inbox'">
<span class="flex items-center">
<feather-icon icon="MailIcon" svgClasses="h-4 w-4" class="mr-2" />
<span>Inbox</span>
</span>
</vs-dropdown-item>
<vs-dropdown-item @click="moveTo('draft')" v-if="mailFilter != 'draft'">
<span class="flex items-center">
<feather-icon icon="Edit2Icon" svgClasses="h-4 w-4" class="mr-2" />
<span>Draft</span>
</span>
</vs-dropdown-item>
<vs-dropdown-item @click="moveTo('spam')" v-if="mailFilter != 'spam'">
<span class="flex items-center">
<feather-icon icon="InfoIcon" svgClasses="h-4 w-4" class="mr-2" />
<span>Spam</span>
</span>
</vs-dropdown-item>
<vs-dropdown-item @click="moveTo('trash')" v-if="mailFilter != 'trash'">
<span class="flex items-center">
<feather-icon icon="TrashIcon" svgClasses="h-4 w-4" class="mr-2" />
<span>Trash</span>
</span>
</vs-dropdown-item>
</vs-dropdown-menu>
</vs-dropdown>
<vs-dropdown vs-custom-content vs-trigger-click class="cursor-pointer">
<feather-icon icon="TagIcon" class="cursor-pointer ml-5" svg-classes="h-6 w-6"></feather-icon>
<vs-dropdown-menu >
<vs-dropdown-item v-for="(label, index) in emailTags" :key="index" @click="updateLabels(label.value)" class="whitespace-no-wrap">
<div class="h-3 w-3 inline-block rounded-full mr-3" :class="'bg-' + label.color"></div>
<span>{{ label.text }}</span>
</vs-dropdown-item>
</vs-dropdown-menu>
</vs-dropdown>
<feather-icon icon="MailIcon" class="ml-5 cursor-pointer" svg-classes="h-6 w-6" @click="updateMarkUnread" />
<feather-icon v-if="mailFilter != 'trash'" icon="TrashIcon" class="cursor-pointer ml-5" svg-classes="h-6 w-6" @click="moveTo('trash')" />
</div>
</div>
<!-- EMAILS LIST -->
<component :is="scrollbarTag" class="email-content-scroll-area" :settings="settings" ref="mailListPS" :key="$vs.rtl">
<transition-group name="list-enter-up" class="email__mails" tag="ul" appear>
<li class="cursor-pointer email__mail-item" v-for="(mail, index) in mails" :key="String(mailFilter) + String(mail.id)" @click="updateOpenMail(mail.id)" :style="{transitionDelay: (index * 0.1) + 's'}">
<mail-item :mail="mail" :isSelected="isMailSelected(mail.id)" @addToSelected="addToSelectedMails" @removeSelected="removeSelectedMail" />
</li>
</transition-group>
</component>
</div>
<!-- EMAIL VIEW SIDEBAR -->
<email-view
:emailTags = "emailTags"
:openMailId = "openMailId"
:isSidebarActive = "isSidebarActive"
:mailFilter = "mailFilter"
@markUnread = "updateSingleMarkUnread"
@removeMail = "removeOpenMail"
@previousMail = "previousMail"
@nextMail = "nextMail"
@moveTo = "moveCurrentTo"
@closeSidebar = "closeMailViewSidebar">
</email-view>
</div>
</template>
<script>
import EmailSidebar from './EmailSidebar.vue'
import MailItem from './MailItem.vue'
import EmailView from './EmailView.vue'
import VuePerfectScrollbar from 'vue-perfect-scrollbar'
import moduleEmail from '@/store/email/moduleEmail.js'
export default {
data () {
return {
openMailId : null,
selectedMails : [],
isSidebarActive : false,
showThread : false,
clickNotClose : true,
isEmailSidebarActive : true,
settings : {
maxScrollbarLength : 60,
wheelSpeed : 0.30
}
}
},
watch: {
isSidebarActive (value) {
if (!value) this.showThread = false
},
mailFilter () {
this.selectedMails = []
const scroll_el = this.$refs.mailListPS.$el || this.$refs.mailListPS
scroll_el.scrollTop = 0
this.$store.commit('email/UPDATE_MAIL_FILTER', this.$route.params.filter)
this.$store.dispatch('email/fetchEmails', { filter: this.$route.params.filter })
this.toggleEmailSidebar()
},
windowWidth () {
this.setSidebarWidth()
}
},
computed: {
mailFilter () {
return this.$route.params.filter
},
emailTags () {
return this.$store.state.email.mailTags
},
searchQuery: {
get () {
return this.$store.state.email.mailSearchQuery
},
set (val) {
this.$store.dispatch('email/setEmailSearchQuery', val)
}
},
selectAllCheckBox: {
get () {
return this.selectedMails.length
},
set (value) {
value ? this.selectedMails = this.mails.map(mail => mail.id) : this.selectedMails = []
}
},
mails () {
return this.$store.getters['email/filteredMails']
},
selectAllIcon () {
return this.selectedMails.length === this.mails.length ? 'icon-check' : 'icon-minus'
},
scrollbarTag () { return this.$store.getters.scrollbarTag },
isMailSelected () {
return (mailId) => this.selectedMails.indexOf(mailId) !== -1
},
windowWidth () {
return this.$store.state.windowWidth
}
},
methods: {
updateOpenMail (mailId) {
this.openMailId = mailId
this.isSidebarActive = true
},
addToSelectedMails (mailId) {
if (this.selectedMails.indexOf(mailId) === -1) this.selectedMails.push(mailId)
},
removeSelectedMail (mailId) {
const mailIndex = this.selectedMails.indexOf(mailId)
if (mailIndex !== -1) this.selectedMails.splice(mailIndex, 1)
},
moveTo (to) {
const payload = { emailIds: this.selectedMails, to }
this.$store.dispatch('email/moveMailsTo', payload)
.catch((error) => { console.error(error) })
this.selectedMails = []
},
moveCurrentTo (to) {
this.selectedMails = [this.openMailId]
this.moveTo(to)
},
updateMarkUnread () {
const payload = { emailIds: this.selectedMails, unreadFlag: true }
this.$store.dispatch('email/setUnread', payload)
this.selectedMails = []
},
removeOpenMail () {
this.selectedMails = [this.openMailId]
this.moveTo('trashed')
this.isSidebarActive = false
},
toggleIsStarred () {
const payload = { mailId: this.currentMail.id, value: !this.currentMail.isStarred }
this.$store.dispatch('email/toggleIsMailStarred', payload)
},
nextMail () {
const currentMailIndex = this.mails.findIndex((mail) => mail.id === this.openMailId)
if (this.mails[currentMailIndex + 1]) this.openMailId = this.mails[currentMailIndex + 1].id
},
previousMail () {
const currentMailIndex = this.mails.findIndex((mail) => mail.id === this.openMailId)
if (this.mails[currentMailIndex - 1]) this.openMailId = this.mails[currentMailIndex - 1].id
},
updateSingleMarkUnread () {
this.selectedMails = [this.openMailId]
this.updateMarkUnread()
this.isSidebarActive = false
},
updateLabels (label) {
this.$store.dispatch('email/updateLabels', { mails: this.selectedMails, label })
this.selectedMails = []
},
closeMailViewSidebar () {
this.isSidebarActive = false
},
setSidebarWidth () {
if (this.windowWidth < 992) {
this.isEmailSidebarActive = this.clickNotClose = false
} else {
this.isEmailSidebarActive = this.clickNotClose = true
}
},
toggleEmailSidebar (value = false) {
if (!value) {
this.closeMailViewSidebar()
if (this.clickNotClose) {
return
}
}
this.isEmailSidebarActive = value
}
},
components: {
MailItem,
EmailSidebar,
EmailView,
VuePerfectScrollbar
},
created () {
this.$store.registerModule('email', moduleEmail)
this.setSidebarWidth()
this.$store.commit('email/UPDATE_MAIL_FILTER', this.$route.params.filter) // Update Mail Filter
this.$store.dispatch('email/fetchEmails', { filter: this.$route.params.filter }) // Fetch Emails From API
this.$store.dispatch('email/fetchMeta') // Fetch Unread Mails
this.$store.dispatch('email/fetchTags') // Fetch Mail Tags
},
beforeDestroy () {
this.$store.unregisterModule('email')
},
mounted () {
this.$store.dispatch('email/setEmailSearchQuery', '')
}
}
</script>
<style lang="scss">
@import "@/assets/scss/vuexy/apps/email.scss";
</style>