mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Add loading indicator to save button on scaffolded forms
This commit is contained in:
parent
576e916504
commit
8af1ad09d0
@ -72,7 +72,7 @@ class FormAction extends SilverStripeComponent {
|
||||
* @returns object|null
|
||||
*/
|
||||
getLoadingIcon() {
|
||||
if (this.props.loading) {
|
||||
if (this.props.loading === true) {
|
||||
return (
|
||||
<div className="btn__loading-icon" >
|
||||
<svg viewBox="0 0 44 12">
|
||||
|
@ -316,6 +316,7 @@ export class FormBuilderComponent extends SilverStripeComponent {
|
||||
*/
|
||||
mapActionsToComponents(actions) {
|
||||
const createFn = this.props.createFn;
|
||||
const form = this.props.form[this.getFormId()];
|
||||
|
||||
return actions.map((action, i) => {
|
||||
let props = deepFreeze(action);
|
||||
@ -327,6 +328,7 @@ export class FormBuilderComponent extends SilverStripeComponent {
|
||||
type: 'submit',
|
||||
label: props.title,
|
||||
icon: 'save',
|
||||
loading: typeof form !== 'undefined' ? form.submitting : false,
|
||||
bootstrapButtonStyle: 'success',
|
||||
}, props));
|
||||
break;
|
||||
@ -401,7 +403,7 @@ export class FormBuilderComponent extends SilverStripeComponent {
|
||||
|
||||
// If there is structural and state data availabe merge those data for each field.
|
||||
// Otherwise just use the structural data.
|
||||
const fieldData = formSchema.schema && formState
|
||||
const fieldData = formSchema.schema && formState && formState.fields
|
||||
? formSchema.schema.fields.map((f, i) => this.mergeFieldData(f, formState.fields[i]))
|
||||
: formSchema.schema.fields;
|
||||
|
||||
|
@ -59,7 +59,7 @@ export function submitForm(submitApi, formId, fieldValues) {
|
||||
return (dispatch) => {
|
||||
dispatch({
|
||||
type: ACTION_TYPES.SUBMIT_FORM_REQUEST,
|
||||
payload: {},
|
||||
payload: { formId },
|
||||
});
|
||||
|
||||
submitApi(Object.assign({ ID: formId }, fieldValues), { 'X-Formschema-Request': 'state' })
|
||||
@ -72,7 +72,7 @@ export function submitForm(submitApi, formId, fieldValues) {
|
||||
.catch((error) => {
|
||||
dispatch({
|
||||
type: ACTION_TYPES.SUBMIT_FORM_FAILURE,
|
||||
payload: { error },
|
||||
payload: { formId, error },
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -6,6 +6,11 @@ const initialState = deepFreeze({});
|
||||
function formReducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case ACTION_TYPES.SUBMIT_FORM_REQUEST:
|
||||
return deepFreeze(Object.assign({}, state, {
|
||||
[action.payload.formId]: { submitting: true },
|
||||
}));
|
||||
|
||||
case ACTION_TYPES.REMOVE_FORM:
|
||||
return deepFreeze(Object.keys(state).reduce((previous, current) => {
|
||||
if (current === action.payload.formId) {
|
||||
@ -18,7 +23,10 @@ function formReducer(state = initialState, action) {
|
||||
|
||||
case ACTION_TYPES.ADD_FORM:
|
||||
return deepFreeze(Object.assign({}, state, {
|
||||
[action.payload.formState.id]: { fields: action.payload.formState.fields },
|
||||
[action.payload.formState.id]: {
|
||||
fields: action.payload.formState.fields,
|
||||
submitting: false,
|
||||
},
|
||||
}));
|
||||
|
||||
case ACTION_TYPES.UPDATE_FIELD:
|
||||
@ -38,9 +46,15 @@ function formReducer(state = initialState, action) {
|
||||
[action.payload.response.id]: {
|
||||
fields: action.payload.response.state.fields,
|
||||
messages: action.payload.response.state.messages,
|
||||
submitting: false,
|
||||
},
|
||||
}));
|
||||
|
||||
case ACTION_TYPES.SUBMIT_FORM_FAILURE:
|
||||
return deepFreeze(Object.assign({}, state, {
|
||||
[action.payload.formId]: { submitting: false },
|
||||
}));
|
||||
|
||||
default:
|
||||
return state;
|
||||
|
||||
|
@ -21,6 +21,7 @@ describe('formReducer', () => {
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
submitting: false,
|
||||
},
|
||||
});
|
||||
|
||||
@ -54,6 +55,7 @@ describe('formReducer', () => {
|
||||
expect(nextState.EditForm.fields[0].messages).toBeDefined();
|
||||
expect(nextState.EditForm.fields[0].valid).toBe(true);
|
||||
expect(nextState.EditForm.fields[0].value).toBe('Test');
|
||||
expect(nextState.EditForm.submitting).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -137,6 +139,7 @@ describe('formReducer', () => {
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
submitting: true,
|
||||
},
|
||||
});
|
||||
|
||||
@ -172,6 +175,59 @@ describe('formReducer', () => {
|
||||
expect(nextState.DetailEditForm.messages.length).toBe(1);
|
||||
expect(nextState.DetailEditForm.messages[0].type).toBe('good');
|
||||
expect(nextState.DetailEditForm.messages[0].value).toBe('Saved.');
|
||||
expect(nextState.DetailEditForm.submitting).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SUBMIT_FORM_REQUEST', () => {
|
||||
it('should set submitting to true', () => {
|
||||
const initialState = deepFreeze({
|
||||
DetailEditForm: {
|
||||
fields: [
|
||||
{
|
||||
data: [],
|
||||
id: 'Form_DetailEditForm_Name',
|
||||
messages: [],
|
||||
valid: true,
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
submitting: false,
|
||||
},
|
||||
});
|
||||
|
||||
const nextState = formReducer(initialState, {
|
||||
type: ACTION_TYPES.SUBMIT_FORM_REQUEST,
|
||||
payload: { formId: 'DetailEditForm' },
|
||||
});
|
||||
|
||||
expect(nextState.DetailEditForm.submitting).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SUBMIT_FORM_FAILURE', () => {
|
||||
it('should set submitting to false', () => {
|
||||
const initialState = deepFreeze({
|
||||
DetailEditForm: {
|
||||
fields: [
|
||||
{
|
||||
data: [],
|
||||
id: 'Form_DetailEditForm_Name',
|
||||
messages: [],
|
||||
valid: true,
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
submitting: true,
|
||||
},
|
||||
});
|
||||
|
||||
const nextState = formReducer(initialState, {
|
||||
type: ACTION_TYPES.SUBMIT_FORM_FAILURE,
|
||||
payload: { formId: 'DetailEditForm' },
|
||||
});
|
||||
|
||||
expect(nextState.DetailEditForm.submitting).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user