[Part 1]: Add space to activity queries/finds (#6177)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-07-30 11:02:06 +04:00 committed by GitHub
parent 7cdfa9747f
commit e51d0f3ae4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 82 additions and 50 deletions

View File

@ -15,7 +15,7 @@
<script lang="ts">
import activity, { ActivityExtension, ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
import { Doc, Ref, SortingOrder } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, isSpace } from '@hcengineering/presentation'
import { Grid, Label, Spinner, location, Lazy } from '@hcengineering/ui'
import { onDestroy, onMount } from 'svelte'
@ -168,7 +168,7 @@
const res = activityMessagesQuery.query(
activity.class.ActivityMessage,
{ attachedTo: objectId },
{ attachedTo: objectId, space: isSpace(object) ? object._id : object.space },
(result: ActivityMessage[]) => {
void combineActivityMessages(result, order).then((messages) => {
activityMessages = messages

View File

@ -22,6 +22,7 @@ import {
isOtherDay,
type Ref,
SortingOrder,
type Space,
type Timestamp
} from '@hcengineering/core'
@ -71,7 +72,6 @@ export class ChannelDataProvider implements IChannelDataProvider {
private readonly tailQuery = createQuery(true)
private chatId: Ref<Doc> | undefined = undefined
private readonly context: DocNotifyContext | undefined = undefined
private readonly msgClass: Ref<Class<ActivityMessage>>
private selectedMsgId: Ref<ActivityMessage> | undefined = undefined
private tailStart: Timestamp | undefined = undefined
@ -118,14 +118,14 @@ export class ChannelDataProvider implements IChannelDataProvider {
})
constructor (
readonly context: DocNotifyContext | undefined,
readonly space: Ref<Space>,
chatId: Ref<Doc>,
_class: Ref<Class<ActivityMessage>>,
context: DocNotifyContext | undefined,
selectedMsgId?: Ref<ActivityMessage>,
selectedMsgId: Ref<ActivityMessage> | undefined,
loadAll = false
) {
this.chatId = chatId
this.context = context
this.msgClass = _class
this.selectedMsgId = selectedMsgId
void this.loadData(loadAll)
@ -175,14 +175,14 @@ export class ChannelDataProvider implements IChannelDataProvider {
this.metadataQuery.query(
this.msgClass,
{ attachedTo: this.chatId },
{ attachedTo: this.chatId, space: this.space },
(res) => {
this.updatesDates(res)
this.metadataStore.set(res)
void this.loadInitialMessages(undefined, loadAll)
},
{
projection: { _id: 1, _class: 1, createdOn: 1, createdBy: 1, attachedTo: 1, modifiedOn: 1 },
projection: { _id: 1, _class: 1, space: 1, createdOn: 1, createdBy: 1, attachedTo: 1, modifiedOn: 1 },
sort: { createdOn: SortingOrder.Ascending }
}
)
@ -255,6 +255,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
this.msgClass,
{
attachedTo: this.chatId,
space: this.space,
...query,
...(this.tailStart !== undefined ? { createdOn: { $gte: this.tailStart } } : {})
},
@ -304,6 +305,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
chunter.class.ChatMessage,
{
attachedTo: this.chatId,
space: this.space,
_id: { $nin: skipIds },
createdOn: isBackward ? { $lte: loadAfter } : { $gte: loadAfter }
},
@ -495,6 +497,7 @@ export class ChannelDataProvider implements IChannelDataProvider {
_class: {
$in: [notification.class.MentionInboxNotification, notification.class.ActivityInboxNotification]
},
space: this.context.space,
docNotifyContext: this.context._id,
isViewed: false
},

View File

@ -16,7 +16,7 @@
import { Class, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
import notification, { DocNotifyContext } from '@hcengineering/notification'
import activity, { ActivityMessage, ActivityMessagesFilter } from '@hcengineering/activity'
import { getClient } from '@hcengineering/presentation'
import { getClient, isSpace } from '@hcengineering/presentation'
import { getMessageFromLoc, messageInFocus } from '@hcengineering/activity-resources'
import { location as locationStore } from '@hcengineering/ui'
@ -79,7 +79,8 @@
user: getCurrentAccount()._id
}))
dataProvider = new ChannelDataProvider(attachedTo, _class, ctx, selectedMessageId, loadAll)
const space = isSpace(object) ? object._id : object.space
dataProvider = new ChannelDataProvider(ctx, space, attachedTo, _class, selectedMessageId, loadAll)
}
}
</script>

View File

@ -74,9 +74,10 @@
{canOpen}
{withAside}
{isAsideShown}
hideBefore
on:aside-toggled
on:close
>
<PinnedMessages {_id} {_class} on:select />
{#if object}
<PinnedMessages {_id} {_class} space={object.space} on:select />
{/if}
</Header>

View File

@ -20,6 +20,7 @@
import { ActivityMessagePresenter } from '@hcengineering/activity-resources'
import chunterResources from '../plugin'
import { getChannelSpace } from '../utils'
export let object: DirectMessage
@ -29,7 +30,7 @@
const messagesQuery = createQuery()
$: messagesQuery.query(
chunter.class.ChatMessage,
{ attachedTo: object._id },
{ attachedTo: object._id, space: getChannelSpace(object._class, object._id, object.space) },
(res) => {
if (res !== undefined) {
messages = res.sort((a, b) => (a.createdOn ?? 0) - (b.createdOn ?? 0))

View File

@ -726,7 +726,7 @@
onScroll={handleScroll}
onResize={handleResize}
>
{#if loadMoreAllowed}
{#if loadMoreAllowed && !embedded}
<HistoryLoading isLoading={$isLoadingMoreStore} />
{/if}
<slot name="header" />

View File

@ -50,7 +50,6 @@
export let withFilters: boolean = false
export let filters: Ref<ActivityMessagesFilter>[] = []
export let adaptive: 'default' | 'freezeActions' | 'doubleRow' | 'disabled' = 'default'
export let hideBefore: boolean = false
export let hideActions: boolean = false
const client = getClient()
@ -63,7 +62,7 @@
<Header
{allowFullsize}
type={allowClose ? 'type-aside' : 'type-component'}
hideBefore={$$slots.default === undefined || hideBefore}
hideBefore={false}
hideActions={!((canOpen && object) || withAside || $$slots.actions) || hideActions}
hideDescription={!description}
adaptive={adaptive !== 'default' ? adaptive : withFilters ? 'freezeActions' : 'disabled'}

View File

@ -17,13 +17,15 @@
import PinnedMessagesPopup from './PinnedMessagesPopup.svelte'
import { createQuery } from '@hcengineering/presentation'
import activity, { ActivityMessage } from '@hcengineering/activity'
import { Class, Doc, Ref } from '@hcengineering/core'
import { Class, Doc, Ref, Space } from '@hcengineering/core'
import view from '@hcengineering/view'
import { ThreadMessage } from '@hcengineering/chunter'
import { createEventDispatcher } from 'svelte'
import chunter from '../plugin'
import { getChannelSpace } from '../utils'
export let space: Ref<Space>
export let _class: Ref<Class<Doc>>
export let _id: Ref<Doc>
@ -34,29 +36,35 @@
let pinnedMessagesCount = 0
let pinnedThreadsCount = 0
$: channelSpace = getChannelSpace(_class, _id, space)
$: pinnedQuery.query(
activity.class.ActivityMessage,
{ attachedTo: _id, isPinned: true },
{ attachedTo: _id, isPinned: true, space: channelSpace },
(res: ActivityMessage[]) => {
pinnedMessagesCount = res.length
},
{ projection: { _id: 1, attachedTo: 1, isPinned: 1 } }
{ projection: { _id: 1, space: 1, attachedTo: 1, isPinned: 1 } }
)
$: pinnedThreadsQuery.query(
chunter.class.ThreadMessage,
{ objectId: _id, isPinned: true },
{ objectId: _id, isPinned: true, space: channelSpace },
(res: ThreadMessage[]) => {
pinnedThreadsCount = res.length
},
{ projection: { _id: 1, objectId: 1, isPinned: 1 } }
{ projection: { _id: 1, space: 1, objectId: 1, isPinned: 1 } }
)
function openMessagesPopup (ev: MouseEvent) {
showPopup(PinnedMessagesPopup, { attachedTo: _id, attachedToClass: _class }, eventToHTMLElement(ev), (result) => {
if (result == null) return
dispatch('select', result)
})
function openMessagesPopup (ev: MouseEvent): void {
showPopup(
PinnedMessagesPopup,
{ attachedTo: _id, attachedToClass: _class, space: channelSpace },
eventToHTMLElement(ev),
(result) => {
if (result == null) return
dispatch('select', result)
}
)
}
$: count = pinnedMessagesCount + pinnedThreadsCount

View File

@ -14,17 +14,18 @@
-->
<script lang="ts">
import { createQuery, getClient } from '@hcengineering/presentation'
import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
import activity, { ActivityMessage } from '@hcengineering/activity'
import { ActivityMessagePresenter, sortActivityMessages } from '@hcengineering/activity-resources'
import { ActionIcon, IconClose } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { ThreadMessage } from '@hcengineering/chunter'
import { Class, Doc, Ref, SortingOrder } from '@hcengineering/core'
import { Class, Doc, Ref, SortingOrder, Space } from '@hcengineering/core'
import chunter from '../plugin'
export let attachedTo: Ref<Doc>
export let attachedToClass: Ref<Class<Doc>>
export let space: Ref<Space>
const client = getClient()
const dispatch = createEventDispatcher()
@ -34,13 +35,17 @@
let pinnedMessages: ActivityMessage[] = []
let pinnedThreads: ThreadMessage[] = []
$: pinnedQuery.query(activity.class.ActivityMessage, { attachedTo, isPinned: true }, (res: ActivityMessage[]) => {
pinnedMessages = res
})
$: pinnedQuery.query(
activity.class.ActivityMessage,
{ attachedTo, isPinned: true, space },
(res: ActivityMessage[]) => {
pinnedMessages = res
}
)
$: pinnedThreadsQuery.query(
chunter.class.ThreadMessage,
{ objectId: attachedTo, isPinned: true },
{ objectId: attachedTo, isPinned: true, space },
(res: ThreadMessage[]) => {
pinnedThreads = res
}
@ -74,7 +79,7 @@
size="small"
icon={IconClose}
action={() => {
unpinMessage(message)
void unpinMessage(message)
}}
/>
</div>

View File

@ -17,12 +17,13 @@
import { Analytics } from '@hcengineering/analytics'
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
import chunter, { ChatMessage, ThreadMessage } from '@hcengineering/chunter'
import { PersonAccount } from '@hcengineering/contact'
import { Class, Doc, generateId, getCurrentAccount, Ref, type CommitResult } from '@hcengineering/core'
import { Class, Doc, generateId, Ref, type CommitResult } from '@hcengineering/core'
import { createQuery, DraftController, draftsStore, getClient, isSpace } from '@hcengineering/presentation'
import { EmptyMarkup } from '@hcengineering/text'
import { createEventDispatcher } from 'svelte'
import { getChannelSpace } from '../../utils'
export let object: Doc
export let chatMessage: ChatMessage | undefined = undefined
export let shouldSaveDraft: boolean = true
@ -42,7 +43,6 @@
? chunter.class.ThreadMessage
: chunter.class.ChatMessage
const createdMessageQuery = createQuery()
const account = getCurrentAccount() as PersonAccount
const draftKey = `${object._id}_${_class}`
const draftController = new DraftController<MessageDraft>(draftKey)
@ -59,12 +59,16 @@
let inputContent = currentMessage.message
$: if (currentDraft != null) {
createdMessageQuery.query(_class, { _id }, (result: ChatMessage[]) => {
if (result.length > 0 && _id !== chatMessage?._id) {
// Ouch we have got comment with same id created already.
clear()
createdMessageQuery.query(
_class,
{ _id, space: getChannelSpace(object._class, object._id, object.space) },
(result: ChatMessage[]) => {
if (result.length > 0 && _id !== chatMessage?._id) {
// Ouch we have got comment with same id created already.
clear()
}
}
})
)
} else {
createdMessageQuery.unsubscribe()
}
@ -188,7 +192,7 @@
bind:this={inputRef}
bind:content={inputContent}
{_class}
space={isSpace(object) ? object._id : object.space}
space={getChannelSpace(object._class, object._id, object.space)}
skipAttachmentsPreload={(currentMessage.attachments ?? 0) === 0}
bind:objectId={_id}
{shouldSaveDraft}

View File

@ -25,6 +25,7 @@
import ChatMessageInput from './ChatMessageInput.svelte'
import ChatMessagePresenter from './ChatMessagePresenter.svelte'
import { getChannelSpace } from '../../utils'
export let objectId: Ref<Doc>
export let object: Doc
@ -40,7 +41,7 @@
$: localStorage.setItem('activity-newest-first', JSON.stringify(activityOrderNewestFirst))
$: query.query(
chunter.class.ChatMessage,
{ attachedTo: objectId },
{ attachedTo: objectId, space: getChannelSpace(object._class, object._id, object.space) },
(res) => {
messages = res.sort((message) => (message?.isPinned ? -1 : 1))
loading = false

View File

@ -15,8 +15,8 @@
<script lang="ts">
import { Doc, Ref } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { Breadcrumbs, IconClose, Label, location as locationStore, Header } from '@hcengineering/ui'
import { createEventDispatcher, onDestroy } from 'svelte'
import { Breadcrumbs, Label, location as locationStore, Header } from '@hcengineering/ui'
import { onDestroy } from 'svelte'
import activity, { ActivityMessage, DisplayActivityMessage } from '@hcengineering/activity'
import { getMessageFromLoc, messageInFocus } from '@hcengineering/activity-resources'
import contact from '@hcengineering/contact'
@ -31,8 +31,6 @@
export let selectedMessageId: Ref<ActivityMessage> | undefined = undefined
export let showHeader: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
const hierarchy = client.getHierarchy()
@ -74,7 +72,14 @@
})
$: if (message !== undefined && dataProvider === undefined) {
dataProvider = new ChannelDataProvider(message._id, chunter.class.ThreadMessage, undefined, selectedMessageId, true)
dataProvider = new ChannelDataProvider(
undefined,
message.space,
message._id,
chunter.class.ThreadMessage,
selectedMessageId,
true
)
}
$: message &&

View File

@ -22,7 +22,7 @@ import activity, {
import { type Channel, type ChatMessage, type DirectMessage, type ThreadMessage } from '@hcengineering/chunter'
import contact, { getName, type Employee, type Person, type PersonAccount } from '@hcengineering/contact'
import { PersonIcon, employeeByIdStore } from '@hcengineering/contact-resources'
import {
import core, {
generateId,
getCurrentAccount,
type Account,
@ -527,3 +527,7 @@ export async function removeChannelAction (
export function isThreadMessage (message: ActivityMessage): message is ThreadMessage {
return message._class === chunter.class.ThreadMessage
}
export function getChannelSpace (_class: Ref<Class<Doc>>, _id: Ref<Doc>, space: Ref<Space>): Ref<Space> {
return getClient().getHierarchy().isDerived(_class, core.class.Space) ? (_id as Ref<Space>) : space
}

View File

@ -170,7 +170,7 @@ export async function getCommonNotificationTxes (
async function getTextPart (doc: Doc, control: TriggerControl): Promise<string | undefined> {
const TextPresenter = getTextPresenter(doc._class, control.hierarchy)
console.log({ _class: doc._class, presenter: TextPresenter })
if (TextPresenter === undefined) return
return await (
await getResource(TextPresenter.presenter)