396 lines
8.9 KiB
JavaScript
Raw Normal View History

2019-12-16 21:53:30 +01:00
/**
*
* EditView
*
*/
2020-01-16 18:17:30 +01:00
import React, { useEffect, useReducer, useRef, useState } from 'react';
2020-01-15 12:17:44 +01:00
import { useHistory, useParams } from 'react-router-dom';
2020-01-16 18:17:30 +01:00
import { get, isEmpty, isEqual } from 'lodash';
2020-01-15 12:17:44 +01:00
import { Header, Inputs as InputsIndex } from '@buffetjs/custom';
2020-01-06 01:52:26 +01:00
import { Play } from '@buffetjs/icons';
2020-01-07 16:00:11 +01:00
import {
request,
useGlobalContext,
getYupInnerErrors,
2020-01-08 16:08:58 +01:00
BackHeader,
2020-01-07 16:00:11 +01:00
} from 'strapi-helper-plugin';
2019-12-18 18:13:24 +01:00
2020-01-13 10:40:10 +01:00
import Inputs from '../../../components/Inputs';
import TriggerContainer from '../../../components/TriggerContainer';
2019-12-18 18:13:24 +01:00
import reducer, { initialState } from './reducer';
2020-01-02 09:55:26 +01:00
import form from './utils/form';
2020-01-15 12:17:44 +01:00
import schema from './utils/schema';
2020-01-16 18:17:30 +01:00
import { cleanData } from './utils/formatData';
2020-01-02 09:55:26 +01:00
import Wrapper from './Wrapper';
2019-12-16 21:53:30 +01:00
function EditView() {
2020-01-16 18:17:30 +01:00
const isMounted = useRef();
2019-12-18 18:13:24 +01:00
const { formatMessage } = useGlobalContext();
2020-01-08 18:28:52 +01:00
const [submittedOnce, setSubmittedOnce] = useState(false);
2019-12-18 18:13:24 +01:00
const [reducerState, dispatch] = useReducer(reducer, initialState);
2020-01-10 15:17:36 +01:00
const { push } = useHistory();
2020-01-16 11:00:38 +01:00
const { id } = useParams();
2020-01-16 18:17:30 +01:00
const abortController = new AbortController();
const { signal } = abortController;
const isCreating = id === 'create';
2019-12-18 18:13:24 +01:00
2020-01-06 01:52:26 +01:00
const {
2020-01-07 16:00:11 +01:00
formErrors,
2020-01-15 12:17:44 +01:00
modifiedData,
initialData,
2020-01-06 01:52:26 +01:00
isTriggering,
triggerResponse,
} = reducerState.toJS();
2019-12-18 18:13:24 +01:00
useEffect(() => {
2020-01-16 18:17:30 +01:00
isMounted.current = true;
const fetchData = async () => {
try {
const { data } = await request(`/admin/webhooks/${id}`, {
method: 'GET',
});
if (isMounted.current) {
dispatch({
type: 'GET_DATA_SUCCEEDED',
data,
});
}
} catch (err) {
if (isMounted.current) {
if (err.code !== 20) {
strapi.notification.error('notification.error');
}
}
}
};
2020-01-13 10:17:10 +01:00
if (!isCreating) {
2020-01-06 11:02:11 +01:00
fetchData();
}
2020-01-16 11:00:38 +01:00
2020-01-16 18:17:30 +01:00
return () => {
isMounted.current = false;
abortController.abort();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
2020-01-17 20:27:16 +01:00
}, [id, isCreating]);
2020-01-16 11:00:38 +01:00
const { name } = modifiedData;
2019-12-18 18:13:24 +01:00
2020-01-15 12:17:44 +01:00
const areActionDisabled =
isEqual(initialData, modifiedData) || Object.keys(formErrors).length > 0;
2019-12-18 18:13:24 +01:00
2020-01-16 11:00:38 +01:00
const isTriggerActionDisabled =
isCreating || (!isCreating && !areActionDisabled) || isTriggering;
2020-01-16 18:17:30 +01:00
const formattedErrors = Object.keys(formErrors)
2020-01-16 11:00:38 +01:00
.filter(key => key.includes('headers'))
.reduce((obj, key) => {
obj[key] = formErrors[key];
return obj;
}, {});
2020-01-10 15:17:36 +01:00
const headerTitle = isCreating
2019-12-18 18:13:24 +01:00
? formatMessage({
id: `Settings.webhooks.create`,
})
: name;
2020-01-16 11:00:38 +01:00
const headersActions = [
2019-12-18 18:13:24 +01:00
{
color: 'primary',
2020-01-15 12:17:44 +01:00
disabled: isTriggerActionDisabled,
2020-01-06 01:52:26 +01:00
label: formatMessage({
2019-12-18 18:13:24 +01:00
id: `Settings.webhooks.trigger`,
}),
2020-01-15 12:17:44 +01:00
onClick: handleTrigger,
2019-12-18 18:13:24 +01:00
style: {
2020-01-10 15:17:36 +01:00
padding: '0 15px',
2019-12-18 18:13:24 +01:00
},
2020-01-15 12:17:44 +01:00
title: isTriggerActionDisabled
2020-01-06 10:48:34 +01:00
? formatMessage({
id: `Settings.webhooks.trigger.save`,
})
: null,
2020-01-10 15:17:36 +01:00
type: 'button',
2020-01-06 10:48:34 +01:00
icon: (
<Play
2020-01-15 12:17:44 +01:00
width="14px"
height="14px"
fill={isTriggerActionDisabled ? '#b4b6ba' : '#ffffff'}
2020-01-06 10:48:34 +01:00
/>
),
2019-12-18 18:13:24 +01:00
},
{
color: 'cancel',
2020-01-15 12:17:44 +01:00
disabled: areActionDisabled,
2020-01-06 01:52:26 +01:00
label: formatMessage({
2019-12-18 18:13:24 +01:00
id: `app.components.Button.reset`,
}),
2020-01-15 12:17:44 +01:00
onClick: handleReset,
2019-12-18 18:13:24 +01:00
style: {
2020-01-10 15:17:36 +01:00
padding: '0 20px',
2019-12-18 18:13:24 +01:00
},
2020-01-10 15:17:36 +01:00
type: 'button',
2019-12-18 18:13:24 +01:00
},
{
color: 'success',
2020-01-15 12:17:44 +01:00
disabled: areActionDisabled,
2020-01-06 01:52:26 +01:00
label: formatMessage({
2019-12-18 18:13:24 +01:00
id: `app.components.Button.save`,
}),
style: {
minWidth: 140,
},
2020-01-10 15:17:36 +01:00
type: 'submit',
2019-12-18 18:13:24 +01:00
},
];
2020-01-07 16:00:11 +01:00
2019-12-18 18:13:24 +01:00
const headerProps = {
title: {
label: headerTitle,
},
2020-01-16 11:00:38 +01:00
actions: headersActions,
2019-12-18 18:13:24 +01:00
};
const checkFormErrors = async (submit = false) => {
try {
await schema.validate(modifiedData, { abortEarly: false });
if (isMounted.current) {
setErrors({});
if (submit) {
submitForm();
}
}
} catch (err) {
if (isMounted.current) {
setErrors(getYupInnerErrors(err));
if (submit) {
strapi.notification.error('notification.form.error.fields');
}
}
}
};
const createWebhooks = async () => {
try {
await request(`/admin/webhooks`, {
method: 'POST',
body: cleanData(modifiedData),
});
if (isMounted.current) {
strapi.notification.success(`notification.success`);
goBack();
}
} catch (err) {
if (isMounted.current) {
strapi.notification.error('notification.error');
}
}
};
const getErrorMessage = error => {
if (!error) {
return null;
}
return formatMessage({
id: error.id,
});
};
const goBack = () => push('/settings/webhooks');
2020-01-10 15:17:36 +01:00
const handleBlur = () => {
2020-01-15 12:17:44 +01:00
if (submittedOnce) {
checkFormErrors();
}
2020-01-08 18:28:52 +01:00
};
2020-01-02 09:55:26 +01:00
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name.split('.'),
value,
});
if (name === 'events' && submittedOnce) {
resetEventsErrors();
}
2020-01-02 09:55:26 +01:00
};
2020-01-03 10:53:58 +01:00
const handleClick = () => {
dispatch({
type: 'ADD_NEW_HEADER',
keys: ['headers'],
});
};
2020-01-16 11:00:38 +01:00
const handleTrigger = async () => {
dispatch({
2020-01-16 18:17:30 +01:00
type: 'SET_IS_TRIGGERING',
2020-01-16 11:00:38 +01:00
});
try {
const { data } = await request(`/admin/webhooks/${id}/trigger`, {
method: 'POST',
signal,
});
2020-01-16 18:17:30 +01:00
if (isMounted.current) {
dispatch({
type: 'TRIGGER_SUCCEEDED',
response: data,
});
}
2020-01-16 11:00:38 +01:00
} catch (err) {
2020-01-16 18:17:30 +01:00
if (isMounted.current) {
if (err.code !== 20) {
strapi.notification.error('notification.error');
}
dispatch({
type: 'SET_IS_TRIGGERING',
});
2020-01-16 11:00:38 +01:00
}
}
};
2020-01-15 12:17:44 +01:00
const handleRemove = index => {
2020-01-07 16:00:11 +01:00
dispatch({
type: 'ON_HEADER_REMOVE',
index,
});
2020-01-15 18:27:05 +01:00
resetHeadersErrors();
2020-01-07 16:00:11 +01:00
};
2020-01-16 11:00:38 +01:00
const handleReset = () =>
dispatch({
type: 'RESET_FORM',
});
2020-01-06 10:48:34 +01:00
const handleSubmit = e => {
e.preventDefault();
2020-01-08 18:28:52 +01:00
setSubmittedOnce(true);
2020-01-10 15:17:36 +01:00
checkFormErrors(true);
2020-01-07 16:00:11 +01:00
};
2020-01-15 12:17:44 +01:00
const onCancelTrigger = () => {
abortController.abort();
2020-01-10 15:17:36 +01:00
2020-01-15 12:17:44 +01:00
dispatch({
type: 'ON_TRIGGER_CANCELED',
});
2020-01-06 16:01:42 +01:00
};
const resetEventsErrors = () => {
const errors = formErrors;
delete errors.events;
setErrors(errors);
};
2020-01-16 11:00:38 +01:00
const resetHeadersErrors = () => {
const errors = formErrors;
const newErrors = Object.keys(errors)
.filter(key => !key.includes('headers'))
.reduce((obj, key) => {
obj[key] = formErrors[key];
return obj;
}, {});
2020-01-15 12:17:44 +01:00
2020-01-16 11:00:38 +01:00
setErrors(newErrors);
};
2020-01-15 12:17:44 +01:00
2020-01-16 11:00:38 +01:00
const setErrors = errors => {
dispatch({
type: 'SET_ERRORS',
2020-01-16 18:17:30 +01:00
errors: errors,
2020-01-16 11:00:38 +01:00
});
};
const submitForm = () => {
if (!isCreating) {
updateWebhook();
} else {
createWebhooks();
}
};
2020-01-15 18:27:05 +01:00
2020-01-16 18:17:30 +01:00
const updateWebhook = async () => {
try {
const body = cleanData(modifiedData);
delete body.id;
await request(`/admin/webhooks/${id}`, {
method: 'PUT',
body,
});
strapi.notification.error('notification.form.success.fields');
} catch (err) {
strapi.notification.error('notification.error');
}
};
2019-12-16 21:53:30 +01:00
return (
2019-12-18 18:13:24 +01:00
<Wrapper>
2020-01-10 15:17:36 +01:00
<BackHeader onClick={goBack} />
2020-01-06 10:48:34 +01:00
<form onSubmit={handleSubmit}>
<Header {...headerProps} />
{(isTriggering || !isEmpty(triggerResponse)) && (
<div className="trigger-wrapper">
<TriggerContainer
isPending={isTriggering}
response={triggerResponse}
2020-01-06 16:01:42 +01:00
onCancel={onCancelTrigger}
2020-01-06 10:48:34 +01:00
/>
</div>
)}
<div className="form-wrapper">
<div className="form-card">
<div className="row">
{Object.keys(form).map(key => {
return (
<div key={key} className={form[key].styleName}>
2020-01-15 12:17:44 +01:00
<InputsIndex
2020-01-06 10:48:34 +01:00
{...form[key]}
2020-01-15 12:17:44 +01:00
customInputs={{
2020-01-15 17:27:41 +01:00
headers: Inputs,
2020-01-15 12:17:44 +01:00
events: Inputs,
}}
2020-01-16 18:17:30 +01:00
label={formatMessage({
id: form[key].label,
})}
error={getErrorMessage(get(formErrors, key, null))}
2020-01-06 10:48:34 +01:00
name={key}
2020-01-08 18:28:52 +01:00
onBlur={handleBlur}
2020-01-06 10:48:34 +01:00
onChange={handleChange}
validations={form[key].validations}
2020-01-15 12:17:44 +01:00
value={modifiedData[key] || form[key].value}
2020-01-15 17:27:41 +01:00
{...(form[key].type === 'headers' && {
onClick: handleClick,
onRemove: handleRemove,
2020-01-16 18:17:30 +01:00
customError: formattedErrors,
2020-01-15 17:27:41 +01:00
})}
2020-01-06 10:48:34 +01:00
/>
</div>
);
})}
</div>
2020-01-03 10:53:58 +01:00
</div>
2020-01-02 09:55:26 +01:00
</div>
2020-01-06 10:48:34 +01:00
</form>
2019-12-18 18:13:24 +01:00
</Wrapper>
2019-12-16 21:53:30 +01:00
);
}
export default EditView;