This repository has been archived on 2024-02-08. You can view files and clone it, but cannot push or open issues or pull requests.
frontend/src/components/notifications/NotificationItem.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>