Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion models/calendar/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
type PrimaryCalendar,
type Calendar,
type CalendarEventPresenter,
type ReminderNotificationPresenter,
type Event,
type ExternalCalendar,
type ReccuringEvent,
Expand Down Expand Up @@ -63,7 +64,8 @@ import attachment from '@hcengineering/model-attachment'
import contact from '@hcengineering/model-contact'
import core, { TAttachedDoc, TClass, TDoc } from '@hcengineering/model-core'
import view, { createAction } from '@hcengineering/model-view'
import notification from '@hcengineering/notification'
import notification, { type NotificationType } from '@hcengineering/notification'
import { type Asset, type IntlString } from '@hcengineering/platform'
import setting from '@hcengineering/setting'
import { type AnyComponent } from '@hcengineering/ui/src/types'
import workbench from '@hcengineering/model-workbench'
Expand Down Expand Up @@ -196,6 +198,15 @@ export class TCalendarEventPresenter extends TClass implements CalendarEventPres
presenter!: AnyComponent
}

@Mixin(calendar.mixin.ReminderNotificationPresenter, core.class.Class)
export class TReminderNotificationPresenter extends TClass implements ReminderNotificationPresenter {
redirectToAttached?: boolean
notificationType?: Ref<NotificationType>
headerIcon?: Asset
header?: IntlString
message?: IntlString
}

export function createModel (builder: Builder): void {
builder.createModel(
TCalendar,
Expand All @@ -205,6 +216,7 @@ export function createModel (builder: Builder): void {
TEvent,
TSchedule,
TCalendarEventPresenter,
TReminderNotificationPresenter,
TPrimaryCalendar
)

Expand Down
18 changes: 17 additions & 1 deletion models/notification/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import {
type NotificationTemplate,
type NotificationType,
type NotificationTypeSetting,
type OnDemandNotification,
type PushSubscription,
type PushSubscriptionKeys,
type ReactionInboxNotification
Expand Down Expand Up @@ -111,6 +112,20 @@ export class TBrowserNotification extends TDoc implements BrowserNotification {
soundAlert!: boolean
}

// Transient (never persisted): created by a client, consumed by the OnDemandNotification trigger.
@Model(notification.class.OnDemandNotification, core.class.Doc, DOMAIN_TRANSIENT)
export class TOnDemandNotification extends TDoc implements OnDemandNotification {
targets!: AccountUuid[]
objectId!: Ref<Doc>
objectClass!: Ref<Class<Doc>>
objectSpace!: Ref<Space>
notificationType!: Ref<NotificationType>
header?: IntlString
message?: IntlString
messageHtml?: Markup
icon?: Asset
}

@Model(notification.class.PushSubscription, core.class.Doc, DOMAIN_USER_NOTIFY)
export class TPushSubscription extends TDoc implements PushSubscription {
user!: AccountUuid
Expand Down Expand Up @@ -371,7 +386,8 @@ export function createModel (builder: Builder): void {
TNotificationProviderSetting,
TNotificationTypeSetting,
TNotificationProviderDefaults,
TReactionInboxNotification
TReactionInboxNotification,
TOnDemandNotification
)

builder.mixin(notification.class.BrowserNotification, core.class.Class, core.mixin.TransientConfiguration, {
Expand Down
8 changes: 8 additions & 0 deletions models/server-notification/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ export function createModel (builder: Builder): void {
}
})

builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverNotification.trigger.OnDemandNotificationSend,
txMatch: {
_class: core.class.TxCreateDoc,
objectClass: notification.class.OnDemandNotification
}
})

builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverNotification.trigger.OnEmployeeDeactivate,
isAsync: true,
Expand Down
23 changes: 23 additions & 0 deletions models/server-training/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,36 @@ import { type Builder } from '@hcengineering/model'

import training from '@hcengineering/model-training'
import serverTraining from '@hcengineering/server-training'
import serverCore from '@hcengineering/server-core'
import core from '@hcengineering/core'
import notification from '@hcengineering/notification'
import serverNotification from '@hcengineering/server-notification'

export { serverTrainingId } from '@hcengineering/server-training/src/index'

export function createModel (builder: Builder): void {
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTraining.trigger.OnTrainingRequest,
txMatch: {
objectClass: training.class.TrainingRequest
}
})

builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTraining.trigger.OnTrainingAttempt,
txMatch: {
objectClass: training.class.TrainingAttempt
}
})

builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTraining.trigger.OnTrainingReminderSettings,
txMatch: {
_class: core.class.TxMixin,
mixin: training.mixin.TrainingReminderSettings
}
})

builder.mixin(
training.notification.TrainingRequest,
notification.class.NotificationType,
Expand Down
2 changes: 2 additions & 0 deletions models/training/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
"@hcengineering/training-resources": "workspace:^0.7.0",
"@hcengineering/activity": "workspace:^0.7.0",
"@hcengineering/attachment": "workspace:^0.7.0",
"@hcengineering/calendar": "workspace:^0.7.0",
"@hcengineering/contact": "workspace:^0.7.0",
"@hcengineering/core": "workspace:^0.7.26",
"@hcengineering/model": "workspace:^0.7.17",
"@hcengineering/model-attachment": "workspace:^0.7.0",
"@hcengineering/model-calendar": "workspace:^0.7.0",
"@hcengineering/model-contact": "workspace:^0.7.0",
"@hcengineering/model-core": "workspace:^0.7.0",
"@hcengineering/model-notification": "workspace:^0.7.0",
Expand Down
77 changes: 76 additions & 1 deletion models/training/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//

import activity from '@hcengineering/activity'
import calendar from '@hcengineering/calendar'
import notification, { type NotificationType } from '@hcengineering/notification'
import { type Asset, type IntlString } from '@hcengineering/platform'
import type { BuildModelKey, KeyFilterPreset, Viewlet, ViewletDescriptor } from '@hcengineering/view'
Expand Down Expand Up @@ -50,6 +51,8 @@ import {
TTraining,
TTrainingAttempt,
TTrainingAttemptState,
TTrainingDeadlineEvent,
TTrainingReminderSettings,
TTrainingRequest,
TTrainingState,
TTrainingsTypeData
Expand Down Expand Up @@ -107,6 +110,7 @@ function defineSpaceType (builder: Builder): void {
}

builder.createModel(TTrainingsTypeData)
builder.createModel(TTrainingReminderSettings)

builder.createDoc(
core.class.SpaceTypeDescriptor,
Expand All @@ -124,7 +128,8 @@ function defineSpaceType (builder: Builder): void {
training.permission.CreateRequestOnSomeoneElsesTraining,
training.permission.ChangeSomeoneElsesSentRequestOwner,
training.permission.ViewSomeoneElsesSentRequest,
training.permission.ViewSomeoneElsesTraineesResults
training.permission.ViewSomeoneElsesTraineesResults,
training.permission.SendTrainingRequestReminder
]
},
training.spaceTypeDescriptor.Trainings
Expand Down Expand Up @@ -582,6 +587,21 @@ function defineTrainingRequest (builder: Builder): void {
training.action.TrainingRequestCancel
)

createAction(
builder,
{
action: training.action.TrainingRequestSendReminderAction,
visibilityTester: training.action.TrainingRequestSendReminderIsAvailable,
input: 'focus',
label: training.string.SendReminder,
icon: training.icon.TrainingRequest,
target: training.class.TrainingRequest,
context: { mode: ['context'], group: 'tools' },
category: training.actionCategory.Training
},
training.action.TrainingRequestSendReminder
)

builder.mixin(training.class.TrainingRequest, core.class.Class, activity.mixin.ActivityDoc, {})

builder.mixin(training.class.TrainingRequest, core.class.Class, view.mixin.ObjectTitle, {
Expand Down Expand Up @@ -613,6 +633,61 @@ function defineTrainingRequest (builder: Builder): void {
},
training.notification.TrainingRequest
)

// Deadline reminder: the actual notification is materialized by the events-processor worker
// (via a direct createDoc), but the type + provider defaults still declare which channels it
// supports and let users toggle them per-type. Mirrors calendar's ReminderNotification.
builder.createModel(TTrainingDeadlineEvent)

// Declaratively tell the events-processor how to present this event's reminders: point them at the
// TrainingRequest and use the training deadline notification type/content. No pod-side code needed.
builder.mixin(training.class.TrainingDeadlineEvent, core.class.Class, calendar.mixin.ReminderNotificationPresenter, {
redirectToAttached: true,
notificationType: training.ids.TrainingDeadlineReminder,
headerIcon: training.icon.TrainingRequest,
header: training.string.TrainingDeadlineReminder,
// Interpolated by the events-processor with the generic `{ title, days }` params.
message: training.string.TrainingDeadlineReminderMessage
})

builder.createDoc<NotificationType>(
notification.class.NotificationType,
core.space.Model,
{
hidden: false,
generated: false,
allowedForAuthor: true,
label: training.string.TrainingDeadlineReminder,
group: training.notification.TrainingGroup,
txClasses: [core.class.TxCreateDoc],
objectClass: training.class.TrainingRequest,
defaultEnabled: true,
templates: {
textTemplate: 'Training {doc} is due soon',
htmlTemplate: '<p>Training <b>{doc}</b> is due soon</p>',
subjectTemplate: 'Training deadline: {doc}'
}
},
training.ids.TrainingDeadlineReminder
)

builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.InboxNotificationProvider,
ignoredTypes: [],
enabledTypes: [training.ids.TrainingDeadlineReminder]
})

builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.PushNotificationProvider,
ignoredTypes: [],
enabledTypes: [training.ids.TrainingDeadlineReminder]
})

definePermission(builder, training.permission.SendTrainingRequestReminder, {
label: training.string.Permission_SendTrainingRequestReminder,
scope: 'space',
description: training.string.Permission_SendTrainingRequestReminder_Description
})
}

function defineTrainingAttempt (builder: Builder): void {
Expand Down
6 changes: 4 additions & 2 deletions models/training/src/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export const roles = [
training.permission.CreateRequestOnSomeoneElsesTraining,
training.permission.ChangeSomeoneElsesSentRequestOwner,
training.permission.ViewSomeoneElsesSentRequest,
training.permission.ViewSomeoneElsesTraineesResults
training.permission.ViewSomeoneElsesTraineesResults,
training.permission.SendTrainingRequestReminder
]
},
{
Expand All @@ -38,7 +39,8 @@ export const roles = [
training.permission.ViewSomeoneElsesTrainingQuestions,
training.permission.CreateRequestOnSomeoneElsesTraining,
training.permission.ViewSomeoneElsesSentRequest,
training.permission.ViewSomeoneElsesTraineesResults
training.permission.ViewSomeoneElsesTraineesResults,
training.permission.SendTrainingRequestReminder
]
},
{
Expand Down
Loading
Loading