mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-30 05:25:00 +02:00
UBERF-4360: rewrite chat (#4265)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
import { NavLink } from '@hcengineering/view-resources'
|
||||
import type { Application } from '@hcengineering/workbench'
|
||||
import workbench from '@hcengineering/workbench'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { DocNotifyContext } from '@hcengineering/notification'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
|
||||
import AppItem from './AppItem.svelte'
|
||||
import preference from '@hcengineering/preference'
|
||||
|
||||
@@ -43,6 +47,19 @@
|
||||
$: filteredApps = apps.filter((it) => !hiddenAppsIds.includes(it._id))
|
||||
$: topApps = filteredApps.filter((it) => it.position === 'top')
|
||||
$: bottomdApps = filteredApps.filter((it) => it.position !== 'top')
|
||||
|
||||
const inboxClient = InboxNotificationsClientImpl.getClient()
|
||||
const docNotifyContextsStore = inboxClient.docNotifyContexts
|
||||
|
||||
async function shouldNotify (app: Application, docNotifyContexts: DocNotifyContext[]) {
|
||||
if (!app.shouldNotify) {
|
||||
return false
|
||||
}
|
||||
|
||||
const shouldNotifyFn = await getResource(app.shouldNotify)
|
||||
|
||||
return await shouldNotifyFn(docNotifyContexts)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex-{direction === 'horizontal' ? 'row-center' : 'col-center'} clear-mins apps-{direction} relative">
|
||||
@@ -57,13 +74,17 @@
|
||||
>
|
||||
{#each topApps as app}
|
||||
<NavLink app={app.alias} shrink={0}>
|
||||
<AppItem selected={app._id === active} icon={app.icon} label={app.label} />
|
||||
{#await shouldNotify(app, $docNotifyContextsStore) then notify}
|
||||
<AppItem selected={app._id === active} icon={app.icon} label={app.label} {notify} />
|
||||
{/await}
|
||||
</NavLink>
|
||||
{/each}
|
||||
<div class="divider" />
|
||||
{#each bottomdApps as app}
|
||||
<NavLink app={app.alias} shrink={0}>
|
||||
<AppItem selected={app._id === active} icon={app.icon} label={app.label} />
|
||||
{#await shouldNotify(app, $docNotifyContextsStore) then notify}
|
||||
<AppItem selected={app._id === active} icon={app.icon} label={app.label} {notify} />
|
||||
{/await}
|
||||
</NavLink>
|
||||
{/each}
|
||||
<div class="apps-space-{direction}" />
|
||||
|
||||
@@ -13,15 +13,20 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core from '@hcengineering/core'
|
||||
import core, { Class, Doc, DocumentQuery, Ref } from '@hcengineering/core'
|
||||
import { Icon, Label } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { TableBrowser } from '@hcengineering/view-resources'
|
||||
import { NavigatorModel } from '@hcengineering/workbench'
|
||||
|
||||
import workbench from '../plugin'
|
||||
import { getSpecialSpaceClass } from '../utils'
|
||||
|
||||
export let model: NavigatorModel | undefined
|
||||
export let _class: Ref<Class<Doc>> = core.class.Space
|
||||
export let config: string[] = ['', '_class', 'modifiedOn']
|
||||
export let baseMenuClass: Ref<Class<Doc>> = core.class.Space
|
||||
export let query: DocumentQuery<Doc> | undefined = undefined
|
||||
</script>
|
||||
|
||||
<div class="ac-header">
|
||||
@@ -32,11 +37,11 @@
|
||||
</div>
|
||||
{#if model}
|
||||
<TableBrowser
|
||||
_class={core.class.Space}
|
||||
config={['', '_class', 'modifiedOn']}
|
||||
{_class}
|
||||
{config}
|
||||
showNotification
|
||||
baseMenuClass={core.class.Space}
|
||||
query={{
|
||||
{baseMenuClass}
|
||||
query={query ?? {
|
||||
_class: { $in: getSpecialSpaceClass(model) },
|
||||
archived: true
|
||||
}}
|
||||
|
||||
@@ -36,9 +36,8 @@
|
||||
SearchEdit,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import { FilterBar, FilterButton, SpacePresenter } from '@hcengineering/view-resources'
|
||||
import { classIcon, FilterBar, FilterButton, SpacePresenter } from '@hcengineering/view-resources'
|
||||
import plugin from '../plugin'
|
||||
import { classIcon } from '../utils'
|
||||
|
||||
export let _class: Ref<Class<Space>>
|
||||
export let label: IntlString
|
||||
|
||||
@@ -14,54 +14,54 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import contact, { Employee, PersonAccount } from '@hcengineering/contact'
|
||||
import core, { Class, Doc, Ref, Space, getCurrentAccount, setCurrentAccount } from '@hcengineering/core'
|
||||
import core, { Class, Doc, getCurrentAccount, Ref, setCurrentAccount, Space } from '@hcengineering/core'
|
||||
import login from '@hcengineering/login'
|
||||
import notification, { notificationId } from '@hcengineering/notification'
|
||||
import { BrowserNotificatator, NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { IntlString, broadcastEvent, getMetadata, getResource } from '@hcengineering/platform'
|
||||
import notification, { inboxId } from '@hcengineering/notification'
|
||||
import { BrowserNotificatator, InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { broadcastEvent, getMetadata, getResource, IntlString } from '@hcengineering/platform'
|
||||
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
|
||||
import setting from '@hcengineering/setting'
|
||||
import support, { SupportStatus } from '@hcengineering/support'
|
||||
import {
|
||||
AnyComponent,
|
||||
areLocationsEqual,
|
||||
Button,
|
||||
closePanel,
|
||||
closePopup,
|
||||
closeTooltip,
|
||||
CompAndProps,
|
||||
Component,
|
||||
defineSeparators,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
getCurrentLocation,
|
||||
getLocation,
|
||||
Label,
|
||||
Location,
|
||||
location,
|
||||
locationStorageKeyId,
|
||||
navigate,
|
||||
openPanel,
|
||||
PanelInstance,
|
||||
Popup,
|
||||
PopupAlignment,
|
||||
PopupPosAlignment,
|
||||
PopupResult,
|
||||
ResolvedLocation,
|
||||
Separator,
|
||||
TooltipInstance,
|
||||
areLocationsEqual,
|
||||
closePanel,
|
||||
closePopup,
|
||||
closeTooltip,
|
||||
defineSeparators,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
getCurrentLocation,
|
||||
getLocation,
|
||||
location,
|
||||
locationStorageKeyId,
|
||||
navigate,
|
||||
openPanel,
|
||||
popupstore,
|
||||
ResolvedLocation,
|
||||
resolvedLocationStore,
|
||||
Separator,
|
||||
setResolvedLocation,
|
||||
showPopup,
|
||||
workbenchSeparators,
|
||||
IconSettings
|
||||
IconSettings,
|
||||
TooltipInstance
|
||||
} from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import {
|
||||
ActionHandler,
|
||||
ListSelectionProvider,
|
||||
NavLink,
|
||||
migrateViewOpttions,
|
||||
NavLink,
|
||||
updateFocus
|
||||
} from '@hcengineering/view-resources'
|
||||
import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@hcengineering/workbench'
|
||||
@@ -124,9 +124,8 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
getResource(login.function.GetWorkspaces).then(async (f) => {
|
||||
const workspaces = await f()
|
||||
$workspacesStore = workspaces
|
||||
getResource(login.function.GetWorkspaces).then(async (getWorkspaceFn) => {
|
||||
$workspacesStore = await getWorkspaceFn()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -162,20 +161,20 @@
|
||||
{ limit: 1 }
|
||||
)
|
||||
|
||||
let hasNotification = false
|
||||
// let hasInboxNotifications = false
|
||||
|
||||
const notificationClient = NotificationClientImpl.getClient()
|
||||
notificationClient.docUpdates.subscribe((res) => {
|
||||
hasNotification = res.some((p) => !p.hidden && p.txes.some((p) => p.isNew))
|
||||
})
|
||||
|
||||
const workspaceId = $location.path[1]
|
||||
|
||||
let hasInboxNotifications = false
|
||||
let syncPromise: Promise<void> | undefined = undefined
|
||||
|
||||
let locUpdate = 0
|
||||
|
||||
const notificationClient = InboxNotificationsClientImpl.getClient()
|
||||
|
||||
notificationClient.inboxNotificationsByContext.subscribe((inboxNotificationsByContext) => {
|
||||
hasInboxNotifications = Array.from(inboxNotificationsByContext.entries()).some(([_, notifications]) =>
|
||||
notifications.some(({ isViewed }) => !isViewed)
|
||||
)
|
||||
})
|
||||
|
||||
const doSyncLoc = async (loc: Location, iteration: number): Promise<void> => {
|
||||
if (workspaceId !== $location.path[1]) {
|
||||
// Switch of workspace
|
||||
@@ -672,14 +671,14 @@
|
||||
/>
|
||||
</div>
|
||||
<!-- <ActivityStatus status="active" /> -->
|
||||
<NavLink app={notificationId} shrink={0}>
|
||||
<NavLink app={inboxId} shrink={0}>
|
||||
<AppItem
|
||||
icon={notification.icon.Inbox}
|
||||
icon={notification.icon.Notifications}
|
||||
label={notification.string.Inbox}
|
||||
selected={currentAppAlias === notificationId || inboxPopup !== undefined}
|
||||
selected={currentAppAlias === inboxId || inboxPopup !== undefined}
|
||||
on:click={(e) => {
|
||||
if (e.metaKey || e.ctrlKey) return
|
||||
if (currentAppAlias === notificationId && lastLoc !== undefined) {
|
||||
if (currentAppAlias === inboxId && lastLoc !== undefined) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
navigate(lastLoc)
|
||||
@@ -688,29 +687,9 @@
|
||||
lastLoc = $location
|
||||
}
|
||||
}}
|
||||
notify={hasNotification}
|
||||
notify={hasInboxNotifications}
|
||||
/>
|
||||
</NavLink>
|
||||
<!-- NOTE: temporarily disabled -->
|
||||
<!-- <NavLink app={inboxId} shrink={0}>-->
|
||||
<!-- <AppItem-->
|
||||
<!-- icon={notification.icon.Notifications}-->
|
||||
<!-- label={notification.string.Inbox}-->
|
||||
<!-- selected={currentAppAlias === inboxId || inboxPopup !== undefined}-->
|
||||
<!-- on:click={(e) => {-->
|
||||
<!-- if (e.metaKey || e.ctrlKey) return-->
|
||||
<!-- if (currentAppAlias === inboxId && lastLoc !== undefined) {-->
|
||||
<!-- e.preventDefault()-->
|
||||
<!-- e.stopPropagation()-->
|
||||
<!-- navigate(lastLoc)-->
|
||||
<!-- lastLoc = undefined-->
|
||||
<!-- } else {-->
|
||||
<!-- lastLoc = $location-->
|
||||
<!-- }-->
|
||||
<!-- }}-->
|
||||
<!-- notify={hasInboxNotifications}-->
|
||||
<!-- />-->
|
||||
<!-- </NavLink>-->
|
||||
<Applications apps={getApps(apps)} active={currentApplication?._id} direction={appsDirection} />
|
||||
</div>
|
||||
<div class="info-box {appsDirection}" class:vertical-mobile={appsDirection === 'vertical'} class:mini={appsMini}>
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
<script lang="ts">
|
||||
import type { Doc, Ref, Space } from '@hcengineering/core'
|
||||
import core from '@hcengineering/core'
|
||||
import { DocUpdates } from '@hcengineering/notification'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { IntlString, getResource } from '@hcengineering/platform'
|
||||
import preference from '@hcengineering/preference'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
@@ -36,12 +34,16 @@
|
||||
TreeItem,
|
||||
TreeNode,
|
||||
getActions as getContributedActions,
|
||||
getSpacePresenter
|
||||
getSpacePresenter,
|
||||
classIcon
|
||||
} from '@hcengineering/view-resources'
|
||||
import { SpacesNavModel } from '@hcengineering/workbench'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { DocNotifyContext, InboxNotification } from '@hcengineering/notification'
|
||||
|
||||
import plugin from '../../plugin'
|
||||
import { classIcon, getSpaceName } from '../../utils'
|
||||
import { getSpaceName } from '../../utils'
|
||||
import TreeSeparator from './TreeSeparator.svelte'
|
||||
|
||||
export let model: SpacesNavModel
|
||||
@@ -104,13 +106,24 @@
|
||||
return result
|
||||
}
|
||||
|
||||
const notificationClient = NotificationClientImpl.getClient()
|
||||
const docUpdates = notificationClient.docUpdatesStore
|
||||
const inboxClient = InboxNotificationsClientImpl.getClient()
|
||||
const notifyContextByDocStore = inboxClient.docNotifyContextByDoc
|
||||
const inboxNotificationsByContextStore = inboxClient.inboxNotificationsByContext
|
||||
|
||||
function isChanged (space: Space, docUpdates: Map<Ref<Doc>, DocUpdates>): boolean {
|
||||
const update = docUpdates.get(space._id)
|
||||
if (update === undefined) return false
|
||||
return update.txes.filter((tx) => tx.isNew).length > 0 && !update.hidden
|
||||
function isChanged (
|
||||
space: Space,
|
||||
notifyContextByDoc: Map<Ref<Doc>, DocNotifyContext>,
|
||||
inboxNotificationsByContext: Map<Ref<DocNotifyContext>, InboxNotification[]>
|
||||
): boolean {
|
||||
const context = notifyContextByDoc.get(space._id)
|
||||
|
||||
if (context === undefined || context.hidden) {
|
||||
return false
|
||||
}
|
||||
|
||||
const inboxNotifications = inboxNotificationsByContext.get(context._id) ?? []
|
||||
|
||||
return inboxNotifications.filter(({ isViewed }) => !isViewed).length > 0
|
||||
}
|
||||
|
||||
function getParentActions (): Action[] {
|
||||
@@ -172,7 +185,7 @@
|
||||
icon={classIcon(client, space._class)}
|
||||
selected={deselect ? false : currentSpace === space._id}
|
||||
actions={async () => await getActions(space)}
|
||||
bold={isChanged(space, $docUpdates)}
|
||||
bold={isChanged(space, $notifyContextByDocStore, $inboxNotificationsByContextStore)}
|
||||
indent
|
||||
/>
|
||||
{/await}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<script lang="ts">
|
||||
import type { Doc, Ref, Space } from '@hcengineering/core'
|
||||
import core from '@hcengineering/core'
|
||||
import { DocUpdates } from '@hcengineering/notification'
|
||||
import { NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { DocNotifyContext, InboxNotification } from '@hcengineering/notification'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { IntlString, getResource } from '@hcengineering/platform'
|
||||
import preference from '@hcengineering/preference'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
@@ -27,10 +27,11 @@
|
||||
TreeItem,
|
||||
TreeNode,
|
||||
getActions as getContributedActions,
|
||||
getSpacePresenter
|
||||
getSpacePresenter,
|
||||
classIcon
|
||||
} from '@hcengineering/view-resources'
|
||||
import { SpacesNavModel } from '@hcengineering/workbench'
|
||||
import { classIcon, getSpaceName } from '../../utils'
|
||||
import { getSpaceName } from '../../utils'
|
||||
|
||||
export let label: IntlString
|
||||
export let spaces: Space[]
|
||||
@@ -85,13 +86,18 @@
|
||||
return result
|
||||
}
|
||||
|
||||
const notificationClient = NotificationClientImpl.getClient()
|
||||
const docUpdates = notificationClient.docUpdatesStore
|
||||
const inboxClient = InboxNotificationsClientImpl.getClient()
|
||||
const docNotifyContextByDocStore = inboxClient.docNotifyContextByDoc
|
||||
const inboxNotificationsByContextStore = inboxClient.inboxNotificationsByContext
|
||||
|
||||
function isChanged (space: Space, docUpdates: Map<Ref<Doc>, DocUpdates>): boolean {
|
||||
const update = docUpdates.get(space._id)
|
||||
if (update === undefined) return false
|
||||
return update.txes.length > 0 && !update.hidden
|
||||
function isChanged (
|
||||
space: Space,
|
||||
docUpdates: Map<Ref<Doc>, DocNotifyContext>,
|
||||
inboxNotificationsByContext: Map<Ref<DocNotifyContext>, InboxNotification[]>
|
||||
): boolean {
|
||||
const notifyContext = docUpdates.get(space._id)
|
||||
if (notifyContext === undefined) return false
|
||||
return !notifyContext.hidden && !!inboxNotificationsByContext.get(notifyContext._id)?.length
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -119,7 +125,7 @@
|
||||
icon={classIcon(client, space._class)}
|
||||
selected={currentSpace === space._id}
|
||||
actions={async () => await getActions(space)}
|
||||
bold={isChanged(space, $docUpdates)}
|
||||
bold={isChanged(space, $docNotifyContextByDocStore, $inboxNotificationsByContextStore)}
|
||||
/>
|
||||
</NavLink>
|
||||
{/await}
|
||||
|
||||
Reference in New Issue
Block a user