165 lines
3.7 KiB
Vue
165 lines
3.7 KiB
Vue
<template>
|
|
<div class="single-notification">
|
|
<div class="read-indicator" :class="{'read': notification.readAt !== null}" />
|
|
<user
|
|
class="user"
|
|
v-if="notification.notification.doer"
|
|
:user="notification.notification.doer"
|
|
:show-username="false"
|
|
:avatar-size="16"
|
|
/>
|
|
<div class="detail">
|
|
<div>
|
|
<span class="has-text-weight-bold mr-1" v-if="notification.notification.doer">
|
|
{{ getDisplayName(notification.notification.doer) }}
|
|
</span>
|
|
<BaseButton :to="to" @click="emit('markNotificationAsRead')">
|
|
{{ notificationText }}
|
|
</BaseButton>
|
|
</div>
|
|
<span class="created" v-tooltip="formatDateLong(notification.created)">
|
|
{{ formatDateSince(notification.created) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {computed} from 'vue'
|
|
|
|
import {useAuthStore} from '@/stores/auth'
|
|
|
|
import {NOTIFICATION_NAMES, type INotification} from '@/modelTypes/INotification'
|
|
import BaseButton from '@/components/base/BaseButton.vue'
|
|
import User from '@/components/misc/user.vue'
|
|
|
|
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
|
import {getDisplayName} from '@/models/user'
|
|
import {getTextIdentifier} from '@/models/task'
|
|
|
|
const props = defineProps<{
|
|
notification: INotification
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'markNotificationAsRead'): void
|
|
}>()
|
|
|
|
const authStore = useAuthStore()
|
|
const userInfo = computed(() => authStore.info)
|
|
|
|
const to = computed(() => {
|
|
const to = {
|
|
name: '',
|
|
params: {},
|
|
}
|
|
|
|
switch (props.notification.name) {
|
|
case NOTIFICATION_NAMES.TASK_COMMENT:
|
|
case NOTIFICATION_NAMES.TASK_ASSIGNED:
|
|
to.name = 'task.detail'
|
|
to.params.id = props.notification.notification.task.id
|
|
break
|
|
case NOTIFICATION_NAMES.TASK_DELETED:
|
|
// Nothing
|
|
break
|
|
case NOTIFICATION_NAMES.LIST_CREATED:
|
|
to.name = 'task.index'
|
|
to.params.listId = props.notification.notification.list.id
|
|
break
|
|
case NOTIFICATION_NAMES.TEAM_MEMBER_ADDED:
|
|
to.name = 'teams.edit'
|
|
to.params.id = props.notification.notification.team.id
|
|
break
|
|
default:
|
|
}
|
|
|
|
return to
|
|
})
|
|
|
|
const notificationText = computed(() => {
|
|
const notification = props.notification.notification
|
|
let who = ''
|
|
|
|
switch (props.notification.name) {
|
|
case NOTIFICATION_NAMES.TASK_COMMENT:
|
|
return `commented on ${getTextIdentifier(notification.task)}`
|
|
case NOTIFICATION_NAMES.TASK_ASSIGNED:
|
|
if (userInfo.value !== null && userInfo.value.id === notification.assignee.id) {
|
|
who = 'you'
|
|
} else {
|
|
who = `${getDisplayName(notification.assignee)}`
|
|
}
|
|
|
|
return `assigned ${who} to ${getTextIdentifier(notification.task)}`
|
|
case NOTIFICATION_NAMES.TASK_DELETED:
|
|
return `deleted ${getTextIdentifier(notification.task)}`
|
|
case NOTIFICATION_NAMES.LIST_CREATED:
|
|
return `created ${notification.list.title}`
|
|
case NOTIFICATION_NAMES.TEAM_MEMBER_ADDED:
|
|
if (userInfo.value !== null && userInfo.value.id === notification.member.id) {
|
|
who = 'you'
|
|
} else {
|
|
who = `${getDisplayName(notification.member)}`
|
|
}
|
|
|
|
return `added ${who} to the ${notification.team.name} team`
|
|
}
|
|
|
|
return ''
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.single-notification {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0.25rem 0;
|
|
transition: background-color $transition;
|
|
|
|
&:hover {
|
|
background: var(--grey-100);
|
|
border-radius: $radius;
|
|
}
|
|
}
|
|
|
|
.read-indicator {
|
|
width: .35rem;
|
|
height: .35rem;
|
|
background: var(--primary);
|
|
border-radius: 100%;
|
|
margin-left: .5rem;
|
|
|
|
&.read {
|
|
background: transparent;
|
|
}
|
|
}
|
|
|
|
// FIXME: this deep styling of user should not be in here
|
|
.user {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
width: auto;
|
|
margin: 0 .5rem;
|
|
|
|
span {
|
|
font-family: $family-sans-serif;
|
|
}
|
|
|
|
.avatar {
|
|
height: 16px;
|
|
}
|
|
|
|
img {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
|
|
.created {
|
|
color: var(--grey-400);
|
|
}
|
|
|
|
a {
|
|
color: var(--grey-800);
|
|
}
|
|
</style> |