mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-07 00:09:34 +00:00
UBER-30 Notify user when added to collaborators (#3200)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
72f1570b7f
commit
4949142b19
@ -32,6 +32,7 @@
|
|||||||
"@hcengineering/model-core": "^0.6.0",
|
"@hcengineering/model-core": "^0.6.0",
|
||||||
"@hcengineering/model-preference": "^0.6.0",
|
"@hcengineering/model-preference": "^0.6.0",
|
||||||
"@hcengineering/model-view": "^0.6.0",
|
"@hcengineering/model-view": "^0.6.0",
|
||||||
|
"@hcengineering/activity": "^0.6.0",
|
||||||
"@hcengineering/view": "^0.6.6",
|
"@hcengineering/view": "^0.6.6",
|
||||||
"@hcengineering/workbench": "^0.6.6",
|
"@hcengineering/workbench": "^0.6.6",
|
||||||
"@hcengineering/model-workbench": "^0.6.1",
|
"@hcengineering/model-workbench": "^0.6.1",
|
||||||
|
@ -52,6 +52,7 @@ import type { Asset, IntlString } from '@hcengineering/platform'
|
|||||||
import setting from '@hcengineering/setting'
|
import setting from '@hcengineering/setting'
|
||||||
import { AnyComponent } from '@hcengineering/ui'
|
import { AnyComponent } from '@hcengineering/ui'
|
||||||
import notification from './plugin'
|
import notification from './plugin'
|
||||||
|
import activity from '@hcengineering/activity'
|
||||||
|
|
||||||
export { notificationId } from '@hcengineering/notification'
|
export { notificationId } from '@hcengineering/notification'
|
||||||
export { notificationOperation } from './migration'
|
export { notificationOperation } from './migration'
|
||||||
@ -301,6 +302,48 @@ export function createModel (builder: Builder): void {
|
|||||||
mode: ['workbench', 'browser', 'editor', 'panel', 'popup']
|
mode: ['workbench', 'browser', 'editor', 'panel', 'popup']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.createDoc(
|
||||||
|
notification.class.NotificationGroup,
|
||||||
|
core.space.Model,
|
||||||
|
{
|
||||||
|
label: notification.string.Notifications,
|
||||||
|
icon: notification.icon.Notifications
|
||||||
|
},
|
||||||
|
notification.ids.NotificationGroup
|
||||||
|
)
|
||||||
|
|
||||||
|
builder.createDoc(
|
||||||
|
notification.class.NotificationType,
|
||||||
|
core.space.Model,
|
||||||
|
{
|
||||||
|
hidden: false,
|
||||||
|
generated: false,
|
||||||
|
label: notification.string.Collaborators,
|
||||||
|
group: notification.ids.NotificationGroup,
|
||||||
|
txClasses: [],
|
||||||
|
objectClass: notification.mixin.Collaborators,
|
||||||
|
providers: {
|
||||||
|
[notification.providers.PlatformNotification]: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notification.ids.CollaboratoAddNotification
|
||||||
|
)
|
||||||
|
|
||||||
|
builder.createDoc(
|
||||||
|
activity.class.TxViewlet,
|
||||||
|
core.space.Model,
|
||||||
|
{
|
||||||
|
objectClass: notification.mixin.Collaborators,
|
||||||
|
icon: notification.icon.Notifications,
|
||||||
|
txClass: core.class.TxMixin,
|
||||||
|
component: notification.activity.TxCollaboratorsChange,
|
||||||
|
display: 'inline',
|
||||||
|
editable: false,
|
||||||
|
hideOnRemove: true
|
||||||
|
},
|
||||||
|
notification.ids.TxCollaboratorsChange
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateClassNotificationTypes (
|
export function generateClassNotificationTypes (
|
||||||
|
@ -20,6 +20,7 @@ import { IntlString, Resource, mergeIds } from '@hcengineering/platform'
|
|||||||
import { AnyComponent } from '@hcengineering/ui'
|
import { AnyComponent } from '@hcengineering/ui'
|
||||||
import { Action, ActionCategory, ViewAction } from '@hcengineering/view'
|
import { Action, ActionCategory, ViewAction } from '@hcengineering/view'
|
||||||
import { Application } from '@hcengineering/workbench'
|
import { Application } from '@hcengineering/workbench'
|
||||||
|
import { TxViewlet } from '@hcengineering/activity'
|
||||||
|
|
||||||
export default mergeIds(notificationId, notification, {
|
export default mergeIds(notificationId, notification, {
|
||||||
string: {
|
string: {
|
||||||
@ -33,6 +34,12 @@ export default mergeIds(notificationId, notification, {
|
|||||||
app: {
|
app: {
|
||||||
Notification: '' as Ref<Application>
|
Notification: '' as Ref<Application>
|
||||||
},
|
},
|
||||||
|
activity: {
|
||||||
|
TxCollaboratorsChange: '' as AnyComponent
|
||||||
|
},
|
||||||
|
ids: {
|
||||||
|
TxCollaboratorsChange: '' as Ref<TxViewlet>
|
||||||
|
},
|
||||||
component: {
|
component: {
|
||||||
NotificationSettings: '' as AnyComponent
|
NotificationSettings: '' as AnyComponent
|
||||||
},
|
},
|
||||||
|
@ -351,13 +351,13 @@
|
|||||||
</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}
|
||||||
{@const compareValue = getPrevValue(client, model[0], tx)}
|
{@const prevValue = getPrevValue(client, model[0], tx)}
|
||||||
<div class="activity-content content" class:indent={isAttached} class:contentHidden>
|
<div class="activity-content content" class:indent={isAttached} class:contentHidden>
|
||||||
<ShowMore ignore={edit || compareValue !== undefined}>
|
<ShowMore ignore={edit || prevValue !== undefined}>
|
||||||
{#if value.isObjectSet}
|
{#if value.isObjectSet}
|
||||||
<ObjectPresenter value={value.set} inline />
|
<ObjectPresenter value={value.set} inline />
|
||||||
{:else if showDiff}
|
{:else if showDiff}
|
||||||
<svelte:component this={model[0].presenter} value={value.set} inline {compareValue} showOnlyDiff />
|
<svelte:component this={model[0].presenter} value={value.set} inline {prevValue} showOnlyDiff />
|
||||||
{/if}
|
{/if}
|
||||||
</ShowMore>
|
</ShowMore>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,7 +77,7 @@ async function createPseudoViewlet (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getDTxProps (dtx: DisplayTx): any {
|
export function getDTxProps (dtx: DisplayTx): any {
|
||||||
return { tx: dtx.tx, value: dtx.doc, isOwnTx: dtx.isOwnTx }
|
return { tx: dtx.tx, value: dtx.doc, isOwnTx: dtx.isOwnTx, prevValue: dtx.prevDoc }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getViewlet (viewlets: Map<ActivityKey, TxViewlet>, dtx: DisplayTx): TxDisplayViewlet | undefined {
|
function getViewlet (viewlets: Map<ActivityKey, TxViewlet>, dtx: DisplayTx): TxDisplayViewlet | undefined {
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
"Inbox": "Inbox",
|
"Inbox": "Inbox",
|
||||||
"Collaborators": "Collaborators",
|
"Collaborators": "Collaborators",
|
||||||
"Change": "Change",
|
"Change": "Change",
|
||||||
"AddedRemoved": "Added/removed"
|
"AddedRemoved": "Added/removed",
|
||||||
|
"YouAddedCollaborators": "You was added to collaborators",
|
||||||
|
"ChangeCollaborators": "changed collaborators"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
"Inbox": "Входящие",
|
"Inbox": "Входящие",
|
||||||
"Collaborators": "Участники",
|
"Collaborators": "Участники",
|
||||||
"Change": "Изменено",
|
"Change": "Изменено",
|
||||||
"AddedRemoved": "Добавлено/удалено"
|
"AddedRemoved": "Добавлено/удалено",
|
||||||
|
"YouAddedCollaborators": "Вы были добавлены как участник",
|
||||||
|
"ChangeCollaborators": "изменил(а) участники"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2023 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 { EmployeeAccount } from '@hcengineering/contact'
|
||||||
|
import { EmployeeAccountRefPresenter } from '@hcengineering/contact-resources'
|
||||||
|
import { Doc, Ref, TxMixin } from '@hcengineering/core'
|
||||||
|
import { Collaborators } from '@hcengineering/notification'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
|
import { IconAdd, IconDelete, Label } from '@hcengineering/ui'
|
||||||
|
import notification from '../../plugin'
|
||||||
|
|
||||||
|
export let tx: TxMixin<Doc, Collaborators>
|
||||||
|
export let value: Collaborators
|
||||||
|
export let prevValue: Collaborators | undefined = undefined
|
||||||
|
|
||||||
|
interface Diff {
|
||||||
|
added: Ref<EmployeeAccount>[]
|
||||||
|
removed: Ref<EmployeeAccount>[]
|
||||||
|
}
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
|
function buildDiff (value: Collaborators, prev: Collaborators | undefined): Diff | undefined {
|
||||||
|
if (prev === undefined) return
|
||||||
|
const added: Ref<EmployeeAccount>[] = []
|
||||||
|
const removed: Ref<EmployeeAccount>[] = []
|
||||||
|
const mixin = hierarchy.as(value, notification.mixin.Collaborators)
|
||||||
|
const prevMixin = hierarchy.as(prev, notification.mixin.Collaborators)
|
||||||
|
const prevSet = new Set(prevMixin?.collaborators ?? [])
|
||||||
|
const newSet = new Set(mixin.collaborators)
|
||||||
|
|
||||||
|
for (const newCollab of mixin.collaborators) {
|
||||||
|
if (!prevSet.has(newCollab)) added.push(newCollab as Ref<EmployeeAccount>)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const oldCollab of prevMixin?.collaborators ?? []) {
|
||||||
|
if (!newSet.has(oldCollab)) removed.push(oldCollab as Ref<EmployeeAccount>)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
added,
|
||||||
|
removed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: diff = buildDiff(value, prevValue)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if diff}
|
||||||
|
<div class="flex-presenter">
|
||||||
|
<Label label={notification.string.ChangeCollaborators} />
|
||||||
|
{#if diff.added.length > 0}
|
||||||
|
<IconAdd size={'x-small'} fill={'var(--theme-trans-color)'} />
|
||||||
|
{#each diff.added as add}
|
||||||
|
<EmployeeAccountRefPresenter value={add} disabled />
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
{#if diff.removed.length > 0}
|
||||||
|
<IconDelete size={'x-small'} fill={'var(--theme-trans-color)'} />
|
||||||
|
{#each diff.removed as removed}
|
||||||
|
<EmployeeAccountRefPresenter value={removed} disabled />
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Label label={notification.string.YouAddedCollaborators} />
|
||||||
|
{/if}
|
@ -18,6 +18,7 @@ import { Resources } from '@hcengineering/platform'
|
|||||||
import Inbox from './components/Inbox.svelte'
|
import Inbox from './components/Inbox.svelte'
|
||||||
import NotificationSettings from './components/NotificationSettings.svelte'
|
import NotificationSettings from './components/NotificationSettings.svelte'
|
||||||
import NotificationPresenter from './components/NotificationPresenter.svelte'
|
import NotificationPresenter from './components/NotificationPresenter.svelte'
|
||||||
|
import TxCollaboratorsChange from './components/activity/TxCollaboratorsChange.svelte'
|
||||||
import { NotificationClientImpl, hasntNotifications, hide, markAsUnread, unsubscribe } from './utils'
|
import { NotificationClientImpl, hasntNotifications, hide, markAsUnread, unsubscribe } from './utils'
|
||||||
|
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
@ -30,6 +31,9 @@ export default async (): Promise<Resources> => ({
|
|||||||
NotificationPresenter,
|
NotificationPresenter,
|
||||||
NotificationSettings
|
NotificationSettings
|
||||||
},
|
},
|
||||||
|
activity: {
|
||||||
|
TxCollaboratorsChange
|
||||||
|
},
|
||||||
function: {
|
function: {
|
||||||
GetNotificationClient: NotificationClientImpl.getClient,
|
GetNotificationClient: NotificationClientImpl.getClient,
|
||||||
HasntNotifications: hasntNotifications
|
HasntNotifications: hasntNotifications
|
||||||
|
@ -28,6 +28,8 @@ export default mergeIds(notificationId, notification, {
|
|||||||
MarkAsRead: '' as IntlString,
|
MarkAsRead: '' as IntlString,
|
||||||
MarkAllAsRead: '' as IntlString,
|
MarkAllAsRead: '' as IntlString,
|
||||||
Change: '' as IntlString,
|
Change: '' as IntlString,
|
||||||
AddedRemoved: '' as IntlString
|
AddedRemoved: '' as IntlString,
|
||||||
|
YouAddedCollaborators: '' as IntlString,
|
||||||
|
ChangeCollaborators: '' as IntlString
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -202,7 +202,9 @@ const notification = plugin(notificationId, {
|
|||||||
NotificationGroup: '' as Ref<Class<NotificationGroup>>
|
NotificationGroup: '' as Ref<Class<NotificationGroup>>
|
||||||
},
|
},
|
||||||
ids: {
|
ids: {
|
||||||
NotificationSettings: '' as Ref<Doc>
|
NotificationSettings: '' as Ref<Doc>,
|
||||||
|
NotificationGroup: '' as Ref<NotificationGroup>,
|
||||||
|
CollaboratoAddNotification: '' as Ref<NotificationType>
|
||||||
},
|
},
|
||||||
providers: {
|
providers: {
|
||||||
PlatformNotification: '' as Ref<NotificationProvider>,
|
PlatformNotification: '' as Ref<NotificationProvider>,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { ShowMore } from '@hcengineering/ui'
|
import { ShowMore } from '@hcengineering/ui'
|
||||||
|
|
||||||
export let value: string | undefined
|
export let value: string | undefined
|
||||||
export let compareValue: string | undefined = undefined
|
export let prevValue: string | undefined = undefined
|
||||||
export let showOnlyDiff: boolean = false
|
export let showOnlyDiff: boolean = false
|
||||||
|
|
||||||
function removeSimilarLines (str1: string | undefined, str2: string | undefined) {
|
function removeSimilarLines (str1: string | undefined, str2: string | undefined) {
|
||||||
@ -35,14 +35,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
value = result1
|
value = result1
|
||||||
compareValue = result2
|
prevValue = result2
|
||||||
}
|
}
|
||||||
|
|
||||||
$: showOnlyDiff && removeSimilarLines(value, compareValue)
|
$: showOnlyDiff && removeSimilarLines(value, prevValue)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ShowMore>
|
<ShowMore>
|
||||||
{#key [value, compareValue]}
|
{#key [value, prevValue]}
|
||||||
<CollaborationDiffViewer content={value ?? ''} comparedVersion={compareValue ?? ''} noButton readonly />
|
<CollaborationDiffViewer content={value ?? ''} comparedVersion={prevValue ?? ''} noButton readonly />
|
||||||
{/key}
|
{/key}
|
||||||
</ShowMore>
|
</ShowMore>
|
||||||
|
@ -421,6 +421,45 @@ async function isShouldNotify (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pushNotification (
|
||||||
|
control: TriggerControl,
|
||||||
|
res: Tx[],
|
||||||
|
target: Ref<Account>,
|
||||||
|
object: Doc,
|
||||||
|
originTx: TxCUD<Doc>,
|
||||||
|
docUpdates: DocUpdates[]
|
||||||
|
): void {
|
||||||
|
const current = docUpdates.find((p) => p.user === target)
|
||||||
|
if (current === undefined) {
|
||||||
|
res.push(
|
||||||
|
control.txFactory.createTxCreateDoc(notification.class.DocUpdates, object.space, {
|
||||||
|
user: target,
|
||||||
|
attachedTo: object._id,
|
||||||
|
attachedToClass: object._class,
|
||||||
|
hidden: false,
|
||||||
|
lastTx: originTx._id,
|
||||||
|
lastTxTime: originTx.modifiedOn,
|
||||||
|
txes: [[originTx._id, originTx.modifiedOn]]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
res.push(
|
||||||
|
control.txFactory.createTxUpdateDoc(current._class, current.space, current._id, {
|
||||||
|
$push: {
|
||||||
|
txes: [originTx._id, originTx.modifiedOn]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
res.push(
|
||||||
|
control.txFactory.createTxUpdateDoc(current._class, current.space, current._id, {
|
||||||
|
lastTx: originTx._id,
|
||||||
|
lastTxTime: originTx.modifiedOn,
|
||||||
|
hidden: false
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getNotificationTxes (
|
async function getNotificationTxes (
|
||||||
control: TriggerControl,
|
control: TriggerControl,
|
||||||
object: Doc,
|
object: Doc,
|
||||||
@ -432,35 +471,7 @@ async function getNotificationTxes (
|
|||||||
const res: Tx[] = []
|
const res: Tx[] = []
|
||||||
const allowed = await isShouldNotify(control, originTx, object, target, isSpace)
|
const allowed = await isShouldNotify(control, originTx, object, target, isSpace)
|
||||||
if (allowed.allowed) {
|
if (allowed.allowed) {
|
||||||
const current = docUpdates.find((p) => p.user === target)
|
pushNotification(control, res, target, object, originTx, docUpdates)
|
||||||
if (current === undefined) {
|
|
||||||
res.push(
|
|
||||||
control.txFactory.createTxCreateDoc(notification.class.DocUpdates, object.space, {
|
|
||||||
user: target,
|
|
||||||
attachedTo: object._id,
|
|
||||||
attachedToClass: object._class,
|
|
||||||
hidden: false,
|
|
||||||
lastTx: originTx._id,
|
|
||||||
lastTxTime: originTx.modifiedOn,
|
|
||||||
txes: [[originTx._id, originTx.modifiedOn]]
|
|
||||||
})
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
res.push(
|
|
||||||
control.txFactory.createTxUpdateDoc(current._class, current.space, current._id, {
|
|
||||||
$push: {
|
|
||||||
txes: [originTx._id, originTx.modifiedOn]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
res.push(
|
|
||||||
control.txFactory.createTxUpdateDoc(current._class, current.space, current._id, {
|
|
||||||
lastTx: originTx._id,
|
|
||||||
lastTxTime: originTx.modifiedOn,
|
|
||||||
hidden: false
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (const type of allowed.emails) {
|
for (const type of allowed.emails) {
|
||||||
const emailTx = await createEmailNotificationTxes(
|
const emailTx = await createEmailNotificationTxes(
|
||||||
@ -572,9 +583,12 @@ export async function collaboratorDocHandler (
|
|||||||
if (tx.space === core.space.DerivedTx) return []
|
if (tx.space === core.space.DerivedTx) return []
|
||||||
return await createCollaboratorDoc(tx as TxCreateDoc<Doc>, control, originTx ?? tx)
|
return await createCollaboratorDoc(tx as TxCreateDoc<Doc>, control, originTx ?? tx)
|
||||||
case core.class.TxUpdateDoc:
|
case core.class.TxUpdateDoc:
|
||||||
case core.class.TxMixin:
|
case core.class.TxMixin: {
|
||||||
if (tx.space === core.space.DerivedTx) return []
|
if (tx.space === core.space.DerivedTx) return []
|
||||||
return await updateCollaboratorDoc(tx as TxUpdateDoc<Doc>, control, originTx ?? tx)
|
let res = await updateCollaboratorDoc(tx as TxUpdateDoc<Doc>, control, originTx ?? tx)
|
||||||
|
res = res.concat(await updateCollaboratorsMixin(tx as TxMixin<Doc, Collaborators>, control, originTx ?? tx))
|
||||||
|
return res
|
||||||
|
}
|
||||||
case core.class.TxRemoveDoc:
|
case core.class.TxRemoveDoc:
|
||||||
return await removeCollaboratorDoc(tx as TxRemoveDoc<Doc>, control)
|
return await removeCollaboratorDoc(tx as TxRemoveDoc<Doc>, control)
|
||||||
case core.class.TxCollectionCUD:
|
case core.class.TxCollectionCUD:
|
||||||
@ -584,6 +598,60 @@ export async function collaboratorDocHandler (
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateCollaboratorsMixin (
|
||||||
|
tx: TxMixin<Doc, Collaborators>,
|
||||||
|
control: TriggerControl,
|
||||||
|
originTx: TxCUD<Doc>
|
||||||
|
): Promise<Tx[]> {
|
||||||
|
if (tx._class !== core.class.TxMixin) return []
|
||||||
|
if (!control.hierarchy.isDerived(tx.mixin, notification.mixin.Collaborators)) return []
|
||||||
|
const res: Tx[] = []
|
||||||
|
if (tx.attributes.collaborators !== undefined) {
|
||||||
|
const createTx = control.hierarchy.isDerived(tx.objectClass, core.class.AttachedDoc)
|
||||||
|
? (
|
||||||
|
await control.findAll(core.class.TxCollectionCUD, {
|
||||||
|
'tx.objectId': tx.objectId,
|
||||||
|
'tx._class': core.class.TxCreateDoc
|
||||||
|
})
|
||||||
|
)[0]
|
||||||
|
: (
|
||||||
|
await control.findAll(core.class.TxCreateDoc, {
|
||||||
|
objectId: tx.objectId
|
||||||
|
})
|
||||||
|
)[0]
|
||||||
|
const mixinTxes = await control.findAll(core.class.TxMixin, {
|
||||||
|
objectId: tx.objectId
|
||||||
|
})
|
||||||
|
const prevDoc = TxProcessor.buildDoc2Doc([createTx, ...mixinTxes]) as Collaborators
|
||||||
|
const set = new Set(prevDoc?.collaborators ?? [])
|
||||||
|
const newCollabs: Ref<Account>[] = []
|
||||||
|
for (const collab of tx.attributes.collaborators) {
|
||||||
|
if (!set.has(collab)) {
|
||||||
|
if (
|
||||||
|
await isAllowed(
|
||||||
|
control,
|
||||||
|
collab as Ref<EmployeeAccount>,
|
||||||
|
notification.ids.CollaboratoAddNotification,
|
||||||
|
notification.providers.PlatformNotification
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
newCollabs.push(collab)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newCollabs.length > 0) {
|
||||||
|
const docUpdates = await control.findAll(notification.class.DocUpdates, {
|
||||||
|
user: { $in: newCollabs },
|
||||||
|
attachedTo: tx.objectId
|
||||||
|
})
|
||||||
|
for (const collab of newCollabs) {
|
||||||
|
pushNotification(control, res, collab, prevDoc, originTx, docUpdates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
async function collectionCollabDoc (tx: TxCollectionCUD<Doc, AttachedDoc>, control: TriggerControl): Promise<Tx[]> {
|
async function collectionCollabDoc (tx: TxCollectionCUD<Doc, AttachedDoc>, control: TriggerControl): Promise<Tx[]> {
|
||||||
const actualTx = TxProcessor.extractTx(tx)
|
const actualTx = TxProcessor.extractTx(tx)
|
||||||
let res = await collaboratorDocHandler(actualTx as TxCUD<Doc>, control, tx)
|
let res = await collaboratorDocHandler(actualTx as TxCUD<Doc>, control, tx)
|
||||||
|
Loading…
Reference in New Issue
Block a user