UNPKG

framework-entersol-web

Version:

Framework based on bootstrap 5

121 lines (110 loc) 3.54 kB
import React from "react"; import Field from "./field"; import bytes from "bytes"; import * as LZMAObj from 'lzma/src/lzma_worker'; import eventHandler from "../../functions/event-handler"; export default class FileField extends Field { static defaultProps = { ...Field.defaultProps, multiple: false, format: 'base64', zip: false } static jsClass = 'FileField'; get type() { return 'file'; } isInvalid(value) { if (this.props.maxSize && this.input.current?.files) { const files = Array.from(this.input.current.files); const error = files.some(file => file.size > bytes(this.props.maxSize, { unit: 'B' })); if (error) { this.input.current.setCustomValidity(this.props.errorMessage); return true; } } return super.isInvalid(value); } async onChange(e) { let { value, files } = e.target; const arrayFiles = Array.from(files); const newState = { value, error: this.isInvalid(value) } this.setState(newState); if (!arrayFiles.length || newState.error) return this.returnData(null); const p6s = arrayFiles.map(file => this.readAs(file, this.props.format)); const final = await Promise.all(p6s); if (this.props.multiple) { this.returnData(final); } else { this.returnData(final[0]); } } readAs(file, format = 'base64') { if (!file) return null; return new Promise((resolve, reject) => { const reader = new FileReader(); switch (format) { case 'base64': reader.readAsDataURL(file); break; case 'text': reader.readAsText(file); break; case 'binaryString': reader.readAsBinaryString(file); break; case 'zip': reader.readAsArrayBuffer(file); break; default: break; } const onFinish = (result, error) => { eventHandler.dispatch('zipping.' + this.props.name, { [this.props.name]: 'end' }); if (error) return reject(error); resolve(result); }; const onPercentage = (percentage) => eventHandler.dispatch('zipping.' + this.props.name, { [this.props.name]: percentage }); reader.onload = () => { if (this.props.format !== 'zip') return resolve(reader.result); eventHandler.dispatch('zipping.' + this.props.name, { [this.props.name]: 'start' }); const array = new Uint8Array(reader.result); const mode = this.props.zip || 9; LZMAObj.LZMA.compress(array, mode, onFinish, onPercentage); }; reader.onerror = error => reject(error); }); } get inputProps() { const ip = super.inputProps; ip.required = ip.required && !(this.state.value); delete ip.value; return ip; } get inputNode() { const { inline, disabled, readOnly } = this.props; const { value } = this.state; const inputNode = (<> {!(value && (disabled || readOnly)) ? <input {...this.inputProps} /> : <p className="form-control mb-1 disabled"> <a href={value} target="_blank"> {value.split(/[\/\\]/).pop().split('?')[0]} </a> </p>} {value && !(disabled || readOnly) && <p className="text-end my-1"> <small><a href={value} target="_blank"> {value.split(/[\/\\]/).pop().split('?')[0]} </a></small> </p>} </>); return (inline ? <div className="col-auto"> {inputNode} </div> : inputNode); } }