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
206 changes: 198 additions & 8 deletions common/config/rush/pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion common/scripts/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"0.7.269"
"0.7.278"
3 changes: 3 additions & 0 deletions desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@
"@hcengineering/ai-assistant": "^0.7.0",
"@hcengineering/ai-assistant-assets": "^0.7.0",
"@hcengineering/ai-assistant-resources": "^0.7.0",
"@hcengineering/inbox": "^0.7.0",
"@hcengineering/inbox-assets": "^0.7.0",
"@hcengineering/inbox-resources": "^0.7.0",
"electron-squirrel-startup": "~1.0.0",
"dotenv": "~16.0.0",
"electron-context-menu": "^4.0.4",
Expand Down
33 changes: 20 additions & 13 deletions desktop/src/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,22 @@ import {
} from '@hcengineering/ui'
import { handleDownloadItem } from '@hcengineering/desktop-downloads'
import notification, { notificationId } from '@hcengineering/notification'
import { chatId } from '@hcengineering/chat'
import { inboxId } from '@hcengineering/inbox'
import workbench, { workbenchId, logOut } from '@hcengineering/workbench'
import view, { Action, encodeObjectURI } from '@hcengineering/view'
import { resolveLocation } from '@hcengineering/notification-resources'
import { themeStore, ThemeVariant } from '@hcengineering/theme'
import type { Application } from '@hcengineering/workbench'
import { isAllowedToRole } from '@hcengineering/workbench-resources'
import card from '@hcengineering/card'
import communication from '@hcengineering/communication'

import { isOwnerOrMaintainer, getCurrentAccount, Ref } from '@hcengineering/core'
import { configurePlatform } from './platform'
import { setupTitleBarMenu } from './titleBarMenu'
import { defineScreenShare, defineGetDisplayMedia } from './screenShare'
import { CommandLogout, CommandSelectWorkspace, CommandOpenSettings, CommandOpenInbox, CommandOpenPlanner, CommandOpenOffice, CommandOpenApplication, LaunchApplication, NotificationParams, CommandCloseTab } from './types'
import { ipcMainExposed } from './typesUtils'
import { themeStore, ThemeVariant } from '@hcengineering/theme'
import type { Application } from '@hcengineering/workbench'
import { isAllowedToRole } from '@hcengineering/workbench-resources'
import { IpcMessage } from './ipcMessages'

function currentOsIsWindows (): boolean {
Expand Down Expand Up @@ -194,39 +196,44 @@ window.addEventListener('DOMContentLoaded', () => {
navigate(parseLocation(urlObject))
}

function getBasicNotificationPath (notificationParams: NotificationParams): string {
return `${workbenchId}/${notificationParams.application ?? notificationId}/${notificationId}`
function getBasicNotificationPath (worksapce: string, app: string): string {
return `${workbenchId}/${worksapce}/${app}`
}

ipcMain.handleNotificationNavigation((notificationParams: NotificationParams) => {
const currentLocation = getCurrentResolvedLocation()
const workspace = currentLocation.path[1]
// Support for new inbox with cardId (card-based)
if (notificationParams.cardId != null) {
const currentLocation = getCurrentResolvedLocation()
navigateToUrl(`${workbenchId}/${currentLocation.path[1]}/${chatId}/${notificationParams.cardId}`)
const objectUri = encodeObjectURI(notificationParams.cardId, card.class.Card)
navigateToUrl(`${workbenchId}/${workspace}/${inboxId}/${objectUri}`)
return
}

const isCommunicationEnabled = getMetadata(communication.metadata.Enabled) ?? false
const app = isCommunicationEnabled ? inboxId : notificationParams.application

// Support for old inbox with objectId + objectClass (legacy)
if (notificationParams.objectId != null && notificationParams.objectClass != null) {
const encodedObjectURI = encodeObjectURI(notificationParams.objectId, notificationParams.objectClass)
const notificationLocation = {
path: [workbenchId, notificationParams.application, notificationId, encodedObjectURI],
path: [workbenchId, workspace, app, encodedObjectURI],
fragment: undefined,
query: {}
query: undefined
}

void resolveLocation(notificationLocation).then((resolvedLocation) => {
if (resolvedLocation?.loc != null) {
navigate(resolvedLocation.loc)
} else {
navigateToUrl(`${workbenchId}/${notificationParams.application}/${notificationId}/${encodedObjectURI}`)
navigateToUrl(`${workbenchId}/${workspace}/${app}/${encodedObjectURI}`)
}
}).catch(() => {
navigateToUrl(getBasicNotificationPath(notificationParams))
navigateToUrl(getBasicNotificationPath(workspace, app))
})
} else {
// Fallback to basic notification navigation
navigateToUrl(getBasicNotificationPath(notificationParams))
navigateToUrl(getBasicNotificationPath(workspace, app))
}
})

Expand Down
4 changes: 2 additions & 2 deletions desktop/src/ui/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import workbench, { workbenchId } from '@hcengineering/workbench'
import desktopPreferences, { defaultNotificationPreference } from '@hcengineering/desktop-preferences'
import { activePreferences } from '@hcengineering/desktop-preferences-resources'
import { getDisplayInboxData, InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { chatId } from '@hcengineering/chat'
import { inboxId } from '@hcengineering/inbox'
import communication from '@hcengineering/communication'
import { ipcMainExposed } from './typesUtils'

Expand Down Expand Up @@ -179,7 +179,7 @@ export function configureNotifications (): void {
notificationHistory.set(notification.id, notification.created.getTime())
electronAPI.sendNotification({
silent: !preferences.playSound,
application: chatId,
application: inboxId,
title: notification.content.title,
body: `${notification.content.senderName}: ${notification.content.shortText}`,
cardId: notification.cardId,
Expand Down
4 changes: 4 additions & 0 deletions desktop/src/ui/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import { viewId } from '@hcengineering/view'
import workbench, { workbenchId } from '@hcengineering/workbench'
import { mailId } from '@hcengineering/mail'
import { chatId } from '@hcengineering/chat'
import { inboxId } from '@hcengineering/inbox'
import { achievementId } from '@hcengineering/achievement'
import communication, { communicationId } from '@hcengineering/communication'
import { emojiId } from '@hcengineering/emoji'
Expand Down Expand Up @@ -133,6 +134,7 @@ import '@hcengineering/view-assets'
import '@hcengineering/workbench-assets'
import '@hcengineering/mail-assets'
import '@hcengineering/chat-assets'
import '@hcengineering/inbox-assets'
import '@hcengineering/achievement-assets'
import '@hcengineering/emoji-assets'
import '@hcengineering/media-assets'
Expand Down Expand Up @@ -256,6 +258,7 @@ function configureI18n (): void {
addStringsLoader(cardId, async (lang: string) => await import(`@hcengineering/card-assets/lang/${lang}.json`))
addStringsLoader(mailId, async (lang: string) => await import(`@hcengineering/mail-assets/lang/${lang}.json`))
addStringsLoader(chatId, async (lang: string) => await import(`@hcengineering/chat-assets/lang/${lang}.json`))
addStringsLoader(inboxId, async (lang: string) => await import(`@hcengineering/inbox-assets/lang/${lang}.json`))
addStringsLoader(processId, async (lang: string) => await import(`@hcengineering/process-assets/lang/${lang}.json`))
addStringsLoader(achievementId, async (lang: string) => await import(`@hcengineering/achievement-assets/lang/${lang}.json`))
addStringsLoader(communicationId, async (lang: string) => await import(`@hcengineering/communication-assets/lang/${lang}.json`))
Expand Down Expand Up @@ -433,6 +436,7 @@ export async function configurePlatform (onWorkbenchConnect?: () => Promise<void
addLocation(surveyId, () => import(/* webpackChunkName: "survey" */ '@hcengineering/survey-resources'))
addLocation(cardId, () => import(/* webpackChunkName: "card" */ '@hcengineering/card-resources'))
addLocation(chatId, () => import(/* webpackChunkName: "chat" */ '@hcengineering/chat-resources'))
addLocation(inboxId, () => import(/* webpackChunkName: "inbox" */ '@hcengineering/inbox-resources'))
addLocation(processId, () => import(/* webpackChunkName: "process" */ '@hcengineering/process-resources'))
addLocation(achievementId, () => import(/* webpackChunkName: "achievement" */ '@hcengineering/achievement-resources'))
addLocation(communicationId, () => import(/* webpackChunkName: "communication" */ '@hcengineering/communication-resources'))
Expand Down
3 changes: 3 additions & 0 deletions dev/prod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@
"@hcengineering/ai-assistant": "^0.7.0",
"@hcengineering/ai-assistant-assets": "^0.7.0",
"@hcengineering/ai-assistant-resources": "^0.7.0",
"@hcengineering/inbox": "^0.7.0",
"@hcengineering/inbox-assets": "^0.7.0",
"@hcengineering/inbox-resources": "^0.7.0",
"readable-stream": "^4.7.0",
"svelte": "^4.2.20"
}
Expand Down
5 changes: 4 additions & 1 deletion dev/prod/src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ import { mailId } from '@hcengineering/mail'
import { chatId } from '@hcengineering/chat'
import github, { githubId } from '@hcengineering/github'
import { bitrixId } from '@hcengineering/bitrix'
import { achievementId } from '@hcengineering/achievement'
import {inboxId} from '@hcengineering/inbox'
import {achievementId} from '@hcengineering/achievement'
import communication, { communicationId } from '@hcengineering/communication'
import { emojiId } from '@hcengineering/emoji'
import billingPlugin, { billingId } from '@hcengineering/billing'
Expand Down Expand Up @@ -129,6 +130,7 @@ import '@hcengineering/media-assets'
import '@hcengineering/view-assets'
import '@hcengineering/workbench-assets'
import '@hcengineering/chat-assets'
import '@hcengineering/inbox-assets'
import '@hcengineering/mail-assets'
import '@hcengineering/github-assets'
import '@hcengineering/achievement-assets'
Expand Down Expand Up @@ -387,6 +389,7 @@ function configureI18n (): void {
communicationId,
async (lang: string) => await import(`@hcengineering/communication-assets/lang/${lang}.json`)
)
addStringsLoader(inboxId, async (lang: string) => await import(`@hcengineering/inbox-assets/lang/${lang}.json`))
addStringsLoader(emojiId, async (lang: string) => await import(`@hcengineering/emoji-assets/lang/${lang}.json`))
addStringsLoader(billingId, async (lang: string) => await import(`@hcengineering/billing-assets/lang/${lang}.json`))
addStringsLoader(
Expand Down
3 changes: 1 addition & 2 deletions models/activity/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
type ViewAction,
type ViewActionAvailabilityFunction
} from '@hcengineering/view'
import { type NotificationGroup, type NotificationType } from '@hcengineering/notification'
import { type NotificationGroup } from '@hcengineering/notification'

export default mergeIds(activityId, activity, {
string: {
Expand All @@ -44,7 +44,6 @@ export default mergeIds(activityId, activity, {
ids: {
ReactionAddedActivityViewlet: '' as Ref<DocUpdateMessageViewlet>,
ActivityNotificationGroup: '' as Ref<NotificationGroup>,
AddReactionNotification: '' as Ref<NotificationType>,
AddReactionAction: '' as Ref<Action>,
SaveForLaterAction: '' as Ref<Action>,
RemoveFromLaterAction: '' as Ref<Action>,
Expand Down
3 changes: 2 additions & 1 deletion models/all/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
"@hcengineering/model-emoji": "^0.7.0",
"@hcengineering/model-billing": "^0.7.0",
"@hcengineering/model-huly-mail": "^0.7.0",
"@hcengineering/model-ai-assistant": "^0.7.0"
"@hcengineering/model-ai-assistant": "^0.7.0",
"@hcengineering/model-inbox": "^0.7.0"
}
}
6 changes: 6 additions & 0 deletions models/all/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ import survey, { surveyId, createModel as surveyModel } from '@hcengineering/mod
import { presenceId, createModel as presenceModel } from '@hcengineering/model-presence'
import chat, { chatId, createModel as chatModel } from '@hcengineering/model-chat'
import processes, { processId, createModel as processModel } from '@hcengineering/model-process'
import inbox, { createModel as inboxModel, inboxId } from '@hcengineering/model-inbox'
import { achievementId, createModel as achievementModel } from '@hcengineering/model-achievement'
import { emojiId, createModel as emojiModel } from '@hcengineering/model-emoji'
import { billingId, createModel as billingModel } from '@hcengineering/model-billing'
Expand Down Expand Up @@ -480,6 +481,11 @@ export default function buildModel (): Builder {
chatId,
{ label: chat.string.Chat, hidden: true, enabled: false, beta: true, classFilter: defaultFilter }
],
[
inboxModel,
inboxId,
{ label: inbox.string.Inbox, hidden: true, enabled: false, beta: true, classFilter: defaultFilter }
],
[achievementModel, achievementId],
[emojiModel, emojiId],
[communicationModel, communicationId],
Expand Down
2 changes: 2 additions & 0 deletions models/all/src/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import { surveyOperation } from '@hcengineering/model-survey'
import { cardOperation } from '@hcengineering/model-card'
import { aiBotId, aiBotOperation } from '@hcengineering/model-ai-bot'
import { chatId, chatOperation } from '@hcengineering/model-chat'
import { inboxId, inboxOperation } from '@hcengineering/model-inbox'
import { processId, processOperation } from '@hcengineering/model-process'
import { communicationId, communicationOperation } from '@hcengineering/model-communication'
import { recorderId, recorderOperation } from '@hcengineering/model-recorder'
Expand Down Expand Up @@ -106,6 +107,7 @@ export const migrateOperations: [string, MigrateOperation][] = [
['survey', surveyOperation],
[aiBotId, aiBotOperation],
[chatId, chatOperation],
[inboxId, inboxOperation],
[processId, processOperation],
[communicationId, communicationOperation],
[recorderId, recorderOperation]
Expand Down
7 changes: 7 additions & 0 deletions models/inbox/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}
4 changes: 4 additions & 0 deletions models/inbox/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/
5 changes: 5 additions & 0 deletions models/inbox/config/rig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
"rigPackageName": "@hcengineering/platform-rig",
"rigProfile": "model"
}
7 changes: 7 additions & 0 deletions models/inbox/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
roots: ["./src"],
coverageReporters: ["text-summary", "html"]
}
50 changes: 50 additions & 0 deletions models/inbox/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@hcengineering/model-inbox",
"version": "0.7.0",
"main": "lib/index.js",
"svelte": "src/index.ts",
"types": "types/index.d.ts",
"author": "Hardcore Engineering Inc",
"template": "@hcengineering/model-package",
"license": "EPL-2.0",
"scripts": {
"build": "compile",
"build:watch": "compile",
"format": "format src",
"_phase:build": "compile transpile src",
"_phase:format": "format src",
"_phase:validate": "compile validate",
"_phase:test": "jest --passWithNoTests --silent --forceExit",
"test": "jest --passWithNoTests --silent --forceExit"
},
"devDependencies": {
"@hcengineering/platform-rig": "^0.7.19",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.54.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint-config-standard-with-typescript": "^40.0.0",
"prettier": "^3.6.2",
"typescript": "^5.9.3",
"@types/node": "^22.15.29",
"jest": "^29.7.0",
"@types/jest": "^29.5.5",
"ts-jest": "^29.1.1"
},
"dependencies": {
"@hcengineering/card": "^0.7.0",
"@hcengineering/inbox": "^0.7.0",
"@hcengineering/inbox-resources": "^0.7.0",
"@hcengineering/core": "^0.7.8",
"@hcengineering/model": "^0.7.5",
"@hcengineering/model-core": "^0.7.0",
"@hcengineering/model-workbench": "^0.7.0",
"@hcengineering/platform": "^0.7.5",
"@hcengineering/setting": "^0.7.0",
"@hcengineering/ui": "^0.7.0",
"@hcengineering/view": "^0.7.0",
"@hcengineering/workbench": "^0.7.0"
}
}
42 changes: 42 additions & 0 deletions models/inbox/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright © 2025 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 { type Builder } from '@hcengineering/model'
import core from '@hcengineering/model-core'
import workbench from '@hcengineering/model-workbench'
import { inboxId } from '@hcengineering/inbox'

import inbox from './plugin'

export { inboxId } from '@hcengineering/inbox'
export { inboxOperation } from './migration'
export default inbox

export function createModel (builder: Builder): void {
builder.createDoc(
workbench.class.Application,
core.space.Model,
{
label: inbox.string.Inbox,
icon: inbox.icon.Inbox,
alias: inboxId,
hidden: false,
component: inbox.component.InboxApplication,
position: 'top',
order: 100
},
inbox.app.Inbox
)
}
21 changes: 21 additions & 0 deletions models/inbox/src/migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Copyright © 2025 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 { type MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model'

export const inboxOperation: MigrateOperation = {
async migrate (client: MigrationClient, mode): Promise<void> {},
async upgrade (state: Map<string, Set<string>>, client: () => Promise<MigrationUpgradeClient>, mode): Promise<void> {}
}
Loading