Files
huly-platform/models/notification/src/index.ts
T
2026-02-17 21:34:15 +07:00

882 lines
27 KiB
TypeScript

//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021, 2022 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.
//
import activity, { type ActivityMessage, type Reaction } from '@hcengineering/activity'
import { type PersonSpace } from '@hcengineering/contact'
import {
AccountRole,
type Collaborator,
type CollectionSize,
DOMAIN_MODEL,
DOMAIN_TRANSIENT,
IndexKind,
type AccountUuid,
type AttachedDoc,
type Class,
type Collection,
type Data,
type Doc,
type DocumentQuery,
type IndexingConfiguration,
type Markup,
type PersonId,
type Ref,
type Space,
type Timestamp,
type Tx,
type TxCUD
} from '@hcengineering/core'
import {
Collection as CollectionType,
Index,
Mixin,
Model,
Prop,
TypeAccountUuid,
TypeBoolean,
TypeDate,
TypeIntlString,
TypeMarkup,
TypeRef,
UX,
type Builder
} from '@hcengineering/model'
import core, { TClass, TDoc } from '@hcengineering/model-core'
import preference, { TPreference } from '@hcengineering/model-preference'
import view, { createAction, template } from '@hcengineering/model-view'
import workbench from '@hcengineering/model-workbench'
import {
type Collaborators,
DOMAIN_DOC_NOTIFY,
DOMAIN_NOTIFICATION,
DOMAIN_USER_NOTIFY,
notificationId,
type ActivityInboxNotification,
type ActivityNotificationViewlet,
type BrowserNotification,
type CommonInboxNotification,
type DocNotifyContext,
type InboxNotification,
type MentionInboxNotification,
type NotificationContextPresenter,
type NotificationGroup,
type NotificationObjectPresenter,
type NotificationPreferencesGroup,
type NotificationPreview,
type NotificationProvider,
type NotificationProviderDefaults,
type NotificationProviderSetting,
type NotificationTemplate,
type NotificationType,
type NotificationTypeSetting,
type PushSubscription,
type PushSubscriptionKeys,
type ReactionInboxNotification
} from '@hcengineering/notification'
import { type Asset, type IntlString, type Resource } from '@hcengineering/platform'
import setting from '@hcengineering/setting'
import { type AnyComponent, type Location } from '@hcengineering/ui/src/types'
import notification from './plugin'
export { DOMAIN_DOC_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_USER_NOTIFY, notificationId } from '@hcengineering/notification'
export { notificationOperation } from './migration'
export { notification as default }
@Model(notification.class.BrowserNotification, core.class.Doc, DOMAIN_TRANSIENT)
export class TBrowserNotification extends TDoc implements BrowserNotification {
senderId?: PersonId | undefined
tag!: Ref<Doc<Space>>
title!: string
body!: string
onClickLocation?: Location | undefined
user!: AccountUuid
messageId?: Ref<ActivityMessage>
messageClass?: Ref<Class<ActivityMessage>>
objectId!: Ref<Doc>
objectClass!: Ref<Class<Doc>>
soundAlert!: boolean
}
@Model(notification.class.PushSubscription, core.class.Doc, DOMAIN_USER_NOTIFY)
export class TPushSubscription extends TDoc implements PushSubscription {
user!: AccountUuid
endpoint!: string
keys!: PushSubscriptionKeys
}
@Model(notification.class.NotificationType, core.class.Doc, DOMAIN_MODEL)
export class TNotificationType extends TDoc implements NotificationType {
generated!: boolean
label!: IntlString
group!: Ref<NotificationGroup>
defaultEnabled!: boolean
hidden!: boolean
templates?: NotificationTemplate
txClasses!: Ref<Class<Tx>>[]
objectClass!: Ref<Class<Doc>>
onlyOwn?: boolean
}
@Model(notification.class.NotificationGroup, core.class.Doc, DOMAIN_MODEL)
export class TNotificationGroup extends TDoc implements NotificationGroup {
label!: IntlString
icon!: Asset
// using for autogenerated settings
objectClass?: Ref<Class<Doc>>
}
@Model(notification.class.NotificationPreferencesGroup, core.class.Doc, DOMAIN_MODEL)
export class TNotificationPreferencesGroup extends TDoc implements NotificationPreferencesGroup {
label!: IntlString
icon!: Asset
presenter!: AnyComponent
}
@Model(notification.class.NotificationTypeSetting, preference.class.Preference)
export class TNotificationTypeSetting extends TPreference implements NotificationTypeSetting {
declare attachedTo: Ref<TNotificationProvider>
type!: Ref<NotificationType>
enabled!: boolean
}
@Model(notification.class.NotificationProviderSetting, preference.class.Preference)
export class TNotificationProviderSetting extends TPreference implements NotificationProviderSetting {
declare attachedTo: Ref<TNotificationProvider>
enabled!: boolean
}
@Mixin(notification.mixin.Collaborators, core.class.Doc)
@UX(notification.string.Collaborators)
export class TCollaborators extends TDoc implements Collaborators {
@Prop(CollectionType(core.class.Collaborator), notification.string.Collaborators)
collaborators!: CollectionSize<Collaborator>
}
@Mixin(notification.mixin.NotificationObjectPresenter, core.class.Class)
export class TNotificationObjectPresenter extends TClass implements NotificationObjectPresenter {
presenter!: AnyComponent
}
@Mixin(notification.mixin.NotificationPreview, core.class.Class)
export class TNotificationPreview extends TClass implements NotificationPreview {
presenter!: AnyComponent
}
@Mixin(notification.mixin.NotificationContextPresenter, core.class.Class)
export class TNotificationContextPresenter extends TClass implements NotificationContextPresenter {
labelPresenter?: AnyComponent
}
@Model(notification.class.DocNotifyContext, core.class.Doc, DOMAIN_DOC_NOTIFY)
export class TDocNotifyContext extends TDoc implements DocNotifyContext {
@Prop(TypeAccountUuid(), core.string.Account)
@Index(IndexKind.Indexed)
user!: AccountUuid
@Prop(TypeRef(core.class.Doc), core.string.Object)
@Index(IndexKind.Indexed)
objectId!: Ref<Doc>
@Prop(TypeRef(core.class.Class), core.string.Class)
objectClass!: Ref<Class<Doc>>
@Prop(TypeRef(core.class.Space), core.string.Space)
objectSpace!: Ref<Space>
declare space: Ref<PersonSpace>
@Prop(TypeDate(), core.string.Date)
lastViewedTimestamp?: Timestamp
@Prop(TypeDate(), core.string.Date)
lastUpdateTimestamp?: Timestamp
@Prop(TypeBoolean(), notification.string.Pinned)
isPinned!: boolean
@Prop(TypeBoolean(), view.string.Hide)
hidden!: boolean
tx?: Ref<TxCUD<Doc>>
}
@Model(notification.class.InboxNotification, core.class.Doc, DOMAIN_NOTIFICATION)
export class TInboxNotification extends TDoc implements InboxNotification {
@Prop(TypeRef(notification.class.DocNotifyContext), core.string.AttachedTo)
@Index(IndexKind.Indexed)
docNotifyContext!: Ref<DocNotifyContext>
@Prop(TypeAccountUuid(), core.string.Account)
@Index(IndexKind.Indexed)
user!: AccountUuid
@Prop(TypeBoolean(), core.string.Boolean)
// @Index(IndexKind.Indexed)
isViewed!: boolean
@Prop(TypeBoolean(), core.string.Boolean)
archived!: boolean
objectId!: Ref<Doc>
objectClass!: Ref<Class<Doc>>
declare space: Ref<PersonSpace>
types?: Ref<NotificationType>[]
title?: IntlString
body?: IntlString
intlParams?: Record<string, string | number>
intlParamsNotLocalized?: Record<string, IntlString>
}
@Model(notification.class.ActivityInboxNotification, notification.class.InboxNotification)
export class TActivityInboxNotification extends TInboxNotification implements ActivityInboxNotification {
@Prop(TypeRef(activity.class.ActivityMessage), core.string.AttachedTo)
attachedTo!: Ref<ActivityMessage>
@Prop(TypeRef(activity.class.ActivityMessage), core.string.AttachedToClass)
attachedToClass!: Ref<Class<ActivityMessage>>
}
@Model(notification.class.CommonInboxNotification, notification.class.InboxNotification)
export class TCommonInboxNotification extends TInboxNotification implements CommonInboxNotification {
@Prop(TypeIntlString(), core.string.String)
header?: IntlString
@Prop(TypeRef(core.class.Doc), core.string.Object)
headerObjectId?: Ref<Doc>
@Prop(TypeRef(core.class.Doc), core.string.Class)
headerObjectClass?: Ref<Class<Doc>>
@Prop(TypeIntlString(), notification.string.Message)
message?: IntlString
headerIcon?: Asset
@Prop(TypeMarkup(), notification.string.Message)
messageHtml?: Markup
props?: Record<string, any>
icon?: Asset
iconProps?: Record<string, any>
}
@Model(notification.class.MentionInboxNotification, notification.class.CommonInboxNotification)
export class TMentionInboxNotification extends TCommonInboxNotification implements MentionInboxNotification {
@Prop(TypeRef(core.class.Doc), core.string.Object)
mentionedIn!: Ref<Doc>
@Prop(TypeRef(core.class.Doc), core.string.Class)
mentionedInClass!: Ref<Class<Doc>>
}
@Model(notification.class.ReactionInboxNotification, notification.class.CommonInboxNotification)
export class TReactionInboxNotification extends TCommonInboxNotification implements ReactionInboxNotification {
emoji!: string
ref!: Ref<Reaction>
@Prop(TypeRef(activity.class.ActivityMessage), core.string.AttachedTo)
attachedTo!: Ref<ActivityMessage>
@Prop(TypeRef(activity.class.ActivityMessage), core.string.AttachedToClass)
attachedToClass!: Ref<Class<ActivityMessage>>
}
@Model(notification.class.ActivityNotificationViewlet, core.class.Doc, DOMAIN_MODEL)
export class TActivityNotificationViewlet extends TDoc implements ActivityNotificationViewlet {
messageMatch!: DocumentQuery<Doc>
presenter!: AnyComponent
}
@Model(notification.class.NotificationProvider, core.class.Doc)
export class TNotificationProvider extends TDoc implements NotificationProvider {
icon!: Asset
label!: IntlString
description!: IntlString
defaultEnabled!: boolean
order!: number
depends?: Ref<NotificationProvider>
ignoreAll?: boolean
canDisable!: boolean
presenter?: AnyComponent
isAvailableFn?: Resource<() => boolean>
}
@Model(notification.class.NotificationProviderDefaults, core.class.Doc)
export class TNotificationProviderDefaults extends TDoc implements NotificationProviderDefaults {
provider!: Ref<NotificationProvider>
excludeIgnore?: Ref<NotificationType>[]
ignoredTypes!: Ref<NotificationType>[]
enabledTypes!: Ref<NotificationType>[]
}
export const notificationActionTemplates = template({
pinContext: {
action: notification.actionImpl.PinDocNotifyContext,
label: notification.string.StarDocument,
icon: view.icon.Star,
input: 'focus',
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
visibilityTester: notification.function.HasDocNotifyContextPinAction,
context: { mode: ['context', 'browser'], group: 'edit' }
},
unpinContext: {
action: notification.actionImpl.UnpinDocNotifyContext,
label: notification.string.UnstarDocument,
icon: view.icon.Star,
input: 'focus',
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
visibilityTester: notification.function.HasDocNotifyContextUnpinAction,
context: { mode: ['context', 'browser'], group: 'edit' }
}
})
export function createModel (builder: Builder): void {
builder.createModel(
TCollaborators,
TBrowserNotification,
TNotificationType,
TNotificationGroup,
TNotificationPreferencesGroup,
TNotificationObjectPresenter,
TNotificationPreview,
TDocNotifyContext,
TInboxNotification,
TActivityInboxNotification,
TCommonInboxNotification,
TNotificationContextPresenter,
TActivityNotificationViewlet,
TNotificationType,
TMentionInboxNotification,
TPushSubscription,
TNotificationProvider,
TNotificationProviderSetting,
TNotificationTypeSetting,
TNotificationProviderDefaults,
TReactionInboxNotification
)
builder.mixin(notification.class.BrowserNotification, core.class.Class, core.mixin.TransientConfiguration, {
broadcastOnly: true
})
builder.createDoc(
setting.class.SettingsCategory,
core.space.Model,
{
name: 'notifications',
label: notification.string.Notifications,
icon: notification.icon.Notifications,
component: notification.component.NotificationSettings,
group: 'settings-account',
role: AccountRole.Guest,
order: 1500
},
notification.ids.NotificationSettings
)
builder.createDoc(
workbench.class.Application,
core.space.Model,
{
label: notification.string.Inbox,
icon: notification.icon.Notifications,
locationDataResolver: notification.function.LocationDataResolver,
alias: notificationId,
hidden: true,
locationResolver: notification.resolver.Location,
component: notification.component.Inbox,
order: 50
},
notification.app.Inbox
)
createAction(builder, {
action: workbench.actionImpl.Navigate,
actionProps: {
mode: 'app',
application: notificationId
},
label: notification.string.Inbox,
icon: view.icon.ArrowRight,
input: 'none',
category: view.category.Navigation,
target: core.class.Doc,
context: {
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: core.class.Collaborator,
defaultEnabled: true
},
notification.ids.CollaboratoAddNotification
)
builder.createDoc(
activity.class.DocUpdateMessageViewlet,
core.space.Model,
{
objectClass: core.class.Collaborator,
action: 'create',
icon: notification.icon.Notifications,
component: notification.component.CollaboratorsChanged
},
notification.ids.CollaboratorsAddMessage
)
builder.createDoc(
activity.class.DocUpdateMessageViewlet,
core.space.Model,
{
objectClass: core.class.Collaborator,
action: 'remove',
icon: notification.icon.Notifications,
component: notification.component.CollaboratorsChanged
},
notification.ids.CollaboratorsRemoveMessage
)
builder.mixin(core.class.Collaborator, core.class.Class, view.mixin.CollectionEditor, {
editor: notification.component.CollaboratorEditor,
inlineEditor: notification.component.CollaboratorEditor
})
createAction(
builder,
{
action: notification.actionImpl.ReadNotifyContext,
label: notification.string.MarkAsRead,
icon: view.icon.Eye,
input: 'focus',
visibilityTester: notification.function.CanReadNotifyContext,
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
context: { mode: ['context', 'panel'], application: notification.app.Notification, group: 'edit' }
},
notification.action.ReadNotifyContext
)
createAction(
builder,
{
action: notification.actionImpl.UnReadNotifyContext,
label: notification.string.MarkAsUnread,
icon: view.icon.EyeCrossed,
input: 'focus',
visibilityTester: notification.function.CanUnReadNotifyContext,
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
context: { mode: ['context', 'panel'], application: notification.app.Notification, group: 'edit' }
},
notification.action.UnReadNotifyContext
)
createAction(
builder,
{
action: notification.actionImpl.ArchiveContextNotifications,
label: view.string.Archive,
icon: view.icon.CheckCircle,
input: 'focus',
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
context: { mode: ['panel'], application: notification.app.Notification, group: 'remove' }
},
notification.action.ArchiveContextNotifications
)
createAction(
builder,
{
action: notification.actionImpl.UnarchiveContextNotifications,
label: view.string.UnArchive,
icon: view.icon.Circle,
input: 'focus',
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
context: { mode: ['panel'], application: notification.app.Notification, group: 'remove' }
},
notification.action.UnarchiveContextNotifications
)
createAction(
builder,
{
action: notification.actionImpl.Unsubscribe,
label: notification.string.Unsubscribe,
icon: notification.icon.BellCrossed,
input: 'focus',
category: notification.category.Notification,
target: notification.class.DocNotifyContext,
context: {
mode: ['panel'],
group: 'remove'
}
},
notification.action.Unsubscribe
)
builder.mixin(notification.class.DocNotifyContext, core.class.Class, view.mixin.ObjectPresenter, {
presenter: notification.component.DocNotifyContextPresenter
})
builder.mixin(notification.class.ActivityInboxNotification, core.class.Class, view.mixin.ObjectPresenter, {
presenter: notification.component.ActivityInboxNotificationPresenter
})
builder.mixin(notification.class.CommonInboxNotification, core.class.Class, view.mixin.ObjectPresenter, {
presenter: notification.component.CommonInboxNotificationPresenter
})
builder.mixin(notification.class.MentionInboxNotification, core.class.Class, view.mixin.ObjectPresenter, {
presenter: notification.component.MentionInboxNotificationPresenter
})
builder.mixin(notification.class.BrowserNotification, core.class.Class, core.mixin.TxAccessLevel, {
removeAccessLevel: AccountRole.Guest
})
builder.mixin(notification.class.NotificationTypeSetting, core.class.Class, core.mixin.TxAccessLevel, {
createAccessLevel: AccountRole.Guest,
updateAccessLevel: AccountRole.Guest,
removeAccessLevel: AccountRole.Guest
})
builder.mixin(notification.class.NotificationProviderSetting, core.class.Class, core.mixin.TxAccessLevel, {
createAccessLevel: AccountRole.Guest,
updateAccessLevel: AccountRole.Guest,
removeAccessLevel: AccountRole.Guest
})
builder.mixin(notification.class.DocNotifyContext, core.class.Class, core.mixin.TxAccessLevel, {
createAccessLevel: AccountRole.Guest,
updateAccessLevel: AccountRole.Guest,
removeAccessLevel: AccountRole.Guest
})
builder.createDoc(
notification.class.NotificationType,
core.space.Model,
{
label: activity.string.Mentions,
generated: false,
hidden: false,
group: notification.ids.NotificationGroup,
txClasses: [core.class.TxCreateDoc, core.class.TxUpdateDoc],
objectClass: core.class.Doc,
defaultEnabled: true,
templates: {
textTemplate: '{sender} mentioned you in {doc}: {message}',
htmlTemplate: '<p><b>{sender}</b> mentioned you in {doc}:</p> <p>{message}</p> <p>{link}</p>',
subjectTemplate: 'You were mentioned in {doc}'
}
},
notification.ids.MentionNotificationType
)
createAction(
builder,
{
action: notification.actionImpl.ArchiveAll,
label: notification.string.ArchiveAll,
icon: view.icon.CheckCircle,
input: 'none',
category: notification.category.Notification,
target: core.class.Doc,
context: {
mode: ['browser'],
group: 'remove'
}
},
notification.action.ArchiveAll
)
createAction(
builder,
{
action: notification.actionImpl.ReadAll,
label: notification.string.MarkReadAll,
icon: view.icon.Eye,
input: 'none',
category: notification.category.Notification,
target: core.class.Doc,
context: {
mode: ['browser'],
group: 'edit'
}
},
notification.action.ReadAll
)
createAction(
builder,
{
action: notification.actionImpl.UnreadAll,
label: notification.string.MarkUnreadAll,
icon: view.icon.EyeCrossed,
input: 'none',
category: notification.category.Notification,
target: core.class.Doc,
context: {
mode: ['browser'],
group: 'edit'
}
},
notification.action.UnreadAll
)
builder.createDoc(
view.class.ActionCategory,
core.space.Model,
{ label: notification.string.Inbox, visible: true },
notification.category.Notification
)
builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, {
domain: DOMAIN_NOTIFICATION,
indexes: [{ keys: { user: 1, archived: 1, space: 1 } }],
disabled: [{ modifiedOn: 1 }, { modifiedBy: 1 }, { createdBy: 1 }, { isViewed: 1 }, { hidden: 1 }]
})
builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, {
domain: DOMAIN_DOC_NOTIFY,
indexes: [{ keys: { user: 1 } }],
disabled: [
{ _class: 1 },
{ modifiedOn: 1 },
{ modifiedBy: 1 },
{ createdBy: 1 },
{ isViewed: 1 },
{ hidden: 1 },
{ createdOn: -1 },
{ attachedTo: 1 },
{ space: 1 }
]
})
builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, {
domain: DOMAIN_USER_NOTIFY,
indexes: [{ keys: { user: 1 } }],
disabled: [
{ _class: 1 },
{ modifiedOn: 1 },
{ modifiedBy: 1 },
{ createdBy: 1 },
{ isViewed: 1 },
{ hidden: 1 },
{ createdOn: -1 },
{ attachedTo: 1 }
]
})
builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, {
domain: DOMAIN_USER_NOTIFY,
indexes: [],
disabled: [
{ _class: 1 },
{ modifiedOn: 1 },
{ modifiedBy: 1 },
{ createdBy: 1 },
{ isViewed: 1 },
{ hidden: 1 },
{ createdOn: -1 },
{ attachedTo: 1 }
]
})
builder.mixin<Class<DocNotifyContext>, IndexingConfiguration<DocNotifyContext>>(
notification.class.DocNotifyContext,
core.class.Class,
core.mixin.IndexConfiguration,
{
searchDisabled: true,
indexes: []
}
)
builder.mixin<Class<InboxNotification>, IndexingConfiguration<InboxNotification>>(
notification.class.InboxNotification,
core.class.Class,
core.mixin.IndexConfiguration,
{
searchDisabled: true,
indexes: []
}
)
builder.mixin<Class<BrowserNotification>, IndexingConfiguration<BrowserNotification>>(
notification.class.BrowserNotification,
core.class.Class,
core.mixin.IndexConfiguration,
{
searchDisabled: true,
indexes: []
}
)
builder.mixin<Class<BrowserNotification>, IndexingConfiguration<BrowserNotification>>(
notification.class.BrowserNotification,
core.class.Class,
core.mixin.IndexConfiguration,
{
searchDisabled: true,
indexes: []
}
)
builder.createDoc(notification.class.NotificationPreferencesGroup, core.space.Model, {
label: notification.string.General,
icon: notification.icon.Notifications,
presenter: notification.component.GeneralPreferencesGroup
})
builder.createDoc(
notification.class.NotificationProvider,
core.space.Model,
{
icon: notification.icon.Inbox,
label: notification.string.Inbox,
description: notification.string.InboxNotificationsDescription,
defaultEnabled: true,
canDisable: false,
order: 100
},
notification.providers.InboxNotificationProvider
)
builder.createDoc(
notification.class.NotificationProvider,
core.space.Model,
{
icon: notification.icon.Notifications,
label: notification.string.Push,
description: notification.string.PushNotificationsDescription,
depends: notification.providers.InboxNotificationProvider,
defaultEnabled: true,
canDisable: true,
order: 200
},
notification.providers.PushNotificationProvider
)
builder.createDoc(
notification.class.NotificationProvider,
core.space.Model,
{
icon: notification.icon.Notifications,
label: notification.string.Sound,
description: notification.string.SoundNotificationsDescription,
depends: notification.providers.PushNotificationProvider,
defaultEnabled: true,
canDisable: true,
order: 250
},
notification.providers.SoundNotificationProvider
)
builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.PushNotificationProvider,
ignoredTypes: [notification.ids.CollaboratoAddNotification],
enabledTypes: []
})
builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.SoundNotificationProvider,
ignoredTypes: [notification.ids.CollaboratoAddNotification],
enabledTypes: []
})
}
export function generateClassNotificationTypes (
builder: Builder,
_class: Ref<Class<Doc>>,
group: Ref<NotificationGroup>,
ignoreKeys: string[] = [],
defaultEnabled: string[] = []
): void {
const hierarchy = builder.hierarchy
const attributes = hierarchy.getAllAttributes(
_class,
hierarchy.isDerived(_class, core.class.AttachedDoc) ? core.class.AttachedDoc : core.class.Doc
)
const filtered = Array.from(attributes.values()).filter((p) => p.hidden !== true && p.readonly !== true)
const enabledInboxTypes: Ref<NotificationType>[] = []
for (const attribute of filtered) {
if (ignoreKeys.includes(attribute.name)) continue
const isCollection: boolean = core.class.Collection === attribute.type._class
const objectClass = !isCollection ? _class : (attribute.type as Collection<AttachedDoc>).of
const txClasses = !isCollection
? hierarchy.isMixin(attribute.attributeOf)
? [core.class.TxMixin]
: [core.class.TxUpdateDoc]
: [core.class.TxCreateDoc, core.class.TxRemoveDoc]
const data: Data<NotificationType> = {
attribute: attribute._id,
field: attribute.name,
group,
generated: true,
objectClass,
txClasses,
hidden: false,
defaultEnabled: false,
templates: {
textTemplate: '{body}',
htmlTemplate: '<p>{body}</p><p>{link}</p>',
subjectTemplate: '{doc} updated'
},
label: attribute.label
}
if (isCollection) {
data.attachedToClass = _class
}
const id = `${notification.class.NotificationType}_${_class}_${attribute.name}` as Ref<NotificationType>
builder.createDoc(notification.class.NotificationType, core.space.Model, data, id)
if (defaultEnabled.includes(attribute.name)) {
enabledInboxTypes.push(id)
}
}
if (enabledInboxTypes.length > 0) {
builder.createDoc(notification.class.NotificationProviderDefaults, core.space.Model, {
provider: notification.providers.InboxNotificationProvider,
ignoredTypes: [],
enabledTypes: enabledInboxTypes
})
}
}