Skip to content

Commit

Permalink
UBERF-5594: render mentions before object is loaded (hcengineering#4738)
Browse files Browse the repository at this point in the history
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
Signed-off-by: Tiago Cruz <tcruz@netic.io>
  • Loading branch information
kristina-fefelova authored and tjaoc committed Mar 5, 2024
1 parent 73f695b commit 0074161
Show file tree
Hide file tree
Showing 32 changed files with 392 additions and 147 deletions.
8 changes: 8 additions & 0 deletions models/contact/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ export function createModel (builder: Builder): void {
component: contact.component.CreateOrganization
})

builder.mixin(contact.class.Contact, core.class.Class, view.mixin.ObjectIdentifier, {
provider: contact.function.ContactTitleProvider
})

builder.mixin(contact.class.Person, core.class.Class, view.mixin.ObjectTooltip, {
provider: contact.function.PersonTooltipProvider
})

builder.createDoc(
workbench.class.Application,
core.space.Model,
Expand Down
8 changes: 8 additions & 0 deletions models/inventory/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export function createModel (builder: Builder): void {
presenter: inventory.component.CategoryPresenter
})

builder.mixin(inventory.class.Category, core.class.Class, view.mixin.ObjectIdentifier, {
provider: inventory.function.CategoryIdProvider
})

builder.mixin(inventory.class.Category, core.class.Class, view.mixin.AttributePresenter, {
presenter: inventory.component.CategoryRefPresenter
})
Expand All @@ -110,6 +114,10 @@ export function createModel (builder: Builder): void {
presenter: inventory.component.ProductPresenter
})

builder.mixin(inventory.class.Product, core.class.Class, view.mixin.ObjectIdentifier, {
provider: inventory.function.ProductIdProvider
})

builder.mixin(inventory.class.Variant, core.class.Class, view.mixin.ObjectPresenter, {
presenter: inventory.component.VariantPresenter
})
Expand Down
8 changes: 6 additions & 2 deletions models/inventory/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
//

import { type ChatMessageViewlet } from '@hcengineering/chunter'
import type { Ref } from '@hcengineering/core'
import type { Client, Doc, Ref } from '@hcengineering/core'
import { inventoryId } from '@hcengineering/inventory'
import inventory from '@hcengineering/inventory-resources/src/plugin'
import { type IntlString, mergeIds } from '@hcengineering/platform'
import { type IntlString, mergeIds, type Resource } from '@hcengineering/platform'
import type { AnyComponent } from '@hcengineering/ui/src/types'
import { type Action, type ActionCategory, type ViewAction, type Viewlet } from '@hcengineering/view'
export default mergeIds(inventoryId, inventory, {
Expand Down Expand Up @@ -51,5 +51,9 @@ export default mergeIds(inventoryId, inventory, {
ids: {
ProductChatMessageViewlet: '' as Ref<ChatMessageViewlet>,
CategoryChatMessageViewlet: '' as Ref<ChatMessageViewlet>
},
function: {
ProductIdProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>,
CategoryIdProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
}
})
4 changes: 4 additions & 0 deletions models/lead/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ export function createModel (builder: Builder): void {
titleProvider: lead.function.LeadTitleProvider
})

builder.mixin(lead.class.Lead, core.class.Class, view.mixin.ObjectIdentifier, {
provider: lead.function.LeadIdProvider
})

builder.mixin(lead.class.Lead, core.class.Class, view.mixin.ClassFilters, {
filters: ['attachedTo']
})
Expand Down
4 changes: 4 additions & 0 deletions models/recruit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,10 @@ export function createModel (builder: Builder): void {
titleProvider: recruit.function.VacTitleProvider
})

builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.ObjectIdentifier, {
provider: recruit.function.VacTitleProvider
})

builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.LinkProvider, {
encode: recruit.function.GetObjectLinkFragment
})
Expand Down
8 changes: 8 additions & 0 deletions models/tracker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ function defineFilters (builder: Builder): void {
titleProvider: tracker.function.MilestoneTitleProvider
})

builder.mixin(tracker.class.Milestone, core.class.Class, view.mixin.ObjectIdentifier, {
provider: tracker.function.MilestoneTitleProvider
})

//
// Project
//
Expand All @@ -234,6 +238,10 @@ function defineFilters (builder: Builder): void {
titleProvider: tracker.function.ComponentTitleProvider
})

builder.mixin(tracker.class.Component, core.class.Class, view.mixin.ObjectIdentifier, {
provider: tracker.function.ComponentTitleProvider
})

//
// Type Milestone Status
//
Expand Down
11 changes: 9 additions & 2 deletions models/view/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import core, { TClass, TDoc } from '@hcengineering/model-core'
import preference, { TPreference } from '@hcengineering/model-preference'
import presentation from '@hcengineering/model-presentation'
import { type Asset, type IntlString, type Resource, type Status } from '@hcengineering/platform'
import { type AnyComponent, type Location } from '@hcengineering/ui/src/types'
import { type AnyComponent, type LabelAndProps, type Location } from '@hcengineering/ui/src/types'
import {
type Action,
type ActionCategory,
Expand Down Expand Up @@ -86,7 +86,8 @@ import {
type ViewletDescriptor,
type ViewletPreference,
type ObjectIdentifier,
type ObjectIcon
type ObjectIcon,
type ObjectTooltip
} from '@hcengineering/view'

import view from './plugin'
Expand Down Expand Up @@ -270,6 +271,11 @@ export class TObjectIdentifier extends TClass implements ObjectIdentifier {
provider!: Resource<<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<string>>
}

@Mixin(view.mixin.ObjectTooltip, core.class.Class)
export class TObjectTooltip extends TClass implements ObjectTooltip {
provider!: Resource<(client: Client, doc?: Doc | null) => Promise<LabelAndProps | undefined>>
}

@Mixin(view.mixin.ListHeaderExtra, core.class.Class)
export class TListHeaderExtra extends TClass implements ListHeaderExtra {
presenters!: AnyComponent[]
Expand Down Expand Up @@ -459,6 +465,7 @@ export function createModel (builder: Builder): void {
TAggregation,
TGroupping,
TObjectIdentifier,
TObjectTooltip,
TObjectIcon
)

Expand Down
28 changes: 11 additions & 17 deletions packages/presentation/src/components/message/Nodes.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
// limitations under the License.
-->
<script lang="ts">
import { CheckBox, Component, navigate, parseLocation } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { CheckBox, navigate, parseLocation } from '@hcengineering/ui'
import { Class, Doc, Ref } from '@hcengineering/core'
import { getMetadata } from '@hcengineering/platform'
import presentation from '../../plugin'
import ObjectNode from './ObjectNode.svelte'
export let nodes: NodeListOf<any>
Expand Down Expand Up @@ -48,11 +48,11 @@
}
} catch {}
}
function correctClass (clName: string): string {
function correctClass (clName: string): Ref<Class<Doc>> {
if (clName === 'contact:class:Employee') {
return 'contact:mixin:Employee'
return 'contact:mixin:Employee' as Ref<Class<Doc>>
}
return clName
return clName as Ref<Class<Doc>>
}
</script>

Expand Down Expand Up @@ -126,17 +126,11 @@
</div>
{/if}
{:else if node.nodeName === 'SPAN'}
{#if node.getAttribute('data-objectclass') !== undefined && node.getAttribute('data-id') !== undefined}
<Component
is={view.component.ObjectPresenter}
inline
props={{
objectId: node.getAttribute('data-id'),
title: node.getAttribute('data-label'),
_class: correctClass(node.getAttribute('data-objectclass')),
inline: true
}}
/>
{@const objectId = node.getAttribute('data-id')}
{@const objectClass = node.getAttribute('data-objectclass')}

{#if objectClass !== undefined && objectId !== undefined}
<ObjectNode _id={objectId} _class={correctClass(objectClass)} title={node.getAttribute('data-label')} />
{:else}
<svelte:self nodes={node.childNodes} />
{/if}
Expand Down
48 changes: 48 additions & 0 deletions packages/presentation/src/components/message/ObjectNode.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
// 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 { Component } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { createQuery } from '../../utils'
export let _id: Ref<Doc> | undefined = undefined
export let _class: Ref<Class<Doc>> | undefined = undefined
export let title: string = ''
const docQuery = createQuery()
let doc: Doc | undefined = undefined
$: if (_class != null && _id != null) {
docQuery.query(_class, { _id }, (r) => {
doc = r.shift()
})
}
</script>

{#if !doc}
<span class="antiMention">@{title}</span>
{:else}
<Component
is={view.component.ObjectMention}
showLoading={false}
props={{
object: doc,
title
}}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { Organization } from '@hcengineering/contact'
import { getEmbeddedLabel } from '@hcengineering/platform'
import { tooltip } from '@hcengineering/ui'
import { DocNavLink } from '@hcengineering/view-resources'
import { DocNavLink, ObjectMention } from '@hcengineering/view-resources'
import Company from './icons/Company.svelte'
export let value: Organization
Expand All @@ -29,18 +29,18 @@
</script>

{#if value}
<DocNavLink {disabled} {inline} object={value} {accent} {noUnderline}>
{#if inline}
<span class="antiMention" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
@{value.name}
</span>
{:else}
{#if inline}
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
{:else}
<DocNavLink {disabled} object={value} {accent} {noUnderline}>
<div class="flex-presenter" style:max-width={maxWidth} use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
<div class="icon circle"><Company size={'small'} /></div>
<div class="icon circle">
<Company size={'small'} />
</div>
<span class="overflow-label label" class:no-underline={noUnderline || disabled} class:fs-bold={accent}
>{value.name}</span
>
</div>
{/if}
</DocNavLink>
</DocNavLink>
{/if}
{/if}
16 changes: 7 additions & 9 deletions plugins/contact-resources/src/components/PersonElement.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<script lang="ts">
import { Employee, Person } from '@hcengineering/contact'
import { IconSize, LabelAndProps, tooltip } from '@hcengineering/ui'
import { DocNavLink } from '@hcengineering/view-resources'
import { DocNavLink, ObjectMention } from '@hcengineering/view-resources'
import Avatar from './Avatar.svelte'
export let value: Person | Employee | undefined | null
Expand All @@ -35,12 +35,10 @@
</script>

{#if value}
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {inline} {colorInherit} {accent} noOverflow>
{#if inline}
<span class="antiMention" use:tooltip={disabled ? undefined : showTooltip}>
@{name}
</span>
{:else}
{#if inline}
<ObjectMention object={value} {disabled} {accent} {noUnderline} {colorInherit} onClick={onEdit} />
{:else}
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {colorInherit} {accent} noOverflow>
<span
use:tooltip={disabled ? undefined : showTooltip}
class="antiPresenter"
Expand All @@ -62,6 +60,6 @@
</span>
{/if}
</span>
{/if}
</DocNavLink>
</DocNavLink>
{/if}
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { getName, Person } from '@hcengineering/contact'
import { getEmbeddedLabel, IntlString } from '@hcengineering/platform'
import type { LabelAndProps, IconSize } from '@hcengineering/ui'
import { personByIdStore, PersonLabelTooltip } from '..'
import { getPersonTooltip, personByIdStore, PersonLabelTooltip } from '..'
import PersonContent from './PersonContent.svelte'
import { getClient } from '@hcengineering/presentation'
import { Ref } from '@hcengineering/core'
Expand Down Expand Up @@ -48,12 +48,9 @@
value: Person | null | undefined
): LabelAndProps | undefined {
if (!tooltipLabels) {
return !value
? undefined
: {
label: getEmbeddedLabel(getName(client.getHierarchy(), value))
}
return getPersonTooltip(client, value)
}
const direction = tooltipLabels?.direction
const component = value ? tooltipLabels.component : undefined
const label = value
Expand Down
4 changes: 3 additions & 1 deletion plugins/contact-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ import {
getCurrentEmployeeEmail,
getCurrentEmployeeName,
getCurrentEmployeePosition,
getPersonTooltip,
resolveLocation
} from './utils'

Expand Down Expand Up @@ -373,7 +374,8 @@ export default async (): Promise<Resources> => ({
GetContactFirstName: getContactFirstName,
GetContactLastName: getContactLastName,
GetContactLink: getContactLink,
ContactTitleProvider: contactTitleProvider
ContactTitleProvider: contactTitleProvider,
PersonTooltipProvider: getPersonTooltip
},
resolver: {
Location: resolveLocation
Expand Down
7 changes: 4 additions & 3 deletions plugins/contact-resources/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
//

import contact, { contactId } from '@hcengineering/contact'
import { type Doc } from '@hcengineering/core'
import { type Client, type Doc } from '@hcengineering/core'
import { type IntlString, mergeIds, type Resource } from '@hcengineering/platform'
import { type Location } from '@hcengineering/ui'
import { type LabelAndProps, type Location } from '@hcengineering/ui'
import { type FilterFunction, type SortFunc } from '@hcengineering/view'

export default mergeIds(contactId, contact, {
Expand Down Expand Up @@ -87,6 +87,7 @@ export default mergeIds(contactId, contact, {
FilterChannelInResult: '' as FilterFunction,
FilterChannelNinResult: '' as FilterFunction,
FilterChannelHasMessagesResult: '' as FilterFunction,
FilterChannelHasNewMessagesResult: '' as FilterFunction
FilterChannelHasNewMessagesResult: '' as FilterFunction,
PersonTooltipProvider: '' as Resource<(client: Client, doc?: Doc | null) => Promise<LabelAndProps | undefined>>
}
})
Loading

0 comments on commit 0074161

Please sign in to comment.