Show card content diff (#10151)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2025-10-26 13:28:55 +05:00
committed by GitHub
parent 6f5740fba2
commit 54593b583d
30 changed files with 695 additions and 552 deletions
+503 -501
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -283,7 +283,7 @@
"electron-updater": "^6.3.4",
"livekit-client": "^2.15.6",
"@hcengineering/server-backup": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"ws": "^8.18.2"
},
"productName": "Huly Desktop",
+1 -1
View File
@@ -183,7 +183,7 @@
"@hcengineering/api-client": "^0.7.5",
"@faker-js/faker": "^8.4.1",
"@hcengineering/hulylake-client": "^0.7.6",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/pod-rating": "^0.7.0"
}
}
+1 -1
View File
@@ -37,7 +37,7 @@
"@hcengineering/card": "^0.7.0",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/communication-resources": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/model": "^0.7.6",
+2 -2
View File
@@ -47,8 +47,8 @@
"@hcengineering/contact": "^0.7.0",
"@hcengineering/collaborator-client": "^0.7.5",
"@hcengineering/communication-client-query": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/core": "^0.7.10",
"@hcengineering/diffview": "^0.7.0",
+1 -1
View File
@@ -51,7 +51,7 @@
"@hcengineering/ui": "^0.7.0",
"@hcengineering/view": "^0.7.0",
"@hcengineering/view-resources": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/emoji": "^0.7.0",
"@hcengineering/emoji-resources": "^0.7.0",
"svelte": "^4.2.20"
+1 -1
View File
@@ -41,7 +41,7 @@
"dependencies": {
"@hcengineering/presence": "^0.7.0",
"@hcengineering/presentation": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-resources": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/ui": "^0.7.0",
+1 -1
View File
@@ -42,7 +42,7 @@
"@hcengineering/card": "^0.7.0",
"@hcengineering/card-resources": "^0.7.0",
"@hcengineering/chat": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/contact-resources": "^0.7.0",
+2 -1
View File
@@ -43,13 +43,14 @@
},
"dependencies": {
"@hcengineering/analytics": "^0.7.5",
"@hcengineering/activity": "^0.7.0",
"@hcengineering/ai-bot": "^0.7.0",
"@hcengineering/ai-bot-resources": "^0.7.0",
"@hcengineering/attachment-resources": "^0.7.0",
"@hcengineering/card": "^0.7.0",
"@hcengineering/chat": "^0.7.0",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/contact-resources": "^0.7.0",
@@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, { type Class, type Client, type Doc, type Mixin, type Ref } from '@hcengineering/core'
import view, { type AttributeModel } from '@hcengineering/view'
import { buildRemovedDoc, getAttributePresenter } from '@hcengineering/view-resources'
import { type Card } from '@hcengineering/card'
import {
type ActivityAttributeUpdate,
type ActivityMessage,
type ActivityUpdate,
ActivityUpdateType,
type Message,
MessageType
} from '@hcengineering/communication-types'
import core, { type Class, type Client, type Doc, type Mixin, type Ref } from '@hcengineering/core'
import view, { type AttributeModel } from '@hcengineering/view'
import { buildRemovedDoc, getAttributePresenter } from '@hcengineering/view-resources'
const valueTypes: ReadonlyArray<Ref<Class<Doc>>> = [
core.class.TypeString,
@@ -52,13 +53,18 @@ export async function getAttributeModel (
update: ActivityUpdate | undefined,
_class: Ref<Class<Card>>
): Promise<AttributeModel | undefined> {
if (update == null || update.type !== ActivityUpdateType.Attribute) return undefined
if (
update == null ||
(update.type !== ActivityUpdateType.Attribute && update.type !== ActivityUpdateType.CollaborativeChange)
) {
return undefined
}
const { attrKey } = update
const model = await getAttributePresenterSafe(
client,
update.mixin ?? _class,
(update as ActivityAttributeUpdate).mixin ?? _class,
attrKey,
view.mixin.ActivityAttributePresenter
)
@@ -67,7 +73,7 @@ export async function getAttributeModel (
return model
}
return await getAttributePresenterSafe(client, update.mixin ?? _class, attrKey)
return await getAttributePresenterSafe(client, (update as ActivityAttributeUpdate).mixin ?? _class, attrKey)
}
export async function getAttributeValues (
@@ -0,0 +1,97 @@
<!--
// Copyright © 2025 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 { ActivityCollaborativeChange } from '@hcengineering/communication-types'
import { MarkupDiffPresenter } from '@hcengineering/view-resources'
import activity from '@hcengineering/activity'
import ui, { Label } from '@hcengineering/ui'
import { AttributeModel } from '@hcengineering/view'
import communication from '../../../plugin'
export let model: AttributeModel | undefined = undefined
export let update: ActivityCollaborativeChange
$: isTooLarge = update.value === activity.string.ValueTooLarge || update.prevValue === activity.string.ValueTooLarge
let isDiffShown = false
function toggleShowMore (): void {
isDiffShown = !isDiffShown
}
</script>
<div>
{#if model !== undefined}
<Label label={model.label} />
<span class="lower"><Label label={activity.string.Edited} /></span>
{/if}
{#if isTooLarge}
<div class="unset row overflow-label">
<Label label={activity.string.ValueTooLarge} />
</div>
{:else}
<div class="showMore" on:click={toggleShowMore}>
<div class="triangle" class:left={!isDiffShown} class:down={isDiffShown} />
<Label label={isDiffShown ? ui.string.ShowLess : ui.string.ShowMore} />
</div>
{/if}
</div>
{#if isDiffShown}
<MarkupDiffPresenter value={update.value} prevValue={update.prevValue} />
{/if}
<style lang="scss">
.showMore {
color: var(--global-primary-LinkColor);
cursor: pointer;
display: flex;
align-items: center;
font-weight: 500;
gap: 0.5rem;
.triangle {
width: 0;
height: 0;
&.left {
border-top: 0.25rem solid transparent;
border-bottom: 0.25rem solid transparent;
border-left: 0.25rem solid var(--global-primary-LinkColor);
border-right: none;
}
&.down {
border-left: 0.25rem solid transparent;
border-right: 0.25rem solid transparent;
border-top: 0.25rem solid var(--global-primary-LinkColor);
border-bottom: none;
}
}
&:hover {
color: var(--global-focus-BorderColor);
.triangle {
&.left {
border-left-color: var(--global-focus-BorderColor);
}
&.down {
border-top-color: var(--global-focus-BorderColor);
}
}
}
}
</style>
@@ -23,6 +23,7 @@
import { Card } from '@hcengineering/card'
import ActivityUpdateTypeViewer from './ActivityUpdateTypeViewer.svelte'
import ActivityUpdateProcessViewer from './ActivityUpdateProcessViewer.svelte'
import ActivityCollaborativeContentViewer from './ActivityCollaborativeContentViewer.svelte'
export let model: AttributeModel | undefined = undefined
export let update: ActivityUpdate
@@ -41,4 +42,6 @@
<ActivityUpdateTypeViewer {update} />
{:else if update.type === ActivityUpdateType.Process}
<ActivityUpdateProcessViewer {update} {content} />
{:else if update.type === ActivityUpdateType.CollaborativeChange}
<ActivityCollaborativeContentViewer {model} {update} />
{/if}
+1 -1
View File
@@ -38,7 +38,7 @@
},
"dependencies": {
"@hcengineering/platform": "^0.7.5",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/core": "^0.7.10",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/ui": "^0.7.0",
+1 -1
View File
@@ -42,7 +42,7 @@
"@hcengineering/card": "^0.7.0",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/communication-resources": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/contact-resources": "^0.7.0",
+1 -1
View File
@@ -58,7 +58,7 @@
"@hcengineering/support-resources": "^0.7.0",
"@hcengineering/view-resources": "^0.7.0",
"@hcengineering/inbox": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"fast-copy": "^3.0.2",
"@hcengineering/analytics": "^0.7.5",
"@hcengineering/account-client": "^0.7.7",
+2 -2
View File
@@ -76,8 +76,8 @@
"@hcengineering/postgres": "^0.7.9",
"@hcengineering/mongo": "^0.7.8",
"@hcengineering/kafka": "^0.7.8",
"@hcengineering/communication-server": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-server": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/hulylake-client": "^0.7.6"
}
}
+2 -2
View File
@@ -64,8 +64,8 @@
"@hcengineering/server-token": "^0.7.5",
"@hcengineering/attachment": "^0.7.0",
"@hcengineering/drive": "^0.7.0",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"dotenv": "~16.0.0",
"kafkajs": "^2.2.4"
}
+2 -2
View File
@@ -61,8 +61,8 @@
"dependencies": {
"@hcengineering/analytics": "^0.7.5",
"@hcengineering/analytics-service": "^0.7.5",
"@hcengineering/communication-server": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-server": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/kafka": "^0.7.8",
@@ -45,8 +45,8 @@
"@hcengineering/server-core": "^0.7.8",
"@hcengineering/server-notification-resources": "^0.7.0",
"@hcengineering/text-core": "^0.7.5",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/server-card": "^0.7.0"
}
}
+2 -2
View File
@@ -43,8 +43,8 @@
"@hcengineering/core": "^0.7.10",
"@hcengineering/platform": "^0.7.5",
"@hcengineering/server-core": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/server-contact": "^0.7.0",
"@hcengineering/contact": "^0.7.0"
+2
View File
@@ -46,6 +46,8 @@
"@types/jest": "^29.5.5"
},
"dependencies": {
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/activity": "^0.7.0",
"@hcengineering/analytics": "^0.7.5",
"@hcengineering/core": "^0.7.10",
+36 -4
View File
@@ -17,7 +17,9 @@ import activity, { DocUpdateMessage } from '@hcengineering/activity'
import { Analytics } from '@hcengineering/analytics'
import { loadCollabJson, loadCollabYdoc, saveCollabJson, saveCollabYdoc } from '@hcengineering/collaboration'
import { decodeDocumentId } from '@hcengineering/collaborator-client'
import core, { AttachedData, MeasureContext, Ref, Space, TxOperations } from '@hcengineering/core'
import { CreateMessageEvent, MessageEventType } from '@hcengineering/communication-sdk-types'
import { ActivityCollaborativeChange, ActivityUpdateType, MessageType } from '@hcengineering/communication-types'
import core, { AttachedData, Doc, MeasureContext, OperationDomain, Ref, Space, TxOperations } from '@hcengineering/core'
import { StorageAdapter } from '@hcengineering/server-core'
import { areEqualMarkups } from '@hcengineering/text'
import { markupToYDoc } from '@hcengineering/text-ydoc'
@@ -263,11 +265,11 @@ export class PlatformStorageAdapter implements CollabStorageAdapter {
await ctx.with(
'activity',
{},
() => {
async () => {
const space = hierarchy.isDerived(current._class, core.class.Space)
? (current._id as Ref<Space>)
: current.space
await sendEvent(client, objectAttr, prevValue, currValue, current)
const data: AttachedData<DocUpdateMessage> = {
objectId,
objectClass,
@@ -282,7 +284,7 @@ export class PlatformStorageAdapter implements CollabStorageAdapter {
isMixin: hierarchy.isMixin(objectClass)
}
}
return client.addCollection(
return await client.addCollection(
activity.class.DocUpdateMessage,
space,
current._id,
@@ -301,6 +303,36 @@ export class PlatformStorageAdapter implements CollabStorageAdapter {
}
}
async function sendEvent (
client: Omit<TxOperations, 'close'>,
attrKey: string,
prevValue: string,
value: string,
doc: Doc
): Promise<void> {
const eventData: ActivityCollaborativeChange = {
type: ActivityUpdateType.CollaborativeChange,
attrKey,
value,
prevValue
}
const event: CreateMessageEvent = {
type: MessageEventType.CreateMessage,
messageType: MessageType.Activity,
cardId: doc._id,
cardType: doc._class,
extra: {
action: 'update',
update: eventData
},
content: '',
socialId: client.txFactory.account,
date: new Date()
}
await client.domainRequest('communication' as OperationDomain, { event })
}
async function withRetry<T> (
ctx: MeasureContext,
retries: number,
+3 -3
View File
@@ -49,10 +49,10 @@
"@hcengineering/drive": "^0.7.0",
"fast-equals": "^5.2.2",
"@hcengineering/storage": "^0.7.5",
"@hcengineering/communication-rest-client": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-rest-client": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/hulylake-client": "^0.7.6"
}
}
+2 -2
View File
@@ -180,8 +180,8 @@
"@hcengineering/card": "^0.7.0",
"@hcengineering/mail": "^0.7.0",
"@hcengineering/kafka": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication": "^0.7.0",
"@hcengineering/communication-assets": "^0.7.0"
}
+2 -2
View File
@@ -64,8 +64,8 @@
"@hcengineering/chat": "^0.7.0",
"@hcengineering/client": "^0.7.6",
"@hcengineering/client-resources": "^0.7.6",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-rest-client": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-rest-client": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/kvs-client": "^0.7.0",
"@hcengineering/mail-common": "^0.7.0",
+3 -3
View File
@@ -50,10 +50,10 @@
"@hcengineering/api-client": "^0.7.5",
"@hcengineering/card": "^0.7.0",
"@hcengineering/chat": "^0.7.0",
"@hcengineering/communication-rest-client": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-rest-client": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/kafka": "^0.7.8",
+3 -3
View File
@@ -62,9 +62,9 @@
"@hcengineering/api-client": "^0.7.5",
"@hcengineering/card": "^0.7.0",
"@hcengineering/chat": "^0.7.0",
"@hcengineering/communication-rest-client": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-rest-client": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/kafka": "^0.7.8",
+2 -2
View File
@@ -66,8 +66,8 @@
"@hcengineering/server-core": "^0.7.8",
"@hcengineering/server-token": "^0.7.5",
"@hcengineering/account-client": "^0.7.7",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@temporalio/client": "1.12.3",
"dotenv": "~16.0.0"
}
+2 -2
View File
@@ -71,8 +71,8 @@
"@hcengineering/postgres": "^0.7.9",
"@hcengineering/mongo": "^0.7.8",
"@hcengineering/kafka": "^0.7.8",
"@hcengineering/communication-server": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-server": "^0.7.9",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/rating": "^0.7.0",
"@hcengineering/contact": "^0.7.0",
"lru-cache": "^11.1.0"
+2 -2
View File
@@ -58,9 +58,9 @@
"@hcengineering/api-client": "^0.7.5",
"@hcengineering/billing-client": "^0.7.0",
"@hcengineering/card": "^0.7.0",
"@hcengineering/communication-sdk-types": "^0.7.8",
"@hcengineering/communication-sdk-types": "^0.7.9",
"@hcengineering/communication-shared": "^0.7.8",
"@hcengineering/communication-types": "^0.7.8",
"@hcengineering/communication-types": "^0.7.9",
"@hcengineering/contact": "^0.7.0",
"@hcengineering/core": "^0.7.10",
"@hcengineering/hulylake-client": "^0.7.6",