Skip to content

Commit 7cd8714

Browse files
feat(notification): add mark as read
1 parent 4a1bc1f commit 7cd8714

2 files changed

Lines changed: 62 additions & 18 deletions

File tree

components/SiteHeader/SiteHeader.vue

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -320,23 +320,35 @@
320320
</p>
321321
</div>
322322
</template>
323-
<button
324-
v-if="nextPage"
325-
type="button"
326-
class="w-full bg-datagouv hover:bg-datagouv-dark text-white p-2 flex items-center justify-center"
327-
:disabled="isLoading"
328-
@click="loadMoreNotifications"
323+
<div
324+
v-if="nextPage || pendingNotifications?.total"
325+
class="px-2 py-2 space-y-2 border-t border-gray-default"
329326
>
330-
<AnimatedLoader
331-
v-if="isLoading"
332-
class="size-5"
333-
/>
334-
<RiAddLine
335-
v-else
336-
class="size-5"
337-
/>
338-
{{ t('Charger plus de notifications') }}
339-
</button>
327+
<BrandedButton
328+
v-if="nextPage"
329+
type="button"
330+
color="primary"
331+
size="xs"
332+
:icon="RiAddLine"
333+
:loading="isLoading"
334+
class="w-full rounded-full"
335+
@click="loadMoreNotifications"
336+
>
337+
{{ t('Charger plus de notifications') }}
338+
</BrandedButton>
339+
<BrandedButton
340+
v-if="pendingNotifications?.total"
341+
type="button"
342+
color="secondary"
343+
size="xs"
344+
:icon="RiCheckLine"
345+
:loading="loading"
346+
class="w-full rounded-full"
347+
@click="() => markWithoutActionAsRead(notificationsCombinedList)"
348+
>
349+
{{ t('Marquer comme lues') }}
350+
</BrandedButton>
351+
</div>
340352
</template>
341353
</Toggletip>
342354
</li>
@@ -508,12 +520,13 @@
508520
<script setup lang="ts">
509521
import { NuxtImg as _NuxtImg } from '#components'
510522
import type { Component } from 'vue'
511-
import { AnimatedLoader, BrandedButton, Toggletip, useGetUserAvatar, toast } from '@datagouv/components-next'
512-
import { RiAccountCircleLine, RiAddLine, RiDatabase2Line, RiInbox2Line, RiLockLine, RiMenuLine, RiSearchLine, RiTerminalLine, RiLineChartLine, RiServerLine, RiArticleLine, RiSettings3Line, RiLogoutBoxRLine, RiBuilding2Line, RiCloseLine } from '@remixicon/vue'
523+
import { BrandedButton, Toggletip, useGetUserAvatar, toast } from '@datagouv/components-next'
524+
import { RiAccountCircleLine, RiAddLine, RiCheckLine, RiDatabase2Line, RiInbox2Line, RiLockLine, RiMenuLine, RiSearchLine, RiTerminalLine, RiLineChartLine, RiServerLine, RiArticleLine, RiSettings3Line, RiLogoutBoxRLine, RiBuilding2Line, RiCloseLine } from '@remixicon/vue'
513525
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems, Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
514526
import CdataLink from '../CdataLink.vue'
515527
import LogoAsText from '../LogoAsText.vue'
516528
import LogoImage from '../LogoImage.vue'
529+
import { useMarkAsRead } from '~/composables/useMarkAsRead'
517530
import { useNotifications } from '~/composables/useNotifications.client'
518531
import { useLogout, useMaybeMe } from '~/utils/auth'
519532
@@ -534,6 +547,7 @@ const router = useRouter()
534547
const route = useRoute()
535548
const { isLoading } = useLoadingIndicator()
536549
const { refreshNotifications, loadMoreNotifications, pendingNotifications, nextPage, notificationsCombinedList } = useNotifications()
550+
const { markWithoutActionAsRead, loading } = useMarkAsRead()
537551
538552
const menu = [
539553
{ label: t('Données'), link: '/datasets' },

composables/useMarkAsRead.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,38 @@ export function useMarkAsRead() {
2020
}
2121
}
2222

23+
const markWithoutActionAsRead = async (notifications: Array<UserNotification>) => {
24+
const withoutActionUnread = notifications.filter((n) => {
25+
const cls = n.details.class
26+
if (cls === 'MembershipRequestNotificationDetails') return false
27+
if (cls === 'TransferRequestNotificationDetails') return false
28+
if (cls === 'ValidateHarvesterNotificationDetails') {
29+
return n.details.status !== 'pending'
30+
}
31+
return !n.handled_at
32+
})
33+
34+
if (withoutActionUnread.length === 0) {
35+
return
36+
}
37+
38+
try {
39+
loading.value = true
40+
await Promise.all(
41+
withoutActionUnread.map(notification =>
42+
$api(`/api/1/notifications/${notification.id}/read/`, { method: 'POST' }),
43+
),
44+
)
45+
await refreshNotifications()
46+
}
47+
finally {
48+
loading.value = false
49+
}
50+
}
51+
2352
return {
2453
markAsRead,
54+
markWithoutActionAsRead,
2555
loading,
2656
}
2757
}

0 commit comments

Comments
 (0)