Card notifications (#10503)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2026-02-12 20:46:54 +05:00
committed by GitHub
parent b17b1dec0d
commit c7dc5c48fe
23 changed files with 116 additions and 17 deletions
+12
View File
@@ -6857,6 +6857,9 @@ importers:
'@hcengineering/model-guest':
specifier: workspace:^0.7.0
version: link:../guest
'@hcengineering/model-notification':
specifier: workspace:^0.7.0
version: link:../notification
'@hcengineering/model-preference':
specifier: workspace:^0.7.0
version: link:../preference
@@ -6872,6 +6875,9 @@ importers:
'@hcengineering/model-workbench':
specifier: workspace:^0.7.0
version: link:../workbench
'@hcengineering/notification':
specifier: workspace:^0.7.0
version: link:../../plugins/notification
'@hcengineering/platform':
specifier: workspace:^0.7.19
version: link:../../foundations/core/packages/platform
@@ -10425,6 +10431,9 @@ importers:
'@hcengineering/server-core':
specifier: workspace:^0.7.18
version: link:../../foundations/server/packages/core
'@hcengineering/server-notification':
specifier: workspace:^0.7.0
version: link:../../server-plugins/notification
devDependencies:
'@hcengineering/platform-rig':
specifier: workspace:^0.7.19
@@ -32222,6 +32231,9 @@ importers:
'@hcengineering/server-core':
specifier: workspace:^0.7.18
version: link:../../foundations/server/packages/core
'@hcengineering/server-notification':
specifier: workspace:^0.7.0
version: link:../notification
devDependencies:
'@hcengineering/platform-rig':
specifier: workspace:^0.7.19
+2
View File
@@ -40,6 +40,8 @@
"@hcengineering/converter": "workspace:^0.7.0",
"@hcengineering/core": "workspace:^0.7.24",
"@hcengineering/model": "workspace:^0.7.17",
"@hcengineering/notification": "workspace:^0.7.0",
"@hcengineering/model-notification": "workspace:^0.7.0",
"@hcengineering/chunter": "workspace:^0.7.0",
"@hcengineering/model-setting": "workspace:^0.7.0",
"@hcengineering/model-view": "workspace:^0.7.0",
+45
View File
@@ -84,6 +84,7 @@ import { type BuildModelKey } from '@hcengineering/view'
import { createActions } from './actions'
import { definePermissions } from './permissions'
import card from './plugin'
import notification from '@hcengineering/notification'
export { cardId } from '@hcengineering/card'
@@ -149,6 +150,9 @@ export class TCard extends TDoc implements Card {
@Hidden()
@ReadOnly()
peerId?: string
@Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments)
comments?: number
}
@Model(card.class.CardSpace, core.class.TypedSpace, DOMAIN_SPACE)
@@ -445,6 +449,47 @@ export function createModel (builder: Builder): void {
PaletteColorIndexes.Arctic
)
builder.createDoc(
notification.class.NotificationGroup,
core.space.Model,
{
label: card.string.Card,
icon: card.icon.Card
},
card.ids.CardNotificationGroup
)
builder.createDoc(
notification.class.NotificationType,
core.space.Model,
{
hidden: false,
generated: false,
label: card.string.CardUpdated,
group: card.ids.CardNotificationGroup,
txClasses: [core.class.TxUpdateDoc, core.class.TxMixin],
objectClass: card.class.Card,
defaultEnabled: false
},
card.ids.CardNotification
)
builder.createDoc(
notification.class.NotificationType,
core.space.Model,
{
hidden: false,
generated: false,
label: chunter.string.Comments,
group: card.ids.CardNotificationGroup,
txClasses: [core.class.TxCreateDoc],
objectClass: chunter.class.ChatMessage,
attachedToClass: card.class.Card,
defaultEnabled: true
},
card.ids.CardMessageNotification
)
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: card.class.CardSpace,
descriptor: view.viewlet.Table,
+5 -1
View File
@@ -22,6 +22,7 @@ import { type TagCategory } from '@hcengineering/tags'
import { type Location, type ResolvedLocation } from '@hcengineering/ui/src/types'
import { type Action, type ActionCategory, type ViewAction } from '@hcengineering/view'
import { type LocationData } from '@hcengineering/workbench'
import { type NotificationGroup, type NotificationType } from '@hcengineering/notification'
export default mergeIds(cardId, card, {
app: {
@@ -46,7 +47,10 @@ export default mergeIds(cardId, card, {
ids: {
MasterTags: '' as Ref<Doc>,
ManageMasterTags: '' as Ref<Doc>,
TagRelations: '' as Ref<Doc>
TagRelations: '' as Ref<Doc>,
CardNotificationGroup: '' as Ref<NotificationGroup>,
CardNotification: '' as Ref<NotificationType>,
CardMessageNotification: '' as Ref<NotificationType>
},
resolver: {
Location: '' as Resource<(loc: Location) => Promise<ResolvedLocation | undefined>>,
+1
View File
@@ -39,6 +39,7 @@
"@hcengineering/platform": "workspace:^0.7.19",
"@hcengineering/card": "workspace:^0.7.0",
"@hcengineering/communication": "workspace:^0.7.0",
"@hcengineering/server-notification": "workspace:^0.7.0",
"@hcengineering/server-card": "workspace:^0.7.0",
"@hcengineering/server-core": "workspace:^0.7.18"
}
+5
View File
@@ -20,6 +20,7 @@ import serverCore from '@hcengineering/server-core'
import serverCard from '@hcengineering/server-card'
import card from '@hcengineering/card'
import communication from '@hcengineering/communication'
import serverNotification from '@hcengineering/server-notification'
export { serverCardId } from '@hcengineering/server-card'
@@ -129,4 +130,8 @@ export function createModel (builder: Builder): void {
},
title: [['title']]
})
builder.mixin(card.class.Card, core.class.Class, serverNotification.mixin.TextPresenter, {
presenter: serverCard.function.CardTextPresenter
})
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Chcete vytvořit novou verzi?",
"RelationCopyDescr": "Které vztahy chcete zkopírovat?",
"Import": "Importovat",
"Export": "Exportovat"
"Export": "Exportovat",
"CardUpdated": "Karta aktualizována"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Möchten Sie eine neue Version erstellen?",
"RelationCopyDescr": "Welche Beziehungen möchten Sie kopieren?",
"Import": "Importieren",
"Export": "Exportieren"
"Export": "Exportieren",
"CardUpdated": "Karte aktualisiert"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Do you want to create a new version?",
"RelationCopyDescr": "Which relations do you want to copy?",
"Import": "Import",
"Export": "Export"
"Export": "Export",
"CardUpdated": "Card updated"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "¿Desea crear una nueva versión?",
"RelationCopyDescr": "¿Qué relaciones quieres copiar?",
"Import": "Importar",
"Export": "Exportar"
"Export": "Exportar",
"CardUpdated": "Tarjeta actualizada"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Voulez-vous créer une nouvelle version ?",
"RelationCopyDescr": "Quelles relations souhaitez-vous copier ?",
"Import": "Importer",
"Export": "Exporter"
"Export": "Exporter",
"CardUpdated": "Carte mise à jour"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Vuoi creare una nuova versione?",
"RelationCopyDescr": "Quali relazioni vuoi copiare?",
"Import": "Importa",
"Export": "Esporta"
"Export": "Esporta",
"CardUpdated": "Scheda aggiornata"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "新しいバージョンを作成しますか?",
"RelationCopyDescr": "どの関連をコピーしますか?",
"Import": "インポート",
"Export": "エクスポート"
"Export": "エクスポート",
"CardUpdated": "カードが更新されました"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Deseja criar uma nova versão?",
"RelationCopyDescr": "Quais relações você deseja copiar?",
"Import": "Importar",
"Export": "Exportar"
"Export": "Exportar",
"CardUpdated": "Cartão atualizado"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Deseja criar uma nova versão?",
"RelationCopyDescr": "Quais relações você deseja copiar?",
"Import": "Importar",
"Export": "Exportar"
"Export": "Exportar",
"CardUpdated": "Cartão atualizado"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Вы хотите создать новую версию?",
"RelationCopyDescr": "Какие связи вы хотите скопировать?",
"Import": "Импортировать",
"Export": "Экспортировать"
"Export": "Экспортировать",
"CardUpdated": "Карточка обновлена"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "Yeni bir sürüm oluşturmak istiyor musunuz?",
"RelationCopyDescr": "Hangi ilişkileri kopyalamak istiyorsunuz?",
"Import": "İçe aktar",
"Export": "Dışa aktar"
"Export": "Dışa aktar",
"CardUpdated": "Kart güncellendi"
}
}
+2 -1
View File
@@ -70,6 +70,7 @@
"NewVersionConfirmation": "您想创建一个新版本吗?",
"RelationCopyDescr": "您想复制哪些关系?",
"Import": "导入",
"Export": "导出"
"Export": "导出",
"CardUpdated": "卡片已更新"
}
}
+2 -1
View File
@@ -159,6 +159,7 @@ export default mergeIds(cardId, card, {
ForbidUpdateCard: '' as IntlString,
ForbidCreateCardPermission: '' as IntlString,
ForbidAddTagPermission: '' as IntlString,
ForbidRemoveTag: '' as IntlString
ForbidRemoveTag: '' as IntlString,
CardUpdated: '' as IntlString
}
})
@@ -876,8 +876,17 @@ export async function OnCardTag (ctx: TxMixin<Card, Card>[], control: TriggerCon
return res
}
export async function CardTextPresenter (doc: Doc): Promise<string> {
const card = doc as Card
return card.title
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async () => ({
function: {
CardTextPresenter
},
trigger: {
OnAttribute,
OnAttributeRemove,
+1
View File
@@ -39,6 +39,7 @@
},
"dependencies": {
"@hcengineering/core": "workspace:^0.7.24",
"@hcengineering/server-notification": "workspace:^0.7.0",
"@hcengineering/server-core": "workspace:^0.7.18",
"@hcengineering/platform": "workspace:^0.7.19"
}
+4
View File
@@ -16,6 +16,7 @@
import type { Metadata, Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import type { TriggerFunc } from '@hcengineering/server-core'
import { type Presenter } from '@hcengineering/server-notification'
/**
* @public
@@ -29,6 +30,9 @@ export default plugin(serverCardId, {
metadata: {
CommunicationEnabled: '' as Metadata<boolean>
},
function: {
CardTextPresenter: '' as Resource<Presenter>
},
trigger: {
OnAttribute: '' as Resource<TriggerFunc>,
OnAttributeRemove: '' as Resource<TriggerFunc>,
@@ -266,10 +266,13 @@ function getMatchedTypes (
isSpace: boolean,
field?: string
): NotificationType[] {
const allTypes = control.modelDb
.findAllSync(notification.class.NotificationType, { ...(field !== undefined ? { field } : {}) })
.filter((p) => (isSpace ? p.spaceSubscribe === true : p.spaceSubscribe !== true))
const filtered: NotificationType[] = []
let allTypes: NotificationType[] = control.modelDb.findAllSync(notification.class.NotificationType, {})
allTypes = allTypes.filter(
(p) =>
(isSpace ? p.spaceSubscribe === true : p.spaceSubscribe !== true) &&
(field === undefined || p.field === field || p.field === undefined)
)
for (const type of allTypes) {
if (isTypeMatched(control, type, tx, isOwn)) {
filtered.push(type)