diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 801f4a0df9..eda08c050c 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -1140,6 +1140,25 @@ export function createModel (builder: Builder): void { recruit.ids.VacancyNotificationGroup ) + builder.createDoc( + notification.class.NotificationType, + core.space.Model, + { + hidden: false, + generated: false, + label: recruit.string.CreateApplication, + group: recruit.ids.VacancyNotificationGroup, + field: 'space', + txClasses: [core.class.TxCreateDoc, core.class.TxUpdateDoc], + objectClass: recruit.class.Applicant, + spaceSubscribe: true, + providers: { + [notification.providers.PlatformNotification]: false + } + }, + recruit.ids.ApplicationCreateNotification + ) + generateClassNotificationTypes(builder, recruit.class.Vacancy, recruit.ids.VacancyNotificationGroup, [], ['comments']) builder.createDoc( diff --git a/models/recruit/src/plugin.ts b/models/recruit/src/plugin.ts index 5651be630c..4cda9bafb9 100644 --- a/models/recruit/src/plugin.ts +++ b/models/recruit/src/plugin.ts @@ -72,7 +72,8 @@ export default mergeIds(recruitId, recruit, { VacancyNotificationGroup: '' as Ref, CandidateNotificationGroup: '' as Ref, ApplicationNotificationGroup: '' as Ref, - AssigneeNotification: '' as Ref + AssigneeNotification: '' as Ref, + ApplicationCreateNotification: '' as Ref }, component: { CreateApplication: '' as AnyComponent, diff --git a/plugins/notification/src/index.ts b/plugins/notification/src/index.ts index a9aefce002..f4ec48eea3 100644 --- a/plugins/notification/src/index.ts +++ b/plugins/notification/src/index.ts @@ -111,6 +111,8 @@ export interface NotificationType extends Doc { attachedToClass?: Ref> // use for update/mixin txes field?: string + // use for space collaborators, not object + spaceSubscribe?: boolean // allowed providers and default value for it providers: Record, boolean> // templates for email (and browser/push?) diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index 2434dc32bc..10bf804dfb 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -423,8 +423,14 @@ function isTypeMatched ( return true } -async function getMatchedTypes (control: TriggerControl, tx: TxCUD): Promise { - const allTypes = await control.modelDb.findAll(notification.class.NotificationType, {}) +async function getMatchedTypes ( + control: TriggerControl, + tx: TxCUD, + isSpace: boolean = false +): Promise { + const allTypes = (await control.modelDb.findAll(notification.class.NotificationType, {})).filter((p) => + isSpace ? p.spaceSubscribe === true : p.spaceSubscribe !== true + ) const extractedTx = TxProcessor.extractTx(tx) as TxCUD const filtered: NotificationType[] = [] for (const type of allTypes) { @@ -444,11 +450,12 @@ async function isShouldNotify ( control: TriggerControl, tx: TxCUD, object: Doc, - user: Ref + user: Ref, + isSpace: boolean ): Promise { let allowed = false const emailTypes: NotificationType[] = [] - const types = await getMatchedTypes(control, tx) + const types = await getMatchedTypes(control, tx, isSpace) for (const type of types) { if (control.hierarchy.hasMixin(type, serverNotification.mixin.TypeMatch)) { const mixin = control.hierarchy.as(type, serverNotification.mixin.TypeMatch) @@ -476,11 +483,12 @@ async function getNotificationTxes ( object: Doc, originTx: TxCUD, target: Ref, - docUpdates: DocUpdates[] + docUpdates: DocUpdates[], + isSpace: boolean ): Promise { if (originTx.modifiedBy === target) return [] const res: Tx[] = [] - const allowed = await isShouldNotify(control, originTx, object, target) + const allowed = await isShouldNotify(control, originTx, object, target, isSpace) if (allowed.allowed) { const current = docUpdates.find((p) => p.user === target) if (current === undefined) { @@ -532,13 +540,14 @@ async function createCollabDocInfo ( collaborators: Ref[], control: TriggerControl, originTx: TxCUD, - object: Doc + object: Doc, + isSpace: boolean = false ): Promise { let res: Tx[] = [] const targets = new Set(collaborators) const docUpdates = await control.findAll(notification.class.DocUpdates, { attachedTo: object._id }) for (const target of targets) { - res = res.concat(await getNotificationTxes(control, object, originTx, target, docUpdates)) + res = res.concat(await getNotificationTxes(control, object, originTx, target, docUpdates, isSpace)) } return res } @@ -563,6 +572,27 @@ export function getMixinTx ( return tx } +async function getSpaceCollabTxes ( + control: TriggerControl, + doc: Doc, + tx: TxCUD, + originTx: TxCUD +): Promise { + const space = (await control.findAll(core.class.Space, { _id: doc.space }))[0] + if (space === undefined) return [] + const mixin = control.hierarchy.classHierarchyMixin( + space._class, + notification.mixin.ClassCollaborators + ) + if (mixin !== undefined) { + const collabs = control.hierarchy.as(space, notification.mixin.Collaborators) + if (collabs.collaborators !== undefined) { + return await createCollabDocInfo(collabs.collaborators, control, originTx, doc, true) + } + } + return [] +} + /** * @public */ @@ -574,8 +604,8 @@ export async function createCollaboratorDoc ( const res: Tx[] = [] const hierarchy = control.hierarchy const mixin = hierarchy.classHierarchyMixin(tx.objectClass, notification.mixin.ClassCollaborators) + const doc = TxProcessor.createDoc2Doc(tx) if (mixin !== undefined) { - const doc = TxProcessor.createDoc2Doc(tx) const collaborators = await getDocCollaborators(doc, mixin, control) const mixinTx = getMixinTx(tx, control, collaborators) @@ -583,6 +613,7 @@ export async function createCollaboratorDoc ( res.push(mixinTx) res.push(...notificationTxes) } + res.push(...(await getSpaceCollabTxes(control, doc, tx, originTx))) return res } @@ -717,6 +748,8 @@ async function updateCollaboratorDoc ( res = res.concat(await createCollabDocInfo(collaborators, control, originTx, doc)) } + res = res.concat(await getSpaceCollabTxes(control, doc, tx, originTx)) + return res }