mirror of
https://github.com/strapi/strapi.git
synced 2025-11-11 15:49:50 +00:00
Add button loader to settings-manager plugin
This commit is contained in:
parent
3ee78ceeea
commit
c2502376c9
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import cn from 'classnames';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
@ -16,9 +17,23 @@ class Button extends React.Component {
|
|||||||
const addShape = this.props.addShape ? <i className="fa fa-plus" /> : '';
|
const addShape = this.props.addShape ? <i className="fa fa-plus" /> : '';
|
||||||
|
|
||||||
const buttonProps = Object.assign({}, this.props);
|
const buttonProps = Object.assign({}, this.props);
|
||||||
const propsToDelete = ['addShape', 'buttonBackground', 'buttonSize', 'handlei18n', 'label'];
|
const propsToDelete = ['addShape', 'buttonBackground', 'buttonSize', 'handlei18n', 'label', 'loader'];
|
||||||
|
|
||||||
propsToDelete.map((value) => delete buttonProps[value]);
|
propsToDelete.map((value) => delete buttonProps[value]);
|
||||||
|
|
||||||
|
if (this.props.loader) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={cn(styles.loader, styles.primary)}
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<div className={styles.saving}>
|
||||||
|
<p></p><p></p><p></p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<button className={`${styles[this.props.buttonSize]} ${styles[this.props.buttonBackground]} ${styles.button}`} {...buttonProps}>
|
<button className={`${styles[this.props.buttonSize]} ${styles[this.props.buttonBackground]} ${styles.button}`} {...buttonProps}>
|
||||||
{addShape}{label}
|
{addShape}{label}
|
||||||
@ -33,6 +48,7 @@ Button.propTypes = {
|
|||||||
buttonSize: PropTypes.string,
|
buttonSize: PropTypes.string,
|
||||||
handlei18n: PropTypes.bool,
|
handlei18n: PropTypes.bool,
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
|
loader: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Button;
|
export default Button;
|
||||||
|
|||||||
@ -46,7 +46,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
.secondary {
|
||||||
// height: 32px !important;
|
|
||||||
color: #F64D0A;
|
color: #F64D0A;
|
||||||
border: 0.1rem solid #F64D0A;
|
border: 0.1rem solid #F64D0A;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -67,3 +66,58 @@
|
|||||||
padding-left: 1.6rem;
|
padding-left: 1.6rem;
|
||||||
padding-right: 1.6rem;
|
padding-right: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0% {
|
||||||
|
opacity: .2;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: .2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.saving {
|
||||||
|
height: 3rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
height: 3rem;
|
||||||
|
padding: 0 0 0 1.2rem;
|
||||||
|
line-height: 3.2rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
letter-spacing: 1rem;
|
||||||
|
font-family: Lato;
|
||||||
|
cursor: not-allowed;
|
||||||
|
position: relative;
|
||||||
|
opacity: .65;
|
||||||
|
width: 15rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.saving p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
animation-name: blink;
|
||||||
|
animation-duration: 1.4s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
&::before {
|
||||||
|
content: '\F111';
|
||||||
|
font-family: 'FontAwesome';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.saving p:nth-child(2) {
|
||||||
|
animation-delay: .2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.saving p:nth-child(3) {
|
||||||
|
animation-delay: .4s;
|
||||||
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import styles from './styles.scss';
|
|||||||
|
|
||||||
class EditForm extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
class EditForm extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
|
const buttonStyle = this.props.showLoader ? { display: 'none' } : {};
|
||||||
return (
|
return (
|
||||||
<div className={styles.editForm}>
|
<div className={styles.editForm}>
|
||||||
<form onSubmit={this.props.handleSubmit} autoComplete="nope">
|
<form onSubmit={this.props.handleSubmit} autoComplete="nope">
|
||||||
@ -41,12 +42,12 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
|||||||
<div className={styles.buttonContainer}>
|
<div className={styles.buttonContainer}>
|
||||||
<FormattedMessage id="settings-manager.form.button.cancel">
|
<FormattedMessage id="settings-manager.form.button.cancel">
|
||||||
{(message) => (
|
{(message) => (
|
||||||
<Button type="button" label={message} buttonSize={"buttonMd"} buttonBackground={"secondary"} onClick={this.props.handleCancel} />
|
<Button type="button" label={message} buttonSize={"buttonMd"} buttonBackground={"secondary"} onClick={this.props.handleCancel} style={buttonStyle} />
|
||||||
)}
|
)}
|
||||||
</FormattedMessage>
|
</FormattedMessage>
|
||||||
<FormattedMessage id="settings-manager.form.button.save">
|
<FormattedMessage id="settings-manager.form.button.save">
|
||||||
{(message) => (
|
{(message) => (
|
||||||
<Button type="submit" label={message} buttonSize={"buttonLg"} buttonBackground={"primary"} onClick={this.props.handleSubmit} />
|
<Button type="submit" loader={this.props.showLoader} label={message} buttonSize={"buttonLg"} buttonBackground={"primary"} onClick={this.props.handleSubmit} />
|
||||||
)}
|
)}
|
||||||
</FormattedMessage>
|
</FormattedMessage>
|
||||||
</div>
|
</div>
|
||||||
@ -63,6 +64,7 @@ EditForm.propTypes = {
|
|||||||
handleChange: PropTypes.func,
|
handleChange: PropTypes.func,
|
||||||
handleSubmit: PropTypes.func,
|
handleSubmit: PropTypes.func,
|
||||||
sections: PropTypes.array,
|
sections: PropTypes.array,
|
||||||
|
showLoader: PropTypes.bool,
|
||||||
values: PropTypes.object,
|
values: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import {
|
|||||||
DATABASE_ACTION_ERROR,
|
DATABASE_ACTION_ERROR,
|
||||||
EMPTY_DB_MODIFIED_DATA,
|
EMPTY_DB_MODIFIED_DATA,
|
||||||
SET_ERRORS,
|
SET_ERRORS,
|
||||||
|
SET_LOADER,
|
||||||
|
UNSET_LOADER,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
export function defaultAction() {
|
export function defaultAction() {
|
||||||
@ -300,3 +302,15 @@ export function setErrors(errors) {
|
|||||||
errors,
|
errors,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setLoader() {
|
||||||
|
return {
|
||||||
|
type: SET_LOADER,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsetLoader() {
|
||||||
|
return {
|
||||||
|
type: UNSET_LOADER,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -30,3 +30,5 @@ export const DATABASE_EDIT = 'SettingsManager/HomePage/DATABASE_EDIT';
|
|||||||
export const DATABASE_ACTION_ERROR = 'SettingsManager/HomePage/DATABASE_ACTION_ERROR';
|
export const DATABASE_ACTION_ERROR = 'SettingsManager/HomePage/DATABASE_ACTION_ERROR';
|
||||||
export const EMPTY_DB_MODIFIED_DATA = 'SettingsManager/HomePage/EMPTY_DB_MODIFIED_DATA';
|
export const EMPTY_DB_MODIFIED_DATA = 'SettingsManager/HomePage/EMPTY_DB_MODIFIED_DATA';
|
||||||
export const SET_ERRORS = 'SettingsManager/HomePage/SET_ERRORS';
|
export const SET_ERRORS = 'SettingsManager/HomePage/SET_ERRORS';
|
||||||
|
export const SET_LOADER = 'SettingsManager/HomePage/SET_LOADER';
|
||||||
|
export const UNSET_LOADER = 'SettingsManager/HomePage/UNSET_LOADER';
|
||||||
|
|||||||
@ -439,6 +439,7 @@ export class HomePage extends React.Component { // eslint-disable-line react/pre
|
|||||||
addListTitleMarginTop={addListTitleMarginTop}
|
addListTitleMarginTop={addListTitleMarginTop}
|
||||||
formErrors={this.props.home.formErrors}
|
formErrors={this.props.home.formErrors}
|
||||||
error={this.props.home.error}
|
error={this.props.home.error}
|
||||||
|
showLoader={this.props.home.showLoader}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -547,7 +548,6 @@ HomePage.propTypes = {
|
|||||||
menuSections: PropTypes.array.isRequired,
|
menuSections: PropTypes.array.isRequired,
|
||||||
newDatabasePost: PropTypes.func.isRequired,
|
newDatabasePost: PropTypes.func.isRequired,
|
||||||
newLanguagePost: PropTypes.func.isRequired,
|
newLanguagePost: PropTypes.func.isRequired,
|
||||||
// params: PropTypes.func.isRequired,
|
|
||||||
setErrors: PropTypes.func.isRequired,
|
setErrors: PropTypes.func.isRequired,
|
||||||
specificDatabaseFetch: PropTypes.func.isRequired,
|
specificDatabaseFetch: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import {
|
|||||||
NEW_LANGUAGE_POST,
|
NEW_LANGUAGE_POST,
|
||||||
EMPTY_DB_MODIFIED_DATA,
|
EMPTY_DB_MODIFIED_DATA,
|
||||||
SET_ERRORS,
|
SET_ERRORS,
|
||||||
|
SET_LOADER,
|
||||||
|
UNSET_LOADER,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
/* eslint-disable new-cap */
|
/* eslint-disable new-cap */
|
||||||
@ -43,6 +45,7 @@ const initialState = fromJS({
|
|||||||
formValidations: [],
|
formValidations: [],
|
||||||
formErrors: [],
|
formErrors: [],
|
||||||
error: false,
|
error: false,
|
||||||
|
showLoader: false,
|
||||||
});
|
});
|
||||||
/* eslint-disable no-case-declarations */
|
/* eslint-disable no-case-declarations */
|
||||||
|
|
||||||
@ -140,6 +143,10 @@ function homePageReducer(state = initialState, action) {
|
|||||||
case SET_ERRORS:
|
case SET_ERRORS:
|
||||||
return state
|
return state
|
||||||
.set('formErrors', action.errors)
|
.set('formErrors', action.errors)
|
||||||
|
case SET_LOADER:
|
||||||
|
return state.set('showLoader', true);
|
||||||
|
case UNSET_LOADER:
|
||||||
|
return state.set('showLoader', false);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import {
|
|||||||
databaseActionSucceeded,
|
databaseActionSucceeded,
|
||||||
specificDatabaseFetchSucceeded,
|
specificDatabaseFetchSucceeded,
|
||||||
databaseActionError,
|
databaseActionError,
|
||||||
|
unsetLoader,
|
||||||
|
setLoader,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
|
|
||||||
/* eslint-disable no-template-curly-in-string */
|
/* eslint-disable no-template-curly-in-string */
|
||||||
@ -240,6 +242,9 @@ export function* postDatabase(action) {
|
|||||||
|
|
||||||
export function* settingsEdit(action) {
|
export function* settingsEdit(action) {
|
||||||
try {
|
try {
|
||||||
|
// Show button loader
|
||||||
|
yield put(setLoader());
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
body: action.newSettings,
|
body: action.newSettings,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@ -252,11 +257,13 @@ export function* settingsEdit(action) {
|
|||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
window.Strapi.notification.success('settings-manager.strapi.notification.success.settingsEdit');
|
window.Strapi.notification.success('settings-manager.strapi.notification.success.settingsEdit');
|
||||||
yield put(editSettingsSucceeded());
|
yield put(editSettingsSucceeded());
|
||||||
|
yield put(unsetLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
window.Strapi.notification.error('settings-manager.strapi.notification.error');
|
window.Strapi.notification.error('settings-manager.strapi.notification.error');
|
||||||
|
yield put(unsetLoader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user