Files
d26924408c Fix message links (#10660)
* Merge with develop

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix errors

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix formatting

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
Co-authored-by: Kristina <kristin.fefelova@gmail.com>
2026-03-23 14:56:03 +07:00

181 lines
6.0 KiB
Svelte

<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// 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 { Class, Doc, Ref } from '@hcengineering/core'
import { getResource, translateCB } from '@hcengineering/platform'
import { createQuery, getClient, IconWithEmoji } from '@hcengineering/presentation'
import { AnyComponent, Icon, LabelAndProps, themeStore, tooltip } from '@hcengineering/ui'
import view from '@hcengineering/view'
import activity, { ActivityMessage } from '@hcengineering/activity'
import { getReferenceLabel } from '@hcengineering/text-editor-resources/src/components/extension/reference'
import { classIcon } from '../utils'
import DocNavLink from './DocNavLink.svelte'
import contact from '@hcengineering/contact'
export let _id: Ref<Doc> | undefined = undefined
export let _class: Ref<Class<Doc>> | undefined = undefined
export let object: Doc | undefined | null
export let title: string = ''
export let component: AnyComponent | undefined = undefined
export let disabled: boolean = false
export let onClick: ((event: MouseEvent) => void) | undefined = undefined
export let transparent: boolean = false
const client = getClient()
const hierarchy = client.getHierarchy()
const docQuery = createQuery()
let parentDoc: Doc | undefined = undefined
let doc: Doc | undefined = object ?? undefined
let docLabel: string = ''
let docTitle: string | undefined = undefined
let docTooltip: LabelAndProps = {
label: view.string.Loading
}
let docComponent: AnyComponent
let displayTitle = ''
$: displayTitle = docTitle || title || docLabel
$: docComponent = getPanelComponent(parentDoc ?? doc, _class)
$: if (object == null && _class != null && _id != null) {
docQuery.query(_class, { _id }, (r) => {
doc = r.shift()
})
} else if (object != null) {
docQuery.unsubscribe()
doc = object
}
$: void updateParentDoc(doc, _class)
async function updateParentDoc (doc: Doc | undefined, _class: Ref<Class<Doc>> | undefined): Promise<void> {
const resultClass = doc?._class ?? _class
if (resultClass == null) {
parentDoc = undefined
return
}
if (hierarchy.isDerived(resultClass, activity.class.ActivityMessage)) {
const message = doc as ActivityMessage
if (parentDoc?._id === message.attachedTo) return
parentDoc = await client.findOne(message.attachedToClass, { _id: message.attachedTo })
} else {
parentDoc = undefined
}
}
$: docClass = doc?._class ?? _class
$: docId = doc?._id ?? _id
$: cl = parentDoc?._class ?? docClass
$: clazz = cl ? hierarchy.findClass(cl) : undefined
$: icon = getIcon(doc)
$: void updateDocTitle(doc)
$: void updateDocTooltip(doc)
$: void updateDocLabel(parentDoc ?? doc, _class)
function getIcon (doc: Doc | undefined): any {
if (doc == null) return undefined
if (hierarchy.isDerived(doc._class, contact.class.Contact)) return undefined
return classIcon(client, doc._class)
}
function getPanelComponent (doc?: Doc, _class?: Ref<Class<Doc>>): AnyComponent {
if (component !== undefined) return component
const resultClass = doc?._class ?? _class
if (resultClass === undefined) {
return view.component.EditDoc
} else if (hierarchy.isDerived(resultClass, activity.class.ActivityMessage)) {
if (doc == null) return view.component.EditDoc
const message = doc as ActivityMessage
const panelComponent = hierarchy.classHierarchyMixin(message.attachedToClass, view.mixin.ObjectPanel)
return panelComponent?.component ?? view.component.EditDoc
} else {
const panelComponent = hierarchy.classHierarchyMixin(resultClass, view.mixin.ObjectPanel)
return panelComponent?.component ?? view.component.EditDoc
}
}
async function updateDocLabel (doc?: Doc, _class?: Ref<Class<Doc>>): Promise<void> {
const resultClass = doc?._class ?? _class
if (resultClass != null) {
translateCB(hierarchy.getClass(resultClass).label, {}, $themeStore.language, (res) => {
docLabel = res
})
} else {
docLabel = ''
}
}
async function updateDocTitle (doc: Doc | undefined): Promise<void> {
docTitle = doc ? await getReferenceLabel(doc._class, doc._id, doc) : undefined
}
async function updateDocTooltip (doc?: Doc): Promise<void> {
if (doc === undefined) {
docTooltip = {}
return
}
const mixin = hierarchy.classHierarchyMixin(doc._class, view.mixin.ObjectTooltip)
if (mixin?.provider !== undefined) {
const providerFn = await getResource(mixin.provider)
docTooltip = (await providerFn(client, doc)) ?? { label: hierarchy.getClass(doc._class).label }
} else {
docTooltip = { label: hierarchy.getClass(doc._class).label }
}
}
</script>
{#if displayTitle}
<span
data-type={'reference'}
data-id={doc?._id}
data-objectclass={doc?._class}
data-label={displayTitle}
use:tooltip={docTooltip}
>
<DocNavLink
object={parentDoc ?? doc}
component={docComponent}
{disabled}
inlineReference
{onClick}
{transparent}
query={docClass && docId && hierarchy.isDerived(docClass, activity.class.ActivityMessage)
? { message: docId }
: undefined}
>
{#if icon}{#if icon === view.ids.IconWithEmoji}<IconWithEmoji
icon={clazz?.color ?? 0}
size={'smaller'}
inline
/>{:else}<Icon {icon} size="small" />{/if}{' '}{:else}@{/if}{displayTitle}
</DocNavLink>
</span>
{/if}