UBERF-5017: show correct collaborators diff and dont send notification for collaborators changer (#4529)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-02-05 18:35:49 +04:00 committed by GitHub
parent 8c45af8d88
commit 5d945aedc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 65 additions and 11 deletions

View File

@ -1,4 +1,5 @@
import { import {
Account,
AttachedDoc, AttachedDoc,
Class, Class,
Doc, Doc,
@ -16,6 +17,9 @@ import {
import core from '@hcengineering/core/lib/component' import core from '@hcengineering/core/lib/component'
import { DocAttributeUpdates, DocUpdateAction } from '@hcengineering/activity' import { DocAttributeUpdates, DocUpdateAction } from '@hcengineering/activity'
import { ActivityControl, DocObjectCache, getAllObjectTransactions } from '@hcengineering/server-activity' import { ActivityControl, DocObjectCache, getAllObjectTransactions } from '@hcengineering/server-activity'
import { getDocCollaborators } from '@hcengineering/server-notification-resources'
import notification from '@hcengineering/notification'
import { TriggerControl } from '@hcengineering/server-core'
function getAvailableAttributesKeys (tx: TxCUD<Doc>, hierarchy: Hierarchy): string[] { function getAvailableAttributesKeys (tx: TxCUD<Doc>, hierarchy: Hierarchy): string[] {
if (hierarchy.isDerived(tx._class, core.class.TxUpdateDoc)) { if (hierarchy.isDerived(tx._class, core.class.TxUpdateDoc)) {
@ -143,17 +147,54 @@ export async function getDocDiff (
return { doc, prevDoc } return { doc, prevDoc }
} }
export function getAttributeDiff ( interface AttributeDiff {
hierarchy: Hierarchy, added: DocAttributeUpdates['added']
removed: DocAttributeUpdates['removed']
}
async function getCollaboratorsDiff (
control: ActivityControl,
doc: Doc,
prevDoc: Doc | undefined
): Promise<AttributeDiff> {
const { hierarchy } = control
const value = hierarchy.as(doc, notification.mixin.Collaborators).collaborators ?? []
let prevValue: Ref<Account>[] = []
if (prevDoc !== undefined && hierarchy.hasMixin(prevDoc, notification.mixin.Collaborators)) {
prevValue = hierarchy.as(prevDoc, notification.mixin.Collaborators).collaborators ?? []
} else if (prevDoc !== undefined) {
const mixin = hierarchy.classHierarchyMixin(prevDoc._class, notification.mixin.ClassCollaborators)
prevValue = mixin !== undefined ? await getDocCollaborators(prevDoc, mixin, control as TriggerControl) : []
}
const added = value.filter((item) => !prevValue.includes(item)) as DocAttributeUpdates['added']
const removed = prevValue.filter((item) => !value.includes(item)) as DocAttributeUpdates['removed']
return {
added,
removed
}
}
export async function getAttributeDiff (
control: ActivityControl,
doc: Doc, doc: Doc,
prevDoc: Doc | undefined, prevDoc: Doc | undefined,
attrKey: string, attrKey: string,
attrClass: Ref<Class<Doc>>, attrClass: Ref<Class<Doc>>,
isMixin: boolean isMixin: boolean
): { added: DocAttributeUpdates['added'], removed: DocAttributeUpdates['removed'] } { ): Promise<AttributeDiff> {
const { hierarchy } = control
let actualDoc: Doc | undefined = doc let actualDoc: Doc | undefined = doc
let actualPrevDoc: Doc | undefined = prevDoc let actualPrevDoc: Doc | undefined = prevDoc
if (isMixin && hierarchy.isDerived(attrClass, notification.mixin.Collaborators)) {
return await getCollaboratorsDiff(control, doc, prevDoc)
}
if (isMixin) { if (isMixin) {
actualDoc = hierarchy.as(doc, attrClass) actualDoc = hierarchy.as(doc, attrClass)
actualPrevDoc = prevDoc === undefined ? undefined : hierarchy.as(prevDoc, attrClass) actualPrevDoc = prevDoc === undefined ? undefined : hierarchy.as(prevDoc, attrClass)
@ -247,7 +288,7 @@ export async function getTxAttributesUpdates (
} }
if (Array.isArray(attrValue) && doc != null) { if (Array.isArray(attrValue) && doc != null) {
const diff = getAttributeDiff(hierarchy, doc, prevDoc, key, attrClass, isMixin) const diff = await getAttributeDiff(control, doc, prevDoc, key, attrClass, isMixin)
added.push(...diff.added) added.push(...diff.added)
removed.push(...diff.removed) removed.push(...diff.removed)
attrValue = [] attrValue = []

View File

@ -681,12 +681,16 @@ async function updateCollaboratorsMixin (
activityMessages: ActivityMessage[], activityMessages: ActivityMessage[],
originTx: TxCUD<Doc> originTx: TxCUD<Doc>
): Promise<Tx[]> { ): Promise<Tx[]> {
const { hierarchy } = control
if (tx._class !== core.class.TxMixin) return [] if (tx._class !== core.class.TxMixin) return []
if (originTx.space === core.space.DerivedTx) return [] if (originTx.space === core.space.DerivedTx) return []
if (!control.hierarchy.isDerived(tx.mixin, notification.mixin.Collaborators)) return [] if (!hierarchy.isDerived(tx.mixin, notification.mixin.Collaborators)) return []
const res: Tx[] = [] const res: Tx[] = []
if (tx.attributes.collaborators !== undefined) { if (tx.attributes.collaborators !== undefined) {
const createTx = control.hierarchy.isDerived(tx.objectClass, core.class.AttachedDoc) const createTx = hierarchy.isDerived(tx.objectClass, core.class.AttachedDoc)
? ( ? (
await control.findAll(core.class.TxCollectionCUD, { await control.findAll(core.class.TxCollectionCUD, {
'tx.objectId': tx.objectId, 'tx.objectId': tx.objectId,
@ -701,12 +705,21 @@ async function updateCollaboratorsMixin (
const mixinTxes = await control.findAll(core.class.TxMixin, { const mixinTxes = await control.findAll(core.class.TxMixin, {
objectId: tx.objectId objectId: tx.objectId
}) })
const prevDoc = TxProcessor.buildDoc2Doc([createTx, ...mixinTxes].filter((t) => t._id !== tx._id)) as Collaborators const prevDoc = TxProcessor.buildDoc2Doc([createTx, ...mixinTxes].filter((t) => t._id !== tx._id)) as Doc
const prevDocMixin = control.hierarchy.as(prevDoc, notification.mixin.Collaborators)
const set = new Set(prevDocMixin?.collaborators ?? [])
const newCollabs: Ref<Account>[] = [] const newCollabs: Ref<Account>[] = []
let prevCollabs: Set<Ref<Account>>
if (hierarchy.hasMixin(prevDoc, notification.mixin.Collaborators)) {
const prevDocMixin = control.hierarchy.as(prevDoc, notification.mixin.Collaborators)
prevCollabs = new Set(prevDocMixin.collaborators ?? [])
} else {
const mixin = hierarchy.classHierarchyMixin(prevDoc._class, notification.mixin.ClassCollaborators)
prevCollabs = mixin !== undefined ? new Set(await getDocCollaborators(prevDoc, mixin, control)) : new Set()
}
for (const collab of tx.attributes.collaborators) { for (const collab of tx.attributes.collaborators) {
if (!set.has(collab)) { if (!prevCollabs.has(collab) && tx.modifiedBy !== collab) {
if ( if (
await isAllowed( await isAllowed(
control, control,

View File

@ -117,9 +117,9 @@ export async function isShouldNotify (
) )
const personAccount = await getPersonAccountById(user, control) const personAccount = await getPersonAccountById(user, control)
const modifiedAccount = await getPersonAccountById(tx.modifiedBy, control)
for (const type of types) { for (const type of types) {
const modifiedAccount = await getPersonAccountById(tx.modifiedBy, control)
if ( if (
type.allowedForAuthor !== true && type.allowedForAuthor !== true &&
(tx.modifiedBy === user || (tx.modifiedBy === user ||