mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-12 02:11:57 +00:00
Mention object icons & bug fixes (#8357)
* Mention object icons & bug fixes Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * ff Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * fmt Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * ff Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * rv Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * ff Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * fmt Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * fixed test Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> --------- Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
parent
62d6a76b4a
commit
0bbf5773e5
@ -394,6 +394,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: documents.component.DocumentMetaPresenter
|
presenter: documents.component.DocumentMetaPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(documents.class.DocumentMeta, core.class.Class, view.mixin.ObjectTitle, {
|
||||||
|
titleProvider: documents.function.DocumentMetaTitleProvider
|
||||||
|
})
|
||||||
|
|
||||||
builder.mixin(documents.class.DocumentMeta, core.class.Class, view.mixin.LinkProvider, {
|
builder.mixin(documents.class.DocumentMeta, core.class.Class, view.mixin.LinkProvider, {
|
||||||
encode: documents.function.GetDocumentMetaLinkFragment
|
encode: documents.function.GetDocumentMetaLinkFragment
|
||||||
})
|
})
|
||||||
|
@ -145,7 +145,7 @@ export class TProject extends TDoc implements Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Model(documents.class.DocumentMeta, core.class.Doc, DOMAIN_DOCUMENTS)
|
@Model(documents.class.DocumentMeta, core.class.Doc, DOMAIN_DOCUMENTS)
|
||||||
@UX(documents.string.Document)
|
@UX(documents.string.ControlledDocument, documents.icon.Document)
|
||||||
export class TDocumentMeta extends TDoc implements DocumentMeta {
|
export class TDocumentMeta extends TDoc implements DocumentMeta {
|
||||||
@Prop(Collection(documents.class.Document), documents.string.Documents)
|
@Prop(Collection(documents.class.Document), documents.string.Documents)
|
||||||
documents!: CollectionSize<Document>
|
documents!: CollectionSize<Document>
|
||||||
|
@ -111,7 +111,7 @@ export class TResource extends TDoc implements Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Model(drive.class.Folder, drive.class.Resource, DOMAIN_DRIVE)
|
@Model(drive.class.Folder, drive.class.Resource, DOMAIN_DRIVE)
|
||||||
@UX(drive.string.Folder)
|
@UX(drive.string.Folder, drive.icon.Folder)
|
||||||
export class TFolder extends TResource implements Folder {
|
export class TFolder extends TResource implements Folder {
|
||||||
@Prop(TypeRef(drive.class.Folder), drive.string.Parent)
|
@Prop(TypeRef(drive.class.Folder), drive.string.Parent)
|
||||||
@Index(IndexKind.Indexed)
|
@Index(IndexKind.Indexed)
|
||||||
@ -126,7 +126,7 @@ export class TFolder extends TResource implements Folder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Model(drive.class.File, drive.class.Resource, DOMAIN_DRIVE)
|
@Model(drive.class.File, drive.class.Resource, DOMAIN_DRIVE)
|
||||||
@UX(drive.string.File)
|
@UX(drive.string.File, drive.icon.File)
|
||||||
export class TFile extends TResource implements File {
|
export class TFile extends TResource implements File {
|
||||||
@Prop(TypeRef(drive.class.Folder), drive.string.Parent)
|
@Prop(TypeRef(drive.class.Folder), drive.string.Parent)
|
||||||
@Index(IndexKind.Indexed)
|
@Index(IndexKind.Indexed)
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
export let shrink: number = 1
|
export let shrink: number = 1
|
||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
export let noOverflow: boolean = false
|
export let noOverflow: boolean = false
|
||||||
|
export let inlineReference: boolean = false
|
||||||
|
|
||||||
function clickHandler (e: MouseEvent): void {
|
function clickHandler (e: MouseEvent): void {
|
||||||
if (disabled) return
|
if (disabled) return
|
||||||
@ -72,6 +73,7 @@
|
|||||||
class:noOverflow
|
class:noOverflow
|
||||||
class:inline
|
class:inline
|
||||||
class:colorInherit
|
class:colorInherit
|
||||||
|
class:antiMention={inlineReference}
|
||||||
class:fs-bold={accent}
|
class:fs-bold={accent}
|
||||||
style:flex-shrink={shrink}
|
style:flex-shrink={shrink}
|
||||||
on:click={clickHandler}
|
on:click={clickHandler}
|
||||||
@ -85,6 +87,7 @@
|
|||||||
class:noOverflow
|
class:noOverflow
|
||||||
class:inline
|
class:inline
|
||||||
class:colorInherit
|
class:colorInherit
|
||||||
|
class:antiMention={inlineReference}
|
||||||
class:fs-bold={accent}
|
class:fs-bold={accent}
|
||||||
style:flex-shrink={shrink}
|
style:flex-shrink={shrink}
|
||||||
on:click={clickHandler}
|
on:click={clickHandler}
|
||||||
@ -95,7 +98,7 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
span,
|
span,
|
||||||
a {
|
a:not(.antiMention) {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
|
|
||||||
|
@ -14,19 +14,23 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||||
import { Component } from '@hcengineering/ui'
|
import { Component, Icon } from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
|
||||||
import { createQuery } from '../../utils'
|
import { createQuery, getClient } from '../../utils'
|
||||||
|
|
||||||
export let _id: Ref<Doc> | undefined = undefined
|
export let _id: Ref<Doc> | undefined = undefined
|
||||||
export let _class: Ref<Class<Doc>> | undefined = undefined
|
export let _class: Ref<Class<Doc>> | undefined = undefined
|
||||||
export let title: string = ''
|
export let title: string = ''
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
const docQuery = createQuery()
|
const docQuery = createQuery()
|
||||||
|
|
||||||
let doc: Doc | undefined = undefined
|
let doc: Doc | undefined = undefined
|
||||||
|
|
||||||
|
$: icon = _class !== undefined ? hierarchy.getClass(_class).icon : null
|
||||||
|
|
||||||
$: if (_class != null && _id != null) {
|
$: if (_class != null && _id != null) {
|
||||||
docQuery.query(_class, { _id }, (r) => {
|
docQuery.query(_class, { _id }, (r) => {
|
||||||
doc = r.shift()
|
doc = r.shift()
|
||||||
@ -35,7 +39,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !doc}
|
{#if !doc}
|
||||||
<span class="antiMention">@{title}</span>
|
<span class="antiMention">
|
||||||
|
{#if icon}<Icon {icon} size="small" />{' '}{:else}@{/if}{title}
|
||||||
|
</span>
|
||||||
{:else}
|
{:else}
|
||||||
<Component
|
<Component
|
||||||
is={view.component.ObjectMention}
|
is={view.component.ObjectMention}
|
||||||
|
@ -21,7 +21,7 @@ describe('dsl', () => {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
expect(jsonToHTML(doc)).toEqual(
|
expect(jsonToHTML(doc)).toEqual(
|
||||||
'<p>Hello, <span data-type="reference" class="antiMention" data-id="123" data-objectclass="world" data-label="World">@World</span></p><p>Check out <a target="_blank" rel="noopener noreferrer" class="cursor-pointer" href="https://example.com"><u>this link</u></a>.</p>'
|
'<p>Hello, <span data-type="reference" data-id="123" data-objectclass="world" data-label="World" class="antiMention">@World</span></p><p>Check out <a target="_blank" rel="noopener noreferrer" class="cursor-pointer" href="https://example.com"><u>this link</u></a>.</p>'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import { Node, mergeAttributes } from '@tiptap/core'
|
import { Node, mergeAttributes } from '@tiptap/core'
|
||||||
import { getDataAttribute } from './utils'
|
import { getDataAttribute } from './utils'
|
||||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||||
|
import { Attrs } from '@tiptap/pm/model'
|
||||||
|
|
||||||
export interface ReferenceNodeProps {
|
export interface ReferenceNodeProps {
|
||||||
id: Ref<Doc>
|
id: Ref<Doc>
|
||||||
@ -24,7 +25,6 @@ export interface ReferenceNodeProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ReferenceOptions {
|
export interface ReferenceOptions {
|
||||||
renderLabel: (props: { options: ReferenceOptions, props: ReferenceNodeProps }) => string
|
|
||||||
suggestion: { char?: string }
|
suggestion: { char?: string }
|
||||||
HTMLAttributes: Record<string, any>
|
HTMLAttributes: Record<string, any>
|
||||||
}
|
}
|
||||||
@ -37,8 +37,6 @@ export const ReferenceNode = Node.create<ReferenceOptions>({
|
|||||||
group: 'inline',
|
group: 'inline',
|
||||||
inline: true,
|
inline: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
atom: true,
|
|
||||||
draggable: true,
|
|
||||||
|
|
||||||
addAttributes () {
|
addAttributes () {
|
||||||
return {
|
return {
|
||||||
@ -50,10 +48,6 @@ export const ReferenceNode = Node.create<ReferenceOptions>({
|
|||||||
|
|
||||||
addOptions () {
|
addOptions () {
|
||||||
return {
|
return {
|
||||||
renderLabel ({ options, props }) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
return `${options.suggestion.char}${props.label ?? props.id}`
|
|
||||||
},
|
|
||||||
suggestion: { char: '@' },
|
suggestion: { char: '@' },
|
||||||
HTMLAttributes: {}
|
HTMLAttributes: {}
|
||||||
}
|
}
|
||||||
@ -62,22 +56,14 @@ export const ReferenceNode = Node.create<ReferenceOptions>({
|
|||||||
parseHTML () {
|
parseHTML () {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
tag: `span[data-type="${this.name}"]`,
|
priority: 60,
|
||||||
getAttrs: (el) => {
|
tag: 'span[data-type="reference"]',
|
||||||
const id = (el as HTMLSpanElement).getAttribute('id')?.trim()
|
getAttrs
|
||||||
const label = (el as HTMLSpanElement).getAttribute('label')?.trim()
|
},
|
||||||
const objectclass = (el as HTMLSpanElement).getAttribute('objectclass')?.trim()
|
{
|
||||||
|
priority: 60,
|
||||||
if (id == null || label == null || objectclass == null) {
|
tag: 'a[data-type="reference"]',
|
||||||
return false
|
getAttrs
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
label,
|
|
||||||
objectclass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -88,20 +74,31 @@ export const ReferenceNode = Node.create<ReferenceOptions>({
|
|||||||
mergeAttributes(
|
mergeAttributes(
|
||||||
{
|
{
|
||||||
'data-type': this.name,
|
'data-type': this.name,
|
||||||
|
'data-id': node.attrs.id,
|
||||||
|
'data-objectclass': node.attrs.objectclass,
|
||||||
|
'data-label': node.attrs.label,
|
||||||
class: 'antiMention'
|
class: 'antiMention'
|
||||||
},
|
},
|
||||||
this.options.HTMLAttributes,
|
this.options.HTMLAttributes,
|
||||||
HTMLAttributes
|
HTMLAttributes
|
||||||
),
|
),
|
||||||
this.options.renderLabel({
|
`${this.options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
|
||||||
options: this.options,
|
|
||||||
props: node.attrs as ReferenceNodeProps
|
|
||||||
})
|
|
||||||
]
|
]
|
||||||
},
|
|
||||||
|
|
||||||
renderText ({ node }) {
|
|
||||||
const options = this.options
|
|
||||||
return options.renderLabel({ options, props: node.attrs as ReferenceNodeProps })
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getAttrs (el: HTMLSpanElement): Attrs | false {
|
||||||
|
const id = el.dataset.id?.trim()
|
||||||
|
const label = el.dataset.label?.trim()
|
||||||
|
const objectclass = el.dataset.objectclass?.trim()
|
||||||
|
|
||||||
|
if (id == null || label == null || objectclass == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
label,
|
||||||
|
objectclass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -518,14 +518,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.antiMention {
|
.antiMention, .antiMention:visited {
|
||||||
display: inline-flex;
|
display: inline;
|
||||||
|
font-weight: normal;
|
||||||
padding: 0 .25rem;
|
padding: 0 .25rem;
|
||||||
width: fit-content;
|
|
||||||
color: var(--theme-link-color);
|
color: var(--theme-link-color);
|
||||||
background-color: var(--theme-mention-bg-color);
|
background-color: var(--theme-mention-bg-color);
|
||||||
|
text-decoration: none;
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
user-select: text;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none !important;
|
||||||
|
background-color: var(--theme-mention-focused-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: sub;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
width: .875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.antiDivider {
|
.antiDivider {
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if inline && value}
|
{#if inline && value}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {onClick} component={card.component.EditCard} />
|
<ObjectMention object={value} {disabled} {onClick} component={card.component.EditCard} />
|
||||||
{:else if value}
|
{:else if value}
|
||||||
{#if type === 'link'}
|
{#if type === 'link'}
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
|
@ -34,13 +34,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention
|
<ObjectMention object={value} {disabled} component={contact.component.EditOrganizationPanel} />
|
||||||
object={value}
|
|
||||||
{disabled}
|
|
||||||
{accent}
|
|
||||||
{noUnderline}
|
|
||||||
component={contact.component.EditOrganizationPanel}
|
|
||||||
/>
|
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={contact.component.EditOrganizationPanel}>
|
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={contact.component.EditOrganizationPanel}>
|
||||||
<div class="flex-presenter" style:max-width={maxWidth} use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" style:max-width={maxWidth} use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} {colorInherit} onClick={onEdit} />
|
<ObjectMention object={value} {disabled} onClick={onEdit} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {colorInherit} {accent} noOverflow>
|
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {colorInherit} {accent} noOverflow>
|
||||||
<span
|
<span
|
||||||
|
@ -114,7 +114,8 @@ import {
|
|||||||
getVisibleFilters,
|
getVisibleFilters,
|
||||||
isFolder,
|
isFolder,
|
||||||
renameFolder,
|
renameFolder,
|
||||||
sortDocumentStates
|
sortDocumentStates,
|
||||||
|
getDocumentMetaTitle
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
|
||||||
export { DocumentStatusTag, DocumentTitle, DocumentVersionPresenter, StatePresenter }
|
export { DocumentStatusTag, DocumentTitle, DocumentVersionPresenter, StatePresenter }
|
||||||
@ -462,6 +463,7 @@ export default async (): Promise<Resources> => ({
|
|||||||
ControlledDocumentReferenceObjectProvider: controlledDocumentReferenceObjectProvider,
|
ControlledDocumentReferenceObjectProvider: controlledDocumentReferenceObjectProvider,
|
||||||
ProjectDocumentReferenceObjectProvider: projectDocumentReferenceObjectProvider,
|
ProjectDocumentReferenceObjectProvider: projectDocumentReferenceObjectProvider,
|
||||||
ControlledDocumentTitleProvider: getControlledDocumentTitle,
|
ControlledDocumentTitleProvider: getControlledDocumentTitle,
|
||||||
|
DocumentMetaTitleProvider: getDocumentMetaTitle,
|
||||||
Comment: comment,
|
Comment: comment,
|
||||||
IsCommentVisible: isCommentVisible
|
IsCommentVisible: isCommentVisible
|
||||||
},
|
},
|
||||||
|
@ -249,6 +249,7 @@ export default mergeIds(documentsId, documents, {
|
|||||||
CanOpenDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
CanOpenDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||||
CanPrintDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
CanPrintDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||||
CanTransferDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
CanTransferDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||||
ControlledDocumentTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
ControlledDocumentTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>,
|
||||||
|
DocumentMetaTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -716,6 +716,18 @@ export async function documentIdentifierProvider (client: Client, ref: Ref<Docum
|
|||||||
return document.code
|
return document.code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getDocumentMetaTitle (
|
||||||
|
client: Client,
|
||||||
|
ref: Ref<DocumentMeta>,
|
||||||
|
doc?: DocumentMeta
|
||||||
|
): Promise<string> {
|
||||||
|
const object = doc ?? (await client.findOne(documents.class.DocumentMeta, { _id: ref }))
|
||||||
|
|
||||||
|
if (object === undefined) return ''
|
||||||
|
|
||||||
|
return object.title
|
||||||
|
}
|
||||||
|
|
||||||
export async function controlledDocumentReferenceObjectProvider (
|
export async function controlledDocumentReferenceObjectProvider (
|
||||||
client: Client,
|
client: Client,
|
||||||
ref: Ref<ControlledDocument>,
|
ref: Ref<ControlledDocument>,
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} component={document.component.EditDoc} />
|
<ObjectMention object={value} {disabled} component={document.component.EditDoc} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={document.component.EditDoc}>
|
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={document.component.EditDoc}>
|
||||||
<div
|
<div
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink {disabled} object={value} {accent} {noUnderline}>
|
<DocNavLink {disabled} object={value} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} onClick={handleClick} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} onClick={handleClick} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter">
|
<div class="flex-presenter">
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink {disabled} object={value} {accent} {noUnderline}>
|
<DocNavLink {disabled} object={value} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {accent} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
||||||
<div class="flex-presenter">
|
<div class="flex-presenter">
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.title) }}>
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(roomName) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(roomName) }}>
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} title={name} />
|
<ObjectMention object={value} {disabled} title={name} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(name) }}>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} title={version} />
|
<ObjectMention object={value} {disabled} title={version} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
||||||
<div class="flex-presenter">
|
<div class="flex-presenter">
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
{#if value && shortLabel}
|
{#if value && shortLabel}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {accent} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
<DocNavLink object={value} {disabled} {noUnderline} {accent}>
|
||||||
<div class="flex-presenter">
|
<div class="flex-presenter">
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} component={recruit.component.EditVacancy} />
|
<ObjectMention object={value} {disabled} component={recruit.component.EditVacancy} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<div class="flex-between flex-gap-2 w-full">
|
<div class="flex-between flex-gap-2 w-full">
|
||||||
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={recruit.component.EditVacancy}>
|
<DocNavLink {disabled} object={value} {accent} {noUnderline} component={recruit.component.EditVacancy}>
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} {colorInherit} onClick={onEdit} />
|
<ObjectMention object={value} {disabled} onClick={onEdit} />
|
||||||
{:else if type === 'link'}
|
{:else if type === 'link'}
|
||||||
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {colorInherit} {accent} noOverflow>
|
<DocNavLink object={value} onClick={onEdit} {disabled} {noUnderline} {colorInherit} {accent} noOverflow>
|
||||||
<div class="flex-presenter" style:max-width={maxWidth}>
|
<div class="flex-presenter" style:max-width={maxWidth}>
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention title={value?.name} object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention title={value?.name} object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline} {onClick}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline} {onClick}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: testManagement.string.TestCase }}>
|
<div class="flex-presenter" use:tooltip={{ label: testManagement.string.TestCase }}>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: testManagement.string.TestResult }}>
|
<div class="flex-presenter" use:tooltip={{ label: testManagement.string.TestResult }}>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {accent} {noUnderline} />
|
<ObjectMention object={value} {disabled} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
<div class="flex-presenter" use:tooltip={{ label: getEmbeddedLabel(value.name) }}>
|
||||||
|
@ -26,6 +26,7 @@ import { getMetadata, getResource } from '@hcengineering/platform'
|
|||||||
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
|
||||||
|
import contact from '@hcengineering/contact'
|
||||||
import { parseLocation, type Location } from '@hcengineering/ui'
|
import { parseLocation, type Location } from '@hcengineering/ui'
|
||||||
import workbench, { type Application } from '@hcengineering/workbench'
|
import workbench, { type Application } from '@hcengineering/workbench'
|
||||||
|
|
||||||
@ -38,10 +39,6 @@ export const ReferenceExtension = ReferenceNode.extend<ReferenceExtensionOptions
|
|||||||
addOptions () {
|
addOptions () {
|
||||||
return {
|
return {
|
||||||
HTMLAttributes: {},
|
HTMLAttributes: {},
|
||||||
renderLabel ({ options, props }) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
return `${options.suggestion.char}${props.label ?? props.id}`
|
|
||||||
},
|
|
||||||
suggestion: {
|
suggestion: {
|
||||||
char: '@',
|
char: '@',
|
||||||
allowSpaces: true,
|
allowSpaces: true,
|
||||||
@ -86,19 +83,21 @@ export const ReferenceExtension = ReferenceNode.extend<ReferenceExtensionOptions
|
|||||||
|
|
||||||
addNodeView () {
|
addNodeView () {
|
||||||
return ({ node, HTMLAttributes }) => {
|
return ({ node, HTMLAttributes }) => {
|
||||||
const span = document.createElement('span')
|
const root = document.createElement('span')
|
||||||
span.setAttribute('data-type', this.name)
|
root.className = 'antiMention'
|
||||||
span.className = 'antimention'
|
|
||||||
const attributes = mergeAttributes(
|
const attributes = mergeAttributes(
|
||||||
{
|
{
|
||||||
'data-type': this.name,
|
'data-type': this.name,
|
||||||
|
'data-id': node.attrs.id,
|
||||||
|
'data-objectclass': node.attrs.objectclass,
|
||||||
|
'data-label': node.attrs.label,
|
||||||
class: 'antiMention'
|
class: 'antiMention'
|
||||||
},
|
},
|
||||||
this.options.HTMLAttributes,
|
this.options.HTMLAttributes,
|
||||||
HTMLAttributes
|
HTMLAttributes
|
||||||
)
|
)
|
||||||
|
|
||||||
span.addEventListener('click', (event) => {
|
root.addEventListener('click', (event) => {
|
||||||
if (event.button !== 0) return
|
if (event.button !== 0) return
|
||||||
|
|
||||||
const link = (event.target as HTMLElement)?.closest('span')
|
const link = (event.target as HTMLElement)?.closest('span')
|
||||||
@ -112,20 +111,40 @@ export const ReferenceExtension = ReferenceNode.extend<ReferenceExtensionOptions
|
|||||||
})
|
})
|
||||||
|
|
||||||
Object.entries(attributes).forEach(([key, value]) => {
|
Object.entries(attributes).forEach(([key, value]) => {
|
||||||
span.setAttribute(key, value)
|
root.setAttribute(key, value)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
const query = createQuery(true)
|
const query = createQuery(true)
|
||||||
const options = this.options
|
const options = this.options
|
||||||
|
|
||||||
const renderLabel = (props: ReferenceNodeProps): void => {
|
const renderLabel = (props: ReferenceNodeProps): void => {
|
||||||
span.setAttribute('data-label', props.label)
|
root.setAttribute('data-label', props.label)
|
||||||
span.innerText = options.renderLabel({ options, props: props ?? (node.attrs as ReferenceNodeProps) })
|
titleSpan.innerText = `${iconUrl !== '' ? '' : options.suggestion.char}${props.label ?? props.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = node.attrs.id
|
const id = node.attrs.id
|
||||||
const objectclass: Ref<Class<Doc>> = node.attrs.objectclass
|
const objectclass: Ref<Class<Doc>> = node.attrs.objectclass
|
||||||
|
|
||||||
|
const icon =
|
||||||
|
objectclass !== undefined && !hierarchy.isDerived(objectclass, contact.class.Contact)
|
||||||
|
? hierarchy.getClass(objectclass).icon
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
const iconUrl = typeof icon === 'string' ? getMetadata(icon) ?? 'https://anticrm.org/logo.svg' : ''
|
||||||
|
|
||||||
|
if (iconUrl !== '') {
|
||||||
|
const svg = root.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||||
|
root.appendChild(document.createTextNode(' '))
|
||||||
|
svg.setAttribute('class', 'svg-small')
|
||||||
|
svg.setAttribute('fill', 'currentColor')
|
||||||
|
const use = svg.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'use'))
|
||||||
|
use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', iconUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
const titleSpan = root.appendChild(document.createElement('span'))
|
||||||
renderLabel({ id, objectclass, label: node.attrs.label })
|
renderLabel({ id, objectclass, label: node.attrs.label })
|
||||||
|
|
||||||
if (id !== undefined && objectclass !== undefined) {
|
if (id !== undefined && objectclass !== undefined) {
|
||||||
@ -141,7 +160,7 @@ export const ReferenceExtension = ReferenceNode.extend<ReferenceExtensionOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dom: span,
|
dom: root,
|
||||||
update (node, decorations) {
|
update (node, decorations) {
|
||||||
renderLabel({ id, objectclass, label: node.attrs.label })
|
renderLabel({ id, objectclass, label: node.attrs.label })
|
||||||
return true
|
return true
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {accent} {onClick} />
|
<ObjectMention object={value} {disabled} {onClick} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {onClick} {disabled} {noUnderline} {accent} component={view.component.EditDoc}>
|
<DocNavLink object={value} {onClick} {disabled} {noUnderline} {accent} component={view.component.EditDoc}>
|
||||||
<span class="flex-presenter flex-row-center" class:list={kind === 'list'}>
|
<span class="flex-presenter flex-row-center" class:list={kind === 'list'}>
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if inline && value}
|
{#if inline && value}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {onClick} component={tracker.component.EditIssue} />
|
<ObjectMention object={value} {disabled} {onClick} component={tracker.component.EditIssue} />
|
||||||
{:else if value}
|
{:else if value}
|
||||||
{#if type === 'link'}
|
{#if type === 'link'}
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if inline}
|
{#if inline}
|
||||||
<ObjectMention object={value} {disabled} {noUnderline} {accent} {onClick} />
|
<ObjectMention object={value} {disabled} {onClick} />
|
||||||
{:else}
|
{:else}
|
||||||
<DocNavLink object={value} {disabled} {accent} {noUnderline} {onClick}>
|
<DocNavLink object={value} {disabled} {accent} {noUnderline} {onClick}>
|
||||||
<div class="flex-presenter" use:tooltip={{ label: tracker.string.Milestone }}>
|
<div class="flex-presenter" use:tooltip={{ label: tracker.string.Milestone }}>
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
export let shrink: number = 1
|
export let shrink: number = 1
|
||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
export let noOverflow: boolean = false
|
export let noOverflow: boolean = false
|
||||||
|
export let inlineReference: boolean = false
|
||||||
|
|
||||||
let _disabled = disabled || $restrictionStore.disableNavigation
|
let _disabled = disabled || $restrictionStore.disableNavigation
|
||||||
$: _disabled = disabled || $restrictionStore.disableNavigation
|
$: _disabled = disabled || $restrictionStore.disableNavigation
|
||||||
@ -58,6 +59,17 @@
|
|||||||
$: if (object !== undefined) getHref(object)
|
$: if (object !== undefined) getHref(object)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NavLink disabled={_disabled} {onClick} {noUnderline} {inline} {shrink} {href} {colorInherit} {accent} {noOverflow}>
|
<NavLink
|
||||||
|
disabled={_disabled}
|
||||||
|
{onClick}
|
||||||
|
{noUnderline}
|
||||||
|
{inline}
|
||||||
|
{shrink}
|
||||||
|
{href}
|
||||||
|
{colorInherit}
|
||||||
|
{accent}
|
||||||
|
{noOverflow}
|
||||||
|
{inlineReference}
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
@ -16,11 +16,13 @@
|
|||||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||||
import { getResource, translateCB } from '@hcengineering/platform'
|
import { getResource, translateCB } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { AnyComponent, LabelAndProps, themeStore, tooltip } from '@hcengineering/ui'
|
import { AnyComponent, Icon, LabelAndProps, themeStore, tooltip } from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
|
|
||||||
import { getReferenceLabel } from '@hcengineering/text-editor-resources/src/components/extension/reference'
|
import { getReferenceLabel } from '@hcengineering/text-editor-resources/src/components/extension/reference'
|
||||||
|
import { classIcon } from '../utils'
|
||||||
import DocNavLink from './DocNavLink.svelte'
|
import DocNavLink from './DocNavLink.svelte'
|
||||||
|
import contact from '@hcengineering/contact'
|
||||||
|
|
||||||
export let _id: Ref<Doc> | undefined = undefined
|
export let _id: Ref<Doc> | undefined = undefined
|
||||||
export let _class: Ref<Class<Doc>> | undefined = undefined
|
export let _class: Ref<Class<Doc>> | undefined = undefined
|
||||||
@ -28,9 +30,6 @@
|
|||||||
export let title: string = ''
|
export let title: string = ''
|
||||||
export let component: AnyComponent | undefined = undefined
|
export let component: AnyComponent | undefined = undefined
|
||||||
export let disabled: boolean = false
|
export let disabled: boolean = false
|
||||||
export let accent: boolean = false
|
|
||||||
export let noUnderline: boolean = false
|
|
||||||
export let colorInherit: boolean = false
|
|
||||||
export let onClick: ((event: MouseEvent) => void) | undefined = undefined
|
export let onClick: ((event: MouseEvent) => void) | undefined = undefined
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
@ -58,6 +57,9 @@
|
|||||||
doc = object
|
doc = object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: icon =
|
||||||
|
doc !== undefined && !hierarchy.isDerived(doc._class, contact.class.Contact) ? classIcon(client, doc._class) : null
|
||||||
|
|
||||||
$: void updateDocTitle(doc)
|
$: void updateDocTitle(doc)
|
||||||
$: void updateDocTooltip(doc)
|
$: void updateDocTooltip(doc)
|
||||||
$: void updateDocLabel(doc, _class)
|
$: void updateDocLabel(doc, _class)
|
||||||
@ -113,19 +115,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if displayTitle}
|
{#if displayTitle}
|
||||||
<DocNavLink
|
<span data-type={'reference'} data-id={doc?._id} data-objectclass={doc?._class} data-label={displayTitle}>
|
||||||
object={doc}
|
<DocNavLink object={doc} component={docComponent} {disabled} inlineReference {onClick}>
|
||||||
component={docComponent}
|
{#if icon}<Icon {icon} size="small" />{' '}{:else}@{/if}{displayTitle}
|
||||||
{disabled}
|
</DocNavLink>
|
||||||
{accent}
|
</span>
|
||||||
{colorInherit}
|
|
||||||
{noUnderline}
|
|
||||||
inline
|
|
||||||
noOverflow
|
|
||||||
{onClick}
|
|
||||||
>
|
|
||||||
<span class="antiMention" class:reference={!disabled} use:tooltip={disabled ? undefined : docTooltip}>
|
|
||||||
@{displayTitle}
|
|
||||||
</span>
|
|
||||||
</DocNavLink>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -287,7 +287,7 @@ export class DocumentContentPage extends CommonPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async checkReferenceInTheText (label: string): Promise<void> {
|
async checkReferenceInTheText (label: string): Promise<void> {
|
||||||
await expect(this.page.locator('span', { hasText: '@' + label })).toHaveAttribute('data-type', 'reference')
|
await expect(this.page.locator('span.antiMention', { hasText: label })).toHaveAttribute('data-type', 'reference')
|
||||||
}
|
}
|
||||||
|
|
||||||
async executeMoreAction (action: string): Promise<void> {
|
async executeMoreAction (action: string): Promise<void> {
|
||||||
|
@ -181,7 +181,7 @@ export class CommonTrackerPage extends CalendarPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async openLinkFromActivitiesByText (linkText: string): Promise<void> {
|
async openLinkFromActivitiesByText (linkText: string): Promise<void> {
|
||||||
await this.linkInActivity().filter({ hasText: linkText }).click()
|
await this.linkInActivity().filter({ hasText: linkText }).first().click()
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCommentWithImage (comment: string, fileName: string): Promise<void> {
|
async addCommentWithImage (comment: string, fileName: string): Promise<void> {
|
||||||
|
@ -112,12 +112,12 @@ test.describe('Mentions issue tests', () => {
|
|||||||
const secondId = await issuesPage.getIssueId(backlinkIssueSecond.title)
|
const secondId = await issuesPage.getIssueId(backlinkIssueSecond.title)
|
||||||
await issuesPage.openIssueByName(backlinkIssueSecond.title)
|
await issuesPage.openIssueByName(backlinkIssueSecond.title)
|
||||||
await issuesDetailsPage.addMentions(defaultId)
|
await issuesDetailsPage.addMentions(defaultId)
|
||||||
await issuesDetailsPage.checkCommentExist(`@${defaultId}`)
|
await issuesDetailsPage.checkCommentExist(defaultId)
|
||||||
await issuesDetailsPage.openLinkFromActivitiesByText(`@${defaultId}`)
|
await issuesDetailsPage.openLinkFromActivitiesByText(defaultId)
|
||||||
await issuesDetailsPage.checkIssue(backlinkIssueDefault)
|
await issuesDetailsPage.checkIssue(backlinkIssueDefault)
|
||||||
await issuesDetailsPage.addMentions(secondId)
|
await issuesDetailsPage.addMentions(secondId)
|
||||||
await issuesDetailsPage.checkCommentExist(`@${secondId}`)
|
await issuesDetailsPage.checkCommentExist(secondId)
|
||||||
await issuesDetailsPage.openLinkFromActivitiesByText(`@${secondId}`)
|
await issuesDetailsPage.openLinkFromActivitiesByText(secondId)
|
||||||
await issuesDetailsPage.checkIssue(backlinkIssueSecond)
|
await issuesDetailsPage.checkIssue(backlinkIssueSecond)
|
||||||
await issuesDetailsPage.clickCloseIssueButton()
|
await issuesDetailsPage.clickCloseIssueButton()
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user