Skip to content
Merged
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
4 changes: 2 additions & 2 deletions models/chunter/src/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ export function defineNotifications (builder: Builder): void {
defaultEnabled: false,
group: chunter.ids.ChunterNotificationGroup,
templates: {
textTemplate: '{body}',
htmlTemplate: '<p>{body}</p>',
textTemplate: '{sender} replied to {doc}:\n\n{message}',
htmlTemplate: '<p><b>{sender}</b> replied to {doc}:</p><p>{message}</p><p>{link}</p>',
subjectTemplate: '{title}'
}
},
Expand Down
4 changes: 2 additions & 2 deletions models/notification/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,8 @@ export function createModel (builder: Builder): void {
group: notification.ids.NotificationGroup,
defaultEnabled: true,
templates: {
textTemplate: '{sender} mentioned you in {doc} {message}',
htmlTemplate: '<p>{sender}</b> mentioned you in {doc}</p> {message}',
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}'
}
},
Expand Down
4 changes: 4 additions & 0 deletions models/server-chunter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export function createModel (builder: Builder): void {
presenter: serverChunter.function.ChatMessageTextPresenter
})

builder.mixin(chunter.class.ChatMessage, core.class.Class, serverNotification.mixin.HTMLPresenter, {
presenter: serverChunter.function.ChatMessageTextPresenter
})

builder.mixin<Class<Doc>, ObjectDDParticipant>(
chunter.class.ChatMessage,
core.class.Class,
Expand Down
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"CommonNotificationCollectionRemoved": "{senderName} removed {collection}",
"Sound": "Sound",
"SoundNotificationsDescription": "Receive sound notifications for events.",
"NoAccessToObject": "You no longer have access to this object"
"NoAccessToObject": "You no longer have access to this object",
"ViewIn": "View in {app}"
}
}
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"SoundNotificationsDescription": "Reciba notificaciones de sonido para eventos.",
"CommonNotificationCollectionAdded": "{senderName} añadió {collection}",
"CommonNotificationCollectionRemoved": "{senderName} eliminó {collection}",
"NoAccessToObject": "Ya no tienes acceso a este objeto"
"NoAccessToObject": "Ya no tienes acceso a este objeto",
"ViewIn": "Ver en {app}"
}
}
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"SoundNotificationsDescription": "Recevez des notifications sonores pour les événements.",
"CommonNotificationCollectionAdded": "{senderName} a ajouté {collection}",
"CommonNotificationCollectionRemoved": "{senderName} a supprimé {collection}",
"NoAccessToObject": "Vous n'avez plus accès à cet objet"
"NoAccessToObject": "Vous n'avez plus accès à cet objet",
"ViewIn": "Voir dans {app}"
}
}
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"SoundNotificationsDescription": "Receba notificações sonoras para eventos.",
"CommonNotificationCollectionAdded": "{senderName} adicionou {collection}",
"CommonNotificationCollectionRemoved": "{senderName} removeu {collection}",
"NoAccessToObject": "Você não tem mais acesso a este objeto"
"NoAccessToObject": "Você não tem mais acesso a este objeto",
"ViewIn": "Ver em {app}"
}
}
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"SoundNotificationsDescription": "Получайте звуковые уведомления о событиях.",
"CommonNotificationCollectionAdded": "{senderName} добавил {collection}",
"CommonNotificationCollectionRemoved": "{senderName} удалил {collection}",
"NoAccessToObject": "У вас больше нет доступа к этому объекту"
"NoAccessToObject": "У вас больше нет доступа к этому объекту",
"ViewIn": "Посмотреть в {app}"
}
}
3 changes: 2 additions & 1 deletion plugins/notification-assets/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"SoundNotificationsDescription": "接收事件的声音通知。",
"CommonNotificationCollectionAdded": "{senderName} 添加了 {collection}",
"CommonNotificationCollectionRemoved": "{senderName} 移除了 {collection}",
"NoAccessToObject": "您不再可以访问此对象"
"NoAccessToObject": "您不再可以访问此对象",
"ViewIn": "在 {app} 中查看"
}
}
31 changes: 24 additions & 7 deletions plugins/notification-resources/src/components/inbox/Inbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<script lang="ts">
import activity, { ActivityMessage } from '@hcengineering/activity'
import chunter from '@hcengineering/chunter'
import { getCurrentAccount, groupByArray, IdMap, Ref, SortingOrder, Space } from '@hcengineering/core'
import { Doc, getCurrentAccount, groupByArray, IdMap, Ref, SortingOrder, Space } from '@hcengineering/core'
import { DocNotifyContext, InboxNotification, notificationId } from '@hcengineering/notification'
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
import {
Expand All @@ -31,7 +31,8 @@
Separator,
TabItem,
TabList,
closePanel
closePanel,
getCurrentLocation
} from '@hcengineering/ui'
import view, { decodeObjectURI } from '@hcengineering/view'
import { parseLinkId } from '@hcengineering/view-resources'
Expand Down Expand Up @@ -143,11 +144,23 @@

$: filteredData = filterData(filter, selectedTabId, inboxData, $contextByIdStore)

locationStore.subscribe((newLocation) => {
void syncLocation(newLocation)
const unsubscribeLoc = locationStore.subscribe((newLocation) => {
void syncLocation(newLocation, $contextByDocStore)
})

async function syncLocation (newLocation: Location): Promise<void> {
let isContextsLoaded = false

const unsubscribeContexts = contextByDocStore.subscribe((docs) => {
if (selectedContext !== undefined || docs.size === 0 || isContextsLoaded) {
return
}

const loc = getCurrentLocation()
void syncLocation(loc, docs)
isContextsLoaded = true
})

async function syncLocation (newLocation: Location, contextByDoc: Map<Ref<Doc>, DocNotifyContext>): Promise<void> {
const loc = await resolveLocation(newLocation)
if (loc?.loc.path[2] !== notificationId) {
return
Expand All @@ -161,7 +174,7 @@

const [id, _class] = decodeObjectURI(loc?.loc.path[3] ?? '')
const _id = await parseLinkId(linkProviders, id, _class)
const context = _id ? $contextByDocStore.get(_id) : undefined
const context = _id ? contextByDoc.get(_id) : undefined

selectedContextId = context?._id

Expand Down Expand Up @@ -357,7 +370,11 @@
}
]
$: $deviceInfo.replacedPanel = replacedPanel
onDestroy(() => ($deviceInfo.replacedPanel = undefined))
onDestroy(() => {
$deviceInfo.replacedPanel = undefined
unsubscribeLoc()
unsubscribeContexts()
})
</script>

<ActionContext
Expand Down
3 changes: 2 additions & 1 deletion plugins/notification/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,8 @@ const notification = plugin(notificationId, {
CommonNotificationCollectionRemoved: '' as IntlString,
SoundNotificationsDescription: '' as IntlString,
Sound: '' as IntlString,
NoAccessToObject: '' as IntlString
NoAccessToObject: '' as IntlString,
ViewIn: '' as IntlString
},
function: {
Notify: '' as Resource<NotifyFunc>,
Expand Down
7 changes: 6 additions & 1 deletion server-plugins/chunter-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
getDocCollaborators,
getMixinTx
} from '@hcengineering/server-notification-resources'
import { markupToText, stripTags } from '@hcengineering/text'
import { markupToHTML, markupToText, stripTags } from '@hcengineering/text'
import { workbenchId } from '@hcengineering/workbench'

import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
Expand Down Expand Up @@ -91,6 +91,10 @@ export async function ChatMessageTextPresenter (doc: ChatMessage): Promise<strin
return markupToText(doc.message)
}

export async function ChatMessageHtmlPresenter (doc: ChatMessage): Promise<string> {
return markupToHTML(doc.message)
}

/**
* @public
*/
Expand Down Expand Up @@ -580,6 +584,7 @@ export default async () => ({
ChannelTextPresenter: channelTextPresenter,
ChunterNotificationContentProvider: getChunterNotificationContent,
ChatMessageTextPresenter,
ChatMessageHtmlPresenter,
JoinChannelTypeMatch
}
})
1 change: 1 addition & 0 deletions server-plugins/chunter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default plugin(serverChunterId, {
ChannelTextPresenter: '' as Resource<Presenter>,
ChunterNotificationContentProvider: '' as Resource<NotificationContentProvider>,
ChatMessageTextPresenter: '' as Resource<Presenter>,
ChatMessageHtmlPresenter: '' as Resource<Presenter>,
JoinChannelTypeMatch: '' as TypeMatchFunc
}
})
8 changes: 5 additions & 3 deletions server-plugins/gmail-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
"@types/jest": "^29.5.5"
},
"dependencies": {
"@hcengineering/activity": "^0.6.0",
"@hcengineering/contact": "^0.6.24",
"@hcengineering/core": "^0.6.32",
"@hcengineering/gmail": "^0.6.22",
"@hcengineering/notification": "^0.6.23",
"@hcengineering/platform": "^0.6.11",
"@hcengineering/server-core": "^0.6.1",
"@hcengineering/server-notification": "^0.6.1",
"@hcengineering/server-notification-resources": "^0.6.0",
"@hcengineering/notification": "^0.6.23",
"@hcengineering/contact": "^0.6.24",
"@hcengineering/gmail": "^0.6.22"
"@hcengineering/text": "^0.6.5"
}
}
12 changes: 7 additions & 5 deletions server-plugins/gmail-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import serverNotification, {
} from '@hcengineering/server-notification'
import { getContentByTemplate } from '@hcengineering/server-notification-resources'
import { getMetadata } from '@hcengineering/platform'
import { ActivityMessage } from '@hcengineering/activity'

/**
* @public
Expand Down Expand Up @@ -134,7 +135,8 @@ async function notifyByEmail (
doc: Doc | undefined,
sender: SenderInfo,
receiver: ReceiverInfo,
data: InboxNotification
data: InboxNotification,
message?: ActivityMessage
): Promise<void> {
const account = receiver.account

Expand All @@ -145,8 +147,7 @@ async function notifyByEmail (
const senderPerson = sender.person
const senderName = senderPerson !== undefined ? formatName(senderPerson.name, control.branding?.lastNameFirst) : ''

const content = await getContentByTemplate(doc, senderName, type, control, '', data)

const content = await getContentByTemplate(doc, senderName, type, control, '', data, message)
if (content !== undefined) {
await sendEmailNotification(control.ctx, content.text, content.html, content.subject, account.email)
}
Expand All @@ -158,7 +159,8 @@ const SendEmailNotifications: NotificationProviderFunc = async (
object: Doc,
data: InboxNotification,
receiver: ReceiverInfo,
sender: SenderInfo
sender: SenderInfo,
message?: ActivityMessage
): Promise<Tx[]> => {
if (types.length === 0) {
return []
Expand All @@ -169,7 +171,7 @@ const SendEmailNotifications: NotificationProviderFunc = async (
}

for (const type of types) {
await notifyByEmail(control, type._id, object, sender, receiver, data)
await notifyByEmail(control, type._id, object, sender, receiver, data, message)
}

return []
Expand Down
40 changes: 32 additions & 8 deletions server-plugins/notification-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import serverNotification, {
SenderInfo
} from '@hcengineering/server-notification'
import serverView from '@hcengineering/server-view'
import { stripTags } from '@hcengineering/text'
import { markupToText, stripTags } from '@hcengineering/text'
import { encodeObjectURI } from '@hcengineering/view'
import { workbenchId } from '@hcengineering/workbench'
import webpush, { WebPushError } from 'web-push'
Expand All @@ -91,13 +91,15 @@ import {
createPushCollaboratorsTx,
getHTMLPresenter,
getNotificationContent,
getNotificationLink,
getTextPresenter,
getUsersInfo,
isAllowed,
isMixinTx,
isShouldNotifyTx,
isUserEmployeeInFieldValue,
isUserInFieldValue,
messageToMarkup,
replaceAll,
toReceiverInfo,
updateNotifyContextsSpace
Expand Down Expand Up @@ -212,19 +214,33 @@ export async function getContentByTemplate (
type: Ref<BaseNotificationType>,
control: TriggerControl,
data: string,
notificationData?: InboxNotification
notificationData?: InboxNotification,
message?: ActivityMessage
): Promise<Content | undefined> {
if (doc === undefined) return
const notificationType = control.modelDb.getObject(type)
if (notificationType.templates === undefined) return

const textPart = await getTextPart(doc, control)
if (textPart === undefined) return
const params =
const params: Record<string, string> =
notificationData !== undefined
? await getTranslatedNotificationContent(notificationData, notificationData._class, control)
: {}

if (message !== undefined) {
const markup = await messageToMarkup(control, message)
params.message = markup !== undefined ? markupToText(markup) : params.message ?? ''
} else if (params.message === undefined) {
params.message = params.body ?? ''
}

const link = await getNotificationLink(control, doc, message?._id)
const app = control.branding?.title ?? 'Huly'
const linkText = await translate(notification.string.ViewIn, { app })

params.link = `<a href='${link}'>${linkText}</a>`

const text = fillTemplate(notificationType.templates.textTemplate, sender, textPart, data, params)
const htmlPart = await getHtmlPart(doc, control)
const html = fillTemplate(notificationType.templates.htmlTemplate, sender, htmlPart ?? textPart, data, params)
Expand Down Expand Up @@ -838,16 +854,24 @@ export async function createCollabDocInfo (
return res
}

const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, { objectId: object._id })

await updateContextsTimestamp(notifyContexts, originTx.modifiedOn, control, originTx.modifiedBy)
await removeContexts(notifyContexts, unsubscribe, control)

const docMessages = activityMessages.filter((message) => message.attachedTo === object._id)

if (docMessages.length === 0) {
if (unsubscribe.length > 0) {
const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, {
objectId: object._id,
user: { $in: unsubscribe }
})
await removeContexts(notifyContexts, unsubscribe, control)
}

return res
}

const notifyContexts = await control.findAllCtx(ctx, notification.class.DocNotifyContext, { objectId: object._id })
await removeContexts(notifyContexts, unsubscribe, control)
await updateContextsTimestamp(notifyContexts, originTx.modifiedOn, control, originTx.modifiedBy)

const targets = new Set(collaborators)

// user is not collaborator of himself, but we should notify user of changes related to users account (mentions, comments etc)
Expand Down
Loading