diff --git a/models/inbox/src/index.ts b/models/inbox/src/index.ts index bde12f03ac..abe9bbbfc9 100644 --- a/models/inbox/src/index.ts +++ b/models/inbox/src/index.ts @@ -32,7 +32,7 @@ export function createModel (builder: Builder): void { label: inbox.string.Inbox, icon: inbox.icon.Inbox, alias: inboxId, - hidden: false, + hidden: true, component: inbox.component.InboxApplication, position: 'top', order: 100 diff --git a/models/notification/src/migration.ts b/models/notification/src/migration.ts index 06fa9a35d4..5bc85e0183 100644 --- a/models/notification/src/migration.ts +++ b/models/notification/src/migration.ts @@ -44,12 +44,9 @@ import notification, { type BrowserNotification, type DocNotifyContext, type InboxNotification, - type OldCollaborators, - type ReactionInboxNotification, - type ActivityInboxNotification + type OldCollaborators } from '@hcengineering/notification' import { DOMAIN_PREFERENCE } from '@hcengineering/preference' -import activity, { type ActivityMessage, type DocUpdateMessage, type Reaction } from '@hcengineering/activity' import { DOMAIN_SPACE, @@ -59,7 +56,6 @@ import { getSocialIdFromOldAccount } from '@hcengineering/model-core' import { DOMAIN_DOC_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_USER_NOTIFY } from './index' -import { DOMAIN_ACTIVITY, DOMAIN_REACTION } from '@hcengineering/model-activity' export async function removeNotifications ( client: MigrationClient, @@ -316,85 +312,11 @@ async function migrateCollaborators (client: MigrationClient): Promise { } async function migrateReactionNotifications (client: MigrationClient): Promise { - const hierarchy = client.hierarchy - const iterator = await client.traverse(DOMAIN_DOC_NOTIFY, { - _class: notification.class.DocNotifyContext - }) - - try { - while (true) { - const contexts = await iterator.next(500) - const res: ReactionInboxNotification[] = [] - const removeIds: Ref[] = [] - if (contexts == null || contexts.length === 0) break - const filtered = contexts.filter((it) => hierarchy.isDerived(it.objectClass, activity.class.ActivityMessage)) - if (filtered.length === 0) continue - - for (const context of filtered) { - const notifications = await client.find(DOMAIN_NOTIFICATION, { - docNotifyContext: context._id, - _class: notification.class.ActivityInboxNotification, - attachedToClass: activity.class.DocUpdateMessage - }) - if (notifications.length === 0) continue - const messages = await client.find(DOMAIN_ACTIVITY, { - _id: { $in: notifications.map((it) => it.attachedTo) as Ref[] }, - _class: activity.class.DocUpdateMessage, - objectClass: activity.class.Reaction - }) - const contextMessage = ( - await client.find(DOMAIN_ACTIVITY, { _id: context.objectId as any }) - )[0] - if (contextMessage == null) continue - const newContext = ( - await client.find(DOMAIN_DOC_NOTIFY, { - user: context.user, - objectId: contextMessage.attachedTo - }) - )[0] - if (newContext == null) { - continue - } - for (const it of notifications) { - const reactionMessage = messages.find((m) => m._id === it.attachedTo) - if (reactionMessage == null) continue - const emoji = - it.data ?? - (await client.find(DOMAIN_REACTION, { _id: reactionMessage.objectId as Ref }))[0].emoji - if (emoji == null || emoji.trim() === '') continue - res.push({ - _id: it._id as Ref, - _class: notification.class.ReactionInboxNotification, - space: it.space, - emoji, - user: it.user, - docNotifyContext: newContext._id, - objectId: newContext.objectId, - objectClass: newContext.objectClass, - ref: reactionMessage.objectId as Ref, - attachedTo: reactionMessage.attachedTo as Ref, - attachedToClass: reactionMessage.attachedToClass as Ref>, - isViewed: it.isViewed, - archived: it.archived, - modifiedOn: it.modifiedOn, - createdBy: it.createdBy, - createdOn: it.createdOn, - modifiedBy: it.modifiedBy - }) - } - } - - if (removeIds.length > 0) { - await client.deleteMany(DOMAIN_NOTIFICATION, { _id: { $in: removeIds } }) - } - - if (res.length > 0) { - await client.create(DOMAIN_NOTIFICATION, res) - } - } - } catch (e) { - console.error(e) - } + /* + Do nothing for now, since previous implementation was very slow and caused issues in production. + Old inbox is used in production now, so later add a tool to migrate old reaction notifications if needed. + TODO: UBERF-14185 + */ } /** diff --git a/plugins/billing-resources/src/components/Settings.svelte b/plugins/billing-resources/src/components/Settings.svelte index 4d52b60b4e..620e9db1c7 100644 --- a/plugins/billing-resources/src/components/Settings.svelte +++ b/plugins/billing-resources/src/components/Settings.svelte @@ -64,7 +64,7 @@ const groups = paymentUrl != null && paymentUrl !== '' ? baseGroups : baseGroups.filter((g) => g.key !== 'subscriptions') - let currentGroupKey = groups[0].key + let currentGroupKey = groups[0]?.key let currentGroup = groups[0] const unsubscribeLocation = resolvedLocationStore.subscribe((loc) => { diff --git a/plugins/workbench-resources/src/components/Workbench.svelte b/plugins/workbench-resources/src/components/Workbench.svelte index 380156d6b9..8b19761eb3 100644 --- a/plugins/workbench-resources/src/components/Workbench.svelte +++ b/plugins/workbench-resources/src/components/Workbench.svelte @@ -29,11 +29,13 @@ import login, { loginId } from '@hcengineering/login' import notification, { DocNotifyContext, InboxNotification, notificationId } from '@hcengineering/notification' import { BrowserNotificatator, InboxNotificationsClientImpl } from '@hcengineering/notification-resources' + import inbox, { inboxId } from '@hcengineering/inbox' import { broadcastEvent, getMetadata, getResource, IntlString, translate } from '@hcengineering/platform' import { ActionContext, ComponentExtensions, createQuery, + createNotificationsQuery, getClient, isAdminUser, reduceCalls @@ -282,6 +284,17 @@ hasInboxNotifications = res }) + let hasNewInboxNotifications = false + + $: if (isCommunicationEnabled) { + const notificationCountQuery = createNotificationsQuery() + notificationCountQuery.query({ read: false, limit: 1 }, (res) => { + hasNewInboxNotifications = res.getResult().length > 0 + }) + } else { + hasNewInboxNotifications = false + } + const doSyncLoc = reduceCalls(async (loc: Location): Promise => { if (workspaceId !== $location.path[1]) { tabs = [] @@ -759,15 +772,17 @@ let inboxPopup: PopupResult | undefined = undefined let lastLoc: Location | undefined = undefined + $: activeInboxId = isCommunicationEnabled ? inboxId : notificationId + $: inboxProps = { - selected: currentAppAlias === notificationId || inboxPopup !== undefined, - navigator: (currentAppAlias === notificationId || inboxPopup !== undefined) && $deviceInfo.navigator.visible, - notify: hasInboxNotifications, + selected: currentAppAlias === activeInboxId || inboxPopup !== undefined, + navigator: (currentAppAlias === activeInboxId || inboxPopup !== undefined) && $deviceInfo.navigator.visible, + notify: isCommunicationEnabled ? hasInboxNotifications || hasNewInboxNotifications : hasInboxNotifications, onClick: (e: MouseEvent) => { if (e.metaKey || e.ctrlKey) return - if (!$deviceInfo.navigator.visible && $deviceInfo.navigator.float && currentAppAlias === notificationId) { + if (!$deviceInfo.navigator.visible && $deviceInfo.navigator.float && currentAppAlias === activeInboxId) { toggleNav() - } else if (currentAppAlias === notificationId && lastLoc !== undefined) { + } else if (currentAppAlias === activeInboxId && lastLoc !== undefined) { e.preventDefault() e.stopPropagation() navigate(lastLoc) @@ -778,7 +793,10 @@ } } - $: customAppProps = new Map([[notificationId, inboxProps]]) + $: customAppProps = new Map([ + [notificationId, inboxProps], + [inboxId, inboxProps] + ]) defineSeparators('workbench', workbenchSeparators) defineSeparators('main', mainSeparators) @@ -859,22 +877,36 @@ on:click={toggleNav} /> - - {#if !isExcludedApp(notificationId) && !isCommunicationEnabled} - - - + {#if !isExcludedApp(activeInboxId)} + {#if !isCommunicationEnabled} + + + + {:else} + + + + {/if} {/if}