|
|
@@ -2,50 +2,68 @@
|
|
|
<v-btn
|
|
|
ref="btn"
|
|
|
icon
|
|
|
- color=""
|
|
|
- @click="click"
|
|
|
+ width="48px"
|
|
|
+ size="small"
|
|
|
>
|
|
|
<v-badge
|
|
|
color="orange"
|
|
|
- offset-y="10"
|
|
|
- :value="unreadNotification.length > 0"
|
|
|
- :content="unreadNotification.length"
|
|
|
- >
|
|
|
- <v-icon class="text-ot-white" small>
|
|
|
- fa-bell
|
|
|
+ offset-x="-4"
|
|
|
+ offset-y="17"
|
|
|
+ :model-value="unreadNotification.length > 0"
|
|
|
+ :content="unreadNotification.length">
|
|
|
+ <v-icon class="text-ot-white">
|
|
|
+ fa fa-bell
|
|
|
</v-icon>
|
|
|
</v-badge>
|
|
|
</v-btn>
|
|
|
|
|
|
- <v-tooltip bottom :activator="btn">
|
|
|
+ <v-tooltip :activator="btn" location="bottom">
|
|
|
<span>{{ $t('notification') }}</span>
|
|
|
</v-tooltip>
|
|
|
|
|
|
- <v-menu :activator="btn" offset-y v-model="isOpen">
|
|
|
- <v-card scrollable max-width="400">
|
|
|
+ <v-menu
|
|
|
+ :activator="btn"
|
|
|
+ v-model="isOpen"
|
|
|
+ >
|
|
|
+ <v-card max-width="400">
|
|
|
<v-card-title class="ot-header-menu text-body-2 font-weight-bold">
|
|
|
{{ $t('notification') }}
|
|
|
</v-card-title>
|
|
|
|
|
|
<v-card-text class="ma-0 pa-0 header-menu">
|
|
|
- <v-list dense :subheader="true">
|
|
|
- <template v-for="(notification, index) in notifications">
|
|
|
- <v-list-item :key="index" :class="`${notification.notificationUsers.length === 0 ? 'unread' : ''}`">
|
|
|
- <v-list-item-content>
|
|
|
- <v-list-item-title class="list_item mt-2 mb-2" v-text="getMessage(notification)"/>
|
|
|
- </v-list-item-content>
|
|
|
- <v-list-item-icon v-if="notification.link" class="pt-4">
|
|
|
- <v-icon @click="download(notification.link)" icon="mdi-download" />
|
|
|
- </v-list-item-icon>
|
|
|
- </v-list-item>
|
|
|
- <v-divider></v-divider>
|
|
|
- </template>
|
|
|
+ <v-list density="compact" :subheader="true">
|
|
|
+ <v-list-item
|
|
|
+ v-for="(notification, index) in notifications"
|
|
|
+ :key="index"
|
|
|
+ :class="`${notification.notificationUsers.length === 0 ? 'unread' : ''}`"
|
|
|
+ >
|
|
|
+
|
|
|
+ <v-list-item-content>
|
|
|
+ <v-list-item-title
|
|
|
+ class="list_item mt-2 mb-2"
|
|
|
+ v-text="getMessage(notification)"
|
|
|
+ style="font-size: 13px; line-height: 16px;"
|
|
|
+ />
|
|
|
+ </v-list-item-content>
|
|
|
+
|
|
|
+ <template #append>
|
|
|
+ <v-icon
|
|
|
+ v-if="notification.link"
|
|
|
+ icon="mdi:mdi-download"
|
|
|
+ @click="download(notification.link)"
|
|
|
+ class="pt-4"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+<!-- <v-divider v-if="index < (notifications.length - 1)"/>-->
|
|
|
+ </v-list-item>
|
|
|
</v-list>
|
|
|
|
|
|
+ <!--suppress VueUnrecognizedDirective -->
|
|
|
<v-card v-intersect="update"></v-card>
|
|
|
|
|
|
<v-row
|
|
|
- v-if="loading"
|
|
|
+ v-if="pending"
|
|
|
class="fill-height mt-3 mb-3"
|
|
|
align="center"
|
|
|
justify="center"
|
|
|
@@ -53,21 +71,23 @@
|
|
|
<v-progress-circular
|
|
|
indeterminate
|
|
|
color="grey lighten-1"
|
|
|
- ></v-progress-circular>
|
|
|
+ />
|
|
|
</v-row>
|
|
|
</v-card-text>
|
|
|
|
|
|
<v-card-actions class="ma-0 pa-0">
|
|
|
- <template>
|
|
|
- <v-list-item
|
|
|
- id="all_notifications"
|
|
|
- :key="$t('all_notification')"
|
|
|
- :href="notificationUrl"
|
|
|
- router
|
|
|
- >
|
|
|
- <v-list-item-title class="text-body-2 text-ot-white" v-text="$t('all_notification')"/>
|
|
|
- </v-list-item>
|
|
|
- </template>
|
|
|
+ <v-list-item
|
|
|
+ id="all_notifications"
|
|
|
+ :key="$t('all_notification')"
|
|
|
+ :href="notificationUrl"
|
|
|
+ router
|
|
|
+ style="width: 100%; height: 52px;"
|
|
|
+ >
|
|
|
+ <v-list-item-title
|
|
|
+ class="text-body-2 text-ot-white"
|
|
|
+ v-text="$t('all_notification')"
|
|
|
+ />
|
|
|
+ </v-list-item>
|
|
|
</v-card-actions>
|
|
|
</v-card>
|
|
|
</v-menu>
|
|
|
@@ -78,12 +98,14 @@ import {NOTIFICATION_TYPE, QUERY_TYPE} from "~/types/enum/enums";
|
|
|
import {Notification} from "~/models/Core/Notification";
|
|
|
import {NotificationUsers} from "~/models/Core/NotificationUsers";
|
|
|
import {useAccessProfileStore} from "~/stores/accessProfile";
|
|
|
-import {ComputedRef, Ref} from "@vue/reactivity";
|
|
|
+import {ComputedRef, Ref, ref} from "@vue/reactivity";
|
|
|
import {useEntityFetch} from "~/composables/data/useEntityFetch";
|
|
|
import {Pagination} from "~/types/data";
|
|
|
+import {useEntityManager} from "~/composables/data/useEntityManager";
|
|
|
+import Url from "~/services/utils/url";
|
|
|
|
|
|
const accessProfileStore = useAccessProfileStore()
|
|
|
-const currentAccessId = accessProfileStore.id
|
|
|
+
|
|
|
const loading: Ref<Boolean> = ref(true)
|
|
|
const isOpen: Ref<Boolean> = ref(false)
|
|
|
const page: Ref<number> = ref(1)
|
|
|
@@ -93,15 +115,19 @@ const runtimeConfig = useRuntimeConfig()
|
|
|
|
|
|
const btn = ref(null)
|
|
|
|
|
|
+const { em } = useEntityManager()
|
|
|
const { fetchCollection } = useEntityFetch()
|
|
|
|
|
|
-const { data: collection, pending } = await fetchCollection(Notification)
|
|
|
+let { data: collection, pending, refresh } = await fetchCollection(Notification)
|
|
|
+
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* On récupère les Notifications via le store
|
|
|
*/
|
|
|
const notifications: ComputedRef = computed(() => {
|
|
|
// TODO: revoir pour reprendre le order by et tout
|
|
|
+ console.log(collection.value?.items[0].id)
|
|
|
return collection.value !== null ? collection.value.items : []
|
|
|
})
|
|
|
|
|
|
@@ -126,11 +152,18 @@ const unreadNotification: ComputedRef<Array<Notification>> = computed(() => {
|
|
|
* (si on a fini de télécharger les éléments précédents)
|
|
|
*/
|
|
|
const update = async () => {
|
|
|
- if (!fetchState.pending && metadata.value?.nextPage && metadata.value.nextPage > 0) {
|
|
|
+ if (
|
|
|
+ !pending &&
|
|
|
+ pagination.value &&
|
|
|
+ pagination.value.next &&
|
|
|
+ pagination.value.next > 0
|
|
|
+ ) {
|
|
|
loading.value = true
|
|
|
- page.value = metadata.value.nextPage
|
|
|
- await fetch()
|
|
|
- //Si des notifications n'avaient pas été marquées comme lues, on le fait immédiatement.
|
|
|
+ page.value = pagination.value.next
|
|
|
+
|
|
|
+ await refresh()
|
|
|
+
|
|
|
+ // Si des notifications n'avaient pas été marquées comme lues, on le fait immédiatement.
|
|
|
markNotificationsAsRead()
|
|
|
}
|
|
|
}
|
|
|
@@ -139,19 +172,19 @@ const update = async () => {
|
|
|
* On construit le message qui va devoir s'afficher pour une notification
|
|
|
* @param notification
|
|
|
*/
|
|
|
-const getMessage = (notification:Notification) => {
|
|
|
+const getMessage = (notification: Notification) => {
|
|
|
switch (notification.type){
|
|
|
case NOTIFICATION_TYPE.FILE :
|
|
|
- return `${i18n.t('your_file')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be_downloaded')}`
|
|
|
+ return `${i18n.t('your_file')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be_downloaded')}`
|
|
|
|
|
|
- case NOTIFICATION_TYPE.MESSAGE:
|
|
|
- if(notification.message?.action)
|
|
|
- return `${i18n.t('your_message')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be')} ${notification.message.action}`
|
|
|
+ case NOTIFICATION_TYPE.MESSAGE:
|
|
|
+ if (notification.message?.action)
|
|
|
+ return `${i18n.t('your_message')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be')} ${notification.message.action}`
|
|
|
|
|
|
- return `${i18n.t('your_message')} ${notification.message?.about ?? ''} ${i18n.t('has_been_sent')} `
|
|
|
+ return `${i18n.t('your_message')} ${notification.message?.about ?? ''} ${i18n.t('has_been_sent')} `
|
|
|
|
|
|
case NOTIFICATION_TYPE.SYSTEM :
|
|
|
- if(notification.message?.about)
|
|
|
+ if (notification.message?.about)
|
|
|
return `${i18n.t(notification.message.about)}`
|
|
|
break;
|
|
|
|
|
|
@@ -164,62 +197,61 @@ const getMessage = (notification:Notification) => {
|
|
|
* Dès l'ouverture du menu, on indique que les notifications non lues, le sont.
|
|
|
*/
|
|
|
const unwatch = watch(isOpen, (newValue, oldValue) => {
|
|
|
- if(newValue){
|
|
|
+ if (newValue){
|
|
|
markNotificationsAsRead()
|
|
|
}
|
|
|
})
|
|
|
-
|
|
|
onUnmounted(() => {
|
|
|
unwatch()
|
|
|
})
|
|
|
|
|
|
/**
|
|
|
- * Marque les notifications non lues comme lues
|
|
|
+ * Créer une nouvelle notification users coté back.
|
|
|
+ * @param notification
|
|
|
+ * @param accessId
|
|
|
*/
|
|
|
-const markNotificationsAsRead = () => {
|
|
|
- unreadNotification.value.map((notification:Notification)=>{
|
|
|
- notification.notificationUsers = ['read']
|
|
|
- repositoryHelper.persist(Notification, notification)
|
|
|
- createNewNotificationUsers(notification)
|
|
|
+const createNewNotificationUsers = (notification: Notification, accessId: number) => {
|
|
|
+ const notificationUsers = em.newInstance(NotificationUsers, {
|
|
|
+ access:`/api/accesses/${accessId}`,
|
|
|
+ notification:`/api/notifications/${notification.id}`,
|
|
|
+ isRead: true
|
|
|
})
|
|
|
+
|
|
|
+ em.persist(NotificationUsers, notificationUsers)
|
|
|
+ notification.notificationUsers = ['read']
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Créer une nouvelle notification users coté back.
|
|
|
- * @param notification
|
|
|
+ * Marque les notifications non lues comme lues
|
|
|
*/
|
|
|
-const createNewNotificationUsers = (notification: Notification) =>{
|
|
|
- const newNotificationUsers = repositoryHelper.persist(NotificationUsers, new NotificationUsers(
|
|
|
- {
|
|
|
- access:`/api/accesses/${currentAccessId}`,
|
|
|
- notification:`/api/notifications/${notification.id}`,
|
|
|
- isRead: true
|
|
|
+const markNotificationsAsRead = () => {
|
|
|
+ unreadNotification.value.map((notification: Notification) => {
|
|
|
+ if (accessProfileStore.id === null) {
|
|
|
+ throw new Error('Current access id is null')
|
|
|
}
|
|
|
- )) as NotificationUsers
|
|
|
-
|
|
|
- $dataPersister.invoke({
|
|
|
- type: QUERY_TYPE.MODEL,
|
|
|
- model: NotificationUsers,
|
|
|
- idTemp: newNotificationUsers.id,
|
|
|
- showProgress: false
|
|
|
+ createNewNotificationUsers(notification, accessProfileStore.id)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Download le lien
|
|
|
+ * Download la cible du lien
|
|
|
* @param link
|
|
|
*/
|
|
|
const download = (link: string) => {
|
|
|
+ if (accessProfileStore.id === null) {
|
|
|
+ throw new Error('Current access id is null')
|
|
|
+ }
|
|
|
const url_parts: Array<string> = link.split('/api');
|
|
|
+
|
|
|
if(accessProfileStore.originalAccess)
|
|
|
- url_parts[0] = `api/${accessProfileStore.originalAccess.id}/${currentAccessId}`
|
|
|
+ url_parts[0] = Url.join('api', String(accessProfileStore.originalAccess.id), String(accessProfileStore.id))
|
|
|
else
|
|
|
- url_parts[0] = `api/${currentAccessId}`
|
|
|
+ url_parts[0] = Url.join('api', String(accessProfileStore.id))
|
|
|
|
|
|
- window.open(`${runtimeConfig.baseUrlLegacy}/${url_parts.join('')}`);
|
|
|
+ window.open(Url.join(runtimeConfig.baseUrlLegacy, url_parts.join('')));
|
|
|
}
|
|
|
|
|
|
-const notificationUrl = `${runtimeConfig.baseURL_adminLegacy}/notifications/list/`
|
|
|
+const notificationUrl = Url.join(runtimeConfig.baseUrlAdminLegacy, 'notifications/list/')
|
|
|
|
|
|
</script>
|
|
|
|