diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index b6d6ca5148..6088367954 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -269,9 +269,10 @@ export function createModel (builder: Builder): void { label: notification.string.Archive, icon: view.icon.Archive, input: 'focus', + keyBinding: ['Backspace'], category: notification.category.Notification, target: notification.class.DocUpdates, - context: { mode: 'context', application: notification.app.Notification, group: 'edit' } + context: { mode: ['context', 'browser'], group: 'edit' } }, notification.action.Hide ) diff --git a/plugins/notification-resources/src/components/Inbox.svelte b/plugins/notification-resources/src/components/Inbox.svelte index e513ef8245..c6a4c396b3 100644 --- a/plugins/notification-resources/src/components/Inbox.svelte +++ b/plugins/notification-resources/src/components/Inbox.svelte @@ -20,6 +20,7 @@ import { createQuery, getClient } from '@hcengineering/presentation' import { AnyComponent, Component, Label, Loading, Scroller } from '@hcengineering/ui' import view from '@hcengineering/view' + import { ActionContext, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources' import NotificationView from './NotificationView.svelte' export let visibileNav: boolean @@ -39,8 +40,11 @@ }, (res) => { docs = res - if (loading && docs.length > 0) { - select(docs[0].attachedTo, docs[0].attachedToClass) + listProvider.update(docs) + if (loading || _id === undefined) { + changeSelected(selected) + } else if (docs.find((p) => p.attachedTo === _id) === undefined) { + changeSelected(selected) } loading = false }, @@ -51,16 +55,32 @@ } ) - function select (objectId: Ref, objectClass: Ref>) { - const targetClass = hierarchy.getClass(objectClass) - const panelComponent = hierarchy.as(targetClass, view.mixin.ObjectPanel) - component = panelComponent.component ?? view.component.EditDoc - _id = objectId - _class = objectClass + $: changeSelected(selected) + + function changeSelected (index: number) { + if (docs[index] !== undefined) { + select(docs[index]) + } else if (docs.length) { + if (index < docs.length - 1) { + selected++ + } else { + selected-- + } + } else { + selected = 0 + component = undefined + _id = undefined + _class = undefined + } } - function selectHandler (e: CustomEvent) { - select(e.detail._id, e.detail._class) + function select (value: DocUpdates) { + listProvider.updateFocus(value) + const targetClass = hierarchy.getClass(value.attachedToClass) + const panelComponent = hierarchy.as(targetClass, view.mixin.ObjectPanel) + component = panelComponent.component ?? view.component.EditDoc + _id = value.attachedTo + _class = value.attachedToClass } let component: AnyComponent | undefined @@ -69,12 +89,28 @@ let viewlets: Map + const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => { + if (dir === 'vertical') { + const value = selected + offset + if (docs[value] !== undefined) { + selected = value + } + } + }) + const descriptors = createQuery() descriptors.query(activity.class.TxViewlet, {}, (result) => { viewlets = new Map(result.map((r) => [activityKey(r.objectClass, r.txClass), r])) }) + + let selected = 0 +
{#if visibileNav}
@@ -88,8 +124,15 @@ {#if loading} {:else} - {#each docs as doc} - + {#each docs as doc, i} + { + selected = i + }} + /> {/each} {/if} @@ -99,9 +142,7 @@ {#if component && _id && _class} {:else} -
- -
+
{/if}
diff --git a/plugins/notification-resources/src/components/NotificationView.svelte b/plugins/notification-resources/src/components/NotificationView.svelte index 3c5a3d2f55..ea1b9c117d 100644 --- a/plugins/notification-resources/src/components/NotificationView.svelte +++ b/plugins/notification-resources/src/components/NotificationView.svelte @@ -24,7 +24,6 @@ import { AnySvelteComponent, Label, TimeSince, getEventPositionElement, showPopup } from '@hcengineering/ui' import view from '@hcengineering/view' import { Menu } from '@hcengineering/view-resources' - import { createEventDispatcher } from 'svelte' import TxView from './TxView.svelte' export let value: DocUpdates @@ -60,10 +59,10 @@ query.query(contact.class.EmployeeAccount, { _id: tx.modifiedBy as Ref }, (r) => ([account] = r)) $: employee = account && $employeeByIdStore.get(account.employee) - const dispatch = createEventDispatcher() - const docQuery = createQuery() - $: docQuery.query(value.attachedToClass, { _id: value.attachedTo }, (res) => ([doc] = res)) + $: docQuery.query(value.attachedToClass, { _id: value.attachedTo }, (res) => { + ;[doc] = res + }) $: newTxes = value.txes.length @@ -74,12 +73,7 @@ {#if doc} -
dispatch('click', { _id: value.attachedTo, _class: value.attachedToClass })} - > +
diff --git a/plugins/notification-resources/src/utils.ts b/plugins/notification-resources/src/utils.ts index 0e56e8eca7..5829041425 100644 --- a/plugins/notification-resources/src/utils.ts +++ b/plugins/notification-resources/src/utils.ts @@ -133,11 +133,19 @@ export async function unsubscribe (object: DocUpdates): Promise { /** * @public */ -export async function hide (object: DocUpdates): Promise { +export async function hide (object: DocUpdates | DocUpdates[]): Promise { const client = getClient() - await client.update(object, { - hidden: true - }) + if (Array.isArray(object)) { + for (const value of object) { + await client.update(value, { + hidden: true + }) + } + } else { + await client.update(object, { + hidden: true + }) + } } /** diff --git a/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte b/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte index c1557691bd..9271cea639 100644 --- a/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/SubIssueList.svelte @@ -15,7 +15,7 @@ 0) { - if (this._current?.focus === undefined) { + if (this._current === undefined) { this.delegate(0, undefined, 'vertical') } else { // Check if we don't have object, we need to select first one. this.delegate(0, this._current?.focus, 'vertical') } - updateFocus({ focus: this._current?.focus, provider: this }) + if (this._current?.focus === undefined) { + updateFocus({ focus: this._current?.focus, provider: this }) + } } } diff --git a/server-plugins/chunter-resources/src/index.ts b/server-plugins/chunter-resources/src/index.ts index d75e28abc3..2da4afeb2f 100644 --- a/server-plugins/chunter-resources/src/index.ts +++ b/server-plugins/chunter-resources/src/index.ts @@ -132,7 +132,10 @@ async function CommentCreate (tx: TxCUD, control: TriggerControl): Promise< const actualTx = TxProcessor.extractTx(tx) if (actualTx._class !== core.class.TxCreateDoc) return [] const doc = TxProcessor.createDoc2Doc(actualTx as TxCreateDoc) - if (!hierarchy.isDerived(doc._class, chunter.class.Comment)) { + if ( + !hierarchy.isDerived(doc._class, chunter.class.Comment) || + hierarchy.isDerived(doc._class, chunter.class.Backlink) + ) { return [] } const res: Tx[] = [] diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index 6d4efd7ee7..2573afe023 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -94,6 +94,16 @@ export async function OnBacklinkCreate (tx: Tx, control: TriggerControl): Promis } ) res.push(collabTx) + res = res.concat( + await createCollabDocInfo( + [receiver._id], + tx as TxCUD, + doc._id, + doc._class, + control, + tx._id as Ref> + ) + ) } } const notifyTx = await createNotificationTxes(