mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-25 01:39:53 +00:00
TSK-1069. Displaying a Mention, as well as a Comment. Fixed MessageViewer. (#2915)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
210d3eebc6
commit
33db59a5e2
@ -30,7 +30,7 @@
|
|||||||
<strong><svelte:self nodes={node.childNodes} /></strong>
|
<strong><svelte:self nodes={node.childNodes} /></strong>
|
||||||
{:else if node.nodeName === 'P'}
|
{:else if node.nodeName === 'P'}
|
||||||
{#if node.childNodes.length > 0}
|
{#if node.childNodes.length > 0}
|
||||||
<p class="p-inline">
|
<p class="p-inline contrast">
|
||||||
<svelte:self nodes={node.childNodes} />
|
<svelte:self nodes={node.childNodes} />
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
@ -138,4 +138,21 @@
|
|||||||
.checkboxContainer {
|
.checkboxContainer {
|
||||||
padding-top: 0.125rem;
|
padding-top: 0.125rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
em,
|
||||||
|
strong,
|
||||||
|
blockquote,
|
||||||
|
pre,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
ol,
|
||||||
|
li,
|
||||||
|
.checkboxContainer,
|
||||||
|
s {
|
||||||
|
color: var(--theme-accent-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
--darker-color: rgba(255, 255, 255, .4);
|
--darker-color: rgba(255, 255, 255, .4);
|
||||||
--dark-color: #62666d;
|
--dark-color: #62666d;
|
||||||
--content-color: #8a8f98;
|
--content-color: #8a8f98;
|
||||||
|
--theme-accent-color: rgba(255, 255, 255, .8);
|
||||||
--accent-color: #d7d8db;
|
--accent-color: #d7d8db;
|
||||||
--caption-color: #f7f8f8;
|
--caption-color: #f7f8f8;
|
||||||
--white-color: #fff;
|
--white-color: #fff;
|
||||||
@ -157,6 +158,7 @@
|
|||||||
--dark-color: #90959d;
|
--dark-color: #90959d;
|
||||||
--content-color: #3c4149;
|
--content-color: #3c4149;
|
||||||
--accent-color: #282a30;
|
--accent-color: #282a30;
|
||||||
|
--theme-accent-color: rgba(0, 0, 0, .8);
|
||||||
--caption-color: #131416;
|
--caption-color: #131416;
|
||||||
--white-color: #fff;
|
--white-color: #fff;
|
||||||
--caret-color: #6e5ed2;
|
--caret-color: #6e5ed2;
|
||||||
|
@ -113,7 +113,9 @@ p:last-child { margin-block-end: 0; }
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
line-height: 150%;
|
line-height: 150%;
|
||||||
color: var(--content-color);
|
|
||||||
|
&.contrast { color: var(--theme-accent-color); }
|
||||||
|
&:not(.contrast) { color: var(--content-color); }
|
||||||
|
|
||||||
a {
|
a {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
@ -378,7 +380,7 @@ input.search {
|
|||||||
|
|
||||||
.bold {
|
.bold {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--caption-color);
|
color: var(--theme-accent-color);
|
||||||
}
|
}
|
||||||
.strong { color: var(--accent-color); }
|
.strong { color: var(--accent-color); }
|
||||||
.lower { text-transform: lowercase; }
|
.lower { text-transform: lowercase; }
|
||||||
|
@ -126,9 +126,3 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSK-1026. Experiment, don't forget to delete.
|
|
||||||
.theme-dark .p-activity .msgactivity-content.comment .msgactivity-content__title.labels-row > .bold,
|
|
||||||
.theme-dark .p-activity .msgactivity-content.comment .activity-content.content .p-inline { color: rgba(255, 255, 255, .8); }
|
|
||||||
.theme-light .p-activity .msgactivity-content.comment .msgactivity-content__title.labels-row > .bold,
|
|
||||||
.theme-light .p-activity .msgactivity-content.comment .activity-content.content .p-inline { color: rgba(0, 0, 0, .8); }
|
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
&:not(.embedded) {
|
&:not(.embedded) {
|
||||||
border-radius: 0 0 .5rem .5rem;
|
border-radius: 0 0 .5rem .5rem;
|
||||||
}
|
}
|
||||||
|
&.embedded { border-left: none; }
|
||||||
|
|
||||||
&.main {
|
&.main {
|
||||||
justify-content: stretch;
|
justify-content: stretch;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import type { AttributeModel } from '@hcengineering/view'
|
import type { AttributeModel } from '@hcengineering/view'
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
|
import chunter from '@hcengineering/chunter'
|
||||||
import { Menu, ObjectPresenter } from '@hcengineering/view-resources'
|
import { Menu, ObjectPresenter } from '@hcengineering/view-resources'
|
||||||
import { ActivityKey, DisplayTx } from '../activity'
|
import { ActivityKey, DisplayTx } from '../activity'
|
||||||
import activity from '../plugin'
|
import activity from '../plugin'
|
||||||
@ -134,6 +135,9 @@
|
|||||||
function isAttachment (_class?: Ref<Class<Doc>>): boolean {
|
function isAttachment (_class?: Ref<Class<Doc>>): boolean {
|
||||||
return _class === attachment.class.Attachment
|
return _class === attachment.class.Attachment
|
||||||
}
|
}
|
||||||
|
function isMention (_class?: Ref<Class<Doc>>): boolean {
|
||||||
|
return _class === chunter.class.Backlink
|
||||||
|
}
|
||||||
|
|
||||||
async function updateMessageType (model: AttributeModel[], tx: DisplayTx): Promise<boolean> {
|
async function updateMessageType (model: AttributeModel[], tx: DisplayTx): Promise<boolean> {
|
||||||
for (const m of model) {
|
for (const m of model) {
|
||||||
@ -152,21 +156,17 @@
|
|||||||
hasMessageType = res
|
hasMessageType = res
|
||||||
})
|
})
|
||||||
$: isComment = viewlet && viewlet?.editable
|
$: isComment = viewlet && viewlet?.editable
|
||||||
$: isAttach = isAttachment(tx.tx.objectClass)
|
$: isAttached = isAttachment(tx.tx.objectClass)
|
||||||
$: isMention = viewlet?.display === 'emphasized' || isMessageType(model[0]?.attribute)
|
$: isMentioned = isMention(tx.tx.objectClass)
|
||||||
$: isColumn = isComment || isMention || hasMessageType
|
$: withAvatar = isComment || isMentioned || isAttached
|
||||||
|
$: isEmphasized = viewlet?.display === 'emphasized' || model.every((m) => isMessageType(m.attribute))
|
||||||
|
$: isColumn = isComment || isEmphasized || hasMessageType
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if (viewlet !== undefined && !((viewlet?.hideOnRemove ?? false) && tx.removed)) || model.length > 0}
|
{#if (viewlet !== undefined && !((viewlet?.hideOnRemove ?? false) && tx.removed)) || model.length > 0}
|
||||||
<div
|
<div class="msgactivity-container" class:showIcon class:withAvatar class:isNew class:isNextNew>
|
||||||
class="msgactivity-container"
|
|
||||||
class:showIcon
|
|
||||||
class:withAvatar={isComment || isAttach}
|
|
||||||
class:isNew
|
|
||||||
class:isNextNew
|
|
||||||
>
|
|
||||||
{#if showIcon}
|
{#if showIcon}
|
||||||
{#if isComment || isAttach}
|
{#if withAvatar}
|
||||||
<div class="msgactivity-avatar">
|
<div class="msgactivity-avatar">
|
||||||
<Component is={contact.component.Avatar} props={{ avatar: employee?.avatar, size: 'medium' }} />
|
<Component is={contact.component.Avatar} props={{ avatar: employee?.avatar, size: 'medium' }} />
|
||||||
</div>
|
</div>
|
||||||
@ -183,10 +183,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="msgactivity-content" class:content={isColumn} class:comment={isComment || isAttach}>
|
<div class="msgactivity-content" class:content={isColumn} class:comment={withAvatar}>
|
||||||
<div class="msgactivity-content__header">
|
<div class="msgactivity-content__header">
|
||||||
<div class="msgactivity-content__title labels-row">
|
<div class="msgactivity-content__title labels-row">
|
||||||
<span class={isComment || isAttach ? 'bold' : 'strong'}>
|
<span class={withAvatar ? 'bold' : 'strong'}>
|
||||||
{#if employee}
|
{#if employee}
|
||||||
{getName(employee)}
|
{getName(employee)}
|
||||||
{:else}
|
{:else}
|
||||||
@ -306,7 +306,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if viewlet && viewlet.display !== 'inline'}
|
{#if viewlet && viewlet.display !== 'inline'}
|
||||||
<div class="activity-content content" class:indent={isAttach} class:contentHidden>
|
<div class="activity-content content" class:indent={isAttached} class:contentHidden>
|
||||||
<ShowMore ignore={edit}>
|
<ShowMore ignore={edit}>
|
||||||
{#if tx.collectionAttribute !== undefined && (tx.txDocIds?.size ?? 0) > 1}
|
{#if tx.collectionAttribute !== undefined && (tx.txDocIds?.size ?? 0) > 1}
|
||||||
<div class="flex-row-center flex-grow flex-wrap clear-mins">
|
<div class="flex-row-center flex-grow flex-wrap clear-mins">
|
||||||
@ -321,7 +321,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{:else if hasMessageType && model.length > 0 && (tx.updateTx || tx.mixinTx)}
|
{:else if hasMessageType && model.length > 0 && (tx.updateTx || tx.mixinTx)}
|
||||||
{#await getValue(client, model[0], tx) then value}
|
{#await getValue(client, model[0], tx) then value}
|
||||||
<div class="activity-content content" class:indent={isAttach} class:contentHidden>
|
<div class="activity-content content" class:indent={isAttached} class:contentHidden>
|
||||||
<ShowMore ignore={edit}>
|
<ShowMore ignore={edit}>
|
||||||
{#if value.isObjectSet}
|
{#if value.isObjectSet}
|
||||||
<ObjectPresenter value={value.set} inline />
|
<ObjectPresenter value={value.set} inline />
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.header {
|
.header {
|
||||||
min-height: 3rem;
|
min-height: 3.1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -80,50 +80,48 @@
|
|||||||
on:contextmenu|preventDefault={showMenu}
|
on:contextmenu|preventDefault={showMenu}
|
||||||
on:click={() => dispatch('click', { _id: value.attachedTo, _class: value.attachedToClass })}
|
on:click={() => dispatch('click', { _id: value.attachedTo, _class: value.attachedToClass })}
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div class="header flex">
|
||||||
<div class="header flex">
|
<Avatar avatar={employee?.avatar} size="medium" />
|
||||||
<Avatar avatar={employee?.avatar} size="medium" />
|
<div class="ml-2 w-full clear-mins">
|
||||||
<div class="ml-2 w-full clear-mins">
|
<div class="flex-between mb-1">
|
||||||
<div class="flex-between mb-1">
|
<div class="labels-row">
|
||||||
<div class="font-medium caption-color flex">
|
{#if employee}
|
||||||
{#if employee}
|
<span class="bold">{getName(employee)}</span>
|
||||||
{getName(employee)}
|
{:else}
|
||||||
{:else}
|
<span class="strong"><Label label={core.string.System} /></span>
|
||||||
<Label label={core.string.System} />
|
{/if}
|
||||||
{/if}
|
{#if newTxes > 0}
|
||||||
{#if newTxes > 0}
|
<div class="counter">
|
||||||
<div class="counter ml-2">
|
{newTxes}
|
||||||
{newTxes}
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="flex-center">
|
|
||||||
<div class="time ml-2"><TimeSince value={tx?.modifiedOn} /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{#if presenter}
|
<div class="time ml-2"><TimeSince value={tx?.modifiedOn} /></div>
|
||||||
<svelte:component this={presenter} value={doc} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
{#if presenter}
|
||||||
|
<svelte:component this={presenter} value={doc} inline />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if tx}
|
|
||||||
<TxView {tx} {viewlets} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
{#if tx}
|
||||||
|
<TxView {tx} {viewlets} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.content {
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--board-card-bg-hover);
|
background-color: var(--highlight-hover);
|
||||||
}
|
}
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: var(--board-card-bg-hover);
|
background-color: var(--highlight-select);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--highlight-select-hover);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,10 +129,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 1px solid;
|
margin-left: 0.25rem;
|
||||||
border-color: var(--divider-color);
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--theme-accent-color);
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -31,23 +31,23 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex-between">
|
<div class="flex-between clear-mins">
|
||||||
<div class="flex-presenter overflow-label mr-2">
|
<div class="flex-presenter inline-presenter mr-2">
|
||||||
{#if currentProject}
|
{#if currentProject}
|
||||||
<Icon icon={currentProject.icon ?? tracker.icon.Home} size="small" />
|
<div class="icon">
|
||||||
<div class="ml-1 mr-1 font-semi-bold">
|
<Icon icon={currentProject.icon ?? tracker.icon.Home} size="small" />
|
||||||
{currentProject.name}
|
|
||||||
</div>
|
</div>
|
||||||
|
<span class="label no-underline nowrap">
|
||||||
|
{currentProject.name}
|
||||||
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="overflow-label">
|
<span class="overflow-label ml-2">
|
||||||
{title}
|
<span class="content-accent-color">{title}</span>
|
||||||
{value.title}
|
{value.title}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{#if status}
|
||||||
{#if status}
|
<IssueStatusIcon value={status} size="small" />
|
||||||
<IssueStatusIcon value={status} size="small" />
|
{/if}
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user