Consistent file uploads (#4699)
* FileSelect component * Use FileSelect component in Actionbar * Convert CreateAccount/Import to FileSelect
This commit is contained in:
52
js/src/ui/Form/FileSelect/fileSelect.css
Normal file
52
js/src/ui/Form/FileSelect/fileSelect.css
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$backgroundNormal: rgba(0, 0, 0, 0.2);
|
||||
$backgroundNormalHover: rgba(0, 0, 0, 0.5);
|
||||
$backgroundError: rgba(255, 0, 0, 0.1);
|
||||
$backgroundErrorHover: rgba(255, 0, 0, 0.2);
|
||||
|
||||
.dropzone {
|
||||
align-items: center;
|
||||
background: $backgroundNormal;
|
||||
border: 2px dashed #666;
|
||||
border-radius: 0.5em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 1.2em;
|
||||
height: 12em;
|
||||
transition: all 0.5s ease;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background: $backgroundNormalHover;
|
||||
border-radius: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background: $backgroundError;
|
||||
|
||||
&:hover {
|
||||
background: $backgroundErrorHover;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
76
js/src/ui/Form/FileSelect/fileSelect.js
Normal file
76
js/src/ui/Form/FileSelect/fileSelect.js
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import styles from './fileSelect.css';
|
||||
|
||||
export default class FileSelect extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
error: nodeOrStringProptype(),
|
||||
label: nodeOrStringProptype(),
|
||||
onSelect: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id='ui.fileSelect.defaultLabel'
|
||||
defaultMessage='Drop a file here, or click to select a file to upload'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, error, label } = this.props;
|
||||
|
||||
return (
|
||||
<Dropzone
|
||||
onDrop={ this.onDrop }
|
||||
multiple={ false }
|
||||
className={
|
||||
[
|
||||
styles.dropzone,
|
||||
error
|
||||
? styles.error
|
||||
: '',
|
||||
className
|
||||
].join(' ') }
|
||||
>
|
||||
<div className={ styles.label }>
|
||||
{ error || label }
|
||||
</div>
|
||||
</Dropzone>
|
||||
);
|
||||
}
|
||||
|
||||
onDrop = (files) => {
|
||||
const { onSelect } = this.props;
|
||||
const reader = new FileReader();
|
||||
const file = files[0];
|
||||
|
||||
reader.onload = (event) => {
|
||||
onSelect(file.name, event.target.result);
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
118
js/src/ui/Form/FileSelect/fileSelect.spec.js
Normal file
118
js/src/ui/Form/FileSelect/fileSelect.spec.js
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import FileSelect from './';
|
||||
|
||||
const FILE = {
|
||||
content: 'some test content',
|
||||
name: 'someName'
|
||||
};
|
||||
|
||||
let component;
|
||||
let globalFileReader;
|
||||
let instance;
|
||||
let onSelect;
|
||||
let processedFile;
|
||||
|
||||
function stubReader () {
|
||||
globalFileReader = global.FileReader;
|
||||
|
||||
global.FileReader = class {
|
||||
readAsText (file) {
|
||||
processedFile = file;
|
||||
|
||||
this.onload({
|
||||
target: {
|
||||
result: file.content
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function restoreReader () {
|
||||
global.FileReader = globalFileReader;
|
||||
}
|
||||
|
||||
function render (props = {}) {
|
||||
onSelect = sinon.stub();
|
||||
component = shallow(
|
||||
<FileSelect
|
||||
onSelect={ onSelect }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
instance = component.instance();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/Form/FileSelect', () => {
|
||||
beforeEach(() => {
|
||||
stubReader();
|
||||
render();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
restoreReader();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
describe('DropZone', () => {
|
||||
let label;
|
||||
let zone;
|
||||
|
||||
beforeEach(() => {
|
||||
label = component.find('FormattedMessage');
|
||||
zone = component.find('Dropzone');
|
||||
});
|
||||
|
||||
it('renders the label', () => {
|
||||
expect(label.props().id).to.equal('ui.fileSelect.defaultLabel');
|
||||
});
|
||||
|
||||
it('attaches the onDrop event', () => {
|
||||
expect(zone.props().onDrop).to.equal(instance.onDrop);
|
||||
});
|
||||
|
||||
it('does not allow multiples', () => {
|
||||
expect(zone.props().multiple).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('event methods', () => {
|
||||
describe('onDrop', () => {
|
||||
beforeEach(() => {
|
||||
instance.onDrop([ FILE ]);
|
||||
});
|
||||
|
||||
it('reads the file as dropped', () => {
|
||||
expect(processedFile).to.deep.equal(FILE);
|
||||
});
|
||||
|
||||
it('calls prop onSelect with file & content', () => {
|
||||
expect(onSelect).to.have.been.calledWith(FILE.name, FILE.content);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
17
js/src/ui/Form/FileSelect/index.js
Normal file
17
js/src/ui/Form/FileSelect/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './fileSelect';
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
export AddressSelect from './AddressSelect';
|
||||
export DappUrlInput from './DappUrlInput';
|
||||
export FileSelect from './FileSelect';
|
||||
export FormWrap from './FormWrap';
|
||||
export Input from './Input';
|
||||
export InputAddress from './InputAddress';
|
||||
|
||||
Reference in New Issue
Block a user