dropzone upload

This commit is contained in:
Lone Iversen
2024-03-27 14:03:16 +01:00
parent 6a29f350de
commit fbcb69d18f
3 changed files with 99 additions and 11 deletions

View File

@@ -6,3 +6,5 @@ export * from './workspace/index.js';
export * from './repository/index.js';
export * from './tree/types.js';
export * from './types.js';
export * from './utils/index.js';

View File

@@ -0,0 +1,28 @@
export enum UmbMediaTypeFileType {
SVG = 'Vector Graphics (SVG)',
IMAGE = 'Image',
AUDIO = 'Audio',
VIDEO = 'Video',
ARTICLE = 'Article',
FILE = 'File',
}
export function getMediaTypeByFileExtension(extension: string) {
if (extension === 'svg') return UmbMediaTypeFileType.SVG;
if (['jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff', 'tif', 'webp'].includes(extension))
return UmbMediaTypeFileType.IMAGE;
if (['mp3', 'weba', 'oga', 'opus'].includes(extension)) return UmbMediaTypeFileType.AUDIO;
if (['mp4', 'webm', 'ogv'].includes(extension)) return UmbMediaTypeFileType.VIDEO;
if (['pdf', 'docx', 'doc'].includes(extension)) return UmbMediaTypeFileType.ARTICLE;
return UmbMediaTypeFileType.FILE;
}
export function getMediaTypeByFileMimeType(mimetype: string) {
if (mimetype === 'image/svg+xml') return UmbMediaTypeFileType.SVG;
const [type, extension] = mimetype.split('/');
if (type === 'image') return UmbMediaTypeFileType.IMAGE;
if (type === 'audio') return UmbMediaTypeFileType.AUDIO;
if (type === 'video') return UmbMediaTypeFileType.VIDEO;
if (['pdf', 'docx', 'doc'].includes(extension)) return UmbMediaTypeFileType.ARTICLE;
return UmbMediaTypeFileType.FILE;
}

View File

@@ -1,16 +1,34 @@
import type { UmbMediaDetailModel } from '../types.js';
import { type UmbMediaTreeStore, UMB_MEDIA_TREE_STORE_CONTEXT } from '../tree/media-tree.store.js';
import type { UmbMediaCollectionContext } from './media-collection.context.js';
import { css, customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { UmbCollectionDefaultElement } from '@umbraco-cms/backoffice/collection';
import { UMB_DEFAULT_COLLECTION_CONTEXT, UmbCollectionDefaultElement } from '@umbraco-cms/backoffice/collection';
import './media-collection-toolbar.element.js';
import type { UUIFileDropzoneEvent } from '@umbraco-cms/backoffice/external/uui';
import { UmbTemporaryFileManager, type UmbTemporaryFileQueueModel } from '@umbraco-cms/backoffice/temporary-file';
import { UMB_MEDIA_ENTITY_TYPE, UmbMediaDetailRepository } from '@umbraco-cms/backoffice/media';
import { UmbTemporaryFileManager } from '@umbraco-cms/backoffice/temporary-file';
import { UmbId } from '@umbraco-cms/backoffice/id';
import { getMediaTypeByFileMimeType, UmbMediaTypeStructureRepository } from '@umbraco-cms/backoffice/media-type';
@customElement('umb-media-collection')
export class UmbMediaCollectionElement extends UmbCollectionDefaultElement {
#fileManager = new UmbTemporaryFileManager(this);
#mediaTypeStructure = new UmbMediaTypeStructureRepository(this);
#mediaDetailRepository = new UmbMediaDetailRepository(this);
#mediaCollection?: UmbMediaCollectionContext;
#mediaTreeStore?: UmbMediaTreeStore;
constructor() {
super();
this.consumeContext(UMB_DEFAULT_COLLECTION_CONTEXT, (instance) => {
this.#mediaCollection = instance as UmbMediaCollectionContext;
});
this.consumeContext(UMB_MEDIA_TREE_STORE_CONTEXT, (instance) => {
this.#mediaTreeStore = instance;
console.log('instance is here', instance);
});
document.addEventListener('dragenter', this.#handleDragEnter.bind(this));
document.addEventListener('dragleave', this.#handleDragLeave.bind(this));
document.addEventListener('drop', this.#handleDrop.bind(this));
@@ -38,26 +56,66 @@ export class UmbMediaCollectionElement extends UmbCollectionDefaultElement {
}
async #onFileUpload(event: UUIFileDropzoneEvent) {
const files: Array<UmbTemporaryFileQueueModel> = event.detail.files.map((file) => ({ file, unique: UmbId.new() }));
/** TODO: Move dropzone and logic into its own component, so that we can reuse it in more places... */
const files: Array<File> = event.detail.files;
if (!files.length) return;
const items = await this.#fileManager.upload(files);
if (!items.length) return;
const { data } = await this.#mediaTypeStructure.requestAllowedChildrenOf(null);
if (!data) return;
console.log('uploadComplete', items);
for (const file of files) {
const mediaTypeDetailUnique = UmbId.new();
const mediaTypeName = getMediaTypeByFileMimeType(file.type);
const mediaType = data.items.find((type) => type.name === mediaTypeName)!;
const mediaTempFileUnique = UmbId.new();
const uploaded = await this.#fileManager.uploadOne({ file, unique: mediaTempFileUnique });
if (uploaded.find((item) => item.status === 'error')) return;
const model: UmbMediaDetailModel = {
unique: mediaTypeDetailUnique,
mediaType: {
unique: mediaType.unique,
collection: null,
},
entityType: UMB_MEDIA_ENTITY_TYPE,
isTrashed: false,
urls: [],
values: [
{
alias: 'umbracoFile',
value: { src: mediaTempFileUnique },
culture: null,
segment: null,
},
],
variants: [
{
culture: null,
segment: null,
name: file.name,
createDate: '',
updateDate: '',
},
],
};
await this.#mediaDetailRepository.create(model, null);
this.#mediaCollection?.requestCollection();
}
}
protected renderToolbar() {
return html`
<umb-media-collection-toolbar slot="header"></umb-media-collection-toolbar>
<!-- TODO: Add the Media Upload dropzone component in here. [LK] -->
return html` <umb-media-collection-toolbar slot="header"></umb-media-collection-toolbar>
<uui-file-dropzone
id="dropzone"
multiple
@change=${this.#onFileUpload}
label="${this.localize.term('media_dragAndDropYourFilesIntoTheArea')}"
accept=""></uui-file-dropzone>
`;
accept=""></uui-file-dropzone>`;
}
static styles = [