mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
parent
72eb5564e1
commit
396dd3e7f4
@ -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' }
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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: {
|
||||
|
@ -19,7 +19,7 @@ export class BitrixClient {
|
||||
await fetch(`${this.url}/${method}${query}`, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'user-agent': 'anticrm'
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
).json()
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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', {
|
||||
|
@ -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>
|
@ -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>
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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] })
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user