feat(#36): Notification rework with single and all comments mark as read
This commit is contained in:
@@ -2,7 +2,6 @@ export { useApplicationFormTemplate } from './applicationFormTemplate/useApplica
|
||||
export { useApplicationForm } from './applicationForm/useApplicationForm'
|
||||
export { useApplicationFormVersion } from './applicationFormVersion/useApplicationFormVersion'
|
||||
export { useApplicationFormVersionApi } from './applicationFormVersion/useApplicationFormVersionApi'
|
||||
export { useNotification } from './notification/useNotification'
|
||||
export { useNotificationApi } from './notification/useNotificationApi'
|
||||
export { useUser } from './user/useUser'
|
||||
export { useUserApi } from './user/useUserApi'
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
import type { NotificationDto } from '~~/.api-client'
|
||||
import { useUserStore } from '~~/stores/useUserStore'
|
||||
|
||||
export const useNotification = () => {
|
||||
const logger = useLogger().withTag('notification')
|
||||
|
||||
const {
|
||||
getNotifications,
|
||||
getUnreadNotifications,
|
||||
getUnreadNotificationCount,
|
||||
markAllNotificationsAsRead,
|
||||
markNotificationAsRead
|
||||
} = useNotificationApi()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const organizationId = computed(() => userStore.selectedOrganization?.id)
|
||||
const { user } = useUserSession()
|
||||
const userId = computed(() => user.value?.keycloakId)
|
||||
|
||||
const notifications = ref<NotificationDto[]>([])
|
||||
const unreadNotifications = ref<NotificationDto[]>([])
|
||||
const unreadCount = ref<number>(0)
|
||||
const isLoading = ref(false)
|
||||
|
||||
const fetchNotifications = async (page: number = 0, size: number = 20) => {
|
||||
if (!organizationId.value) {
|
||||
logger.warn('No organization selected')
|
||||
return
|
||||
}
|
||||
isLoading.value = true
|
||||
try {
|
||||
const response = await getNotifications(organizationId.value, page, size)
|
||||
notifications.value = response.content || []
|
||||
return response
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch notifications:', error)
|
||||
throw error
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const fetchUnreadNotifications = async () => {
|
||||
if (!organizationId.value) {
|
||||
logger.warn('No organization selected')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const response = await getUnreadNotifications(organizationId.value)
|
||||
unreadNotifications.value = response || []
|
||||
return response
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch unread notifications:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const fetchUnreadCount = async () => {
|
||||
if (!userId.value || !organizationId.value) {
|
||||
logger.warn('No user or organization selected')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const count = await getUnreadNotificationCount(userId.value, organizationId.value)
|
||||
unreadCount.value = count || 0
|
||||
return count
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch unread count:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const markAllAsRead = async () => {
|
||||
if (!organizationId.value) {
|
||||
logger.warn('No organization selected')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await markAllNotificationsAsRead(organizationId.value)
|
||||
unreadCount.value = 0
|
||||
unreadNotifications.value = []
|
||||
notifications.value = notifications.value.map((n) => ({ ...n, isRead: true }))
|
||||
} catch (error) {
|
||||
logger.error('Failed to mark all as read:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const markAsRead = async (notificationId: string) => {
|
||||
if (!organizationId.value) {
|
||||
logger.warn('No organization selected')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await markNotificationAsRead(notificationId, organizationId.value)
|
||||
const index = notifications.value.findIndex((n) => n.id === notificationId)
|
||||
if (index !== -1 && notifications.value[index]) {
|
||||
notifications.value[index].isRead = true
|
||||
}
|
||||
// Remove from unread notifications
|
||||
unreadNotifications.value = unreadNotifications.value.filter((n) => n.id !== notificationId)
|
||||
|
||||
if (unreadCount.value > 0) {
|
||||
unreadCount.value--
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to mark notification as read:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const handleNotificationClick = async (notification: NotificationDto) => {
|
||||
if (!notification.isRead) {
|
||||
await markAsRead(notification.id)
|
||||
}
|
||||
if (notification.clickTarget) {
|
||||
await navigateTo(notification.clickTarget)
|
||||
}
|
||||
}
|
||||
|
||||
const startPeriodicRefresh = (intervalMs: number = 30000) => {
|
||||
const interval = setInterval(() => {
|
||||
void fetchUnreadCount()
|
||||
}, intervalMs)
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval)
|
||||
})
|
||||
|
||||
return interval
|
||||
}
|
||||
|
||||
return {
|
||||
notifications,
|
||||
unreadNotifications,
|
||||
unreadCount,
|
||||
isLoading,
|
||||
fetchNotifications,
|
||||
fetchUnreadNotifications,
|
||||
fetchUnreadCount,
|
||||
markAllAsRead,
|
||||
markAsRead,
|
||||
handleNotificationClick,
|
||||
startPeriodicRefresh
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,12 @@ export function useNotificationApi() {
|
||||
return notificationApiClient.markNotificationAsRead({ id, organizationId })
|
||||
}
|
||||
|
||||
async function clearAllNotifications(organizationId: string): Promise<void> {
|
||||
return notificationApiClient.clearAllNotifications({ organizationId })
|
||||
async function clearAllNotifications(): Promise<void> {
|
||||
return notificationApiClient.clearAllNotifications()
|
||||
}
|
||||
|
||||
async function deleteNotification(id: string): Promise<void> {
|
||||
return notificationApiClient.deleteNotification({ id })
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -55,6 +59,7 @@ export function useNotificationApi() {
|
||||
getUnreadNotificationCount,
|
||||
markAllNotificationsAsRead,
|
||||
markNotificationAsRead,
|
||||
clearAllNotifications
|
||||
clearAllNotifications,
|
||||
deleteNotification
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,17 @@ export function useUser() {
|
||||
userId: string,
|
||||
email: string | null,
|
||||
emailOnFormCreated: boolean,
|
||||
emailOnFormSubmitted: boolean
|
||||
emailOnFormSubmitted: boolean,
|
||||
emailOnFormUpdated: boolean,
|
||||
emailOnCommentAdded: boolean
|
||||
): Promise<UserDto> {
|
||||
const updateDto: UpdateEmailPreferencesDto = { email, emailOnFormCreated, emailOnFormSubmitted }
|
||||
const updateDto: UpdateEmailPreferencesDto = {
|
||||
email,
|
||||
emailOnFormCreated,
|
||||
emailOnFormSubmitted,
|
||||
emailOnFormUpdated,
|
||||
emailOnCommentAdded
|
||||
}
|
||||
|
||||
return await userApi.updateEmailPreferences(userId, updateDto)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user