mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
UBERF-5675: fix activity and notifications for colelction update (#4819)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
ff9e4abb7d
commit
9dab305008
@ -87,6 +87,8 @@ export class TRequestPresenter extends TClass implements RequestPresenter {
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TRequest, TRequestDecisionComment, TRequestPresenter)
|
||||
|
||||
builder.mixin(request.class.Request, core.class.Class, activity.mixin.IgnoreActivity, {})
|
||||
|
||||
builder.mixin(request.class.Request, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: request.component.EditRequest
|
||||
})
|
||||
|
@ -23,6 +23,6 @@ export { serverRequestId } from '@hcengineering/server-request'
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverRequest.trigger.OnRequestUpdate
|
||||
trigger: serverRequest.trigger.OnRequest
|
||||
})
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ function getDocUpdateMessageTx (
|
||||
)
|
||||
}
|
||||
|
||||
async function pushDocUpdateMessages (
|
||||
ctx: MeasureContext,
|
||||
export async function pushDocUpdateMessages (
|
||||
ctx: MeasureContext | undefined,
|
||||
control: ActivityControl,
|
||||
res: TxCollectionCUD<Doc, DocUpdateMessage>[],
|
||||
object: Doc | undefined,
|
||||
@ -295,7 +295,7 @@ export async function generateDocUpdateMessages (
|
||||
case core.class.TxCollectionCUD: {
|
||||
const actualTx = TxProcessor.extractTx(tx) as TxCUD<Doc>
|
||||
res = await generateDocUpdateMessages(ctx, actualTx, control, res, tx, objectCache)
|
||||
if ([core.class.TxCreateDoc, core.class.TxRemoveDoc, core.class.TxUpdateDoc].includes(actualTx._class)) {
|
||||
if ([core.class.TxCreateDoc, core.class.TxRemoveDoc].includes(actualTx._class)) {
|
||||
if (!isActivityDoc(tx.objectClass, control.hierarchy)) {
|
||||
return res
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ export async function pushActivityInboxNotifications (
|
||||
}
|
||||
}
|
||||
|
||||
async function getNotificationTxes (
|
||||
export async function getNotificationTxes (
|
||||
control: TriggerControl,
|
||||
object: Doc,
|
||||
tx: TxCUD<Doc>,
|
||||
@ -608,6 +608,12 @@ export async function createCollabDocInfo (
|
||||
return res
|
||||
}
|
||||
|
||||
const docMessages = activityMessage.filter((message) => message.attachedTo === object._id)
|
||||
|
||||
if (docMessages.length === 0) {
|
||||
return res
|
||||
}
|
||||
|
||||
const targets = new Set(collaborators)
|
||||
|
||||
// user is not collaborator of himself, but we should notify user of changes related to users account (mentions, comments etc)
|
||||
@ -619,7 +625,7 @@ export async function createCollabDocInfo (
|
||||
}
|
||||
|
||||
const notifyContexts = await control.findAll(notification.class.DocNotifyContext, {
|
||||
attachedTo: { $in: activityMessage.map(({ attachedTo }) => attachedTo) }
|
||||
attachedTo: object._id
|
||||
})
|
||||
|
||||
for (const target of targets) {
|
||||
@ -633,7 +639,7 @@ export async function createCollabDocInfo (
|
||||
isOwn,
|
||||
isSpace,
|
||||
notifyContexts,
|
||||
activityMessage,
|
||||
docMessages,
|
||||
shouldUpdateTimestamp
|
||||
)
|
||||
)
|
||||
@ -800,15 +806,6 @@ async function collectionCollabDoc (
|
||||
return res
|
||||
}
|
||||
|
||||
const isNotificationPushed = (res as TxCUD<Doc>[]).some(
|
||||
({ _class, objectClass }) =>
|
||||
_class === core.class.TxCreateDoc && objectClass === notification.class.ActivityInboxNotification
|
||||
)
|
||||
|
||||
if (isNotificationPushed) {
|
||||
return res
|
||||
}
|
||||
|
||||
const mixin = control.hierarchy.classHierarchyMixin(tx.objectClass, notification.mixin.ClassCollaborators)
|
||||
|
||||
if (mixin === undefined) {
|
||||
@ -821,18 +818,10 @@ async function collectionCollabDoc (
|
||||
return res
|
||||
}
|
||||
|
||||
if (control.hierarchy.hasMixin(doc, notification.mixin.Collaborators)) {
|
||||
const collaborators = control.hierarchy.as(doc, notification.mixin.Collaborators)
|
||||
const collaborators = await getCollaborators(doc, control, tx, res)
|
||||
|
||||
res = res.concat(
|
||||
await createCollabDocInfo(collaborators.collaborators, control, actualTx, tx, doc, activityMessages, false)
|
||||
)
|
||||
} else {
|
||||
const collaborators = await getDocCollaborators(doc, mixin, control)
|
||||
res = res.concat(await createCollabDocInfo(collaborators, control, actualTx, tx, doc, activityMessages, false))
|
||||
|
||||
res.push(getMixinTx(tx, control, collaborators))
|
||||
res = res.concat(await createCollabDocInfo(collaborators, control, actualTx, tx, doc, activityMessages, false))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@ -1107,6 +1096,28 @@ async function OnActivityNotificationViewed (
|
||||
)
|
||||
}
|
||||
|
||||
export async function getCollaborators (
|
||||
doc: Doc,
|
||||
control: TriggerControl,
|
||||
tx: TxCUD<Doc>,
|
||||
res: Tx[]
|
||||
): Promise<Ref<Account>[]> {
|
||||
const mixin = control.hierarchy.classHierarchyMixin(doc._class, notification.mixin.ClassCollaborators)
|
||||
|
||||
if (mixin === undefined) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (control.hierarchy.hasMixin(doc, notification.mixin.Collaborators)) {
|
||||
return control.hierarchy.as(doc, notification.mixin.Collaborators).collaborators
|
||||
} else {
|
||||
const collaborators = await getDocCollaborators(doc, mixin, control)
|
||||
|
||||
res.push(getMixinTx(tx, control, collaborators))
|
||||
return collaborators
|
||||
}
|
||||
}
|
||||
|
||||
export * from './types'
|
||||
export * from './utils'
|
||||
|
||||
|
@ -38,8 +38,11 @@
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-request": "^0.6.0",
|
||||
"@hcengineering/request": "^0.6.6",
|
||||
"@hcengineering/chunter": "^0.6.12",
|
||||
"@hcengineering/view": "^0.6.9",
|
||||
"@hcengineering/contact": "^0.6.20"
|
||||
"@hcengineering/contact": "^0.6.20",
|
||||
"@hcengineering/server-activity-resources": "^0.6.0",
|
||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||
"@hcengineering/notification": "^0.6.16",
|
||||
"@hcengineering/activity": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -13,18 +13,42 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import core, { Doc, Hierarchy, Tx, TxCollectionCUD, TxUpdateDoc } from '@hcengineering/core'
|
||||
import core, { Doc, Tx, TxCUD, TxCollectionCUD, TxCreateDoc, TxUpdateDoc, TxProcessor } from '@hcengineering/core'
|
||||
import request, { Request, RequestStatus } from '@hcengineering/request'
|
||||
import type { TriggerControl } from '@hcengineering/server-core'
|
||||
import { pushDocUpdateMessages } from '@hcengineering/server-activity-resources'
|
||||
import { DocUpdateMessage } from '@hcengineering/activity'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { getNotificationTxes, getCollaborators } from '@hcengineering/server-notification-resources'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnRequestUpdate (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
export async function OnRequest (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
if (tx._class !== core.class.TxCollectionCUD) {
|
||||
return []
|
||||
}
|
||||
|
||||
const hierarchy = control.hierarchy
|
||||
const ptx = tx as TxCollectionCUD<Doc, Request>
|
||||
if (!checkTx(ptx, hierarchy)) return []
|
||||
const ctx = ptx.tx as TxUpdateDoc<Request>
|
||||
|
||||
if (!hierarchy.isDerived(ptx.tx.objectClass, request.class.Request)) {
|
||||
return []
|
||||
}
|
||||
|
||||
let res: Tx[] = []
|
||||
|
||||
res = res.concat(await getRequestNotificationTx(ptx, control))
|
||||
|
||||
if (ptx.tx._class === core.class.TxUpdateDoc) {
|
||||
res = res.concat(await OnRequestUpdate(ptx, control))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
async function OnRequestUpdate (tx: TxCollectionCUD<Doc, Request>, control: TriggerControl): Promise<Tx[]> {
|
||||
const ctx = tx.tx as TxUpdateDoc<Request>
|
||||
if (ctx.operations.$push?.approved === undefined) return []
|
||||
const request = (await control.findAll(ctx.objectClass, { _id: ctx.objectId }))[0]
|
||||
if (request.approved.length === request.requiredApprovesCount) {
|
||||
@ -33,9 +57,9 @@ export async function OnRequestUpdate (tx: Tx, control: TriggerControl): Promise
|
||||
})
|
||||
collectionTx.space = core.space.Tx
|
||||
const resTx = control.txFactory.createTxCollectionCUD(
|
||||
ptx.objectClass,
|
||||
ptx.objectId,
|
||||
ptx.objectSpace,
|
||||
tx.objectClass,
|
||||
tx.objectId,
|
||||
tx.objectSpace,
|
||||
'requests',
|
||||
collectionTx
|
||||
)
|
||||
@ -46,20 +70,59 @@ export async function OnRequestUpdate (tx: Tx, control: TriggerControl): Promise
|
||||
return []
|
||||
}
|
||||
|
||||
function checkTx (ptx: TxCollectionCUD<Doc, Request>, hierarchy: Hierarchy): boolean {
|
||||
if (ptx._class !== core.class.TxCollectionCUD) {
|
||||
return false
|
||||
async function getRequest (tx: TxCUD<Request>, control: TriggerControl): Promise<Request | undefined> {
|
||||
if (tx._class === core.class.TxCreateDoc) {
|
||||
return TxProcessor.createDoc2Doc(tx as TxCreateDoc<Request>)
|
||||
}
|
||||
if (tx._class === core.class.TxRemoveDoc) {
|
||||
return control.removedMap.get(tx.objectId) as Request
|
||||
}
|
||||
if (tx._class === core.class.TxUpdateDoc) {
|
||||
return (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0]
|
||||
}
|
||||
|
||||
if (ptx.tx._class !== core.class.TxUpdateDoc || !hierarchy.isDerived(ptx.tx.objectClass, request.class.Request)) {
|
||||
return false
|
||||
return undefined
|
||||
}
|
||||
|
||||
// We need request-specific logic to attach a activity message on request create/update to parent, but use request collaborators for notifications
|
||||
async function getRequestNotificationTx (tx: TxCollectionCUD<Doc, Request>, control: TriggerControl): Promise<Tx[]> {
|
||||
const request = await getRequest(tx.tx, control)
|
||||
|
||||
if (request === undefined) return []
|
||||
|
||||
const doc = (await control.findAll(tx.objectClass, { _id: tx.objectId }, { limit: 1 }))[0]
|
||||
|
||||
if (doc === undefined) return []
|
||||
|
||||
const res: Tx[] = []
|
||||
const messagesTxes = await pushDocUpdateMessages(undefined, control, [], doc, tx)
|
||||
|
||||
if (messagesTxes.length === 0) return []
|
||||
|
||||
res.push(...messagesTxes)
|
||||
|
||||
const messages = messagesTxes.map((messageTx) =>
|
||||
TxProcessor.createDoc2Doc(messageTx.tx as TxCreateDoc<DocUpdateMessage>)
|
||||
)
|
||||
const collaborators = await getCollaborators(request, control, tx.tx, res)
|
||||
|
||||
if (collaborators.length === 0) return res
|
||||
|
||||
const notifyContexts = await control.findAll(notification.class.DocNotifyContext, {
|
||||
attachedTo: doc._id
|
||||
})
|
||||
|
||||
for (const target of collaborators) {
|
||||
const txes = await getNotificationTxes(control, request, tx.tx, tx, target, true, false, notifyContexts, messages)
|
||||
res.push(...txes)
|
||||
}
|
||||
return true
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnRequestUpdate
|
||||
OnRequest
|
||||
}
|
||||
})
|
||||
|
@ -26,6 +26,6 @@ export const serverRequestId = 'server-request' as Plugin
|
||||
*/
|
||||
export default plugin(serverRequestId, {
|
||||
trigger: {
|
||||
OnRequestUpdate: '' as Resource<TriggerFunc>
|
||||
OnRequest: '' as Resource<TriggerFunc>
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user