refactor: notifications panel code
This commit is contained in:
parent
fd23d66ccd
commit
37bf0f6ff9
@ -18,15 +18,12 @@
|
||||
>
|
||||
<template #right>
|
||||
<Badge
|
||||
v-if="
|
||||
!isSidebarCollapsed &&
|
||||
notificationsStore().unreadNotificationsCount
|
||||
"
|
||||
:label="notificationsStore().unreadNotificationsCount"
|
||||
v-if="!isSidebarCollapsed && unreadNotificationsCount"
|
||||
:label="unreadNotificationsCount"
|
||||
variant="subtle"
|
||||
/>
|
||||
<div
|
||||
v-else-if="notificationsStore().unreadNotificationsCount"
|
||||
v-else-if="unreadNotificationsCount"
|
||||
class="absolute -left-1.5 top-1 z-20 h-[5px] w-[5px] translate-x-6 translate-y-1 rounded-full bg-gray-800 ring-1 ring-white"
|
||||
/>
|
||||
</template>
|
||||
@ -112,7 +109,10 @@ import NotificationsIcon from '@/components/Icons/NotificationsIcon.vue'
|
||||
import SidebarLink from '@/components/SidebarLink.vue'
|
||||
import Notifications from '@/components/Notifications.vue'
|
||||
import { viewsStore } from '@/stores/views'
|
||||
import { notificationsStore } from '@/stores/notifications'
|
||||
import {
|
||||
unreadNotificationsCount,
|
||||
notificationsStore,
|
||||
} from '@/stores/notifications'
|
||||
import { FeatherIcon } from 'frappe-ui'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { computed, h } from 'vue'
|
||||
|
||||
@ -25,8 +25,8 @@
|
||||
>
|
||||
<template #right>
|
||||
<Badge
|
||||
v-if="notificationsStore().unreadNotificationsCount"
|
||||
:label="notificationsStore().unreadNotificationsCount"
|
||||
v-if="unreadNotificationsCount"
|
||||
:label="unreadNotificationsCount"
|
||||
variant="subtle"
|
||||
/>
|
||||
</template>
|
||||
@ -101,7 +101,7 @@ import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||
import NotificationsIcon from '@/components/Icons/NotificationsIcon.vue'
|
||||
import SidebarLink from '@/components/SidebarLink.vue'
|
||||
import { viewsStore } from '@/stores/views'
|
||||
import { notificationsStore } from '@/stores/notifications'
|
||||
import { unreadNotificationsCount } from '@/stores/notifications'
|
||||
import { computed, h } from 'vue'
|
||||
import { mobileSidebarOpened as sidebarOpened } from '@/composables/settings'
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="notificationsStore().visible"
|
||||
v-if="visible"
|
||||
ref="target"
|
||||
class="absolute z-20 h-screen bg-white transition-all duration-300 ease-in-out"
|
||||
:style="{
|
||||
@ -27,7 +27,7 @@
|
||||
</Tooltip>
|
||||
<Tooltip :text="__('Close')">
|
||||
<div>
|
||||
<Button variant="ghost" @click="() => toggleNotificationPanel()">
|
||||
<Button variant="ghost" @click="() => toggle()">
|
||||
<template #icon>
|
||||
<FeatherIcon name="x" class="h-4 w-4" />
|
||||
</template>
|
||||
@ -37,11 +37,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="notificationsStore().allNotifications?.length"
|
||||
v-if="notifications.data?.length"
|
||||
class="divide-y overflow-auto text-base"
|
||||
>
|
||||
<RouterLink
|
||||
v-for="n in notificationsStore().allNotifications"
|
||||
v-for="n in notifications.data"
|
||||
:key="n.comment"
|
||||
:to="getRoute(n)"
|
||||
class="flex cursor-pointer items-start gap-2.5 px-4 py-2.5 hover:bg-gray-100"
|
||||
@ -91,7 +91,11 @@ import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
|
||||
import MarkAsDoneIcon from '@/components/Icons/MarkAsDoneIcon.vue'
|
||||
import NotificationsIcon from '@/components/Icons/NotificationsIcon.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import { notificationsStore } from '@/stores/notifications'
|
||||
import {
|
||||
visible,
|
||||
notifications,
|
||||
notificationsStore,
|
||||
} from '@/stores/notifications'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { timeAgo } from '@/utils'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
@ -100,32 +104,27 @@ import { Tooltip } from 'frappe-ui'
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
const { $socket } = globalStore()
|
||||
const { mark_as_read, toggle, mark_doc_as_read } = notificationsStore()
|
||||
|
||||
const target = ref(null)
|
||||
onClickOutside(
|
||||
target,
|
||||
() => {
|
||||
if (notificationsStore().visible) {
|
||||
toggleNotificationPanel()
|
||||
}
|
||||
if (visible.value) toggle()
|
||||
},
|
||||
{
|
||||
ignore: ['#notifications-btn'],
|
||||
},
|
||||
)
|
||||
|
||||
function toggleNotificationPanel() {
|
||||
notificationsStore().toggle()
|
||||
}
|
||||
|
||||
function markAsRead(doc) {
|
||||
capture('notification_mark_as_read')
|
||||
notificationsStore().mark_doc_as_read(doc)
|
||||
mark_doc_as_read(doc)
|
||||
}
|
||||
|
||||
function markAllAsRead() {
|
||||
capture('notification_mark_all_as_read')
|
||||
notificationsStore().mark_as_read.reload()
|
||||
mark_as_read.reload()
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@ -134,7 +133,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
onMounted(() => {
|
||||
$socket.on('crm_notification', () => {
|
||||
notificationsStore().notifications.reload()
|
||||
notifications.reload()
|
||||
})
|
||||
})
|
||||
|
||||
@ -154,6 +153,4 @@ function getRoute(notification) {
|
||||
hash: notification.hash,
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<div>
|
||||
<Button
|
||||
:label="__('Mark all as read')"
|
||||
@click="() => notificationsStore().mark_as_read.reload()"
|
||||
@click="() => mark_as_read.reload()"
|
||||
>
|
||||
<template #prefix>
|
||||
<MarkAsDoneIcon class="h-4 w-4" />
|
||||
@ -24,15 +24,15 @@
|
||||
</LayoutHeader>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<div
|
||||
v-if="notificationsStore().allNotifications?.length"
|
||||
v-if="notifications.data?.length"
|
||||
class="divide-y overflow-y-auto text-base"
|
||||
>
|
||||
<RouterLink
|
||||
v-for="n in notificationsStore().allNotifications"
|
||||
v-for="n in notifications.data"
|
||||
:key="n.comment"
|
||||
:to="getRoute(n)"
|
||||
class="flex cursor-pointer items-start gap-3 px-2.5 py-3 hover:bg-gray-100"
|
||||
@click="mark_as_read(n.comment || n.notification_type_doc)"
|
||||
@click="mark_doc_as_read(n.comment || n.notification_type_doc)"
|
||||
>
|
||||
<div class="mt-1 flex items-center gap-2.5">
|
||||
<div
|
||||
@ -75,17 +75,14 @@ import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
|
||||
import MarkAsDoneIcon from '@/components/Icons/MarkAsDoneIcon.vue'
|
||||
import NotificationsIcon from '@/components/Icons/NotificationsIcon.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import { notificationsStore } from '@/stores/notifications'
|
||||
import { notifications, notificationsStore } from '@/stores/notifications'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { timeAgo } from '@/utils'
|
||||
import { Breadcrumbs, Tooltip } from 'frappe-ui'
|
||||
import { onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
const { $socket } = globalStore()
|
||||
|
||||
function mark_as_read(doc) {
|
||||
notificationsStore().mark_doc_as_read(doc)
|
||||
}
|
||||
const { mark_as_read, mark_doc_as_read } = notificationsStore()
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
$socket.off('crm_notification')
|
||||
@ -93,7 +90,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
onMounted(() => {
|
||||
$socket.on('crm_notification', () => {
|
||||
notificationsStore().notifications.reload()
|
||||
notifications.reload()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -2,18 +2,21 @@ import { defineStore } from 'pinia'
|
||||
import { createResource } from 'frappe-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
export const visible = ref(false)
|
||||
|
||||
export const notifications = createResource({
|
||||
url: 'crm.api.notifications.get_notifications',
|
||||
initialData: [],
|
||||
auto: true,
|
||||
})
|
||||
|
||||
export const unreadNotificationsCount = computed(
|
||||
() => notifications.data?.filter((n) => !n.read).length || 0,
|
||||
)
|
||||
|
||||
export const notificationsStore = defineStore('crm-notifications', () => {
|
||||
let visible = ref(false)
|
||||
|
||||
const notifications = createResource({
|
||||
url: 'crm.api.notifications.get_notifications',
|
||||
initialData: [],
|
||||
auto: true,
|
||||
})
|
||||
|
||||
const mark_as_read = createResource({
|
||||
url: 'crm.api.notifications.mark_as_read',
|
||||
auto: false,
|
||||
onSuccess: () => {
|
||||
mark_as_read.params = {}
|
||||
notifications.reload()
|
||||
@ -24,11 +27,6 @@ export const notificationsStore = defineStore('crm-notifications', () => {
|
||||
visible.value = !visible.value
|
||||
}
|
||||
|
||||
const allNotifications = computed(() => notifications.data || [])
|
||||
const unreadNotificationsCount = computed(
|
||||
() => notifications.data?.filter((n) => !n.read).length || 0
|
||||
)
|
||||
|
||||
function mark_doc_as_read(doc) {
|
||||
mark_as_read.params = { doc: doc }
|
||||
mark_as_read.reload()
|
||||
@ -36,9 +34,6 @@ export const notificationsStore = defineStore('crm-notifications', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
notifications,
|
||||
visible,
|
||||
allNotifications,
|
||||
unreadNotificationsCount,
|
||||
mark_as_read,
|
||||
mark_doc_as_read,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user