TSK-1334 Vacancy application notification (#3108)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2023-04-28 14:22:39 +06:00 committed by GitHub
parent 082bc85ff2
commit 8acdcf7c73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 10 deletions

View File

@ -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(

View File

@ -72,7 +72,8 @@ export default mergeIds(recruitId, recruit, {
VacancyNotificationGroup: '' as Ref<NotificationGroup>,
CandidateNotificationGroup: '' as Ref<NotificationGroup>,
ApplicationNotificationGroup: '' as Ref<NotificationGroup>,
AssigneeNotification: '' as Ref<NotificationType>
AssigneeNotification: '' as Ref<NotificationType>,
ApplicationCreateNotification: '' as Ref<NotificationType>
},
component: {
CreateApplication: '' as AnyComponent,

View File

@ -111,6 +111,8 @@ export interface NotificationType extends Doc {
attachedToClass?: Ref<Class<Doc>>
// use for update/mixin txes
field?: string
// use for space collaborators, not object
spaceSubscribe?: boolean
// allowed providers and default value for it
providers: Record<Ref<NotificationProvider>, boolean>
// templates for email (and browser/push?)

View File

@ -423,8 +423,14 @@ function isTypeMatched (
return true
}
async function getMatchedTypes (control: TriggerControl, tx: TxCUD<Doc>): Promise<NotificationType[]> {
const allTypes = await control.modelDb.findAll(notification.class.NotificationType, {})
async function getMatchedTypes (
control: TriggerControl,
tx: TxCUD<Doc>,
isSpace: boolean = false
): Promise<NotificationType[]> {
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<Doc>
const filtered: NotificationType[] = []
for (const type of allTypes) {
@ -444,11 +450,12 @@ async function isShouldNotify (
control: TriggerControl,
tx: TxCUD<Doc>,
object: Doc,
user: Ref<Account>
user: Ref<Account>,
isSpace: boolean
): Promise<NotifyResult> {
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<Doc>,
target: Ref<Account>,
docUpdates: DocUpdates[]
docUpdates: DocUpdates[],
isSpace: boolean
): Promise<Tx[]> {
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<Account>[],
control: TriggerControl,
originTx: TxCUD<Doc>,
object: Doc
object: Doc,
isSpace: boolean = false
): Promise<Tx[]> {
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<Doc>,
originTx: TxCUD<Doc>
): Promise<Tx[]> {
const space = (await control.findAll(core.class.Space, { _id: doc.space }))[0]
if (space === undefined) return []
const mixin = control.hierarchy.classHierarchyMixin<Doc, ClassCollaborators>(
space._class,
notification.mixin.ClassCollaborators
)
if (mixin !== undefined) {
const collabs = control.hierarchy.as<Doc, Collaborators>(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
}