diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index f59a7b6ea3..c95db4bba2 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -48,7 +48,7 @@ export class TContact extends TDoc implements Contact { @Index(IndexKind.FullText) name!: string - avatar?: string + avatar?: string | null @Prop(Collection(contact.class.Channel), contact.string.ContactInfo) channels?: number diff --git a/packages/presentation/lang/en.json b/packages/presentation/lang/en.json index 11105ac236..263b820aa2 100644 --- a/packages/presentation/lang/en.json +++ b/packages/presentation/lang/en.json @@ -8,6 +8,8 @@ "Close": "Close", "NotSelected": "Not selected", "Deselect": "Deselect", - "AddSocialLinks": "Add social links" + "AddSocialLinks": "Add social links", + "Change": "Change", + "Remove": "Remove" } } diff --git a/packages/presentation/lang/ru.json b/packages/presentation/lang/ru.json index 314cf407ac..4d379b637b 100644 --- a/packages/presentation/lang/ru.json +++ b/packages/presentation/lang/ru.json @@ -8,6 +8,8 @@ "Close": "Закрыть", "NotSelected": "Не выбрано", "Deselect": "Снять выделение", - "AddSocialLinks": "Добавить контактную информацию" + "AddSocialLinks": "Добавить контактную информацию", + "Change": "Изменить", + "Remove": "Удалить" } } diff --git a/packages/presentation/src/components/Avatar.svelte b/packages/presentation/src/components/Avatar.svelte index 5b2a42427c..e9dbcbf7f2 100644 --- a/packages/presentation/src/components/Avatar.svelte +++ b/packages/presentation/src/components/Avatar.svelte @@ -18,7 +18,7 @@ import { getBlobURL, getFileUrl } from '../utils' - export let avatar: string | undefined = undefined + export let avatar: string | null | undefined = undefined export let direct: Blob | undefined = undefined export let size: 'x-small' | 'small' | 'medium' | 'large' | 'x-large' @@ -27,7 +27,7 @@ getBlobURL(direct).then((blobURL) => { url = blobURL }) - } else if (avatar !== undefined) { + } else if (avatar !== undefined && avatar !== null) { url = getFileUrl(avatar) } else { url = undefined diff --git a/packages/presentation/src/components/EditAvatarPopup.svelte b/packages/presentation/src/components/EditAvatarPopup.svelte index 489bf0eda9..cdd69b4823 100644 --- a/packages/presentation/src/components/EditAvatarPopup.svelte +++ b/packages/presentation/src/components/EditAvatarPopup.svelte @@ -19,27 +19,57 @@ import imageCropper from '@anticrm/image-cropper' import plugin from '../plugin' - export let file: File + export let file: Blob + let inputRef: HTMLInputElement + const targetMimes = ['image/png', 'image/jpg', 'image/jpeg'] const dispatch = createEventDispatcher() const CropperP = getResource(imageCropper.component.Cropper) let cropper: any + function onSelect (e: any) { + const newFile = e.target?.files[0] as File | undefined + if (newFile === undefined || !targetMimes.includes(newFile.type)) { + return + } + file = newFile + + e.target.value = null + } + async function onCrop () { const res = await cropper.crop() dispatch('close', res) } + + async function remove () { + dispatch('close', null) + } + + + function selectAnother () { + inputRef.click() + } +
{ dispatch('close') }} />
{#await CropperP then Cropper}
- +
+
+
+
{/await}
@@ -85,5 +115,6 @@ .footer { display: flex; flex-direction: row-reverse; + padding: 1rem 1.5rem; } diff --git a/packages/presentation/src/components/EditableAvatar.svelte b/packages/presentation/src/components/EditableAvatar.svelte index 4bde15251a..cc06db0540 100644 --- a/packages/presentation/src/components/EditableAvatar.svelte +++ b/packages/presentation/src/components/EditableAvatar.svelte @@ -15,13 +15,13 @@ {#if object !== undefined}
{#if editable} - + {:else} {/if} diff --git a/plugins/contact-resources/src/components/OrganizationEditor.svelte b/plugins/contact-resources/src/components/OrganizationEditor.svelte index 9588933d23..bc9bc62239 100644 --- a/plugins/contact-resources/src/components/OrganizationEditor.svelte +++ b/plugins/contact-resources/src/components/OrganizationEditor.svelte @@ -34,7 +34,7 @@ return { _id: org._id, label: org.name, - image: org.avatar + image: org.avatar === null ? undefined : org.avatar } }) if (value !== undefined) { diff --git a/plugins/contact-resources/src/components/OrganizationSelector.svelte b/plugins/contact-resources/src/components/OrganizationSelector.svelte index 20f4549dfb..ceda7204b4 100644 --- a/plugins/contact-resources/src/components/OrganizationSelector.svelte +++ b/plugins/contact-resources/src/components/OrganizationSelector.svelte @@ -39,7 +39,7 @@ return { _id: org._id, label: org.name, - image: org.avatar + image: org.avatar === null ? undefined : org.avatar } }) if (value !== undefined) { diff --git a/plugins/contact/src/index.ts b/plugins/contact/src/index.ts index f8a92c2e19..29cb4de4c2 100644 --- a/plugins/contact/src/index.ts +++ b/plugins/contact/src/index.ts @@ -51,7 +51,7 @@ export interface Channel extends AttachedDoc { */ export interface Contact extends Doc { name: string - avatar?: string + avatar?: string | null attachments?: number comments?: number channels?: number diff --git a/plugins/image-cropper-resources/src/components/Cropper.svelte b/plugins/image-cropper-resources/src/components/Cropper.svelte index 2593fd3964..168fe5aba4 100644 --- a/plugins/image-cropper-resources/src/components/Cropper.svelte +++ b/plugins/image-cropper-resources/src/components/Cropper.svelte @@ -16,13 +16,13 @@ import Cropper from 'cropperjs' import smartcrop from 'smartcrop' -export let image: File +export let image: Blob export let cropSize = 1200 let imgRef: HTMLImageElement let cropper: Cropper | undefined -async function init () { +async function init (image: Blob) { const bitmap = await createImageBitmap(image) const canvas = document.createElement('canvas') canvas.height = bitmap.height @@ -42,6 +42,10 @@ async function init () { const initialArea = (await smartcrop.crop(canvas, { width: 100, height: 100 })).topCrop + if (cropper !== undefined) { + cropper.destroy() + cropper = undefined + } const cropperInst = new Cropper(imgRef, { aspectRatio: 1, viewMode: 1, @@ -82,7 +86,7 @@ export async function crop () {
img - {#await init()} + {#await init(image)} Waiting... {/await}
diff --git a/plugins/recruit-resources/src/components/CreateCandidate.svelte b/plugins/recruit-resources/src/components/CreateCandidate.svelte index 867db73243..b68778b443 100644 --- a/plugins/recruit-resources/src/components/CreateCandidate.svelte +++ b/plugins/recruit-resources/src/components/CreateCandidate.svelte @@ -113,12 +113,13 @@ }) async function createCandidate () { - const uploadFile = await getResource(attachment.helper.UploadFile) - const avatarProp = avatar !== undefined ? { avatar: await uploadFile(avatar) } : {} const candidate: Data = { name: combineName(firstName, lastName), - city: object.city, - ...avatarProp + city: object.city + } + if (avatar !== undefined) { + const uploadFile = await getResource(attachment.helper.UploadFile) + candidate.avatar = await uploadFile(avatar) } const candidateData: MixinData = { title: object.title, @@ -381,6 +382,10 @@ $: findPerson(client, { ...object, name: combineName(firstName, lastName) }, channels).then((p) => { matches = p }) + + function removeAvatar (): void { + avatar = undefined + }
- +
diff --git a/plugins/setting-resources/src/components/Profile.svelte b/plugins/setting-resources/src/components/Profile.svelte index c41acb5f69..25bb8a0c24 100644 --- a/plugins/setting-resources/src/components/Profile.svelte +++ b/plugins/setting-resources/src/components/Profile.svelte @@ -63,6 +63,17 @@ avatar: uuid }) } + + async function removeAvatar (): Promise { + if (employee === undefined) return + const deleteFile = await getResource(attachment.helper.DeleteFile) + if (employee.avatar != null) { + await client.updateDoc(employee._class, employee.space, employee._id, { + avatar: null + }) + await deleteFile(employee.avatar) + } + }
@@ -73,7 +84,7 @@ {#if employee}
- +