Add loading button to ctm and to upload && modify design

This commit is contained in:
cyril lopez 2018-03-06 09:31:44 +01:00
parent 71e4009317
commit 3e32741114
16 changed files with 99 additions and 21 deletions

View File

@ -15,9 +15,11 @@ import {
ON_CANCEL,
RESET_PROPS,
SET_FILE_RELATIONS,
SET_LOADER,
SET_FORM_ERRORS,
SUBMIT,
SUBMIT_SUCCESS,
UNSET_LOADER,
} from './constants';
export function changeData({ target }) {
@ -87,6 +89,12 @@ export function setFormErrors(formErrors) {
};
}
export function setLoader() {
return {
type: SET_LOADER,
};
}
export function submit() {
return {
type: SUBMIT,
@ -98,3 +106,9 @@ export function submitSuccess() {
type: SUBMIT_SUCCESS,
};
}
export function unsetLoader() {
return {
type: UNSET_LOADER,
};
}

View File

@ -11,6 +11,8 @@ export const INIT_MODEL_PROPS = 'ContentManager/EditPage/INIT_MODEL_PROPS';
export const ON_CANCEL = 'ContentManager/EditPage/ON_CANCEL';
export const RESET_PROPS = 'ContentManager/EditPage/RESET_PROPS';
export const SET_FILE_RELATIONS = 'ContentManager/EditPage/SET_FILE_RELATIONS';
export const SET_LOADER = 'ContentManager/EditPage/SET_LOADER';
export const SET_FORM_ERRORS = 'ContentManager/EditPage/SET_FORM_ERRORS';
export const SUBMIT = 'ContentManager/EditPage/SUBMIT';
export const SUBMIT_SUCCESS = 'ContentManager/EditPage/SUBMIT_SUCCESS';
export const UNSET_LOADER = 'ContentManager/EditPage/UNSET_LOADER';

View File

@ -191,31 +191,34 @@ export class EditPage extends React.Component {
}, {})
)
pluginHeaderActions = [
{
label: 'content-manager.containers.Edit.reset',
kind: 'secondary',
onClick: this.props.onCancel,
type: 'button',
},
{
kind: 'primary',
label: 'content-manager.containers.Edit.submit',
onClick: this.handleSubmit,
type: 'submit',
},
];
pluginHeaderActions = () => (
[
{
label: 'content-manager.containers.Edit.reset',
kind: 'secondary',
onClick: this.props.onCancel,
type: 'button',
},
{
kind: 'primary',
label: 'content-manager.containers.Edit.submit',
onClick: this.handleSubmit,
type: 'submit',
loader: this.props.editPage.showLoader,
},
]
);
render() {
const { editPage } = this.props;
console.log(editPage.showLoader);
return (
<div>
<form onSubmit={this.handleSubmit}>
<BackHeader onClick={() => this.props.history.goBack()} />
<div className={cn('container-fluid', styles.containerFluid)}>
<PluginHeader
actions={this.pluginHeaderActions}
actions={this.pluginHeaderActions()}
title={{ id: toString(editPage.pluginHeaderTitle) }}
/>
<div className="row">

View File

@ -13,7 +13,9 @@ import {
RESET_PROPS,
SET_FILE_RELATIONS,
SET_FORM_ERRORS,
SET_LOADER,
SUBMIT_SUCCESS,
UNSET_LOADER,
} from './constants';
const initialState = fromJS({
@ -27,6 +29,7 @@ const initialState = fromJS({
modelName: '',
pluginHeaderTitle: 'New Entry',
record: Map({}),
showLoader: false,
source: 'content-manager',
submitSuccess: false,
});
@ -60,8 +63,13 @@ function editPageReducer(state = initialState, action) {
return state
.update('didCheckErrors', (v) => v = !v)
.update('formErrors', () => List(action.formErrors));
case SET_LOADER:
return state
.update('showLoader', () => true);
case SUBMIT_SUCCESS:
return state.update('submitSuccess', (v) => v = !v);
case UNSET_LOADER:
return state.update('showLoader', () => false);
default:
return state;
}

View File

@ -15,7 +15,13 @@ import cleanData from 'utils/cleanData';
import request from 'utils/request';
import templateObject from 'utils/templateObject';
import { getDataSucceeded, setFormErrors, submitSuccess } from './actions';
import {
getDataSucceeded,
setFormErrors,
setLoader,
submitSuccess,
unsetLoader,
} from './actions';
import { GET_DATA,SUBMIT } from './constants';
import {
makeSelectFileRelations,
@ -50,6 +56,8 @@ export function* submit() {
const source = yield select(makeSelectSource());
try {
// Show button loader
yield put(setLoader());
const recordCleaned = Object.keys(record).reduce((acc, current) => {
const cleanedData = cleanData(record[current], 'value', 'id');
@ -126,6 +134,8 @@ export function* submit() {
yield put(setFormErrors([{ name, errors }]));
}
strapi.notification.error(isCreating ? 'content-manager.error.record.create' : 'content-manager.error.record.update');
} finally {
yield put(unsetLoader());
}
}

View File

@ -10,7 +10,7 @@
height: 100%;
margin-left: 32px;
margin-right: 32px;
line-height: 54px;
line-height: 48px;
border-bottom: 1px solid rgba(14,22,34,0.04);
justify-content: space-between;

View File

@ -11,6 +11,12 @@
width: 100%;
padding: 0 !important;
list-style: none;
> li:nth-child(2) {
height: 57px;
> div {
line-height: 54px !important;
}
}
> li {
width: 100%;
margin-top: 0;

View File

@ -30,6 +30,7 @@ class PluginInputFile extends React.PureComponent {
const {
name,
onChange,
showLoader,
} = this.props;
const { isDraging } = this.state;
const link = (
@ -40,7 +41,7 @@ class PluginInputFile extends React.PureComponent {
return (
<label
className={cn(styles.pluginInputFile, isDraging && styles.pluginInputFileHover)}
className={cn(styles.pluginInputFile, isDraging && styles.pluginInputFileHover, showLoader && styles.pluginInputFileHover)}
onDragEnter={this.handleDragEnter}
onDragOver={(e) => {
e.preventDefault();
@ -49,7 +50,8 @@ class PluginInputFile extends React.PureComponent {
onDrop={this.handleDrop}
>
<p className={styles.textWrapper}>
<FormattedMessage id="upload.PluginInputFile.text" values={{ link }} />
{!showLoader && <FormattedMessage id="upload.PluginInputFile.text" values={{ link }} /> }
{showLoader && <FormattedMessage id="upload.PluginInputFile.loading" />}
</p>
<div
onDragLeave={this.handleDragLeave}
@ -74,6 +76,7 @@ PluginInputFile.propTypes = {
name: PropTypes.string.isRequired,
onChange: PropTypes.func,
onDrop: PropTypes.func.isRequired,
showLoader: PropTypes.bool.isRequired,
};
export default PluginInputFile;

View File

@ -38,7 +38,7 @@
}
.pluginInputFileHover {
background: rgba(28,93,231,0.01) !important;
background-color: rgba(28,93,231,0.01) !important;
border: 2px dashed rgba(28,93,231,0.10) !important;
}

View File

@ -14,7 +14,9 @@ import {
ON_DROP,
ON_SEARCH,
ON_SEARCH_SUCCESS,
SET_LOADING,
SET_PARAMS,
UNSET_LOADING,
} from './constants';
export function changeParams({ target }) {
@ -78,6 +80,12 @@ export function onSearch({ target }) {
};
}
export function setLoading() {
return {
type: SET_LOADING,
};
}
export function setParams(params) {
return {
type: SET_PARAMS,
@ -91,3 +99,9 @@ export function onSearchSuccess(data) {
data,
};
}
export function unsetLoading() {
return {
type: UNSET_LOADING,
};
}

View File

@ -13,4 +13,6 @@ export const GET_DATA_SUCCESS = 'Upload/HomePage/GET_DATA_SUCCESS';
export const ON_DROP = 'Upload/HomePage/ON_DROP';
export const ON_SEARCH = 'Upload/HomePage/ON_SEARCH';
export const ON_SEARCH_SUCCESS = 'Upload/HomePage/ON_SEARCH_SUCCESS';
export const SET_LOADING = 'Upload/HomePage/SET_LOADING';
export const SET_PARAMS = 'Upload/HomePage/SET_PARAMS';
export const UNSET_LOADING = 'Upload/HomePage/UNSET_LOADING';

View File

@ -137,6 +137,7 @@ export class HomePage extends React.Component {
<PluginInputFile
name="files"
onDrop={this.props.onDrop}
showLoader={this.props.uploadFilesLoading}
/>
<div className={styles.entriesWrapper}>
<div>
@ -199,6 +200,7 @@ HomePage.propTypes = {
search: PropTypes.string.isRequired,
setParams: PropTypes.func.isRequired,
uploadedFiles: PropTypes.arrayOf(PropTypes.object),
uploadFilesLoading: PropTypes.bool.isRequired,
};
function mapDispatchToProps(dispatch) {

View File

@ -13,13 +13,16 @@ import {
GET_DATA_SUCCESS,
ON_SEARCH,
ON_SEARCH_SUCCESS,
SET_LOADING,
SET_PARAMS,
UNSET_LOADING,
} from './constants';
const initialState = fromJS({
deleteSuccess: false,
dataToDelete: '',
entriesNumber: 0,
uploadFilesLoading: false,
search: '',
uploadedFiles: List([]),
params: Map({
@ -46,8 +49,12 @@ function homePageReducer(state = initialState, action) {
return state.update('search', () => action.value);
case ON_SEARCH_SUCCESS:
return state.update('uploadedFiles', () => List(action.data));
case SET_LOADING:
return state.update('uploadFilesLoading', () => true);
case SET_PARAMS:
return state.set('params', Map(action.params));
case UNSET_LOADING:
return state.update('uploadFilesLoading', () => false);
default:
return state;
}

View File

@ -9,6 +9,8 @@ import {
dropSuccess,
getDataSuccess,
onSearchSuccess,
setLoading,
unsetLoading,
} from './actions';
import {
DELETE_DATA,
@ -55,6 +57,7 @@ function* dataGet() {
function* uploadFiles(action) {
try {
yield put(setLoading());
const headers = {
'X-Forwarded-Host': 'strapi',
};
@ -71,6 +74,8 @@ function* uploadFiles(action) {
} catch(err) {
strapi.notification.error('notification.error');
} finally {
yield put(unsetLoading());
}
}

View File

@ -27,6 +27,7 @@
"PluginInputFile.text": "Drag & drop your files into this area or {link} from a file to upload",
"PluginInputFile.link": "browse",
"PluginInputFile.loading": "Your files are being uploaded",
"notification.delete.success": "The file has been deleted",
"notification.dropFile.success": "Your file has been uploaded",

View File

@ -27,6 +27,7 @@
"PluginInputFile.text": "Drag & drop vos fichiers dans cette zone ou {link} un fichier à télécharger",
"PluginInputFile.link": "recherchez",
"PluginInputFile.loading": "Vos fichiers sont en train d'être téléchargés",
"notification.delete.success": "Le fichier a bien été supprimé",
"notification.dropFile.success": "Votre fichier a été téléchargé",