diff --git a/.changeset/long-clouds-relate.md b/.changeset/long-clouds-relate.md new file mode 100644 index 0000000000..0c921b36e4 --- /dev/null +++ b/.changeset/long-clouds-relate.md @@ -0,0 +1,5 @@ +--- +'@directus/app': minor +--- + +Added item count to the notification drawer diff --git a/app/src/utils/format-items-count.ts b/app/src/utils/format-items-count.ts index 1da5bcb06e..d5b9238c2d 100644 --- a/app/src/utils/format-items-count.ts +++ b/app/src/utils/format-items-count.ts @@ -1,4 +1,4 @@ -import { useI18n } from 'vue-i18n'; +import { ComposerNumberFormatting, ComposerTranslation, useI18n } from 'vue-i18n'; export type FormatItemsCountPaginatedOptions = { currentItems: number; @@ -6,6 +6,7 @@ export type FormatItemsCountPaginatedOptions = { perPage: number; isFiltered?: boolean; totalItems?: number; + i18n?: { t: ComposerTranslation; n: ComposerNumberFormatting }; }; export function formatItemsCountPaginated({ @@ -14,8 +15,9 @@ export function formatItemsCountPaginated({ perPage, isFiltered, totalItems, + i18n, }: FormatItemsCountPaginatedOptions) { - const { t, n } = useI18n(); + const { t, n } = i18n ? i18n : useI18n(); const values = { start: n((currentPage - 1) * perPage + 1), @@ -39,14 +41,16 @@ export type FormatItemsCountRelativeOptions = { totalItems: number; currentItems: number; isFiltered?: boolean; + i18n?: { t: ComposerTranslation; n: ComposerNumberFormatting }; }; export function formatItemsCountRelative({ totalItems, currentItems, isFiltered = false, + i18n, }: FormatItemsCountRelativeOptions) { - const { t, n } = useI18n(); + const { t, n } = i18n ? i18n : useI18n(); const values = { count: n(currentItems), diff --git a/app/src/views/private/components/notifications-drawer.vue b/app/src/views/private/components/notifications-drawer.vue index 9b6882a8e0..34720535c3 100644 --- a/app/src/views/private/components/notifications-drawer.vue +++ b/app/src/views/private/components/notifications-drawer.vue @@ -4,11 +4,13 @@ import useDatetime from '@/components/use-datetime.vue'; import { useCollectionsStore } from '@/stores/collections'; import { useNotificationsStore } from '@/stores/notifications'; import { useUserStore } from '@/stores/user'; +import { formatItemsCountPaginated } from '@/utils/format-items-count'; import { getCollectionRoute, getItemRoute } from '@/utils/get-route'; import SearchInput from '@/views/private/components/search-input.vue'; import { useItems } from '@directus/composables'; import { useAppStore } from '@directus/stores'; import { Filter, Notification } from '@directus/types'; +import { mergeFilters } from '@directus/utils'; import { storeToRefs } from 'pinia'; import { computed, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; @@ -18,7 +20,7 @@ type LocalNotification = Notification & { to?: string; }; -const { t } = useI18n(); +const { t, n } = useI18n(); const appStore = useAppStore(); const userStore = useUserStore(); const collectionsStore = useCollectionsStore(); @@ -69,30 +71,36 @@ function toggleNotification(id: string) { } } -const filter = computed(() => ({ - _and: [ - { - recipient: { - _eq: userStore.currentUser!.id, - }, - }, - { - status: { - _eq: tab.value[0], - }, - }, - userFilter.value, - ], -})); +const filterSystem = computed( + () => + ({ + _and: [ + { + recipient: { + _eq: userStore.currentUser!.id, + }, + }, + { + status: { + _eq: tab.value[0], + }, + }, + ], + }) as Filter, +); -const { items, loading, getItems, totalPages, getItemCount } = useItems(ref('directus_notifications'), { - filter, - fields: ref(['id', 'subject', 'message', 'collection', 'item', 'timestamp']), - sort: ref(['-timestamp']), - search, - limit, - page, -}); +const { items, loading, totalPages, totalCount, itemCount, getItems, getItemCount, getTotalCount } = useItems( + collection, + { + filter: computed(() => mergeFilters(filter.value, filterSystem.value)), + filterSystem, + fields: ref(['id', 'subject', 'message', 'collection', 'item', 'timestamp']), + sort: ref(['-timestamp']), + search, + limit, + page, + }, +); const notifications = computed(() => { return items.value.map((item) => { @@ -117,9 +125,24 @@ const notifications = computed(() => { }); }); +const showingCount = computed(() => { + // Don't show count if there are no items + if (!totalCount.value || !itemCount.value) return; + + return formatItemsCountPaginated({ + currentItems: itemCount.value, + currentPage: page.value, + perPage: limit.value, + isFiltered: !!filter.value, + totalItems: totalCount.value, + i18n: { t, n }, + }); +}); + async function refresh() { - await getItemCount(); await getItems(); + await getTotalCount(); + await getItemCount(); } async function archiveAll() { @@ -168,8 +191,16 @@ function onLinkClick(to: string) { :sidebar-label="t('folders')" @cancel="notificationsDrawerOpen = false" > + +