From 3d2e2a762a09ab853dd240151fe227ab448e7c6d Mon Sep 17 00:00:00 2001 From: Oleg Solodkov <94829167+sol-0@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:29:46 +0400 Subject: [PATCH] [UBER-824] Mention notification fix (#3658) Signed-off-by: Oleg Solodkov <oleg.solodkov@xored.com> --- models/chunter/src/index.ts | 4 + .../src/components/CommentPanel.svelte | 95 +++++++++++++++++++ plugins/chunter-resources/src/index.ts | 4 +- plugins/chunter-resources/src/plugin.ts | 3 +- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 plugins/chunter-resources/src/components/CommentPanel.svelte diff --git a/models/chunter/src/index.ts b/models/chunter/src/index.ts index cf1cd313d3..a87f956c39 100644 --- a/models/chunter/src/index.ts +++ b/models/chunter/src/index.ts @@ -467,6 +467,10 @@ export function createModel (builder: Builder, options = { addApplication: true presenter: chunter.component.CommentsPresenter }) + builder.mixin(chunter.class.Comment, core.class.Class, view.mixin.ObjectPanel, { + component: chunter.component.CommentPanel + }) + builder.createDoc( activity.class.TxViewlet, core.space.Model, diff --git a/plugins/chunter-resources/src/components/CommentPanel.svelte b/plugins/chunter-resources/src/components/CommentPanel.svelte new file mode 100644 index 0000000000..a0dbdf562f --- /dev/null +++ b/plugins/chunter-resources/src/components/CommentPanel.svelte @@ -0,0 +1,95 @@ +<!-- +// Copyright © 2023 Anticrm Platform Contributors. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +--> +<script lang="ts"> + import contact, { PersonAccount } from '@hcengineering/contact' + import chunter, { Backlink, Comment } from '@hcengineering/chunter' + import view, { ObjectPanel } from '@hcengineering/view' + import { createQuery, getClient } from '@hcengineering/presentation' + import { AnyComponent, Component, Loading } from '@hcengineering/ui' + import { Class, Doc, Ref, getCurrentAccount } from '@hcengineering/core' + + export let _id: Ref<Comment> | undefined + export let embedded: boolean = true + + const client = getClient() + const hierarchy = client.getHierarchy() + + let comment: Comment | undefined + const commentQuery = createQuery() + let loadingComment = true + + $: if (_id !== undefined) { + commentQuery.query(chunter.class.Comment, { _id }, (res) => { + ;[comment] = res + loadingComment = false + }) + } else { + commentQuery.unsubscribe() + loadingComment = false + } + + let backlinks: Backlink[] = [] + const backlinksQuery = createQuery() + let loadingBacklinks = true + + const mePerson = (getCurrentAccount() as PersonAccount).person + let isMeMentioned = false + + $: if (_id !== undefined) { + backlinksQuery.query(chunter.class.Backlink, { attachedDocId: _id }, (res) => { + backlinks = res + for (const backlink of backlinks) { + if (hierarchy.isDerived(backlink.attachedToClass, contact.class.Person) && mePerson === backlink.attachedTo) { + isMeMentioned = true + break + } + } + loadingBacklinks = false + }) + } else { + backlinksQuery.unsubscribe() + loadingBacklinks = false + } + + let attachedDocId: Ref<Doc> | undefined + let attachedDocClass: Ref<Class<Doc>> | undefined + + $: loading = loadingComment || loadingBacklinks + + let component: AnyComponent + $: getComponent(loading, comment) + + async function getComponent (loading: boolean, comment?: Comment): Promise<void> { + if (comment == null || loading) { + return + } + + let panelComponent: ObjectPanel | undefined + if (isMeMentioned) { + panelComponent = hierarchy.classHierarchyMixin(comment.attachedToClass, view.mixin.ObjectPanel) + } + + component = panelComponent?.component ?? view.component.EditDoc + + attachedDocId = comment.attachedTo + attachedDocClass = comment.attachedToClass + } +</script> + +{#if loading} + <Loading /> +{:else if component && attachedDocId && attachedDocClass} + <Component is={component} props={{ _id: attachedDocId, _class: attachedDocClass, embedded }} on:close /> +{/if} diff --git a/plugins/chunter-resources/src/index.ts b/plugins/chunter-resources/src/index.ts index 6ed65be296..528647dfe6 100644 --- a/plugins/chunter-resources/src/index.ts +++ b/plugins/chunter-resources/src/index.ts @@ -38,6 +38,7 @@ import CommentInput from './components/CommentInput.svelte' import CommentPopup from './components/CommentPopup.svelte' import CommentPresenter from './components/CommentPresenter.svelte' import CommentsPresenter from './components/CommentsPresenter.svelte' +import CommentPanel from './components/CommentPanel.svelte' import ConvertDmToPrivateChannelModal from './components/ConvertDmToPrivateChannel.svelte' import CreateChannel from './components/CreateChannel.svelte' import CreateDirectMessage from './components/CreateDirectMessage.svelte' @@ -292,7 +293,8 @@ export default async (): Promise<Resources> => ({ EditChannel, Threads, ThreadView, - SavedMessages + SavedMessages, + CommentPanel }, function: { GetDmName: getDmName, diff --git a/plugins/chunter-resources/src/plugin.ts b/plugins/chunter-resources/src/plugin.ts index cdd51acb9e..c52d1f932b 100644 --- a/plugins/chunter-resources/src/plugin.ts +++ b/plugins/chunter-resources/src/plugin.ts @@ -31,7 +31,8 @@ export default mergeIds(chunterId, chunter, { EditChannel: '' as AnyComponent, ChannelPreview: '' as AnyComponent, MessagePreview: '' as AnyComponent, - DirectMessageInput: '' as AnyComponent + DirectMessageInput: '' as AnyComponent, + CommentPanel: '' as AnyComponent }, function: { GetDmName: '' as Resource<(client: Client, space: Space) => Promise<string>>