353 lines
7.8 KiB
JavaScript
Raw Normal View History

2019-12-16 21:53:30 +01:00
/**
*
* EditView
*
*/
2020-01-06 11:02:11 +01:00
import React, { useEffect, useReducer, useCallback } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
2020-01-07 16:00:11 +01:00
import { cloneDeep, get, isEmpty, isEqual, set } from 'lodash';
2019-12-18 18:13:24 +01:00
import { Header } 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,
} from 'strapi-helper-plugin';
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-07 16:00:11 +01:00
import createYupSchema from './utils/schema';
2020-01-02 09:55:26 +01:00
import Inputs from '../../../components/Inputs';
2020-01-06 01:52:26 +01:00
import TriggerContainer from '../../../components/TriggerContainer';
2020-01-02 09:55:26 +01:00
import Wrapper from './Wrapper';
2019-12-16 21:53:30 +01:00
function EditView() {
2019-12-18 18:13:24 +01:00
const { formatMessage } = useGlobalContext();
const [reducerState, dispatch] = useReducer(reducer, initialState);
const location = useLocation();
2020-01-06 11:02:11 +01:00
const { goBack } = useHistory();
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-06 01:52:26 +01:00
modifiedWebhook,
initialWebhook,
isTriggering,
triggerResponse,
2020-01-06 11:02:11 +01:00
shouldRefetchData,
2020-01-06 01:52:26 +01:00
} = reducerState.toJS();
2019-12-18 18:13:24 +01:00
const { name } = modifiedWebhook;
const id = location.pathname.split('/')[3];
const isCreatingWebhook = id === 'create';
2020-01-06 16:01:42 +01:00
const abortController = new AbortController();
const { signal } = abortController;
2019-12-18 18:13:24 +01:00
useEffect(() => {
2020-01-07 16:00:11 +01:00
if (!isCreatingWebhook || (!isCreatingWebhook && shouldRefetchData)) {
2020-01-06 11:02:11 +01:00
fetchData();
}
2020-01-07 16:00:11 +01:00
}, [fetchData, isCreatingWebhook, shouldRefetchData]);
2020-01-06 11:02:11 +01:00
const fetchData = useCallback(async () => {
2019-12-18 18:13:24 +01:00
try {
const { data } = await request(`/admin/webhooks/${id}`, {
method: 'GET',
});
dispatch({
type: 'GET_DATA_SUCCEEDED',
data,
});
} catch (err) {
if (err.code !== 20) {
strapi.notification.error('notification.error');
}
}
2020-01-06 11:02:11 +01:00
}, [id]);
2019-12-18 18:13:24 +01:00
// Header props
const headerTitle = isCreatingWebhook
? formatMessage({
id: `Settings.webhooks.create`,
})
: name;
2020-01-06 01:52:26 +01:00
const actionsAreDisabled = isEqual(initialWebhook, modifiedWebhook);
2020-01-06 10:48:34 +01:00
const triggerActionIsDisabled =
isCreatingWebhook || (!isCreatingWebhook && !actionsAreDisabled);
2020-01-06 01:52:26 +01:00
const handleTrigger = async () => {
dispatch({
type: 'ON_TRIGGER',
});
try {
2020-01-06 16:01:42 +01:00
const { data } = await request(`/admin/webhooks/${id}/trigger`, {
2020-01-06 01:52:26 +01:00
method: 'POST',
2020-01-06 16:01:42 +01:00
signal,
2020-01-06 01:52:26 +01:00
});
dispatch({
type: 'TRIGGER_SUCCEEDED',
2020-01-06 16:01:42 +01:00
response: data,
2020-01-06 01:52:26 +01:00
});
} catch (err) {
if (err.code !== 20) {
strapi.notification.error('notification.error');
}
}
};
2019-12-18 18:13:24 +01:00
2020-01-06 16:01:42 +01:00
const onCancelTrigger = () => {
abortController.abort();
dispatch({
type: 'ON_TRIGGER_CANCELED',
});
};
const handleReset = () => {
dispatch({
type: 'RESET',
});
};
2019-12-18 18:13:24 +01:00
const actions = [
{
color: 'primary',
2020-01-06 10:48:34 +01:00
disabled: triggerActionIsDisabled,
2019-12-18 18:13:24 +01:00
type: 'button',
2020-01-06 01:52:26 +01:00
label: formatMessage({
2019-12-18 18:13:24 +01:00
id: `Settings.webhooks.trigger`,
}),
2020-01-06 01:52:26 +01:00
onClick: () => {
handleTrigger();
},
2019-12-18 18:13:24 +01:00
style: {
paddingRight: 15,
paddingLeft: 15,
},
2020-01-06 10:48:34 +01:00
title: triggerActionIsDisabled
? formatMessage({
id: `Settings.webhooks.trigger.save`,
})
: null,
icon: (
<Play
width="6px"
height="7px"
fill={triggerActionIsDisabled ? '#b4b6ba' : '#ffffff'}
/>
),
2019-12-18 18:13:24 +01:00
},
{
2020-01-06 16:01:42 +01:00
onClick: () => {
handleReset();
},
2019-12-18 18:13:24 +01:00
color: 'cancel',
disabled: actionsAreDisabled,
type: 'button',
2020-01-06 01:52:26 +01:00
label: formatMessage({
2019-12-18 18:13:24 +01:00
id: `app.components.Button.reset`,
}),
style: {
paddingRight: 20,
paddingLeft: 20,
},
},
{
color: 'success',
disabled: actionsAreDisabled,
type: 'submit',
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-07 16:00:11 +01:00
2019-12-18 18:13:24 +01:00
const headerProps = {
title: {
label: headerTitle,
},
actions: actions,
};
2020-01-02 09:55:26 +01:00
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name.split('.'),
value,
});
};
2020-01-03 10:53:58 +01:00
const handleClick = () => {
dispatch({
type: 'ADD_NEW_HEADER',
keys: ['headers'],
});
};
2020-01-07 16:00:11 +01:00
const handleRemove = ({ event, index }) => {
dispatch({
type: 'ON_HEADER_REMOVE',
index,
event,
});
};
2020-01-06 10:48:34 +01:00
const handleSubmit = e => {
e.preventDefault();
2020-01-07 16:00:11 +01:00
checkFormErrors();
};
const submitForm = () => {
2020-01-06 11:02:11 +01:00
if (!isCreatingWebhook) {
updateWebhook();
} else {
createWebhooks();
}
2020-01-06 10:48:34 +01:00
};
2020-01-07 16:00:11 +01:00
const checkFormErrors = async () => {
const webhookToCheck = cloneDeep(modifiedWebhook);
set(webhookToCheck, 'headers', cleanHeaders());
2020-01-06 10:48:34 +01:00
try {
2020-01-07 16:00:11 +01:00
await createYupSchema(form).validate(webhookToCheck, {
abortEarly: false,
});
resetErrors();
submitForm();
} catch (err) {
2020-01-08 14:55:37 +01:00
strapi.notification.error('notification.form.error.fields');
2020-01-07 16:00:11 +01:00
2020-01-08 14:55:37 +01:00
const errors = getYupInnerErrors(err);
2020-01-07 16:00:11 +01:00
setErrors(errors);
}
};
2020-01-06 10:48:34 +01:00
2020-01-07 16:00:11 +01:00
const cleanHeaders = () => {
const { headers } = modifiedWebhook;
if (Object.keys(headers).length === 1) {
const { key, value } = headers[0];
if (key.length === 0 && value.length === 0) return [];
}
return headers;
};
const resetErrors = () => {
dispatch({
type: 'SET_ERRORS',
errors: null,
});
};
const setErrors = errors => {
dispatch({
type: 'SET_ERRORS',
errors,
});
};
const formatWebhook = () => {
const webhooks = cloneDeep(modifiedWebhook);
set(webhooks, 'headers', unformatLayout(cleanHeaders()));
return webhooks;
};
const createWebhooks = async () => {
try {
2020-01-06 10:48:34 +01:00
await request(`/admin/webhooks`, {
method: 'POST',
2020-01-07 16:00:11 +01:00
body: formatWebhook(),
2020-01-06 10:48:34 +01:00
});
2020-01-07 16:00:11 +01:00
strapi.notification.success(`notification.success`);
2020-01-06 11:02:11 +01:00
goBack();
} catch (err) {
strapi.notification.error('notification.error');
}
};
const updateWebhook = async () => {
try {
2020-01-07 16:00:11 +01:00
const body = formatWebhook();
2020-01-06 16:01:42 +01:00
delete body.id;
2020-01-06 11:02:11 +01:00
await request(`/admin/webhooks/${id}`, {
method: 'PUT',
body,
});
2020-01-06 10:48:34 +01:00
dispatch({
type: 'SUBMIT_SUCCEEDED',
});
2020-01-07 16:00:11 +01:00
strapi.notification.success(`notification.success`);
2020-01-06 10:48:34 +01:00
} catch (err) {
strapi.notification.error('notification.error');
}
};
// utils
const unformatLayout = headers => {
2020-01-07 16:00:11 +01:00
return headers.reduce((obj, item) => {
2020-01-06 10:48:34 +01:00
const { key, value } = item;
return {
...obj,
[key]: value,
};
}, {});
2020-01-06 16:01:42 +01:00
};
2019-12-16 21:53:30 +01:00
return (
2019-12-18 18:13:24 +01:00
<Wrapper>
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}>
<Inputs
{...form[key]}
2020-01-07 16:00:11 +01:00
error={get(formErrors, [key, 'id'], null)}
2020-01-06 10:48:34 +01:00
name={key}
onChange={handleChange}
onClick={handleClick}
2020-01-06 16:46:30 +01:00
onRemove={handleRemove}
2020-01-06 10:48:34 +01:00
validations={form[key].validations}
value={modifiedWebhook[key] || form[key].value}
/>
</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;