UBERF-4360: rewrite chat (#4265)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina
2024-01-11 21:46:11 +07:00
committed by GitHub
parent 06f6f6a222
commit 7f6f5e28a6
183 changed files with 6360 additions and 5051 deletions
@@ -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}