UBERF-5393: fix backlink for thread (#4578)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-02-08 16:26:00 +04:00 committed by GitHub
parent 60da5e28e3
commit 57ee6f5f49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 81 additions and 32 deletions

View File

@ -414,7 +414,7 @@ export function createModel (builder: Builder, options = { addApplication: true
} }
builder.mixin(chunter.class.ThreadMessage, core.class.Class, view.mixin.LinkProvider, { builder.mixin(chunter.class.ThreadMessage, core.class.Class, view.mixin.LinkProvider, {
encode: chunter.function.GetFragment encode: chunter.function.GetThreadLink
}) })
createAction( createAction(

View File

@ -108,7 +108,8 @@ export default mergeIds(chunterId, chunter, {
CanDeleteMessage: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>, CanDeleteMessage: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanReplyToThread: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>, CanReplyToThread: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanCopyMessageLink: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>, CanCopyMessageLink: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
GetChunterSpaceLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>> GetChunterSpaceLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
GetThreadLink: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>
}, },
filter: { filter: {
BacklinksFilter: '' as Resource<(message: ActivityMessage, _class?: Ref<Doc>) => boolean>, BacklinksFilter: '' as Resource<(message: ActivityMessage, _class?: Ref<Doc>) => boolean>,

View File

@ -16,7 +16,7 @@
import { Person } from '@hcengineering/contact' import { Person } from '@hcengineering/contact'
import { personByIdStore, Avatar } from '@hcengineering/contact-resources' import { personByIdStore, Avatar } from '@hcengineering/contact-resources'
import { Doc, IdMap, Ref, WithLookup } from '@hcengineering/core' import { Doc, IdMap, Ref, WithLookup } from '@hcengineering/core'
import { getLocation, Label, TimeSince } from '@hcengineering/ui' import { getLocation, Label, navigate, TimeSince } from '@hcengineering/ui'
import activity, { ActivityMessage } from '@hcengineering/activity' import activity, { ActivityMessage } from '@hcengineering/activity'
import notification, { import notification, {
ActivityInboxNotification, ActivityInboxNotification,
@ -27,7 +27,7 @@
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { get } from 'svelte/store' import { get } from 'svelte/store'
import { navigateToThread } from '../utils' import { buildThreadLink } from '../utils'
export let object: ActivityMessage export let object: ActivityMessage
export let embedded = false export let embedded = false
@ -97,7 +97,7 @@
return return
} }
navigateToThread(getLocation(), context._id, object._id) navigate(buildThreadLink(getLocation(), context._id, object._id))
} }
</script> </script>

View File

@ -14,8 +14,13 @@
--> -->
<script lang="ts"> <script lang="ts">
import { ThreadMessage } from '@hcengineering/chunter' import { ThreadMessage } from '@hcengineering/chunter'
import { Action, Label } from '@hcengineering/ui'
import { getDocLinkTitle } from '@hcengineering/view-resources'
import { getClient } from '@hcengineering/presentation'
import activity from '@hcengineering/activity'
import chunter from '../../plugin'
import ChatMessagePresenter from '../chat-message/ChatMessagePresenter.svelte' import ChatMessagePresenter from '../chat-message/ChatMessagePresenter.svelte'
import { Action } from '@hcengineering/ui'
export let value: ThreadMessage | undefined export let value: ThreadMessage | undefined
export let showNotify: boolean = false export let showNotify: boolean = false
@ -30,26 +35,43 @@
export let actions: Action[] = [] export let actions: Action[] = []
export let excludedActions: string[] = [] export let excludedActions: string[] = []
export let hoverable = true export let hoverable = true
export let inline = false
export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover' export let hoverStyles: 'borderedHover' | 'filledHover' = 'borderedHover'
export let onClick: (() => void) | undefined = undefined export let onClick: (() => void) | undefined = undefined
export let onReply: (() => void) | undefined = undefined export let onReply: (() => void) | undefined = undefined
const client = getClient()
</script> </script>
<ChatMessagePresenter {#if inline && value}
{value} {#await getDocLinkTitle(client, value.objectId, value.objectClass) then title}
{showNotify} <span>
{isHighlighted} <span class="lower">
{isSelected} <Label label={chunter.string.Thread} />
{shouldScroll} </span>
{withActions} <span class="lower">
{showEmbedded} <Label label={activity.string.In} />
{embedded} </span>
{skipLabel} {title}
{withFlatActions} </span>
{excludedActions} {/await}
{actions} {:else}
{hoverable} <ChatMessagePresenter
{hoverStyles} {value}
{onClick} {showNotify}
{onReply} {isHighlighted}
/> {isSelected}
{shouldScroll}
{withActions}
{showEmbedded}
{embedded}
{skipLabel}
{withFlatActions}
{excludedActions}
{actions}
{hoverable}
{hoverStyles}
{onClick}
{onReply}
/>
{/if}

View File

@ -82,7 +82,8 @@ import {
getTitle, getTitle,
getUnreadThreadsCount, getUnreadThreadsCount,
canCopyMessageLink, canCopyMessageLink,
navigateToThread buildThreadLink,
getThreadLink
} from './utils' } from './utils'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources' import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { type Mode } from './components/chat/types' import { type Mode } from './components/chat/types'
@ -244,7 +245,7 @@ export async function replyToThread (message: ActivityMessage): Promise<void> {
loc.path[2] = chunterId loc.path[2] = chunterId
} }
navigateToThread(loc, contextId, message._id) navigate(buildThreadLink(loc, contextId, message._id))
} }
export default async (): Promise<Resources> => ({ export default async (): Promise<Resources> => ({
@ -297,7 +298,8 @@ export default async (): Promise<Resources> => ({
CanReplyToThread: canReplyToThread, CanReplyToThread: canReplyToThread,
CanCopyMessageLink: canCopyMessageLink, CanCopyMessageLink: canCopyMessageLink,
GetChunterSpaceLinkFragment: chunterSpaceLinkFragmentProvider, GetChunterSpaceLinkFragment: chunterSpaceLinkFragmentProvider,
GetUnreadThreadsCount: getUnreadThreadsCount GetUnreadThreadsCount: getUnreadThreadsCount,
GetThreadLink: getThreadLink
}, },
activity: { activity: {
BacklinkCreatedLabel BacklinkCreatedLabel

View File

@ -51,7 +51,7 @@ import activity, {
type DocUpdateMessage type DocUpdateMessage
} from '@hcengineering/activity' } from '@hcengineering/activity'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources' import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { type DocNotifyContext, inboxId } from '@hcengineering/notification' import notification, { type DocNotifyContext, inboxId } from '@hcengineering/notification'
import { get, type Unsubscriber } from 'svelte/store' import { get, type Unsubscriber } from 'svelte/store'
import chunter from './plugin' import chunter from './plugin'
@ -380,14 +380,13 @@ export async function filterChatMessages (
return messages.filter((message) => filtersFns.some((filterFn) => filterFn(message, objectClass))) return messages.filter((message) => filtersFns.some((filterFn) => filterFn(message, objectClass)))
} }
export function navigateToThread (loc: Location, contextId: Ref<DocNotifyContext>, _id: Ref<ActivityMessage>): void { export function buildThreadLink (loc: Location, contextId: Ref<DocNotifyContext>, _id: Ref<ActivityMessage>): Location {
const specials = chatSpecials.map(({ id }) => id) const specials = chatSpecials.map(({ id }) => id)
if (loc.path[2] === chunterId && specials.includes(loc.path[3])) { if (loc.path[2] === chunterId && specials.includes(loc.path[3])) {
loc.path[4] = _id loc.path[4] = _id
loc.query = { message: _id } loc.query = { message: _id }
navigate(loc) return loc
return
} }
if (loc.path[2] !== inboxId) { if (loc.path[2] !== inboxId) {
@ -398,7 +397,32 @@ export function navigateToThread (loc: Location, contextId: Ref<DocNotifyContext
loc.path[4] = _id loc.path[4] = _id
loc.fragment = undefined loc.fragment = undefined
loc.query = { message: _id } loc.query = { message: _id }
navigate(loc)
return loc
}
export async function getThreadLink (doc: ThreadMessage): Promise<Location> {
const loc = getCurrentResolvedLocation()
const client = getClient()
const inboxClient = InboxNotificationsClientImpl.getClient()
let contextId: Ref<DocNotifyContext> | undefined = get(inboxClient.docNotifyContextByDoc).get(doc.objectId)?._id
if (contextId === undefined) {
contextId = await client.createDoc(notification.class.DocNotifyContext, doc.space, {
attachedTo: doc.attachedTo,
attachedToClass: doc.attachedToClass,
user: getCurrentAccount()._id,
hidden: false,
lastViewedTimestamp: Date.now()
})
}
if (contextId === undefined) {
return loc
}
return buildThreadLink(loc, contextId, doc.attachedTo)
} }
export async function joinChannel (channel: Channel, value: Ref<Account> | Array<Ref<Account>>): Promise<void> { export async function joinChannel (channel: Channel, value: Ref<Account> | Array<Ref<Account>>): Promise<void> {