From 626fb36e7a6bf497957749b49fa28678965c0270 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Mon, 13 Mar 2023 11:42:51 +0700 Subject: [PATCH] Bitrix import fixes (#2722) Signed-off-by: Andrey Sobolev --- dev/prod/public/config-dev.json | 6 ++ models/recruit/src/index.ts | 2 + .../src/components/Activity.svelte | 27 ++++++++- plugins/bitrix/package.json | 2 +- plugins/bitrix/src/sync.ts | 56 +++++++++++-------- plugins/bitrix/src/types.ts | 2 - plugins/bitrix/src/utils.ts | 34 ++++++----- .../src/components/ChannelsPresenter.svelte | 6 +- 8 files changed, 88 insertions(+), 47 deletions(-) create mode 100644 dev/prod/public/config-dev.json diff --git a/dev/prod/public/config-dev.json b/dev/prod/public/config-dev.json new file mode 100644 index 0000000000..0186e8c0d1 --- /dev/null +++ b/dev/prod/public/config-dev.json @@ -0,0 +1,6 @@ +{ + "ACCOUNTS_URL":"https://account.hc.engineering", + "COLLABORATOR_URL": "wss://collaborator.hc.engineering", + "UPLOAD_URL":"/files", + "MODEL_VERSION": null +} \ No newline at end of file diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 85ad506509..f7979fdb08 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -398,6 +398,7 @@ export function createModel (builder: Builder): void { key: '@applications', label: recruit.string.Applications }, + 'comments', '$lookup.company', '$lookup.company.$lookup.channels', 'location', @@ -427,6 +428,7 @@ export function createModel (builder: Builder): void { key: '@applications', label: recruit.string.Applications }, + 'comments', '$lookup.channels', { key: '@applications.modifiedOn', diff --git a/plugins/activity-resources/src/components/Activity.svelte b/plugins/activity-resources/src/components/Activity.svelte index 7eae703ab8..424c2b913f 100644 --- a/plugins/activity-resources/src/components/Activity.svelte +++ b/plugins/activity-resources/src/components/Activity.svelte @@ -19,7 +19,7 @@ import { getResource, IntlString } from '@hcengineering/platform' import { createQuery, getClient } from '@hcengineering/presentation' import notification from '@hcengineering/notification' - import { Component, Grid, IconActivity, Label, Scroller, Button, showPopup } from '@hcengineering/ui' + import { Component, Grid, IconActivity, Label, Scroller, Button, showPopup, Spinner } from '@hcengineering/ui' import { ActivityKey, activityKey, DisplayTx, newActivity } from '../activity' import TxView from './TxView.svelte' import { filterCollectionTxes } from '../utils' @@ -78,11 +78,18 @@ $: viewlets = new Map(allViewlets.map((r) => [activityKey(r.objectClass, r.txClass), r])) + let loading = false + function updateTxes (object: Doc): void { + loading = true activityQuery.update( object, (result) => { txes = filterCollectionTxes(result) + + if (txes.length > 0) { + loading = false + } }, SortingOrder.Descending, editableMap ?? new Map() @@ -141,7 +148,14 @@
- + +
{/if} @@ -173,7 +187,14 @@
- + + {#if selectedFilter === 'All'} {:else} diff --git a/plugins/bitrix/package.json b/plugins/bitrix/package.json index 907a3a473b..33d5889b22 100644 --- a/plugins/bitrix/package.json +++ b/plugins/bitrix/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/bitrix", - "version": "0.6.24", + "version": "0.6.26", "main": "lib/index.js", "author": "Anticrm Platform Contributors", "license": "EPL-2.0", diff --git a/plugins/bitrix/src/sync.ts b/plugins/bitrix/src/sync.ts index b70200afed..c1e5a85b8e 100644 --- a/plugins/bitrix/src/sync.ts +++ b/plugins/bitrix/src/sync.ts @@ -115,7 +115,6 @@ export async function syncDocument ( mixins[bitrix.mixin.BitrixSyncDoc] = { type: resultDoc.document.type, bitrixId: resultDoc.document.bitrixId, - rawData: resultDoc.rawData, syncTime: Date.now() } @@ -156,13 +155,18 @@ export async function syncDocument ( await syncClass(applyOp, gmail.class.Message, resultDoc.gmailDocuments, idMapping, emailReadId) } + const attachIds = Array.from( + new Set(resultDoc.blobs.map((it) => idMapping.get(it[0].attachedTo) ?? it[0].attachedTo)).values() + ) + const existingBlobs = await client.findAll(attachment.class.Attachment, { - attachedTo: resultDoc.document._id + attachedTo: { $in: [resultDoc.document._id, ...attachIds] } }) for (const [ed, op, upd] of resultDoc.blobs) { - const existing = existingBlobs.find( - (it) => hierarchy.as(it, bitrix.mixin.BitrixSyncDoc).bitrixId === ed.bitrixId - ) + const existing = existingBlobs.find((it) => { + const bdoc = hierarchy.as(it, bitrix.mixin.BitrixSyncDoc) + return bdoc.bitrixId === ed.bitrixId + }) // For Attachments, just do it once per attachment and assume it is not changed. if (existing === undefined) { const attachmentId: Ref = generateId() @@ -243,9 +247,10 @@ export async function syncDocument ( // Update document id, for existing document. valValue.attachedTo = resultDoc.document._id } - const existingIdx = existingByClass.findIndex( - (it) => hierarchy.as(it, bitrix.mixin.BitrixSyncDoc).bitrixId === valValue.bitrixId - ) + const existingIdx = existingByClass.findIndex((it) => { + const bdoc = hierarchy.as(it, bitrix.mixin.BitrixSyncDoc) + return bdoc.bitrixId === valValue.bitrixId && bdoc.type === valValue.type + }) let existing: Doc | undefined if (existingIdx >= 0) { existing = existingByClass.splice(existingIdx, 1).shift() @@ -277,15 +282,14 @@ export async function syncDocument ( existingM, { type: valValue.type, - bitrixId: valValue.bitrixId, - rawData: valValue.rawData + bitrixId: valValue.bitrixId }, bitrix.mixin.BitrixSyncDoc, valValue.modifiedBy, valValue.modifiedOn ) } else { - const { bitrixId, rawData, ...data } = valValue + const { bitrixId, ...data } = valValue await applyOp.addCollection( valValue._class, valValue.space, @@ -305,8 +309,7 @@ export async function syncDocument ( bitrix.mixin.BitrixSyncDoc, { type: valValue.type, - bitrixId: valValue.bitrixId, - rawData: valValue.rawData + bitrixId: valValue.bitrixId }, valValue.modifiedOn, valValue.modifiedBy @@ -322,7 +325,7 @@ export async function syncDocument ( return (await updateDoc(applyOp, existing, resultDoc.document, resultDoc.document.modifiedOn)) as BitrixSyncDoc // Go over extra documents. } else { - const { bitrixId, rawData, ...data } = resultDoc.document + const { bitrixId, ...data } = resultDoc.document const id = await applyOp.createDoc( resultDoc.document._class, resultDoc.document.space, @@ -499,7 +502,7 @@ async function doPerformSync (ops: SyncOptions & SyncOptionsExtra): Promise(tags.class.TagElement, {}) @@ -520,7 +523,8 @@ async function doPerformSync (ops: SyncOptions & SyncOptionsExtra): Promise(ops.mapping.ofClass, { - [bitrix.mixin.BitrixSyncDoc + '.bitrixId']: { $in: toProcess.map((it) => `${it.ID as string}`) } + [bitrix.mixin.BitrixSyncDoc + '.bitrixId']: { $in: toProcess.map((it) => `${it.ID as string}`) }, + [bitrix.mixin.BitrixSyncDoc + '.type']: ops.mapping.type }) const defaultCategories = await ops.client.findAll(tags.class.TagCategory, { default: true @@ -537,7 +541,7 @@ async function doPerformSync (ops: SyncOptions & SyncOptionsExtra): Promise syncTime) { - // No need to sync, sime sync time is not yet arrived. + // No need to sync, same sync time is not yet arrived. toProcess.splice(0, 1) added++ ops.monitor?.(result.total) @@ -657,13 +661,12 @@ async function performOrganizationContactSynchronization ( console.log('total', total) } }) - const existingContacts = await ops.client.findAll(contact.class.Member, { - attachedTo: extra.res.document._id, - contact: { $in: contacts.map((it) => it._id as unknown as Ref) } + const existingMembers = await ops.client.findAll(contact.class.Member, { + attachedTo: extra.res.document._id }) for (const c of contacts) { - const ex = existingContacts.find((e) => e.contact === (c._id as unknown as Ref)) - if (ex === undefined) { + const ex = existingMembers.findIndex((e) => e.contact === (c._id as unknown as Ref)) + if (ex === -1) { await ops.client.addCollection( contact.class.Member, extra.res.document.space, @@ -674,8 +677,15 @@ async function performOrganizationContactSynchronization ( contact: c._id as unknown as Ref } ) + } else { + // remove from list + existingMembers.splice(ex, 1) } } + // Remove not expected members + for (const ex of existingMembers) { + await ops.client.remove(ex) + } // We need to create Member's for organization contacts. } @@ -718,7 +728,6 @@ async function downloadComments ( message: processComment(it.COMMENT as string), bitrixId: `${it.ID as string}`, type: it.ENTITY_TYPE, - rawData: it, attachedTo: res.document._id, attachedToClass: res.document._class, collection: 'comments', @@ -796,7 +805,6 @@ async function downloadComments ( sendOn: new Date(comm.CREATED ?? new Date().toString()).getTime(), subject: comm.SUBJECT, bitrixId: `${comm.ID}`, - rawData: comm, from: comm.SETTINGS?.EMAIL_META?.from ?? '', to: comm.SETTINGS?.EMAIL_META?.to ?? '', replyTo: comm.SETTINGS?.EMAIL_META?.replyTo ?? comm.SETTINGS?.MESSAGE_HEADERS?.['Reply-To'] ?? '', diff --git a/plugins/bitrix/src/types.ts b/plugins/bitrix/src/types.ts index 017733b9c1..78076c0ef5 100644 --- a/plugins/bitrix/src/types.ts +++ b/plugins/bitrix/src/types.ts @@ -89,8 +89,6 @@ export interface BitrixSyncDoc extends Doc { type?: string bitrixId: string syncTime?: number - // raw bitrix document data. - rawData?: any } /** diff --git a/plugins/bitrix/src/utils.ts b/plugins/bitrix/src/utils.ts index 913ebf13b5..3632317150 100644 --- a/plugins/bitrix/src/utils.ts +++ b/plugins/bitrix/src/utils.ts @@ -65,7 +65,6 @@ export interface BitrixSyncRequest { */ export interface ConvertResult { document: BitrixSyncDoc // Document we should sync - rawData: any mixins: Record>, Data> // Mixins of document we will sync extraDocs: Doc[] // Extra documents we will sync, etc. extraSync: (AttachedDoc & BitrixSyncDoc)[] // Extra documents we will sync, etc. @@ -278,20 +277,26 @@ export async function convert ( } } } - const c: Channel & BitrixSyncDoc = { - _id: generateId(), - _class: contact.class.Channel, - attachedTo: document._id, - attachedToClass: attr.attributeOf, - collection: attr.name, - modifiedBy: document.modifiedBy, - value: svalue, - provider: f.provider, - space: document.space, - modifiedOn: document.modifiedOn, - bitrixId: svalue + const existingC = newExtraSyncDocs + .filter((it) => it._class === contact.class.Channel) + .map((it) => it as unknown as Channel) + .find((it) => it.value === svalue) + if (existingC === undefined) { + const c: Channel & BitrixSyncDoc = { + _id: generateId(), + _class: contact.class.Channel, + attachedTo: document._id, + attachedToClass: attr.attributeOf, + collection: attr.name, + modifiedBy: document.modifiedBy, + value: svalue, + provider: f.provider, + space: document.space, + modifiedOn: document.modifiedOn, + bitrixId: svalue + } + newExtraSyncDocs.push(c) } - newExtraSyncDocs.push(c) } } } @@ -484,7 +489,6 @@ export async function convert ( extraSync: newExtraSyncDocs, extraDocs: newExtraDocs, blobs, - rawData: rawDocument, syncRequests, gmailDocuments: [] } diff --git a/plugins/contact-resources/src/components/ChannelsPresenter.svelte b/plugins/contact-resources/src/components/ChannelsPresenter.svelte index 73c7ac466c..35a979e934 100644 --- a/plugins/contact-resources/src/components/ChannelsPresenter.svelte +++ b/plugins/contact-resources/src/components/ChannelsPresenter.svelte @@ -38,11 +38,13 @@ if (ev.detail.action !== undefined && Array.isArray(value)) { const action = await getResource(ev.detail.action as ViewAction) const channel = value.find((it) => it.value === ev.detail.value) - if (action !== undefined && channel !== undefined) { + if (action != null && channel != null) { action(channel, ev) } } } - +{#if value} + +{/if}