Skip to content

Instantly share code, notes, and snippets.

@ykrkn
Last active March 12, 2021 11:09
Show Gist options
  • Save ykrkn/7c146095ac6fb94630b4439842edc00f to your computer and use it in GitHub Desktop.
Save ykrkn/7c146095ac6fb94630b4439842edc00f to your computer and use it in GitHub Desktop.
blueprintjs react upload file
package service;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import java.util.LinkedHashSet;
import java.util.Set;
@Data
public class UploadedFileContext {
private final String name;
private final long size;
private final String filename;
private final int year;
private Set messages = new LinkedHashSet();
private String error;
public UploadedFileContext(MultipartFile file, int year) {
name = file.getName();
size = file.getSize();
filename = file.getOriginalFilename();
this.year = year;
}
}
.UploadFiles {
border: 1px solid grey;
box-shadow: 0px 0px 6px 6px #ccc;
border-radius: 16px;
width: 600px;
position: absolute;
left: calc(50% - 300px);
top: 200px;
}
.UploadFiles h3 {
text-align: center;
opacity: 0.8;
}
.UploadFiles .item {
margin: 16px;
}
.UploadFiles .File .error {
color: red;
font-weight: bold;
}
import { FileInput, Intent, ProgressBar } from '@blueprintjs/core';
import React from 'react';
import './UploadFiles.css';
class File extends React.Component {
constructor(props) {
super(props);
this.state = {
intent: Intent.PRIMARY,
percent : 0,
enabled : true,
messages: [],
error: null,
label : props.label,
};
this.progressIntv = null;
}
upload(e) {
const progressHandler = (event) => {
const {loaded, total} = event;
let percent = (loaded / total);
if(!isFinite(percent) || isNaN(percent)) percent = 0;
if(percent == 1) {
this.progressIntv = setInterval(() => {
let percent = this.state.percent += .01;
if(percent > 1) percent = 1;
this.setState({percent});
}, 1000);
}
percent *= .5;
this.setState({percent});
}
const completeHandler = (event) => {
try {
clearInterval(this.progressIntv);
let res = JSON.parse(event.target.responseText);
this.setState({percent:1, messages : res.messages, error: res.error, intent: (res.error ? Intent.DANGER : Intent.SUCCESS), enabled: true});
} catch (e) {
console.error(e);
this.setState({percent:1, messages: [], error: e.message, intent: Intent.DANGER, enabled: true});
}
}
const errorHandler = (event) => {
clearInterval(this.progressIntv);
this.setState({intent: Intent.DANGER, messages: [], error: 'Service Error', enabled: true});
}
const abortHandler = (event) => {
clearInterval(this.progressIntv);
this.setState({percent: 0, messages: [], error: null, intent: Intent.PRIMARY, enabled: true});
}
const file = e.target.files[0];
const formdata = new FormData();
formdata.append(this.props.name, file);
formdata.append("year", this.props.year);
const ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "/api/upload");
ajax.send(formdata);
this.setState({percent: 0, messages: [], error: null, intent: Intent.PRIMARY, enabled: false, label: file.name});
}
render() {
const {label, percent, intent, enabled, messages, error} = this.state;
return (<div className='File'>
<FileInput disabled={!enabled} text={label} onInputChange={(e) => this.upload(e)} inputProps={{accept:'.xlsx'}} fill={true} onClick={(e) => e.target.value=null} />
<ProgressBar value={percent} animate={false} intent={intent} stripes={false} />
<div>{messages.map(e => <p>{e}</p>)}</div>
<div className='error'>{error}</div>
</div>);
}
}
const currentYear = new Date().getFullYear();
export class UploadFiles extends React.Component {
constructor(props) {
super(props);
this.state = {
year: currentYear
};
}
render() {
return (<div className='UploadFiles'>
<h3>Upload Excel</h3>
<div className='item year'>
<div class="bp3-select">
<select onChange={e => this.setState({year:parseInt(e.target.value)})} value={this.state.year}>
{Array.from({length: 10}, (_, i) => i + currentYear).map(e => <option value={e}>{e}</option>)}
</select>
</div>
</div>
<div className='item file'>
<File year={this.state.year} name={'file1'} label={'CTR Tragets'}/>
</div>
<div className='item file'>
<File year={this.state.year} name={'file2'} label={'CTR COS Targets'}/>
</div>
</div>);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment