mirror of
https://github.com/strapi/strapi.git
synced 2026-01-06 12:13:52 +00:00
Handle upload dynamic
This commit is contained in:
parent
05a229b8fc
commit
5538e4ffc2
@ -47,7 +47,7 @@ class Notification extends React.Component { // eslint-disable-line react/prefer
|
||||
: <FormattedMessage id={message} defaultMessage={message} />;
|
||||
|
||||
return (
|
||||
<li key={this.props.notification.id} className={`${styles.notification} ${styles[options.class]}`}>
|
||||
<li key={this.props.notification.id} className={`${styles.notification} ${styles[options.class]}`} onClick={this.handleCloseClicked}>
|
||||
<i className={`fa ${options.icon} ${styles.notificationIcon}`} />
|
||||
<div className={styles.notificationContent}>
|
||||
<p className={styles.notificationTitle}>
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="105px" height="84px" viewBox="0 0 105 84" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.1 (44463) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="1.35416667" width="77.3333333" height="62.2916667" rx="4"></rect>
|
||||
<rect id="path-2" x="0" y="1.35416667" width="77.3333333" height="62.2916667" rx="4"></rect>
|
||||
</defs>
|
||||
<g id="Pages" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.049999997">
|
||||
<g id="Users-&-Groups---Edit-view" transform="translate(-420.000000, -918.000000)">
|
||||
<g id="Content" transform="translate(269.000000, 157.000000)">
|
||||
<g id="Main-data">
|
||||
<g id="File-#1" transform="translate(23.000000, 695.000000)">
|
||||
<g id="Empty" transform="translate(-8.000000, 21.000000)">
|
||||
<g id="Icon" transform="translate(135.000000, 44.000000)">
|
||||
<g id="picture-o" transform="translate(46.000000, 40.500000) rotate(-12.000000) translate(-46.000000, -40.500000) translate(6.000000, 8.000000)">
|
||||
<g id="Rectangle-4">
|
||||
<use fill="#FAFAFB" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
<rect stroke="#979797" stroke-width="1" x="0.5" y="1.85416667" width="76.3333333" height="61.2916667" rx="4"></rect>
|
||||
</g>
|
||||
<path d="M69.3333333,35.2083333 L69.3333333,54.1666667 L10.6666667,54.1666667 L10.6666667,46.0416667 L24,32.5 L30.6666667,39.2708333 L52,17.6041667 L69.3333333,35.2083333 Z M73.3333333,5.41666667 L6.66666667,5.41666667 C6.30555556,5.41666667 5.99305556,5.55067274 5.72916667,5.8186849 C5.46527778,6.08669705 5.33333333,6.40407986 5.33333333,6.77083333 L5.33333333,58.2291667 C5.33333333,58.5959201 5.46527778,58.913303 5.72916667,59.1813151 C5.99305556,59.4493273 6.30555556,59.5833333 6.66666667,59.5833333 L73.3333333,59.5833333 C73.6944444,59.5833333 74.0069444,59.4493273 74.2708333,59.1813151 C74.5347222,58.913303 74.6666667,58.5959201 74.6666667,58.2291667 L74.6666667,6.77083333 C74.6666667,6.40407986 74.5347222,6.08669705 74.2708333,5.8186849 C74.0069444,5.55067274 73.6944444,5.41666667 73.3333333,5.41666667 Z M80,6.77083333 L80,58.2291667 C80,60.0911458 79.3472222,61.6851128 78.0416667,63.0110677 C76.7361111,64.3370226 75.1666667,65 73.3333333,65 L6.66666667,65 C4.83333333,65 3.26388889,64.3370226 1.95833333,63.0110677 C0.652777778,61.6851128 0,60.0911458 0,58.2291667 L0,6.77083333 C0,4.90885417 0.652777778,3.31488715 1.95833333,1.98893229 C3.26388889,0.662977431 4.83333333,0 6.66666667,0 L73.3333333,0 C75.1666667,0 76.7361111,0.662977431 78.0416667,1.98893229 C79.3472222,3.31488715 80,4.90885417 80,6.77083333 Z" id="Shape" fill="#333740" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
<g id="picture-o" transform="translate(60.000000, 44.500000) rotate(15.000000) translate(-60.000000, -44.500000) translate(20.000000, 12.000000)">
|
||||
<g id="Rectangle-4">
|
||||
<use fill="#FAFAFB" fill-rule="evenodd" xlink:href="#path-2"></use>
|
||||
<rect stroke="#979797" stroke-width="1" x="0.5" y="1.85416667" width="76.3333333" height="61.2916667" rx="4"></rect>
|
||||
</g>
|
||||
<path d="M26.6666667,18.9583333 C26.6666667,21.2152778 25.8888889,23.1336806 24.3333333,24.7135417 C22.7777778,26.2934028 20.8888889,27.0833333 18.6666667,27.0833333 C16.4444444,27.0833333 14.5555556,26.2934028 13,24.7135417 C11.4444444,23.1336806 10.6666667,21.2152778 10.6666667,18.9583333 C10.6666667,16.7013889 11.4444444,14.7829861 13,13.203125 C14.5555556,11.6232639 16.4444444,10.8333333 18.6666667,10.8333333 C20.8888889,10.8333333 22.7777778,11.6232639 24.3333333,13.203125 C25.8888889,14.7829861 26.6666667,16.7013889 26.6666667,18.9583333 Z M69.3333333,35.2083333 L69.3333333,54.1666667 L10.6666667,54.1666667 L10.6666667,46.0416667 L24,32.5 L30.6666667,39.2708333 L52,17.6041667 L69.3333333,35.2083333 Z M73.3333333,5.41666667 L6.66666667,5.41666667 C6.30555556,5.41666667 5.99305556,5.55067274 5.72916667,5.8186849 C5.46527778,6.08669705 5.33333333,6.40407986 5.33333333,6.77083333 L5.33333333,58.2291667 C5.33333333,58.5959201 5.46527778,58.913303 5.72916667,59.1813151 C5.99305556,59.4493273 6.30555556,59.5833333 6.66666667,59.5833333 L73.3333333,59.5833333 C73.6944444,59.5833333 74.0069444,59.4493273 74.2708333,59.1813151 C74.5347222,58.913303 74.6666667,58.5959201 74.6666667,58.2291667 L74.6666667,6.77083333 C74.6666667,6.40407986 74.5347222,6.08669705 74.2708333,5.8186849 C74.0069444,5.55067274 73.6944444,5.41666667 73.3333333,5.41666667 Z M80,6.77083333 L80,58.2291667 C80,60.0911458 79.3472222,61.6851128 78.0416667,63.0110677 C76.7361111,64.3370226 75.1666667,65 73.3333333,65 L6.66666667,65 C4.83333333,65 3.26388889,64.3370226 1.95833333,63.0110677 C0.652777778,61.6851128 0,60.0911458 0,58.2291667 L0,6.77083333 C0,4.90885417 0.652777778,3.31488715 1.95833333,1.98893229 C3.26388889,0.662977431 4.83333333,0 6.66666667,0 L73.3333333,0 C75.1666667,0 76.7361111,0.662977431 78.0416667,1.98893229 C79.3472222,3.31488715 80,4.90885417 80,6.77083333 Z" id="Shape" fill="#333740" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.40317 83.13328"><title>icon_upload_2</title><g opacity="0.05"><rect x="5.02914" y="8.63138" width="77.33334" height="62.29167" rx="4" ry="4" transform="translate(-7.45722 9.32921) rotate(-12)" fill="#fafafb"/><rect x="5.52914" y="9.13138" width="76.33334" height="61.29167" rx="4" ry="4" transform="translate(-7.45722 9.32921) rotate(-12)" fill="none" stroke="#979797"/><path d="M74.25543,36.05041l3.94166,18.54405L20.81242,66.79194l-1.68928-7.94745,10.2265-16.01791,7.92872,5.2368,16.3624-25.62865ZM71.974,6.07811,6.76414,19.93889a1.27175,1.27175,0,0,0-.83343.58815,1.31145,1.31145,0,0,0-.18922,1.01364L16.44028,71.87453a1.31145,1.31145,0,0,0,.58515.849,1.27176,1.27176,0,0,0,1.0006.19831L83.23586,59.06111a1.27177,1.27177,0,0,0,.83343-.58815,1.31146,1.31146,0,0,0,.18922-1.01364L73.55972,7.12547a1.31146,1.31146,0,0,0-.58514-.849A1.27177,1.27177,0,0,0,71.974,6.07811Zm6.80253-.0615L89.4753,56.35046A6.5712,6.5712,0,0,1,88.554,61.435a6.37055,6.37055,0,0,1-4.19192,2.92439L19.15221,78.22019a6.37056,6.37056,0,0,1-5.019-.96655,6.57121,6.57121,0,0,1-2.90975-4.27024L.5247,22.64955A6.57121,6.57121,0,0,1,1.446,17.565a6.37056,6.37056,0,0,1,4.19192-2.92439L70.84779.77981a6.37055,6.37055,0,0,1,5.019.96655A6.5712,6.5712,0,0,1,78.77651,6.01661Z" transform="translate(-0.14193 -0.62489)" fill="#333740"/><rect x="26.56627" y="4.48824" width="62.29167" height="77.33333" rx="4" ry="4" transform="translate(0.94874 87.10632) rotate(-75)" fill="#fafafb"/><rect x="27.06627" y="4.98824" width="61.29167" height="76.33333" rx="4" ry="4" transform="translate(0.94874 87.10632) rotate(-75)" fill="none" stroke="#979797"/><path d="M49.62583,26.96884A7.89786,7.89786,0,0,1,45.88245,31.924a7.96,7.96,0,0,1-10.94716-2.93328,7.89786,7.89786,0,0,1-.76427-6.163,7.89787,7.89787,0,0,1,3.74338-4.95519,7.96,7.96,0,0,1,10.94716,2.93328A7.89787,7.89787,0,0,1,49.62583,26.96884Zm37.007,26.73924L81.72608,72.02042,25.05843,56.83637l2.1029-7.84815L43.54519,39.3589l4.68708,8.26558L74.44644,32.21756ZM98.20721,25.96681,33.81216,8.71221a1.27175,1.27175,0,0,0-1.00961.14568,1.31145,1.31145,0,0,0-.62878.81726L18.85537,59.38007a1.31145,1.31145,0,0,0,.13591,1.02215,1.27176,1.27176,0,0,0,.80151.631l64.39506,17.2546a1.27177,1.27177,0,0,0,1.0096-.14567,1.31146,1.31146,0,0,0,.62877-.81726l13.3184-49.70493a1.31146,1.31146,0,0,0-.13591-1.02215A1.27177,1.27177,0,0,0,98.20721,25.96681Zm6.089,3.03348L90.97784,78.70523a6.5712,6.5712,0,0,1-3.12925,4.1121,6.37055,6.37055,0,0,1-5.06267.70256L18.39086,66.26529a6.37056,6.37056,0,0,1-4.03313-3.13977,6.57121,6.57121,0,0,1-.654-5.12581L27.02217,8.29477a6.57121,6.57121,0,0,1,3.12925-4.11211,6.37056,6.37056,0,0,1,5.06267-.70255l64.39506,17.2546a6.37055,6.37055,0,0,1,4.03312,3.13977A6.5712,6.5712,0,0,1,104.29623,29.0003Z" transform="translate(-0.14193 -0.62489)" fill="#333740"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@ -6,6 +6,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
@ -13,6 +14,13 @@ import styles from './styles.scss';
|
||||
class PluginInputFile extends React.PureComponent {
|
||||
state = { isDraging: false };
|
||||
|
||||
handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
console.log('click');
|
||||
this.refs.input.click();
|
||||
}
|
||||
|
||||
handleDragEnter = () => this.setState({ isDraging: true });
|
||||
|
||||
handleDragLeave = () => this.setState({ isDraging: false });
|
||||
@ -20,6 +28,7 @@ class PluginInputFile extends React.PureComponent {
|
||||
handleDrop = (e) => {
|
||||
e.preventDefault();
|
||||
this.setState({ isDraging: false });
|
||||
this.props.onDrop(e);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -28,10 +37,15 @@ class PluginInputFile extends React.PureComponent {
|
||||
onChange,
|
||||
} = this.props;
|
||||
const { isDraging } = this.state;
|
||||
const link = (
|
||||
<FormattedMessage id="upload.PluginInputFile.link">
|
||||
{(message) => <u onClick={this.handleClick}>{message}</u>}
|
||||
</FormattedMessage>
|
||||
);
|
||||
|
||||
return (
|
||||
<label
|
||||
className={cn(styles.pluginInputFile)}
|
||||
className={cn(styles.pluginInputFile, isDraging && styles.pluginInputFileHover)}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
@ -39,13 +53,19 @@ class PluginInputFile extends React.PureComponent {
|
||||
}}
|
||||
onDrop={this.handleDrop}
|
||||
>
|
||||
<p className={styles.textWrapper}>
|
||||
<FormattedMessage id="upload.PluginInputFile.text" values={{ link }} />
|
||||
</p>
|
||||
|
||||
<div
|
||||
onDragLeave={this.handleDragLeave}
|
||||
className={cn(isDraging && styles.isDraging)}
|
||||
/>
|
||||
<input
|
||||
multiple
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
ref="input"
|
||||
type="file"
|
||||
/>
|
||||
</label>
|
||||
|
||||
@ -4,9 +4,10 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
// TODO change background
|
||||
background-color: red;
|
||||
background-image: url('../../assets/icons/icon_upload_2.svg');
|
||||
background-size: auto 64px;
|
||||
background-position: center 27px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.pluginInputFile {
|
||||
@ -14,8 +15,29 @@
|
||||
height: 144px;
|
||||
width: 100%;
|
||||
border: 2px dashed #E3E9F3;
|
||||
border-radius: 2px;
|
||||
background-image: url('../../assets/icons/icon_upload_2.svg');
|
||||
background-size: auto 64px;
|
||||
background-position: center 27px;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
> input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.textWrapper {
|
||||
margin-top: 103px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: #9EA7B8;
|
||||
|
||||
u {
|
||||
color: #1C5DE7;
|
||||
}
|
||||
}
|
||||
|
||||
.pluginInputFileHover {
|
||||
background: rgba(28,93,231,0.01) !important;
|
||||
border: 2px solid rgba(28,93,231,0.10) !important;
|
||||
}
|
||||
|
||||
@ -4,7 +4,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { ON_SEARCH } from './constants';
|
||||
import {
|
||||
DROP_SUCCESS,
|
||||
ON_DROP,
|
||||
ON_SEARCH,
|
||||
} from './constants';
|
||||
|
||||
export function dropSuccess(newFiles) {
|
||||
return {
|
||||
type: DROP_SUCCESS,
|
||||
newFiles,
|
||||
};
|
||||
}
|
||||
|
||||
export function onDrop({ dataTransfer: { files } }) {
|
||||
return {
|
||||
type: ON_DROP,
|
||||
files,
|
||||
}
|
||||
}
|
||||
|
||||
export function onSearch({ target }) {
|
||||
return {
|
||||
|
||||
@ -4,4 +4,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
export const DROP_SUCCESS = 'Upload/HomePage/DROP_SUCCESS';
|
||||
export const ON_DROP = 'Upload/HomePage/ON_DROP';
|
||||
export const ON_SEARCH = 'Upload/HomePage/ON_SEARCH';
|
||||
|
||||
@ -27,6 +27,7 @@ import injectSaga from 'utils/injectSaga';
|
||||
|
||||
// Actions
|
||||
import {
|
||||
onDrop,
|
||||
onSearch,
|
||||
} from './actions';
|
||||
|
||||
@ -66,6 +67,7 @@ export class HomePage extends React.Component {
|
||||
</div>
|
||||
<PluginInputFile
|
||||
name="files"
|
||||
onDrop={this.props.onDrop}
|
||||
/>
|
||||
|
||||
</ContainerFluid>
|
||||
@ -78,6 +80,7 @@ HomePage.contextTypes = {
|
||||
};
|
||||
|
||||
HomePage.propTypes = {
|
||||
onDrop: PropTypes.func.isRequired,
|
||||
onSearch: PropTypes.func.isRequired,
|
||||
search: PropTypes.string.isRequired,
|
||||
};
|
||||
@ -85,6 +88,7 @@ HomePage.propTypes = {
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(
|
||||
{
|
||||
onDrop,
|
||||
onSearch,
|
||||
},
|
||||
dispatch,
|
||||
|
||||
@ -4,16 +4,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { fromJS } from 'immutable';
|
||||
import { fromJS, List } from 'immutable';
|
||||
|
||||
import { ON_SEARCH } from './constants';
|
||||
import {
|
||||
DROP_SUCCESS,
|
||||
ON_SEARCH,
|
||||
} from './constants';
|
||||
|
||||
const initialState = fromJS({
|
||||
search: '',
|
||||
uploadedFiles: List([]),
|
||||
});
|
||||
|
||||
function homePageReducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case DROP_SUCCESS:
|
||||
return state
|
||||
.update('uploadedFiles', (list) => List(action.newFiles).concat(list));
|
||||
case ON_SEARCH:
|
||||
return state.update('search', () => action.value);
|
||||
default:
|
||||
|
||||
@ -1,9 +1,39 @@
|
||||
// import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import { fork, select, takeLatest } from 'redux-saga/effects';
|
||||
import { fork, put, select, takeLatest } from 'redux-saga/effects';
|
||||
|
||||
import { ON_SEARCH } from './constants';
|
||||
|
||||
import {
|
||||
dropSuccess,
|
||||
} from './actions';
|
||||
import {
|
||||
ON_DROP,
|
||||
ON_SEARCH,
|
||||
} from './constants';
|
||||
import { makeSelectSearch } from './selectors';
|
||||
|
||||
function* uploadFiles(action) {
|
||||
try {
|
||||
const files = action.files;
|
||||
|
||||
const newFiles = Object.keys(files).reduce((acc, current) => {
|
||||
acc.push(files[current]);
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
yield put(dropSuccess(newFiles));
|
||||
|
||||
if (newFiles.length > 1) {
|
||||
strapi.notification.success({ id: 'upload.notification.dropFile.success' });
|
||||
} else {
|
||||
strapi.notification.success({ id: 'upload.notification.dropFiles.success', values: { number: newFiles.length } });
|
||||
}
|
||||
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
function* search() {
|
||||
try {
|
||||
const search = yield select(makeSelectSearch());
|
||||
@ -16,6 +46,7 @@ function* search() {
|
||||
|
||||
// Individual exports for testing
|
||||
export function* defaultSaga() {
|
||||
yield fork(takeLatest, ON_DROP, uploadFiles);
|
||||
yield fork(takeLatest, ON_SEARCH, search);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
{
|
||||
"HomePage.title": "Upload",
|
||||
"HomePage.description": "Discover all the uploaded files",
|
||||
"HomePage.InputSearch.placeholder": "Search for a file...",
|
||||
|
||||
"HomePage.InputSearch.placeholder": "Search for a file..."
|
||||
"PluginInputFile.text": "Drag & drop your files into this area or {link} from a file to upload",
|
||||
"PluginInputFile.link": "browse",
|
||||
|
||||
"notification.dropFile.success": "Your file has been uploaded",
|
||||
"notification.dropFiles.success": "{number} files have been uploaded"
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
{
|
||||
"HomePage.title": "Upload",
|
||||
"HomePage.description": "Découvrez tous les fichiers téléchargés",
|
||||
"HomePage.InputSearch.placeholder": "Rechercher un fichier...",
|
||||
|
||||
"HomePage.InputSearch.placeholder": "Rechercher un fichier..."
|
||||
"PluginInputFile.text": "Drag & drop vos fichiers dans cette zone ou {link} un fichier à télécharger",
|
||||
"PluginInputFile.link": "recherchez",
|
||||
|
||||
"notification.dropFile.success": "Votre fichier a été téléchargé",
|
||||
"notification.dropFiles.success": "{number} fichiers ont été téléchargées"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user