Browse Source

Improve TS for custom file upload option (#6578)

Fix D&D file upload TS
markdanial-patch-1
Artur Arseniev 6 months ago
committed by GitHub
parent
commit
1c8506eb7b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      packages/core/src/asset_manager/config/config.ts
  2. 7
      packages/core/src/asset_manager/index.ts
  3. 17
      packages/core/src/asset_manager/types.ts
  4. 13
      packages/core/src/asset_manager/view/FileUploader.ts
  5. 9
      packages/core/src/dom_components/view/ComponentImageView.ts
  6. 22
      packages/core/src/utils/Droppable.ts

4
packages/core/src/asset_manager/config/config.ts

@ -1,3 +1,5 @@
import { UploadFileFn } from '../types';
export interface AssetManagerConfig {
/**
* Default assets.
@ -83,7 +85,7 @@ export interface AssetManagerConfig {
* // ...send somewhere
* }
*/
uploadFile?: (ev: DragEvent) => void;
uploadFile?: UploadFileFn;
/**
* In the absence of 'uploadFile' or 'upload' assets will be embedded as Base64.
* @default true

7
packages/core/src/asset_manager/index.ts

@ -40,13 +40,10 @@ import { ProjectData } from '../storage_manager';
import defConfig, { AssetManagerConfig } from './config/config';
import Asset from './model/Asset';
import Assets from './model/Assets';
import AssetsEvents, { AssetOpenOptions } from './types';
import AssetsEvents, { AssetAddInput, AssetOpenOptions, AssetProps } from './types';
import AssetsView from './view/AssetsView';
import FileUploaderView from './view/FileUploader';
// TODO
type AssetProps = Record<string, any>;
const assetCmd = 'open-assets';
export default class AssetManager extends ItemManagerModule<AssetManagerConfig, Assets> {
@ -153,7 +150,7 @@ export default class AssetManager extends ItemManagerModule<AssetManagerConfig,
* });
* assetManager.add([{ src: 'img2.jpg' }, { src: 'img2.png' }]);
*/
add(asset: string | AssetProps | (string | AssetProps)[], opts: AddOptions = {}) {
add(asset: AssetAddInput | AssetAddInput[], opts: AddOptions = {}) {
// Put the model at the beginning
if (typeof opts.at == 'undefined') {
opts.at = 0;

17
packages/core/src/asset_manager/types.ts

@ -1,7 +1,10 @@
import ComponentView from '../dom_components/view/ComponentView';
import Asset from './model/Asset';
export type AssetEvent = `${AssetsEvents}`;
export type AssetAddInput = string | AssetProps | Asset;
export interface AssetOpenOptions {
select?: (asset: Asset, complete: boolean) => void;
types?: string[];
@ -9,6 +12,20 @@ export interface AssetOpenOptions {
target?: any;
}
export interface AssetProps {
src: string;
[key: string]: unknown;
}
export interface UploadFileOptions {
componentView?: ComponentView;
file?: File;
}
export type UploadFileClb = (result: { data: (AssetProps | string)[] }) => void;
export type UploadFileFn = (ev: DragEvent, clb?: UploadFileClb, opts?: UploadFileOptions) => Promise<void> | undefined;
/**{START_EVENTS}*/
export enum AssetsEvents {
/**

13
packages/core/src/asset_manager/view/FileUploader.ts

@ -4,6 +4,7 @@ import EditorModel from '../../editor/model/Editor';
import fetch from '../../utils/fetch';
import html from '../../utils/html';
import { AssetManagerConfig } from '../config/config';
import { UploadFileClb, UploadFileOptions } from '../types';
type FileUploaderTemplateProps = {
pfx: string;
@ -53,7 +54,7 @@ export default class FileUploaderView extends View {
constructor(opts: any = {}) {
super(opts);
this.options = opts;
const c = opts.config || {};
const c = (opts.config || {}) as AssetManagerConfig & { pStylePrefix?: string; disableUpload?: boolean };
this.module = opts.module;
this.config = c;
// @ts-ignore
@ -113,7 +114,7 @@ export default class FileUploaderView extends View {
* @param {string} text Response text
* @private
*/
onUploadResponse(text: string, clb?: (json: any) => void) {
onUploadResponse(text: string, clb?: UploadFileClb) {
const { module, config, target } = this;
let json;
try {
@ -138,9 +139,9 @@ export default class FileUploaderView extends View {
* @return {Promise}
* @private
* */
uploadFile(e: DragEvent, clb?: () => void) {
// @ts-ignore
const files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
uploadFile(e: DragEvent, clb?: UploadFileClb, opts?: UploadFileOptions) {
opts; // Options are not used here but can be used by the custom uploadFile function
const files = e.dataTransfer ? e.dataTransfer.files : ((e.target as any)?.files as FileList);
const { config } = this;
const { beforeUpload } = config;
@ -293,7 +294,7 @@ export default class FileUploaderView extends View {
return this;
}
static embedAsBase64(e: DragEvent, clb?: () => void) {
static embedAsBase64(e: DragEvent, clb?: UploadFileClb) {
// List files dropped
// @ts-ignore
const files = e.dataTransfer ? e.dataTransfer.files : e.target.files;

9
packages/core/src/dom_components/view/ComponentImageView.ts

@ -40,14 +40,17 @@ export default class ComponentImageView<TComp extends ComponentImage = Component
const fu = em.Assets.FileUploader();
fu?.uploadFile(
{
// @ts-ignore
dataTransfer: { files: [file] },
},
(res: any) => {
} as unknown as DragEvent,
(res) => {
const obj = res && res.data && res.data[0];
const src = obj && (isString(obj) ? obj : obj.src);
src && model.set({ src });
},
{
componentView: this,
file,
},
);
model.set('file', '');
}

22
packages/core/src/utils/Droppable.ts

@ -1,12 +1,12 @@
import { bindAll, indexOf } from 'underscore';
import CanvasModule from '../canvas';
import { ObjectStrings } from '../common';
import Component from '../dom_components/model/Component';
import EditorModel from '../editor/model/Editor';
import { getDocumentScroll, off, on } from './dom';
import { DragDirection, DragSource } from './sorter/types';
import CanvasNewComponentNode from './sorter/CanvasNewComponentNode';
import ComponentSorter from './sorter/ComponentSorter';
import Component from '../dom_components/model/Component';
import { DragDirection, DraggableContent, DragSource } from './sorter/types';
// TODO move in sorter
type SorterOptions = {
@ -233,7 +233,7 @@ export default class Droppable {
handleDrop(ev: Event | DragEvent) {
ev.preventDefault();
const dt = (ev as DragEvent).dataTransfer;
const content = this.getContentByData(dt).content;
const content = this.getContentByData(dt!).content || '';
if (this.draggedNode) {
this.draggedNode.content = content;
}
@ -241,12 +241,12 @@ export default class Droppable {
this.endDrop(!content, ev);
}
getContentByData(dt: any) {
getContentByData(dt?: DataTransfer) {
const em = this.em;
const types = dt && dt.types;
const files = (dt && dt.files) || [];
const types = dt?.types || [];
const files = dt?.files || [];
const dragSource: DragSource<Component> = em.get('dragSource');
let content = dt && dt.getData('text');
let content: DraggableContent['content'] = dt?.getData('text') || '';
if (files.length) {
content = [];
@ -280,9 +280,13 @@ export default class Droppable {
content = `<div>${content}</div>`;
}
const result = { content };
const result = {
content,
setContent(content: DraggableContent['content']) {
result.content = content;
},
};
em.trigger('canvas:dragdata', dt, result);
return result;
}
}

Loading…
Cancel
Save