mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
1686 fix (#1690)
Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
parent
50ad39d037
commit
03cb718c72
@ -24,9 +24,9 @@ import type {
|
||||
Person,
|
||||
Persons
|
||||
} from '@anticrm/contact'
|
||||
import type { Domain, Ref } from '@anticrm/core'
|
||||
import type { Domain, Ref, Timestamp } from '@anticrm/core'
|
||||
import { DOMAIN_MODEL, IndexKind } from '@anticrm/core'
|
||||
import { Builder, Collection, Index, Model, Prop, TypeRef, TypeString, UX } from '@anticrm/model'
|
||||
import { Builder, Collection, Index, Model, Prop, TypeRef, TypeString, TypeTimestamp, UX } from '@anticrm/model'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
import chunter from '@anticrm/model-chunter'
|
||||
import core, { TAccount, TAttachedDoc, TDoc, TSpace } from '@anticrm/model-core'
|
||||
@ -70,7 +70,7 @@ export class TContact extends TDoc implements Contact {
|
||||
}
|
||||
|
||||
@Model(contact.class.Channel, core.class.AttachedDoc, DOMAIN_CHANNEL)
|
||||
@UX(contact.string.Channel, contact.icon.Person, undefined, 'modifiedOn')
|
||||
@UX(contact.string.Channel, contact.icon.Person, undefined, 'lastMessage')
|
||||
export class TChannel extends TAttachedDoc implements Channel {
|
||||
@Prop(TypeRef(contact.class.ChannelProvider), contact.string.ChannelProvider)
|
||||
provider!: Ref<ChannelProvider>
|
||||
@ -80,6 +80,9 @@ export class TChannel extends TAttachedDoc implements Channel {
|
||||
value!: string
|
||||
|
||||
items?: number
|
||||
|
||||
@Prop(TypeTimestamp(), core.string.Modified)
|
||||
lastMessage?: Timestamp
|
||||
}
|
||||
|
||||
@Model(contact.class.Person, contact.class.Contact)
|
||||
|
@ -30,6 +30,7 @@
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.6",
|
||||
"@anticrm/model-core": "~0.6.0",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/model-contact": "~0.6.1",
|
||||
"@anticrm/gmail": "~0.6.0",
|
||||
"@anticrm/gmail-resources": "~0.6.0",
|
||||
|
@ -1,6 +1,5 @@
|
||||
//
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
// Copyright © 2021 Hardcore Engineering Inc.
|
||||
// Copyright © 2022 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
|
||||
@ -15,12 +14,13 @@
|
||||
//
|
||||
|
||||
import activity from '@anticrm/activity'
|
||||
import { Domain, IndexKind, Timestamp, Type } from '@anticrm/core'
|
||||
import { Channel } from '@anticrm/contact'
|
||||
import { Class, Domain, IndexKind, Ref, Timestamp, Type } from '@anticrm/core'
|
||||
import type { Message, NewMessage, SharedMessage, SharedMessages } from '@anticrm/gmail'
|
||||
import { ArrOf, Builder, Collection, Index, Model, Prop, TypeBoolean, TypeString, TypeTimestamp } from '@anticrm/model'
|
||||
import contact from '@anticrm/model-contact'
|
||||
import core, { TDoc, TAttachedDoc } from '@anticrm/model-core'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
import contact from '@anticrm/model-contact'
|
||||
import core, { TAttachedDoc, TDoc } from '@anticrm/model-core'
|
||||
import setting from '@anticrm/setting'
|
||||
import gmail from './plugin'
|
||||
|
||||
@ -32,6 +32,9 @@ function TypeSharedMessage (): Type<SharedMessage> {
|
||||
|
||||
@Model(gmail.class.Message, core.class.AttachedDoc, DOMAIN_GMAIL)
|
||||
export class TMessage extends TAttachedDoc implements Message {
|
||||
declare attachedTo: Ref<Channel>
|
||||
declare attachedToClass: Ref<Class<Channel>>
|
||||
|
||||
@Prop(TypeString(), gmail.string.MessageID)
|
||||
messageId!: string
|
||||
|
||||
|
@ -29,4 +29,8 @@ export function createModel (builder: Builder): void {
|
||||
collectDocs: serverGmail.function.FindMessages
|
||||
}
|
||||
)
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverGmail.trigger.OnMessageCreate
|
||||
})
|
||||
}
|
||||
|
@ -29,4 +29,8 @@ export function createModel (builder: Builder): void {
|
||||
collectDocs: serverTelegram.function.FindMessages
|
||||
}
|
||||
)
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverTelegram.trigger.OnMessageCreate
|
||||
})
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
"@anticrm/model-core": "~0.6.0",
|
||||
"@anticrm/model-attachment": "~0.6.0",
|
||||
"@anticrm/model-contact": "~0.6.1",
|
||||
"@anticrm/contact": "~0.6.5",
|
||||
"@anticrm/telegram": "~0.6.2",
|
||||
"@anticrm/telegram-resources": "~0.6.0",
|
||||
"@anticrm/setting": "~0.6.1",
|
||||
|
@ -24,9 +24,10 @@ import type {
|
||||
SharedTelegramMessage,
|
||||
SharedTelegramMessages
|
||||
} from '@anticrm/telegram'
|
||||
import { Domain, IndexKind, Timestamp, Type } from '@anticrm/core'
|
||||
import { Class, Domain, IndexKind, Ref, Timestamp, Type } from '@anticrm/core'
|
||||
import setting from '@anticrm/setting'
|
||||
import activity from '@anticrm/activity'
|
||||
import { Channel } from '@anticrm/contact'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
|
||||
export const DOMAIN_TELEGRAM = 'telegram' as Domain
|
||||
@ -37,6 +38,9 @@ function TypeSharedMessage (): Type<SharedTelegramMessage> {
|
||||
|
||||
@Model(telegram.class.Message, core.class.AttachedDoc, DOMAIN_TELEGRAM)
|
||||
export class TTelegramMessage extends TAttachedDoc implements TelegramMessage {
|
||||
declare attachedTo: Ref<Channel>
|
||||
declare attachedToClass: Ref<Class<Channel>>
|
||||
|
||||
@Prop(TypeString(), telegram.string.Content)
|
||||
@Index(IndexKind.FullText)
|
||||
content!: string
|
||||
|
@ -13,9 +13,31 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import core, { TxOperations } from '@anticrm/core'
|
||||
import core, { SortingOrder, TxOperations } from '@anticrm/core'
|
||||
import telegram from './plugin'
|
||||
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
|
||||
import contact from '@anticrm/model-contact'
|
||||
|
||||
async function updateChannlLastMessage (client: TxOperations): Promise<void> {
|
||||
const channels = await client.findAll(contact.class.Channel, {
|
||||
provider: contact.channelProvider.Telegram
|
||||
})
|
||||
const targets = channels.filter((p) => p.lastMessage === undefined)
|
||||
for (const channel of targets) {
|
||||
const lastMessage = await client.findOne(
|
||||
telegram.class.Message,
|
||||
{
|
||||
attachedTo: channel._id
|
||||
},
|
||||
{ sort: { sendOn: SortingOrder.Descending } }
|
||||
)
|
||||
if (lastMessage !== undefined) {
|
||||
await client.updateDoc(channel._class, channel.space, channel._id, {
|
||||
lastMessage: lastMessage.sendOn
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const telegramOperation: MigrateOperation = {
|
||||
async migrate (client: MigrationClient): Promise<void> {},
|
||||
@ -38,5 +60,7 @@ export const telegramOperation: MigrateOperation = {
|
||||
telegram.space.Telegram
|
||||
)
|
||||
}
|
||||
|
||||
await updateChannlLastMessage(tx)
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +73,9 @@
|
||||
}
|
||||
|
||||
function isNew (item: Channel, lastViews: Map<Ref<Doc>, Timestamp>): boolean {
|
||||
if (item.lastMessage === undefined) return false
|
||||
const lastView = (item as Channel)._id !== undefined ? lastViews.get((item as Channel)._id) : undefined
|
||||
return lastView ? lastView < item.modifiedOn : (item.items ?? 0) > 0
|
||||
return lastView ? lastView < item.lastMessage : (item.items ?? 0) > 0
|
||||
}
|
||||
|
||||
async function update (value: AttachedData<Channel>[] | Channel | null, lastViews: Map<Ref<Doc>, Timestamp>) {
|
||||
|
@ -65,8 +65,9 @@
|
||||
}
|
||||
|
||||
function isNew (item: Channel, lastViews: Map<Ref<Doc>, Timestamp>): boolean {
|
||||
if (item.lastMessage === undefined) return false
|
||||
const lastView = (item as Channel)._id !== undefined ? lastViews.get((item as Channel)._id) : undefined
|
||||
return lastView ? lastView < item.modifiedOn : (item.items ?? 0) > 0
|
||||
return lastView ? lastView < item.lastMessage : (item.items ?? 0) > 0
|
||||
}
|
||||
|
||||
async function update (value: AttachedData<Channel>[] | Channel | null, lastViews: Map<Ref<Doc>, Timestamp>) {
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
FindResult,
|
||||
Ref,
|
||||
Space,
|
||||
Timestamp,
|
||||
UXObject
|
||||
} from '@anticrm/core'
|
||||
import type { Asset, Plugin } from '@anticrm/platform'
|
||||
@ -56,6 +57,7 @@ export interface Channel extends AttachedDoc {
|
||||
provider: Ref<ChannelProvider>
|
||||
value: string
|
||||
items?: number
|
||||
lastMessage?: Timestamp
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,11 +18,14 @@ import type { Plugin } from '@anticrm/platform'
|
||||
import type { Doc, Ref, Class, Space, AttachedDoc, Timestamp } from '@anticrm/core'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import type { IntegrationType, Handler } from '@anticrm/setting'
|
||||
import { Channel } from '@anticrm/contact'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Message extends BaseMessage, AttachedDoc {
|
||||
attachedTo: Ref<Channel>
|
||||
attachedToClass: Ref<Class<Channel>>
|
||||
messageId: string
|
||||
from: string
|
||||
textContent: string
|
||||
|
@ -18,6 +18,7 @@ import type { Plugin } from '@anticrm/platform'
|
||||
import type { Doc, Ref, Class, Space, AttachedDoc, Timestamp } from '@anticrm/core'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import type { IntegrationType, Handler } from '@anticrm/setting'
|
||||
import { Channel } from '@anticrm/contact'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -31,6 +32,9 @@ export interface BaseTelegramMessage extends Doc {
|
||||
* @public
|
||||
*/
|
||||
export interface TelegramMessage extends BaseTelegramMessage, AttachedDoc {
|
||||
attachedTo: Ref<Channel>
|
||||
attachedToClass: Ref<Class<Channel>>
|
||||
|
||||
incoming: boolean
|
||||
|
||||
sendOn: Timestamp
|
||||
|
@ -14,8 +14,38 @@
|
||||
//
|
||||
|
||||
import contact, { Channel } from '@anticrm/contact'
|
||||
import gmail from '@anticrm/gmail'
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import core, {
|
||||
AttachedDoc,
|
||||
Class,
|
||||
Doc,
|
||||
DocumentQuery,
|
||||
FindOptions,
|
||||
FindResult,
|
||||
Hierarchy,
|
||||
Ref,
|
||||
Tx,
|
||||
TxCollectionCUD,
|
||||
TxCreateDoc,
|
||||
TxProcessor
|
||||
} from '@anticrm/core'
|
||||
import gmail, { Message } from '@anticrm/gmail'
|
||||
import { TriggerControl } from '@anticrm/server-core'
|
||||
|
||||
const extractTx = (tx: Tx): Tx => {
|
||||
if (tx._class === core.class.TxCollectionCUD) {
|
||||
const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>
|
||||
if (ctx.tx._class === core.class.TxCreateDoc) {
|
||||
const create = ctx.tx as TxCreateDoc<AttachedDoc>
|
||||
create.attributes.attachedTo = ctx.objectId
|
||||
create.attributes.attachedToClass = ctx.objectClass
|
||||
create.attributes.collection = ctx.collection
|
||||
return create
|
||||
}
|
||||
return ctx.tx
|
||||
}
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -33,13 +63,45 @@ export async function FindMessages (
|
||||
if (channel.provider !== contact.channelProvider.Email) {
|
||||
return []
|
||||
}
|
||||
const messages = await findAll(gmail.class.Message, { attachedTo: doc._id })
|
||||
const newMessages = await findAll(gmail.class.NewMessage, { attachedTo: doc._id })
|
||||
const messages = await findAll(gmail.class.Message, { attachedTo: channel._id })
|
||||
const newMessages = await findAll(gmail.class.NewMessage, { attachedTo: channel._id })
|
||||
return [...messages, ...newMessages]
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnMessageCreate (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
const actualTx = extractTx(tx)
|
||||
if (actualTx._class !== core.class.TxCreateDoc) {
|
||||
return []
|
||||
}
|
||||
|
||||
const createTx = tx as TxCreateDoc<Message>
|
||||
|
||||
if (!control.hierarchy.isDerived(createTx.objectClass, gmail.class.Message)) {
|
||||
return []
|
||||
}
|
||||
const message = TxProcessor.createDoc2Doc<Message>(createTx)
|
||||
|
||||
const channel = (await control.findAll(contact.class.Channel, { _id: message.attachedTo }, { limit: 1 }))[0]
|
||||
if (channel === undefined) {
|
||||
return []
|
||||
}
|
||||
if (channel.lastMessage === undefined || channel.lastMessage < message.sendOn) {
|
||||
const tx = control.txFactory.createTxUpdateDoc(channel._class, channel.space, channel._id, {
|
||||
lastMessage: message.sendOn
|
||||
})
|
||||
return [tx]
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnMessageCreate
|
||||
},
|
||||
function: {
|
||||
FindMessages
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.6"
|
||||
"@anticrm/platform": "~0.6.6",
|
||||
"@anticrm/server-core": "~0.6.1"
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import type { Plugin, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import { TriggerFunc } from '@anticrm/server-core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -27,6 +28,9 @@ export const serverGmailId = 'server-gmail' as Plugin
|
||||
* @public
|
||||
*/
|
||||
export default plugin(serverGmailId, {
|
||||
trigger: {
|
||||
OnMessageCreate: '' as Resource<TriggerFunc>
|
||||
},
|
||||
function: {
|
||||
FindMessages: '' as Resource<
|
||||
(
|
||||
|
@ -32,7 +32,7 @@ const extractTx = (tx: Tx): Tx => {
|
||||
create.attributes.collection = ctx.collection
|
||||
return create
|
||||
}
|
||||
return ctx
|
||||
return ctx.tx
|
||||
}
|
||||
|
||||
return tx
|
||||
|
@ -14,8 +14,38 @@
|
||||
//
|
||||
|
||||
import contact, { Channel } from '@anticrm/contact'
|
||||
import telegram from '@anticrm/telegram'
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import core, {
|
||||
AttachedDoc,
|
||||
Class,
|
||||
Doc,
|
||||
DocumentQuery,
|
||||
FindOptions,
|
||||
FindResult,
|
||||
Hierarchy,
|
||||
Ref,
|
||||
Tx,
|
||||
TxCollectionCUD,
|
||||
TxCreateDoc,
|
||||
TxProcessor
|
||||
} from '@anticrm/core'
|
||||
import { TriggerControl } from '@anticrm/server-core'
|
||||
import telegram, { TelegramMessage } from '@anticrm/telegram'
|
||||
|
||||
const extractTx = (tx: Tx): Tx => {
|
||||
if (tx._class === core.class.TxCollectionCUD) {
|
||||
const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>
|
||||
if (ctx.tx._class === core.class.TxCreateDoc) {
|
||||
const create = ctx.tx as TxCreateDoc<AttachedDoc>
|
||||
create.attributes.attachedTo = ctx.objectId
|
||||
create.attributes.attachedToClass = ctx.objectClass
|
||||
create.attributes.collection = ctx.collection
|
||||
return create
|
||||
}
|
||||
return ctx.tx
|
||||
}
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -33,13 +63,45 @@ export async function FindMessages (
|
||||
if (channel.provider !== contact.channelProvider.Telegram) {
|
||||
return []
|
||||
}
|
||||
const messages = await findAll(telegram.class.Message, { attachedTo: doc._id })
|
||||
const newMessages = await findAll(telegram.class.NewMessage, { attachedTo: doc._id })
|
||||
const messages = await findAll(telegram.class.Message, { attachedTo: channel._id })
|
||||
const newMessages = await findAll(telegram.class.NewMessage, { attachedTo: channel._id })
|
||||
return [...messages, ...newMessages]
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnMessageCreate (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
const actualTx = extractTx(tx)
|
||||
if (actualTx._class !== core.class.TxCreateDoc) {
|
||||
return []
|
||||
}
|
||||
|
||||
const createTx = tx as TxCreateDoc<TelegramMessage>
|
||||
|
||||
if (!control.hierarchy.isDerived(createTx.objectClass, telegram.class.Message)) {
|
||||
return []
|
||||
}
|
||||
const message = TxProcessor.createDoc2Doc<TelegramMessage>(createTx)
|
||||
|
||||
const channel = (await control.findAll(contact.class.Channel, { _id: message.attachedTo }, { limit: 1 }))[0]
|
||||
if (channel === undefined) {
|
||||
return []
|
||||
}
|
||||
if (channel.lastMessage === undefined || channel.lastMessage < message.sendOn) {
|
||||
const tx = control.txFactory.createTxUpdateDoc(channel._class, channel.space, channel._id, {
|
||||
lastMessage: message.sendOn
|
||||
})
|
||||
return [tx]
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnMessageCreate
|
||||
},
|
||||
function: {
|
||||
FindMessages
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.6"
|
||||
"@anticrm/platform": "~0.6.6",
|
||||
"@anticrm/server-core": "~0.6.1"
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import type { Plugin, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import { TriggerFunc } from '@anticrm/server-core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -27,6 +28,9 @@ export const serverTelegramId = 'server-telegram' as Plugin
|
||||
* @public
|
||||
*/
|
||||
export default plugin(serverTelegramId, {
|
||||
trigger: {
|
||||
OnMessageCreate: '' as Resource<TriggerFunc>
|
||||
},
|
||||
function: {
|
||||
FindMessages: '' as Resource<
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user