2021-02-21 15:13:58 +00:00
|
|
|
<template>
|
|
|
|
<div class="notifications">
|
2021-06-23 20:08:20 +00:00
|
|
|
<div class="is-flex is-justify-content-center">
|
|
|
|
<a @click.stop="showNotifications = !showNotifications" class="trigger-button">
|
|
|
|
<span class="unread-indicator" v-if="unreadNotifications > 0"></span>
|
|
|
|
<icon icon="bell"/>
|
|
|
|
</a>
|
|
|
|
</div>
|
2021-02-21 15:13:58 +00:00
|
|
|
|
|
|
|
<transition name="fade">
|
|
|
|
<div class="notifications-list" v-if="showNotifications" ref="popup">
|
2021-07-09 08:22:20 +00:00
|
|
|
<span class="head">{{ $t('notification.title') }}</span>
|
2021-02-21 15:13:58 +00:00
|
|
|
<div
|
|
|
|
v-for="(n, index) in notifications"
|
|
|
|
:key="n.id"
|
|
|
|
class="single-notification"
|
|
|
|
>
|
|
|
|
<div class="read-indicator" :class="{'read': n.readAt !== null}"></div>
|
|
|
|
<user
|
|
|
|
:user="n.notification.doer"
|
2021-04-18 15:21:14 +00:00
|
|
|
:show-username="false"
|
2021-02-21 15:13:58 +00:00
|
|
|
:avatar-size="16"
|
|
|
|
v-if="n.notification.doer"/>
|
|
|
|
<span class="detail">
|
2021-04-18 15:21:14 +00:00
|
|
|
<p>
|
|
|
|
|
|
|
|
<span class="has-text-weight-bold" v-if="n.notification.doer">
|
|
|
|
{{ n.notification.doer.getDisplayName() }}
|
|
|
|
</span>
|
2021-02-21 15:13:58 +00:00
|
|
|
<a @click="() => to(n, index)()">
|
|
|
|
{{ n.toText(userInfo) }}
|
|
|
|
</a>
|
2021-04-18 15:21:14 +00:00
|
|
|
</p>
|
|
|
|
<div class="created" v-tooltip="formatDate(n.created)">
|
|
|
|
{{ formatDateSince(n.created) }}
|
|
|
|
</div>
|
2021-02-21 15:13:58 +00:00
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<p class="nothing" v-if="notifications.length === 0">
|
2021-06-23 23:24:57 +00:00
|
|
|
{{ $t('notification.none') }}<br/>
|
2021-02-21 15:13:58 +00:00
|
|
|
<span class="explainer">
|
2021-06-23 23:24:57 +00:00
|
|
|
{{ $t('notification.explainer') }}
|
2021-02-21 15:13:58 +00:00
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</transition>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import NotificationService from '@/services/notification'
|
2021-07-25 13:27:15 +00:00
|
|
|
import User from '@/components/misc/user.vue'
|
2021-09-10 14:21:33 +00:00
|
|
|
import names from '@/models/constants/notificationNames.json'
|
2021-02-21 15:13:58 +00:00
|
|
|
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
|
|
|
import {mapState} from 'vuex'
|
|
|
|
|
2021-09-08 09:59:46 +00:00
|
|
|
const LOAD_NOTIFICATIONS_INTERVAL = 10000
|
|
|
|
|
2021-02-21 15:13:58 +00:00
|
|
|
export default {
|
|
|
|
name: 'notifications',
|
|
|
|
components: {User},
|
|
|
|
data() {
|
|
|
|
return {
|
2021-09-08 09:59:38 +00:00
|
|
|
notificationService: new NotificationService(),
|
2021-04-18 15:21:14 +00:00
|
|
|
allNotifications: [],
|
2021-02-21 15:13:58 +00:00
|
|
|
showNotifications: false,
|
|
|
|
interval: null,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
this.loadNotifications()
|
|
|
|
document.addEventListener('click', this.hidePopup)
|
2021-09-08 09:59:46 +00:00
|
|
|
this.interval = setInterval(this.loadNotifications, LOAD_NOTIFICATIONS_INTERVAL)
|
2021-02-21 15:13:58 +00:00
|
|
|
},
|
2021-08-19 19:36:09 +00:00
|
|
|
beforeUnmount() {
|
2021-02-21 15:13:58 +00:00
|
|
|
document.removeEventListener('click', this.hidePopup)
|
|
|
|
clearInterval(this.interval)
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
unreadNotifications() {
|
|
|
|
return this.notifications.filter(n => n.readAt === null).length
|
|
|
|
},
|
2021-04-18 15:21:14 +00:00
|
|
|
notifications() {
|
|
|
|
return this.allNotifications.filter(n => n.name !== '')
|
|
|
|
},
|
2021-02-21 15:13:58 +00:00
|
|
|
...mapState({
|
|
|
|
userInfo: state => state.auth.info,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
hidePopup(e) {
|
|
|
|
if (this.showNotifications) {
|
|
|
|
closeWhenClickedOutside(e, this.$refs.popup, () => this.showNotifications = false)
|
|
|
|
}
|
|
|
|
},
|
2021-10-11 17:37:20 +00:00
|
|
|
async loadNotifications() {
|
|
|
|
this.allNotifications = await this.notificationService.getAll()
|
2021-02-21 15:13:58 +00:00
|
|
|
},
|
|
|
|
to(n, index) {
|
|
|
|
const to = {
|
|
|
|
name: '',
|
|
|
|
params: {},
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (n.name) {
|
|
|
|
case names.TASK_COMMENT:
|
|
|
|
case names.TASK_ASSIGNED:
|
|
|
|
to.name = 'task.detail'
|
|
|
|
to.params.id = n.notification.task.id
|
|
|
|
break
|
|
|
|
case names.TASK_DELETED:
|
|
|
|
// Nothing
|
|
|
|
break
|
|
|
|
case names.LIST_CREATED:
|
|
|
|
to.name = 'task.index'
|
|
|
|
to.params.listId = n.notification.list.id
|
|
|
|
break
|
|
|
|
case names.TEAM_MEMBER_ADDED:
|
|
|
|
to.name = 'teams.edit'
|
|
|
|
to.params.id = n.notification.team.id
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2021-10-11 17:37:20 +00:00
|
|
|
return async () => {
|
2021-02-21 15:13:58 +00:00
|
|
|
if (to.name !== '') {
|
|
|
|
this.$router.push(to)
|
|
|
|
}
|
|
|
|
|
|
|
|
n.read = true
|
2021-10-11 17:37:20 +00:00
|
|
|
this.allNotifications[index] = await this.notificationService.update(n)
|
2021-02-21 15:13:58 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
</script>
|