import * as React from "react"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import { WidgetType } from "constants/WidgetConstants"; import Uppy from "@uppy/core"; import GoogleDrive from "@uppy/google-drive"; import Webcam from "@uppy/webcam"; import Url from "@uppy/url"; import OneDrive from "@uppy/onedrive"; import FilePickerComponent from "components/designSystems/appsmith/FilePickerComponent"; import { WidgetPropertyValidationType } from "utils/ValidationFactory"; import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { EventType } from "constants/ActionConstants"; import { DerivedPropertiesMap, TriggerPropertiesMap, } from "utils/WidgetFactory"; import Dashboard from "@uppy/dashboard"; import shallowequal from "shallowequal"; class FilePickerWidget extends BaseWidget { uppy: any; constructor(props: FilePickerWidgetProps) { super(props); this.refreshUppy(props); } static getPropertyValidationMap(): WidgetPropertyValidationType { return { label: VALIDATION_TYPES.TEXT, maxNumFiles: VALIDATION_TYPES.NUMBER, allowedFileTypes: VALIDATION_TYPES.ARRAY, isRequired: VALIDATION_TYPES.BOOLEAN, }; } static getDerivedPropertiesMap(): DerivedPropertiesMap { return { isValid: `{{ this.isRequired ? this.files.length > 0 : true }}`, }; } refreshUppy = (props: FilePickerWidgetProps) => { this.uppy = Uppy({ id: this.props.widgetId, autoProceed: false, allowMultipleUploads: true, debug: false, restrictions: { maxFileSize: null, maxNumberOfFiles: props.maxNumFiles, minNumberOfFiles: null, allowedFileTypes: props.allowedFileTypes, }, }) .use(Dashboard, { target: "body", metaFields: [], inline: false, width: 750, height: 550, thumbnailWidth: 280, showLinkToFileUploadResult: true, showProgressDetails: false, hideUploadButton: false, hideProgressAfterFinish: false, note: null, closeAfterFinish: true, closeModalOnClickOutside: true, disableStatusBar: false, disableInformer: false, disableThumbnailGenerator: false, disablePageScrollWhenModalOpen: true, proudlyDisplayPoweredByUppy: false, onRequestCloseModal: () => { this.uppy.getPlugin("Dashboard").closeModal(); }, locale: {}, }) .use(GoogleDrive, { companionUrl: "https://companion.uppy.io" }) .use(Url, { companionUrl: "https://companion.uppy.io" }) .use(OneDrive, { companionUrl: "https://companion.uppy.io/", }) .use(Webcam, { onBeforeSnapshot: () => Promise.resolve(), countdown: false, mirror: true, facingMode: "user", locale: {}, }); this.uppy.on("file-removed", (file: any) => { const updatedFiles = this.props.files.filter(dslFile => { return file.id !== dslFile.id; }); this.updateWidgetMetaProperty("files", updatedFiles); }); this.uppy.on("file-added", (file: any) => { const dslFiles = this.props.files; const reader = new FileReader(); reader.readAsDataURL(file.data); reader.onloadend = () => { const base64data = reader.result; const newFile = { id: file.id, base64: base64data, blob: file.data, }; dslFiles.push(newFile); this.updateWidgetMetaProperty("files", dslFiles); }; }); this.uppy.on("upload", () => { this.onFilesSelected(); }); }; static getTriggerPropertyMap(): TriggerPropertiesMap { return { onFilesSelected: true, }; } onFilesSelected() { if (this.props.onFilesSelected) { this.executeAction({ dynamicString: this.props.onFilesSelected, event: { type: EventType.ON_FILES_SELECTED, }, }); } } componentDidUpdate(prevProps: FilePickerWidgetProps) { super.componentDidUpdate(prevProps); if ( !shallowequal(prevProps.allowedFileTypes, this.props.allowedFileTypes) || prevProps.maxNumFiles !== this.props.maxNumFiles ) { this.refreshUppy(this.props); } } componentDidMount() { super.componentDidMount(); this.refreshUppy(this.props); } componentWillUnmount() { this.uppy.close(); } getPageView() { return ( ); } getWidgetType(): WidgetType { return "FILE_PICKER_WIDGET"; } } export interface FilePickerWidgetProps extends WidgetProps { label: string; maxNumFiles?: number; files: any[]; allowedFileTypes: string[]; onFilesSelected?: string; isRequired?: boolean; } export default FilePickerWidget;