mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-25 18:02:04 +00:00
Fix telegram/gmail notifications (#4976)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
b7775cb26c
commit
ecf2a5193a
@ -292,6 +292,18 @@ export function createModel (builder: Builder): void {
|
||||
provider: contact.function.PersonTooltipProvider
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Channel, core.class.Class, view.mixin.ObjectIdentifier, {
|
||||
provider: contact.function.ChannelIdentifierProvider
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Channel, core.class.Class, view.mixin.ObjectTitle, {
|
||||
titleProvider: contact.function.ChannelTitleProvider
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Channel, core.class.Class, view.mixin.ObjectIcon, {
|
||||
component: contact.component.ChannelIcon
|
||||
})
|
||||
|
||||
builder.createDoc(
|
||||
workbench.class.Application,
|
||||
core.space.Model,
|
||||
|
@ -60,7 +60,8 @@ export default mergeIds(contactId, contact, {
|
||||
ActivityChannelPresenter: '' as AnyComponent,
|
||||
EmployeeFilter: '' as AnyComponent,
|
||||
EmployeeFilterValuePresenter: '' as AnyComponent,
|
||||
PersonAccountFilterValuePresenter: '' as AnyComponent
|
||||
PersonAccountFilterValuePresenter: '' as AnyComponent,
|
||||
ChannelIcon: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
Persons: '' as IntlString,
|
||||
@ -137,6 +138,8 @@ export default mergeIds(contactId, contact, {
|
||||
GetContactName: '' as Resource<TemplateFieldFunc>,
|
||||
GetContactFirstName: '' as Resource<TemplateFieldFunc>,
|
||||
GetContactLastName: '' as Resource<TemplateFieldFunc>,
|
||||
ContactTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
||||
ContactTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>,
|
||||
ChannelTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>,
|
||||
ChannelIdentifierProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
||||
}
|
||||
})
|
||||
|
@ -176,6 +176,19 @@ export function createModel (builder: Builder): void {
|
||||
gmail.ids.TxSharedCreate
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
activity.class.DocUpdateMessageViewlet,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass: gmail.class.Message,
|
||||
icon: contact.icon.Email,
|
||||
action: 'create',
|
||||
component: gmail.activity.GmailWriteMessage,
|
||||
label: gmail.string.HaveWrittenEmail
|
||||
},
|
||||
gmail.ids.GmailWriteMessageActivityViewlet
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
activity.class.TxViewlet,
|
||||
core.space.Model,
|
||||
@ -192,6 +205,20 @@ export function createModel (builder: Builder): void {
|
||||
gmail.ids.TxSharedCreate
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
activity.class.DocUpdateMessageViewlet,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass: gmail.class.SharedMessages,
|
||||
icon: contact.icon.Email,
|
||||
action: 'create',
|
||||
component: gmail.activity.GmailSharedMessage,
|
||||
label: gmail.string.SharedMessages,
|
||||
hideIfRemoved: true
|
||||
},
|
||||
gmail.ids.GmailSharedMessageActivityViewlet
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ import { type IntlString, mergeIds, type Resource } from '@hcengineering/platfor
|
||||
import { gmailId } from '@hcengineering/gmail'
|
||||
import gmail from '@hcengineering/gmail-resources/src/plugin'
|
||||
import type { AnyComponent } from '@hcengineering/ui/src/types'
|
||||
import type { TxViewlet } from '@hcengineering/activity'
|
||||
import type { DocUpdateMessageViewlet, TxViewlet } from '@hcengineering/activity'
|
||||
import { type Action } from '@hcengineering/view'
|
||||
import { type NotificationGroup } from '@hcengineering/notification'
|
||||
|
||||
@ -45,11 +45,15 @@ export default mergeIds(gmailId, gmail, {
|
||||
ids: {
|
||||
TxSharedCreate: '' as Ref<TxViewlet>,
|
||||
NewMessageNotification: '' as Ref<TxViewlet>,
|
||||
EmailNotificationGroup: '' as Ref<NotificationGroup>
|
||||
EmailNotificationGroup: '' as Ref<NotificationGroup>,
|
||||
GmailSharedMessageActivityViewlet: '' as Ref<DocUpdateMessageViewlet>,
|
||||
GmailWriteMessageActivityViewlet: '' as Ref<DocUpdateMessageViewlet>
|
||||
},
|
||||
activity: {
|
||||
TxSharedCreate: '' as AnyComponent,
|
||||
TxWriteMessage: '' as AnyComponent
|
||||
TxWriteMessage: '' as AnyComponent,
|
||||
GmailSharedMessage: '' as AnyComponent,
|
||||
GmailWriteMessage: '' as AnyComponent
|
||||
},
|
||||
function: {
|
||||
HasEmail: '' as Resource<(doc?: Doc | Doc[] | undefined) => Promise<boolean>>
|
||||
|
@ -144,7 +144,7 @@ export function createModel (builder: Builder): void {
|
||||
action: 'create',
|
||||
icon: contact.icon.Telegram,
|
||||
component: telegram.activity.TelegramMessageCreated,
|
||||
label: telegram.string.SharedMessages
|
||||
label: telegram.string.SharedMessage
|
||||
},
|
||||
telegram.ids.TelegramMessageCreatedActivityViewlet
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ import {
|
||||
getDocLinkTitle,
|
||||
hasAttributePresenter
|
||||
} from '@hcengineering/view-resources'
|
||||
import { type Person } from '@hcengineering/contact'
|
||||
import contact, { type Person } from '@hcengineering/contact'
|
||||
import { type IntlString } from '@hcengineering/platform'
|
||||
import { type AnyComponent } from '@hcengineering/ui'
|
||||
import { get } from 'svelte/store'
|
||||
@ -220,20 +220,42 @@ function combineByCreateThreshold (docUpdateMessages: DocUpdateMessage[]): DocUp
|
||||
})
|
||||
}
|
||||
|
||||
function wrapMessages (
|
||||
hierarchy: Hierarchy,
|
||||
messages: ActivityMessage[]
|
||||
): { toCombine: DocUpdateMessage[], uncombined: ActivityMessage[] } {
|
||||
const toCombine: DocUpdateMessage[] = []
|
||||
const uncombined: ActivityMessage[] = []
|
||||
|
||||
for (const message of messages) {
|
||||
if (isDocUpdateMessage(message)) {
|
||||
if (hierarchy.isDerived(message.attachedToClass, contact.class.Channel)) {
|
||||
uncombined.push(message)
|
||||
} else {
|
||||
toCombine.push(message)
|
||||
}
|
||||
} else {
|
||||
uncombined.push(message)
|
||||
}
|
||||
}
|
||||
|
||||
return { toCombine, uncombined }
|
||||
}
|
||||
|
||||
export async function combineActivityMessages (
|
||||
messages: ActivityMessage[],
|
||||
sortingOrder: SortingOrder = SortingOrder.Ascending
|
||||
): Promise<DisplayActivityMessage[]> {
|
||||
const client = getClient()
|
||||
const uncombinedMessages = messages.filter((message) => message._class !== activity.class.DocUpdateMessage)
|
||||
|
||||
const docUpdateMessages = combineByCreateThreshold(messages.filter(isDocUpdateMessage))
|
||||
const { uncombined, toCombine } = wrapMessages(client.getHierarchy(), messages)
|
||||
const docUpdateMessages = combineByCreateThreshold(toCombine)
|
||||
|
||||
if (docUpdateMessages.length === 0) {
|
||||
return sortActivityMessages(uncombinedMessages, sortingOrder)
|
||||
return sortActivityMessages(uncombined, sortingOrder)
|
||||
}
|
||||
|
||||
const result: Array<DisplayActivityMessage | undefined> = [...uncombinedMessages]
|
||||
const result: Array<DisplayActivityMessage | undefined> = [...uncombined]
|
||||
|
||||
const groupedByType: Map<string, DocUpdateMessage[]> = groupByArray(docUpdateMessages, getDocUpdateMessageKey)
|
||||
|
||||
|
@ -185,11 +185,14 @@
|
||||
<ShowMore>
|
||||
<div class="customContent">
|
||||
{#each value?.previousMessages ?? [] as msg}
|
||||
<Component is={viewlet.component} props={{ message: msg, _id: msg.objectId, _class: msg.objectClass }} />
|
||||
<Component
|
||||
is={viewlet.component}
|
||||
props={{ message: msg, _id: msg.objectId, _class: msg.objectClass, onClick }}
|
||||
/>
|
||||
{/each}
|
||||
<Component
|
||||
is={viewlet.component}
|
||||
props={{ message: value, _id: value.objectId, _class: value.objectClass, value: object }}
|
||||
props={{ message: value, _id: value.objectId, _class: value.objectClass, value: object, onClick }}
|
||||
/>
|
||||
</div>
|
||||
</ShowMore>
|
||||
|
@ -22,6 +22,7 @@ import attachment, { type SavedAttachments } from '@hcengineering/attachment'
|
||||
import activity from '@hcengineering/activity'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { type Action, showPopup } from '@hcengineering/ui'
|
||||
import contact from '@hcengineering/contact'
|
||||
|
||||
import { type ChatNavGroupModel, type ChatNavItemModel } from './types'
|
||||
import chunter from '../../plugin'
|
||||
@ -115,7 +116,8 @@ export const chatNavGroupModels: ChatNavGroupModel[] = [
|
||||
query: {
|
||||
isPinned: { $ne: true },
|
||||
attachedToClass: {
|
||||
$nin: [chunter.class.DirectMessage, chunter.class.Channel]
|
||||
// Ignore external channels until support is provided for them
|
||||
$nin: [chunter.class.DirectMessage, chunter.class.Channel, contact.class.Channel]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
plugins/contact-resources/src/components/ChannelIcon.svelte
Normal file
40
plugins/contact-resources/src/components/ChannelIcon.svelte
Normal file
@ -0,0 +1,40 @@
|
||||
<!--
|
||||
// Copyright © 2024 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Channel, ChannelProvider } from '@hcengineering/contact'
|
||||
import { Icon, IconSize } from '@hcengineering/ui'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { classIcon } from '@hcengineering/view-resources'
|
||||
|
||||
import contact from '../plugin'
|
||||
|
||||
export let value: Channel | undefined
|
||||
export let size: IconSize = 'small'
|
||||
|
||||
const client = getClient()
|
||||
|
||||
let provider: ChannelProvider | undefined = undefined
|
||||
|
||||
$: value &&
|
||||
client.findOne(contact.class.ChannelProvider, { _id: value.provider }).then((res) => {
|
||||
provider = res
|
||||
})
|
||||
|
||||
$: icon = provider?.icon ?? classIcon(client, contact.class.Channel)
|
||||
</script>
|
||||
|
||||
{#if icon}
|
||||
<Icon {size} {icon} />
|
||||
{/if}
|
@ -18,10 +18,12 @@
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { AnyComponent, Component } from '@hcengineering/ui'
|
||||
import { channelProviders } from '../utils'
|
||||
import { DocUpdateMessage } from '@hcengineering/activity'
|
||||
|
||||
export let _id: Ref<Channel>
|
||||
export let _class: Ref<Class<Channel>>
|
||||
export let embedded: boolean = false
|
||||
export let activityMessage: DocUpdateMessage | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
|
||||
@ -45,7 +47,14 @@
|
||||
{#if presenter}
|
||||
<Component
|
||||
is={presenter}
|
||||
props={{ embedded, _id: channel?.attachedTo, _class: channel?.attachedToClass, channel }}
|
||||
props={{
|
||||
embedded,
|
||||
_id: channel?.attachedTo,
|
||||
_class: channel?.attachedToClass,
|
||||
channel,
|
||||
messageId: activityMessage?.objectId
|
||||
}}
|
||||
on:close
|
||||
/>
|
||||
{/if}
|
||||
{/await}
|
||||
|
@ -104,9 +104,12 @@ import SelectUsersPopup from './components/SelectUsersPopup.svelte'
|
||||
import IconAddMember from './components/icons/AddMember.svelte'
|
||||
import UserDetails from './components/UserDetails.svelte'
|
||||
import EditOrganizationPanel from './components/EditOrganizationPanel.svelte'
|
||||
import ChannelIcon from './components/ChannelIcon.svelte'
|
||||
|
||||
import contact from './plugin'
|
||||
import {
|
||||
channelIdentifierProvider,
|
||||
channelTitleProvider,
|
||||
contactTitleProvider,
|
||||
employeeSort,
|
||||
filterChannelHasMessagesResult,
|
||||
@ -334,7 +337,8 @@ export default async (): Promise<Resources> => ({
|
||||
DeleteConfirmationPopup,
|
||||
PersonAccountRefPresenter,
|
||||
PersonIcon,
|
||||
EditOrganizationPanel
|
||||
EditOrganizationPanel,
|
||||
ChannelIcon
|
||||
},
|
||||
completion: {
|
||||
EmployeeQuery: async (
|
||||
@ -377,7 +381,9 @@ export default async (): Promise<Resources> => ({
|
||||
GetContactLastName: getContactLastName,
|
||||
GetContactLink: getContactLink,
|
||||
ContactTitleProvider: contactTitleProvider,
|
||||
PersonTooltipProvider: getPersonTooltip
|
||||
PersonTooltipProvider: getPersonTooltip,
|
||||
ChannelTitleProvider: channelTitleProvider,
|
||||
ChannelIdentifierProvider: channelIdentifierProvider
|
||||
},
|
||||
resolver: {
|
||||
Location: resolveLocation
|
||||
|
@ -26,7 +26,8 @@ import {
|
||||
formatName,
|
||||
getFirstName,
|
||||
getLastName,
|
||||
getName
|
||||
getName,
|
||||
type Channel
|
||||
} from '@hcengineering/contact'
|
||||
import {
|
||||
type Client,
|
||||
@ -41,7 +42,7 @@ import {
|
||||
type Class
|
||||
} from '@hcengineering/core'
|
||||
import notification, { type DocNotifyContext, type InboxNotification } from '@hcengineering/notification'
|
||||
import { getEmbeddedLabel, getResource } from '@hcengineering/platform'
|
||||
import { getEmbeddedLabel, getResource, translate } from '@hcengineering/platform'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { type TemplateDataProvider } from '@hcengineering/templates'
|
||||
import {
|
||||
@ -402,3 +403,22 @@ export function getPersonTooltip (client: Client, value: Person | null | undefin
|
||||
label: getEmbeddedLabel(getName(hierarchy, value))
|
||||
}
|
||||
}
|
||||
|
||||
export async function channelIdentifierProvider (client: Client, ref: Ref<Channel>, doc?: Channel): Promise<string> {
|
||||
const channel = doc ?? (await client.findOne(contact.class.Channel, { _id: ref }))
|
||||
if (channel === undefined) return ''
|
||||
|
||||
const provider = await client.findOne(contact.class.ChannelProvider, { _id: channel.provider })
|
||||
|
||||
if (provider === undefined) return channel.value
|
||||
|
||||
return await translate(provider.label, {})
|
||||
}
|
||||
|
||||
export async function channelTitleProvider (client: Client, ref: Ref<Channel>, doc?: Channel): Promise<string> {
|
||||
const channel = doc ?? (await client.findOne(contact.class.Channel, { _id: ref }))
|
||||
|
||||
if (channel === undefined) return ''
|
||||
|
||||
return channel.value
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<script lang="ts">
|
||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||
import { employeeByIdStore } from '@hcengineering/contact-resources'
|
||||
import { getCurrentAccount } from '@hcengineering/core'
|
||||
import { getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import { Message, SharedMessage } from '@hcengineering/gmail'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
@ -33,28 +33,41 @@
|
||||
import IntegrationSelector from './IntegrationSelector.svelte'
|
||||
import NewMessage from './NewMessage.svelte'
|
||||
|
||||
export let channel: Channel
|
||||
export let channel: Channel | undefined
|
||||
// export let embedded = false
|
||||
export let message: Message | undefined = undefined
|
||||
export let messageId: Ref<Message> | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const inboxClient = InboxNotificationsClientImpl.getClient()
|
||||
|
||||
const messageQuery = createQuery()
|
||||
|
||||
let object: Contact
|
||||
let gmailMessage: Message | undefined = message
|
||||
let currentMessage: SharedMessage | undefined = undefined
|
||||
|
||||
let newMessage: boolean = false
|
||||
let integrations: Integration[] = []
|
||||
let selectedIntegration: Integration | undefined = undefined
|
||||
|
||||
inboxClient.forceReadDoc(getClient(), channel._id, channel._class)
|
||||
channel && inboxClient.forceReadDoc(getClient(), channel._id, channel._class)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const query = createQuery()
|
||||
$: query.query(channel.attachedToClass, { _id: channel.attachedTo }, (result) => {
|
||||
object = result[0] as Contact
|
||||
})
|
||||
$: channel &&
|
||||
query.query(channel.attachedToClass, { _id: channel.attachedTo }, (result) => {
|
||||
object = result[0] as Contact
|
||||
})
|
||||
|
||||
$: if (message === undefined && messageId !== undefined) {
|
||||
messageQuery.query(gmail.class.Message, { _id: messageId }, (result) => {
|
||||
gmailMessage = result[0] as Message
|
||||
})
|
||||
} else {
|
||||
gmailMessage = message
|
||||
}
|
||||
|
||||
function back () {
|
||||
if (newMessage) {
|
||||
@ -87,10 +100,10 @@
|
||||
selectedIntegration = integrations.find((p) => p.createdBy === me) ?? integrations[0]
|
||||
})
|
||||
|
||||
$: message &&
|
||||
$: gmailMessage &&
|
||||
channel &&
|
||||
object &&
|
||||
convertMessage(object, channel, message, $employeeByIdStore).then((p) => (currentMessage = p))
|
||||
convertMessage(object, channel, gmailMessage, $employeeByIdStore).then((p) => (currentMessage = p))
|
||||
</script>
|
||||
|
||||
{#if channel && object}
|
||||
|
@ -0,0 +1,46 @@
|
||||
<!--
|
||||
// Copyright © 2024 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { SharedMessages } from '@hcengineering/gmail'
|
||||
|
||||
import gmail from '../../plugin'
|
||||
import SharedMessagesView from '../SharedMessages.svelte'
|
||||
|
||||
export let _id: Ref<SharedMessages> | undefined = undefined
|
||||
export let value: SharedMessages | undefined = undefined
|
||||
|
||||
const query = createQuery()
|
||||
|
||||
let doc: SharedMessages | undefined = undefined
|
||||
|
||||
$: loadObject(_id, value)
|
||||
|
||||
function loadObject (_id?: Ref<SharedMessages>, value?: SharedMessages): void {
|
||||
if (value === undefined && _id !== undefined) {
|
||||
query.query(gmail.class.SharedMessages, { _id }, (res) => {
|
||||
doc = res[0]
|
||||
})
|
||||
} else {
|
||||
doc = value
|
||||
query.unsubscribe()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if doc}
|
||||
<SharedMessagesView value={doc} />
|
||||
{/if}
|
@ -0,0 +1,69 @@
|
||||
<!--
|
||||
// Copyright © 2024 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
import { Message } from '@hcengineering/gmail'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
|
||||
import gmail from '../../plugin'
|
||||
import Main from '../Main.svelte'
|
||||
|
||||
export let _id: Ref<Message> | undefined = undefined
|
||||
export let value: Message | undefined = undefined
|
||||
|
||||
export let onClick: ((ev: MouseEvent) => void) | undefined = undefined
|
||||
const query = createQuery()
|
||||
|
||||
let doc: Message | undefined = undefined
|
||||
|
||||
$: loadObject(_id, value)
|
||||
|
||||
function loadObject (_id?: Ref<Message>, value?: Message): void {
|
||||
if (value === undefined && _id !== undefined) {
|
||||
query.query(gmail.class.Message, { _id }, (res) => {
|
||||
doc = res[0]
|
||||
})
|
||||
} else {
|
||||
doc = value
|
||||
query.unsubscribe()
|
||||
}
|
||||
}
|
||||
|
||||
async function click (ev: MouseEvent): Promise<void> {
|
||||
ev.stopPropagation()
|
||||
|
||||
if (onClick) {
|
||||
onClick(ev)
|
||||
return
|
||||
}
|
||||
|
||||
if (doc === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
const channel = await client.findOne(doc.attachedToClass, { _id: doc.attachedTo })
|
||||
if (channel !== undefined) {
|
||||
showPopup(Main, { channel, message: doc }, 'float')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if doc}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<span class="over-underline overflow-label" on:click={click}>{doc.subject}</span>
|
||||
{/if}
|
@ -19,6 +19,8 @@ import { getMetadata, type Resources } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import TxSharedCreate from './components/activity/TxSharedCreate.svelte'
|
||||
import TxWriteMessage from './components/activity/TxWriteMessage.svelte'
|
||||
import GmailWriteMessage from './components/activity/GmailWriteMessage.svelte'
|
||||
import GmailSharedMessage from './components/activity/GmailSharedMessage.svelte'
|
||||
import Configure from './components/Configure.svelte'
|
||||
import Connect from './components/Connect.svelte'
|
||||
import IconGmail from './components/icons/GmailColor.svelte'
|
||||
@ -37,7 +39,9 @@ export default async (): Promise<Resources> => ({
|
||||
},
|
||||
activity: {
|
||||
TxSharedCreate,
|
||||
TxWriteMessage
|
||||
TxWriteMessage,
|
||||
GmailWriteMessage,
|
||||
GmailSharedMessage
|
||||
},
|
||||
function: {
|
||||
HasEmail: checkHasEmail
|
||||
|
@ -22,24 +22,25 @@
|
||||
import view, { Viewlet } from '@hcengineering/view'
|
||||
import {
|
||||
AnyComponent,
|
||||
ButtonWithDropdown,
|
||||
Component,
|
||||
defineSeparators,
|
||||
IconDropdown,
|
||||
Label,
|
||||
Loading,
|
||||
location as locationStore,
|
||||
Location,
|
||||
Scroller,
|
||||
Separator,
|
||||
TabItem,
|
||||
TabList,
|
||||
Location,
|
||||
IconDropdown,
|
||||
ButtonWithDropdown
|
||||
TabList
|
||||
} from '@hcengineering/ui'
|
||||
import chunter, { ThreadMessage } from '@hcengineering/chunter'
|
||||
import { Ref, WithLookup } from '@hcengineering/core'
|
||||
import { ViewletSelector } from '@hcengineering/view-resources'
|
||||
import activity, { ActivityMessage } from '@hcengineering/activity'
|
||||
import { isReactionMessage } from '@hcengineering/activity-resources'
|
||||
import { get } from 'svelte/store'
|
||||
|
||||
import { inboxMessagesStore, InboxNotificationsClientImpl } from '../../inboxNotificationsClient'
|
||||
import Filter from '../Filter.svelte'
|
||||
@ -99,6 +100,8 @@
|
||||
let viewlet: WithLookup<Viewlet> | undefined
|
||||
let loading = true
|
||||
|
||||
let selectedMessage: ActivityMessage | undefined = undefined
|
||||
|
||||
void client.findAll(notification.class.ActivityNotificationViewlet, {}).then((res) => {
|
||||
viewlets = res
|
||||
})
|
||||
@ -136,6 +139,17 @@
|
||||
if (selectedContextId !== selectedContext?._id) {
|
||||
selectedContext = undefined
|
||||
}
|
||||
|
||||
const selectedMessageId = loc?.loc.query?.message as Ref<ActivityMessage> | undefined
|
||||
|
||||
if (selectedMessageId !== undefined) {
|
||||
selectedMessage = get(inboxClient.activityInboxNotifications).find(
|
||||
({ attachedTo }) => attachedTo === selectedMessageId
|
||||
)?.$lookup?.attachedTo
|
||||
if (selectedMessage === undefined) {
|
||||
selectedMessage = await client.findOne(activity.class.ActivityMessage, { _id: selectedMessageId })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$: selectedContext = selectedContextId
|
||||
@ -368,6 +382,7 @@
|
||||
_class: selectedContext.attachedToClass,
|
||||
embedded: true,
|
||||
context: selectedContext,
|
||||
activityMessage: selectedMessage,
|
||||
props: { context: selectedContext }
|
||||
}}
|
||||
on:close={() => selectContext(undefined)}
|
||||
|
@ -0,0 +1,51 @@
|
||||
<!--
|
||||
// Copyright © 2024 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.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createQuery, MessageViewer } from '@hcengineering/presentation'
|
||||
import { TelegramMessage } from '@hcengineering/telegram'
|
||||
import { Ref } from '@hcengineering/core'
|
||||
|
||||
import telegram from '../plugin'
|
||||
|
||||
export let _id: Ref<TelegramMessage> | undefined = undefined
|
||||
export let value: TelegramMessage | undefined = undefined
|
||||
|
||||
const query = createQuery()
|
||||
|
||||
let doc: TelegramMessage | undefined = undefined
|
||||
|
||||
$: if (value === undefined && _id !== undefined) {
|
||||
query.query(telegram.class.Message, { _id }, (res) => {
|
||||
doc = res[0]
|
||||
})
|
||||
} else {
|
||||
doc = value
|
||||
query.unsubscribe()
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if doc}
|
||||
<div class="content lines-limit-2">
|
||||
<MessageViewer message={doc.content} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
min-width: 0;
|
||||
min-height: 1rem;
|
||||
max-height: 2.125rem;
|
||||
}
|
||||
</style>
|
@ -25,6 +25,7 @@ import TxMessage from './components/activity/TxMessage.svelte'
|
||||
import IconTelegram from './components/icons/TelegramColor.svelte'
|
||||
import TxSharedCreate from './components/activity/TxSharedCreate.svelte'
|
||||
import TelegramMessageCreated from './components/activity/TelegramMessageCreated.svelte'
|
||||
import MessagePresenter from './components/MessagePresenter.svelte'
|
||||
|
||||
import telegram from './plugin'
|
||||
import { getCurrentEmployeeTG, getIntegrationOwnerTG } from './utils'
|
||||
@ -36,7 +37,8 @@ export default async (): Promise<Resources> => ({
|
||||
Connect,
|
||||
Reconnect,
|
||||
IconTelegram,
|
||||
SharedMessages
|
||||
SharedMessages,
|
||||
MessagePresenter
|
||||
},
|
||||
activity: {
|
||||
TxSharedCreate,
|
||||
|
@ -618,7 +618,7 @@ export function makeViewletKey (loc?: Location): string {
|
||||
loc.query = undefined
|
||||
|
||||
// TODO: make better fix. Just temporary fix for correct inbox viewlets.
|
||||
if (loc.path[2] === 'inbox') {
|
||||
if (loc.path[2] === 'notification') {
|
||||
loc.path = loc.path.slice(0, 3)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user