From b15f94f8859e7f5664495d3cd7df393f94e911c9 Mon Sep 17 00:00:00 2001 From: Kristina Date: Thu, 25 Jan 2024 10:00:30 +0400 Subject: [PATCH] Fix hidden notifications (#4436) Signed-off-by: Kristina Fefelova --- .../src/components/inbox/Inbox.svelte | 5 ++- .../inbox/InboxGroupedListView.svelte | 4 +- plugins/notification-resources/src/utils.ts | 38 ++++++++++++++++--- plugins/view-resources/src/utils.ts | 17 +++++++-- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/plugins/notification-resources/src/components/inbox/Inbox.svelte b/plugins/notification-resources/src/components/inbox/Inbox.svelte index 23a52b3e6c..04fd36c755 100644 --- a/plugins/notification-resources/src/components/inbox/Inbox.svelte +++ b/plugins/notification-resources/src/components/inbox/Inbox.svelte @@ -44,7 +44,6 @@ import Filter from '../Filter.svelte' import { getDisplayInboxNotifications, resolveLocation } from '../../utils' import { InboxNotificationsFilter } from '../../types' - import { onDestroy } from 'svelte' export let visibleNav: boolean = true export let navFloat: boolean = false @@ -91,7 +90,9 @@ viewlets = res }) - $: displayNotifications = getDisplayInboxNotifications($notificationsByContextStore, filter) + $: getDisplayInboxNotifications($notificationsByContextStore, filter).then((res) => { + displayNotifications = res + }) $: displayContextsIds = new Set(displayNotifications.map(({ docNotifyContext }) => docNotifyContext)) $: filteredNotifications = filterNotifications(selectedTabId, displayNotifications, $notifyContextsStore) diff --git a/plugins/notification-resources/src/components/inbox/InboxGroupedListView.svelte b/plugins/notification-resources/src/components/inbox/InboxGroupedListView.svelte index d29639917f..545636bbbb 100644 --- a/plugins/notification-resources/src/components/inbox/InboxGroupedListView.svelte +++ b/plugins/notification-resources/src/components/inbox/InboxGroupedListView.svelte @@ -76,14 +76,14 @@ key.preventDefault() key.stopPropagation() - const context = $notifyContextsStore.find(({ _id }) => _id === displayData[listSelection][0]) + const context = $notifyContextsStore.find(({ _id }) => _id === displayData[listSelection]?.[0]) deleteContextNotifications(context) } if (key.code === 'Enter') { key.preventDefault() key.stopPropagation() - const context = $notifyContextsStore.find(({ _id }) => _id === displayData[listSelection][0]) + const context = $notifyContextsStore.find(({ _id }) => _id === displayData[listSelection]?.[0]) dispatch('click', { context }) } } diff --git a/plugins/notification-resources/src/utils.ts b/plugins/notification-resources/src/utils.ts index ee2ab4d201..d6828c88c8 100644 --- a/plugins/notification-resources/src/utils.ts +++ b/plugins/notification-resources/src/utils.ts @@ -44,6 +44,7 @@ import { activityMessagesComparator, combineActivityMessages } from '@hcengineer import { type InboxNotificationsFilter } from './types' import { InboxNotificationsClientImpl } from './inboxNotificationsClient' +import { checkIsObjectRemoved } from '@hcengineering/view-resources' /** * @public @@ -355,11 +356,12 @@ async function generateLocation ( } } -export function getDisplayInboxNotifications ( +export async function getDisplayInboxNotifications ( notificationsByContext: Map, InboxNotification[]>, filter: InboxNotificationsFilter = 'all', objectClass?: Ref> -): DisplayInboxNotification[] { +): Promise { + const client = getClient() const filteredNotifications = Array.from(notificationsByContext.values()) .flat() .filter(({ isViewed }) => { @@ -375,6 +377,10 @@ export function getDisplayInboxNotifications ( } }) + const viewletsHideIfRemoved = client + .getModel() + .findAllSync(activity.class.DocUpdateMessageViewlet, { hideIfRemoved: true }) + const activityNotifications = filteredNotifications.filter( (n): n is WithLookup => n._class === notification.class.ActivityInboxNotification ) @@ -397,9 +403,31 @@ export function getDisplayInboxNotifications ( return (message as DocUpdateMessage).objectClass === objectClass }) - .sort(activityMessagesComparator) - const combinedMessages = combineActivityMessages(messages, SortingOrder.Descending) + for (const [index, message] of messages.entries()) { + if (message._class !== activity.class.DocUpdateMessage) { + continue + } + + const docUpdateMessage = message as DocUpdateMessage + + const hideIfRemoved = viewletsHideIfRemoved.some( + (viewlet) => viewlet.action === docUpdateMessage.action && viewlet.objectClass === docUpdateMessage.objectClass + ) + + if (!hideIfRemoved) { + continue + } + + const isRemoved = await checkIsObjectRemoved(client, docUpdateMessage.objectId, docUpdateMessage.objectClass) + + if (isRemoved) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete messages[index] + } + } + + const combinedMessages = combineActivityMessages(messages.sort(activityMessagesComparator), SortingOrder.Descending) for (const message of combinedMessages) { if (message._class === activity.class.DocUpdateMessage) { @@ -439,7 +467,7 @@ export function getDisplayInboxNotifications ( export async function hasInboxNotifications ( notificationsByContext: Map, InboxNotification[]> ): Promise { - const displayNotifications = getDisplayInboxNotifications(notificationsByContext) + const displayNotifications = await getDisplayInboxNotifications(notificationsByContext) return displayNotifications.some(({ isViewed }) => !isViewed) } diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts index 4c1e505d9c..df23335c5b 100644 --- a/plugins/view-resources/src/utils.ts +++ b/plugins/view-resources/src/utils.ts @@ -44,7 +44,8 @@ import core, { type TxCreateDoc, type TxUpdateDoc, type TxMixin, - ClassifierKind + ClassifierKind, + type TypeAny } from '@hcengineering/core' import type { Asset, IntlString } from '@hcengineering/platform' import { getResource, translate } from '@hcengineering/platform' @@ -172,6 +173,7 @@ export async function getAttributePresenter ( const hierarchy = client.getHierarchy() const attribute = hierarchy.getAttribute(_class, key) + const presenterClass = getAttributePresenterClass(hierarchy, attribute) const isCollectionAttr = presenterClass.category === 'collection' const mixin = isCollectionAttr ? view.mixin.CollectionPresenter : actualMixinClass @@ -181,7 +183,15 @@ export async function getAttributePresenter ( if (presenterMixin?.presenter === undefined && mixinClass != null && mixin === mixinClass) { presenterMixin = hierarchy.classHierarchyMixin(presenterClass.attrClass, view.mixin.AttributePresenter) } - if (presenterMixin?.presenter === undefined) { + + let presenter: AnySvelteComponent + + if (presenterMixin?.presenter !== undefined) { + presenter = await getResource(presenterMixin.presenter) + } else if (presenterClass.attrClass === core.class.TypeAny) { + const typeAny = attribute.type as TypeAny + presenter = await getResource(typeAny.presenter) + } else { throw new Error('attribute presenter not found for ' + JSON.stringify(preserveKey)) } @@ -191,7 +201,6 @@ export async function getAttributePresenter ( : attribute.type._class === core.class.ArrOf ? resultKey + '.length' : resultKey - const presenter = await getResource(presenterMixin.presenter) return { key: preserveKey.key, @@ -201,7 +210,7 @@ export async function getAttributePresenter ( presenter, props: preserveKey.props, displayProps: preserveKey.displayProps, - icon: presenterMixin.icon, + icon: presenterMixin?.icon, attribute, collectionAttr: isCollectionAttr, isLookup: false