From 61ceab31da846c7ce1e26ab4b651dc9618093c65 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Thu, 12 Feb 2026 15:35:44 +0500 Subject: [PATCH] Card notifications Signed-off-by: Denis Bykhov --- common/config/rush/pnpm-lock.yaml | 12 +++++ models/card/package.json | 2 + models/card/src/index.ts | 45 +++++++++++++++++++ models/card/src/plugin.ts | 6 ++- models/server-card/package.json | 1 + models/server-card/src/index.ts | 5 +++ plugins/card-assets/lang/cs.json | 3 +- plugins/card-assets/lang/de.json | 3 +- plugins/card-assets/lang/en.json | 3 +- plugins/card-assets/lang/es.json | 3 +- plugins/card-assets/lang/fr.json | 3 +- plugins/card-assets/lang/it.json | 3 +- plugins/card-assets/lang/ja.json | 3 +- plugins/card-assets/lang/pt-br.json | 3 +- plugins/card-assets/lang/pt.json | 3 +- plugins/card-assets/lang/ru.json | 3 +- plugins/card-assets/lang/tr.json | 3 +- plugins/card-assets/lang/zh.json | 3 +- plugins/card-resources/src/plugin.ts | 3 +- server-plugins/card-resources/src/index.ts | 9 ++++ server-plugins/card/package.json | 1 + server-plugins/card/src/index.ts | 4 ++ .../notification-resources/src/utils.ts | 9 ++-- 23 files changed, 116 insertions(+), 17 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 0c2da87ce84..7da6d5f66ef 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -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 diff --git a/models/card/package.json b/models/card/package.json index 833ff66d019..72ce95c6fb3 100644 --- a/models/card/package.json +++ b/models/card/package.json @@ -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", diff --git a/models/card/src/index.ts b/models/card/src/index.ts index e156dbeb84f..b3a3a59426d 100644 --- a/models/card/src/index.ts +++ b/models/card/src/index.ts @@ -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, diff --git a/models/card/src/plugin.ts b/models/card/src/plugin.ts index b17913c44c4..1db60f2a067 100644 --- a/models/card/src/plugin.ts +++ b/models/card/src/plugin.ts @@ -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, ManageMasterTags: '' as Ref, - TagRelations: '' as Ref + TagRelations: '' as Ref, + CardNotificationGroup: '' as Ref, + CardNotification: '' as Ref, + CardMessageNotification: '' as Ref }, resolver: { Location: '' as Resource<(loc: Location) => Promise>, diff --git a/models/server-card/package.json b/models/server-card/package.json index c36b9bf3cde..909cfadf075 100644 --- a/models/server-card/package.json +++ b/models/server-card/package.json @@ -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" } diff --git a/models/server-card/src/index.ts b/models/server-card/src/index.ts index 9008fbee708..e5c66f54175 100644 --- a/models/server-card/src/index.ts +++ b/models/server-card/src/index.ts @@ -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 + }) } diff --git a/plugins/card-assets/lang/cs.json b/plugins/card-assets/lang/cs.json index df3b9dec1db..c66e477bd6b 100644 --- a/plugins/card-assets/lang/cs.json +++ b/plugins/card-assets/lang/cs.json @@ -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" } } diff --git a/plugins/card-assets/lang/de.json b/plugins/card-assets/lang/de.json index 374ffea2c1b..1524d538ea9 100644 --- a/plugins/card-assets/lang/de.json +++ b/plugins/card-assets/lang/de.json @@ -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" } } diff --git a/plugins/card-assets/lang/en.json b/plugins/card-assets/lang/en.json index fc1defaaf4f..b3eb41e468c 100644 --- a/plugins/card-assets/lang/en.json +++ b/plugins/card-assets/lang/en.json @@ -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" } } diff --git a/plugins/card-assets/lang/es.json b/plugins/card-assets/lang/es.json index 773fe047c16..ac1f754c3b6 100644 --- a/plugins/card-assets/lang/es.json +++ b/plugins/card-assets/lang/es.json @@ -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" } } diff --git a/plugins/card-assets/lang/fr.json b/plugins/card-assets/lang/fr.json index 04d85431f1d..0a4867c3aff 100644 --- a/plugins/card-assets/lang/fr.json +++ b/plugins/card-assets/lang/fr.json @@ -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" } } diff --git a/plugins/card-assets/lang/it.json b/plugins/card-assets/lang/it.json index d06a1e04b72..98976f5e50e 100644 --- a/plugins/card-assets/lang/it.json +++ b/plugins/card-assets/lang/it.json @@ -70,6 +70,7 @@ "NewVersionConfirmation": "Vuoi creare una nuova versione?", "RelationCopyDescr": "Quali relazioni vuoi copiare?", "Import": "Importa", - "Export": "Esporta" + "Export": "Esporta", + "CardUpdated": "Scheda aggiornata" } } diff --git a/plugins/card-assets/lang/ja.json b/plugins/card-assets/lang/ja.json index 2fbe52c9f73..5b18951fe03 100644 --- a/plugins/card-assets/lang/ja.json +++ b/plugins/card-assets/lang/ja.json @@ -70,6 +70,7 @@ "NewVersionConfirmation": "新しいバージョンを作成しますか?", "RelationCopyDescr": "どの関連をコピーしますか?", "Import": "インポート", - "Export": "エクスポート" + "Export": "エクスポート", + "CardUpdated": "カードが更新されました" } } diff --git a/plugins/card-assets/lang/pt-br.json b/plugins/card-assets/lang/pt-br.json index 4347f3427f8..c2148a4c4b4 100644 --- a/plugins/card-assets/lang/pt-br.json +++ b/plugins/card-assets/lang/pt-br.json @@ -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" } } diff --git a/plugins/card-assets/lang/pt.json b/plugins/card-assets/lang/pt.json index 4347f3427f8..c2148a4c4b4 100644 --- a/plugins/card-assets/lang/pt.json +++ b/plugins/card-assets/lang/pt.json @@ -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" } } diff --git a/plugins/card-assets/lang/ru.json b/plugins/card-assets/lang/ru.json index c5e0a3bf596..98ef2647baf 100644 --- a/plugins/card-assets/lang/ru.json +++ b/plugins/card-assets/lang/ru.json @@ -70,6 +70,7 @@ "NewVersionConfirmation": "Вы хотите создать новую версию?", "RelationCopyDescr": "Какие связи вы хотите скопировать?", "Import": "Импортировать", - "Export": "Экспортировать" + "Export": "Экспортировать", + "CardUpdated": "Карточка обновлена" } } diff --git a/plugins/card-assets/lang/tr.json b/plugins/card-assets/lang/tr.json index 89c08295b20..f0522bfaae5 100644 --- a/plugins/card-assets/lang/tr.json +++ b/plugins/card-assets/lang/tr.json @@ -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" } } diff --git a/plugins/card-assets/lang/zh.json b/plugins/card-assets/lang/zh.json index c83eace50ea..371a92de03c 100644 --- a/plugins/card-assets/lang/zh.json +++ b/plugins/card-assets/lang/zh.json @@ -70,6 +70,7 @@ "NewVersionConfirmation": "您想创建一个新版本吗?", "RelationCopyDescr": "您想复制哪些关系?", "Import": "导入", - "Export": "导出" + "Export": "导出", + "CardUpdated": "卡片已更新" } } diff --git a/plugins/card-resources/src/plugin.ts b/plugins/card-resources/src/plugin.ts index bcc7d4c606a..0ea733cab93 100644 --- a/plugins/card-resources/src/plugin.ts +++ b/plugins/card-resources/src/plugin.ts @@ -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 } }) diff --git a/server-plugins/card-resources/src/index.ts b/server-plugins/card-resources/src/index.ts index b6c2f6ea125..98cbd5dd3fd 100644 --- a/server-plugins/card-resources/src/index.ts +++ b/server-plugins/card-resources/src/index.ts @@ -876,8 +876,17 @@ export async function OnCardTag (ctx: TxMixin[], control: TriggerCon return res } +export async function CardTextPresenter (doc: Doc): Promise { + 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, diff --git a/server-plugins/card/package.json b/server-plugins/card/package.json index 9a89ef5fa64..e36a103f002 100644 --- a/server-plugins/card/package.json +++ b/server-plugins/card/package.json @@ -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" } diff --git a/server-plugins/card/src/index.ts b/server-plugins/card/src/index.ts index 39e2c597a3f..ad195ea658c 100644 --- a/server-plugins/card/src/index.ts +++ b/server-plugins/card/src/index.ts @@ -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 }, + function: { + CardTextPresenter: '' as Resource + }, trigger: { OnAttribute: '' as Resource, OnAttributeRemove: '' as Resource, diff --git a/server-plugins/notification-resources/src/utils.ts b/server-plugins/notification-resources/src/utils.ts index 8bcd5809da3..a3187ccc4cd 100644 --- a/server-plugins/notification-resources/src/utils.ts +++ b/server-plugins/notification-resources/src/utils.ts @@ -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)