Minor fixes (#2490)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-01-05 11:45:38 +07:00 committed by GitHub
parent 72eb5564e1
commit 396dd3e7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 192 additions and 67 deletions

View File

@ -87,7 +87,7 @@ export function createModel (builder: Builder): void {
},
label: bitrix.string.BitrixImport,
icon: bitrix.icon.Bitrix,
input: 'any',
input: 'none',
category: view.category.General,
target: core.class.Doc,
context: { mode: ['workbench', 'browser', 'editor', 'panel', 'popup'], group: 'create' }

View File

@ -87,7 +87,7 @@
async function createAttachment (file: File) {
try {
const uuid = await uploadFile(file, { space, attachedTo: objectId })
const uuid = await uploadFile(file)
const _id: Ref<Attachment> = generateId()
attachments.set(_id, {
_id,

View File

@ -112,7 +112,7 @@
async function createAttachment (file: File) {
if (space === undefined || objectId === undefined || _class === undefined) return
try {
const uuid = await uploadFile(file, { space, attachedTo: objectId })
const uuid = await uploadFile(file)
const _id: Ref<Attachment> = generateId()
attachments.set(_id, {
_id,

View File

@ -47,7 +47,7 @@
if (!file.type.startsWith('image/')) return
loading++
try {
const uuid = await uploadFile(file, { space, attachedTo: objectId })
const uuid = await uploadFile(file)
client.addCollection(attachment.class.Photo, space, objectId, _class, 'photos', {
name: file.name,
file: uuid,

View File

@ -21,7 +21,7 @@ import { getMetadata, setPlatformStatus, unknownError } from '@hcengineering/pla
import attachment from './plugin'
export async function uploadFile (file: File, opts?: { space: Ref<Space>, attachedTo: Ref<Doc> }): Promise<string> {
export async function uploadFile (file: File): Promise<string> {
const uploadUrl = getMetadata(login.metadata.UploadUrl)
if (uploadUrl === undefined) {
@ -31,20 +31,7 @@ export async function uploadFile (file: File, opts?: { space: Ref<Space>, attach
const data = new FormData()
data.append('file', file)
const params =
opts !== undefined
? [
['space', opts.space],
['attachedTo', opts.attachedTo]
]
.filter((x): x is [string, Ref<any>] => x[1] !== undefined)
.map(([name, value]) => `${name}=${value}`)
.join('&')
: ''
const suffix = params === '' ? params : `?${params}`
const url = `${uploadUrl}${suffix}`
const resp = await fetch(url, {
const resp = await fetch(uploadUrl, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + (getMetadata(login.metadata.LoginToken) as string)
@ -87,7 +74,7 @@ export async function createAttachments (
for (let index = 0; index < list.length; index++) {
const file = list.item(index)
if (file !== null) {
const uuid = await uploadFile(file, { space, attachedTo: objectId })
const uuid = await uploadFile(file)
await client.addCollection(attachmentClass, space, objectId, objectClass, 'attachments', {
...extraData,
name: file.name,

View File

@ -14,7 +14,7 @@
// limitations under the License.
//
import type { AttachedDoc, Class, Doc, Ref, Space } from '@hcengineering/core'
import type { AttachedDoc, Class, Ref } from '@hcengineering/core'
import type { Asset, Plugin } from '@hcengineering/platform'
import { IntlString, plugin, Resource } from '@hcengineering/platform'
import type { Preference } from '@hcengineering/preference'
@ -66,7 +66,7 @@ export default plugin(attachmentId, {
SavedAttachments: '' as Ref<Class<SavedAttachments>>
},
helper: {
UploadFile: '' as Resource<(file: File, opts?: { space: Ref<Space>, attachedTo: Ref<Doc> }) => Promise<string>>,
UploadFile: '' as Resource<(file: File) => Promise<string>>,
DeleteFile: '' as Resource<(id: string) => Promise<void>>
},
string: {

View File

@ -19,7 +19,7 @@ export class BitrixClient {
await fetch(`${this.url}/${method}${query}`, {
method: 'get',
headers: {
'user-agent': 'anticrm'
'Content-Type': 'application/json'
}
})
).json()

View File

@ -56,6 +56,12 @@
action: (_: any, evt: MouseEvent) => {
addMapping(evt, MappingOperation.CreateChannel)
}
},
{
label: getEmbeddedLabel('Add Download Attachment mapping'),
action: (_: any, evt: MouseEvent) => {
addMapping(evt, MappingOperation.DownloadAttachment)
}
}
] as Action[]
</script>

View File

@ -29,7 +29,7 @@
let items: any[] = []
function loadItems (order: boolean): void {
bitrixClient
.call(mapping.type + '.list', { select: ['*', 'UF_*'], order: { ID: order ? 'ASC' : 'DSC' } })
.call(mapping.type + '.list', { select: ['*', 'UF_*', 'EMAIL', 'IM'], order: { ID: order ? 'ASC' : 'DSC' } })
.then((res) => {
items = res.result
})

View File

@ -7,6 +7,7 @@
import CopyMapping from './mappings/CopyMapping.svelte'
import CreateChannelMapping from './mappings/CreateChannelMapping.svelte'
import CreateTagMapping from './mappings/CreateTagMapping.svelte'
import DownloadAttachmentMapping from './mappings/DownloadAttachmentMapping.svelte'
export let mapping: BitrixEntityMapping
export let fields: Fields = {}
@ -16,7 +17,7 @@
$: _kind = kind ?? field?.operation.kind
let op: CopyMapping | CreateTagMapping | CreateChannelMapping
let op: CopyMapping | CreateTagMapping | CreateChannelMapping | DownloadAttachmentMapping
async function save (): Promise<void> {
op.save()
@ -39,5 +40,7 @@
<CreateTagMapping {mapping} {fields} {attribute} {field} bind:this={op} />
{:else if _kind === MappingOperation.CreateChannel}
<CreateChannelMapping {mapping} {fields} {attribute} {field} bind:this={op} />
{:else if _kind === MappingOperation.DownloadAttachment}
<DownloadAttachmentMapping {mapping} {fields} {attribute} {field} bind:this={op} />
{/if}
</Card>

View File

@ -6,6 +6,7 @@
import CopyMappingPresenter from './mappings/CopyMappingPresenter.svelte'
import CreateChannelMappingPresenter from './mappings/CreateChannelMappingPresenter.svelte'
import CreateTagMappingPresenter from './mappings/CreateTagMappingPresenter.svelte'
import DownloadAttachmentPresenter from './mappings/DownloadAttachmentPresenter.svelte'
export let mapping: BitrixEntityMapping
export let value: BitrixFieldMapping
@ -29,6 +30,8 @@
<CreateTagMappingPresenter {mapping} {value} />
{:else if kind === MappingOperation.CreateChannel}
<CreateChannelMappingPresenter {mapping} {value} />
{:else if kind === MappingOperation.DownloadAttachment}
<DownloadAttachmentPresenter {mapping} {value} />
{/if}
{/if}
</div>

View File

@ -252,8 +252,13 @@
let added = 0
while (added <= limit) {
const sel = ['*', 'UF_*']
if (mapping.type === BitrixEntityType.Lead) {
sel.push('EMAIL')
sel.push('IM')
}
const result = await bitrixClient.call(mapping.type + '.list', {
select: ['*', 'UF_*'],
select: sel,
order: { ID: direction },
start: processed
})
@ -261,18 +266,11 @@
const extraDocs: Doc[] = []
const convertResults: ConvertResult[] = []
const fields = mapping.$lookup?.fields as BitrixFieldMapping[]
for (const r of result.result) {
// Convert documents.
const res = await convert(
client,
mapping,
space,
mapping.$lookup?.fields as BitrixFieldMapping[],
r,
extraDocs,
tagElements,
userList
)
const res = await convert(client, mapping, space, fields, r, extraDocs, tagElements, userList)
if (mapping.comments) {
res.comments = bitrixClient
.call(BitrixEntityType.Comment + '.list', {

View File

@ -0,0 +1,100 @@
<script lang="ts">
import {
BitrixEntityMapping,
BitrixFieldMapping,
DownloadAttachmentOperation,
Fields,
MappingOperation
} from '@hcengineering/bitrix'
import { AnyAttribute } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import { Button, DropdownTextItem, IconAdd, IconDelete } from '@hcengineering/ui'
import DropdownLabels from '@hcengineering/ui/src/components/DropdownLabels.svelte'
import bitrix from '../../plugin'
export let mapping: BitrixEntityMapping
export let fields: Fields = {}
export let attribute: AnyAttribute
export let field: BitrixFieldMapping | undefined
let downloadFields: { field: string }[] = [...((field?.operation as DownloadAttachmentOperation)?.fields ?? [])]
const client = getClient()
export async function save (): Promise<void> {
if (field !== undefined) {
await client.update(field, {
operation: {
kind: MappingOperation.DownloadAttachment,
fields: downloadFields
}
})
} else {
await client.addCollection(bitrix.class.FieldMapping, mapping.space, mapping._id, mapping._class, 'fields', {
ofClass: attribute.attributeOf,
attributeName: attribute.name,
operation: {
kind: MappingOperation.DownloadAttachment,
fields: downloadFields
}
})
}
}
function getItems (fields: Fields): DropdownTextItem[] {
return Object.entries(fields)
.filter((it) => it[1].type === 'file')
.map((it) => ({
id: it[0],
label: `${it[1].formLabel ?? it[1].title}${it[0].startsWith('UF_') ? ' *' : ''} - ${it[0]}`
}))
}
$: items = getItems(fields)
</script>
<div class="flex-col flex-wrap">
{#each downloadFields as p, i}
<div class="pattern flex-row-center gap-2">
<DropdownLabels minW0={false} label={bitrix.string.FieldMapping} {items} bind:selected={p.field} />
<div class="ml-1">
<Button
icon={IconDelete}
size={'small'}
on:click={() => {
downloadFields.splice(i, 1)
downloadFields = downloadFields
}}
/>
</div>
</div>
{/each}
<div class="ml-2">
<Button
icon={IconAdd}
size={'small'}
on:click={() => {
downloadFields = [...downloadFields, { field: items[0].id }]
}}
/>
</div>
</div>
<style lang="scss">
.pattern {
margin: 0.5rem;
padding: 0.5rem;
flex-shrink: 0;
border: 1px dashed var(--accent-color);
border-radius: 0.25rem;
font-weight: 500;
font-size: 0.75rem;
// text-transform: uppercase;
color: var(--accent-color);
&:hover {
color: var(--caption-color);
}
}
</style>

View File

@ -0,0 +1,37 @@
<script lang="ts">
import { BitrixEntityMapping, BitrixFieldMapping, DownloadAttachmentOperation } from '@hcengineering/bitrix'
export let mapping: BitrixEntityMapping
export let value: BitrixFieldMapping
$: op = value.operation as DownloadAttachmentOperation
</script>
<div class="flex flex-wrap">
{#each op.fields as p, i}
<div class="pattern flex-row-center gap-2">
{#if mapping.bitrixFields}
{p.field ? mapping.bitrixFields[p.field]?.formLabel ?? mapping.bitrixFields[p.field]?.title : p.field ?? ''}
{/if}
</div>
{/each}
</div>
<style lang="scss">
.pattern {
margin: 0.1rem;
padding: 0.3rem;
flex-shrink: 0;
border: 1px dashed var(--accent-color);
border-radius: 0.25rem;
font-weight: 500;
font-size: 0.75rem;
// text-transform: uppercase;
color: var(--accent-color);
&:hover {
color: var(--caption-color);
}
}
</style>

View File

@ -97,7 +97,8 @@ export interface BitrixEntityMapping extends Doc {
export enum MappingOperation {
CopyValue,
CreateTag, // Create tag
CreateChannel // Create channel
CreateChannel, // Create channel
DownloadAttachment
}
/**
* @public
@ -149,6 +150,15 @@ export interface CreateChannelOperation {
fields: ChannelFieldMapping[]
}
/**
* @public
*/
export interface DownloadAttachmentOperation {
kind: MappingOperation.DownloadAttachment
fields: { field: string }[]
}
/**
* @public
*/
@ -156,7 +166,7 @@ export interface BitrixFieldMapping extends AttachedDoc {
ofClass: Ref<Class<Doc>> // Specify mixin if applicable
attributeName: string
operation: CopyValueOperation | CreateTagOperation | CreateChannelOperation
operation: CopyValueOperation | CreateTagOperation | CreateChannelOperation | DownloadAttachmentOperation
}
/**

View File

@ -90,7 +90,7 @@
async function createAttachment (file: File) {
try {
const uploadFile = await getResource(attachmentP.helper.UploadFile)
const uuid = await uploadFile(file, { space: plugin.space.Gmail, attachedTo: objectId })
const uuid = await uploadFile(file)
await client.addCollection(
attachmentP.class.Attachment,
plugin.space.Gmail,

View File

@ -294,11 +294,15 @@ export function navigateToWorkspace (workspace: string, loginInfo?: WorkspaceLog
if (navigateUrl !== undefined) {
const loc = JSON.parse(decodeURIComponent(navigateUrl)) as Location
const url = JSON.parse(decodeURIComponent(loc.query?.navigateUrl ?? '')) as Location
if (url.path[1] === workspace) {
navigate(url)
try {
const url = JSON.parse(decodeURIComponent(loc.query?.navigateUrl ?? '{}')) as Location
if (url.path[1] === workspace) {
navigate(url)
return
return
}
} catch (err: any) {
// Json parse error could be ignored
}
}
navigate({ path: [workbenchId, workspace] })

View File

@ -456,10 +456,7 @@
try {
const uploadFile = await getResource(attachment.helper.UploadFile)
resume.uuid = await uploadFile(file, {
space: contact.space.Contacts,
attachedTo: candidateId
})
resume.uuid = await uploadFile(file)
resume.name = file.name
resume.size = file.size
resume.type = file.type

View File

@ -243,26 +243,6 @@ export function start (
const token = authHeader.split(' ')[1]
const payload = decodeToken(token)
const uuid = await minioUpload(config.minio, payload.workspace, file)
// console.log('uploaded uuid', uuid)
// const space = req.query.space as Ref<Space> | undefined
// const attachedTo = req.query.attachedTo as Ref<Doc> | undefined
// if (space !== undefined && attachedTo !== undefined) {
// const elastic = await createElasticAdapter(config.elasticUrl, payload.workspace)
// const indexedDoc: IndexedDoc = {
// id: uuid as Ref<Doc>,
// _class: attachment.class.Attachment,
// space,
// modifiedOn: Date.now(),
// modifiedBy: 'core:account:System' as Ref<Account>,
// attachedTo,
// data: file.data.toString('base64')
// }
// await elastic.index(indexedDoc)
// }
res.status(200).send(uuid)
} catch (error) {