2019-12-16 21:53:30 +01:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* EditView
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2020-01-08 18:28:52 +01:00
|
|
|
import React, { useEffect, useReducer, useCallback, useState } from 'react';
|
2020-01-06 11:02:11 +01:00
|
|
|
import { useHistory, useLocation } from 'react-router-dom';
|
2020-01-10 15:17:36 +01:00
|
|
|
import { get, isEmpty, isEqual, set, setWith } 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,
|
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
|
|
|
|
|
|
|
|
import reducer, { initialState } from './reducer';
|
2020-01-02 09:55:26 +01:00
|
|
|
import form from './utils/form';
|
2020-01-10 15:17:36 +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();
|
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);
|
|
|
|
|
const location = useLocation();
|
2020-01-10 15:17:36 +01:00
|
|
|
const { push } = 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];
|
2020-01-10 15:17:36 +01:00
|
|
|
const isCreating = id === 'create';
|
2019-12-18 18:13:24 +01:00
|
|
|
|
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-10 15:17:36 +01:00
|
|
|
if (!isCreating || (!isCreating && shouldRefetchData)) {
|
2020-01-06 11:02:11 +01:00
|
|
|
fetchData();
|
|
|
|
|
}
|
2020-01-10 15:17:36 +01:00
|
|
|
}, [fetchData, isCreating, 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
|
|
|
|
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-08 18:28:52 +01:00
|
|
|
const actionsAreDisabled =
|
|
|
|
|
isEqual(initialWebhook, modifiedWebhook) ||
|
|
|
|
|
Object.keys(formErrors).length > 0;
|
|
|
|
|
|
2020-01-06 10:48:34 +01:00
|
|
|
const triggerActionIsDisabled =
|
2020-01-10 15:17:36 +01:00
|
|
|
isCreating || (!isCreating && !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',
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-10 15:17:36 +01:00
|
|
|
const handleReset = () =>
|
2020-01-06 16:01:42 +01:00
|
|
|
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,
|
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: {
|
2020-01-10 15:17:36 +01:00
|
|
|
padding: '0 15px',
|
2019-12-18 18:13:24 +01:00
|
|
|
},
|
2020-01-06 10:48:34 +01:00
|
|
|
title: triggerActionIsDisabled
|
|
|
|
|
? 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
|
|
|
|
|
width="6px"
|
|
|
|
|
height="7px"
|
|
|
|
|
fill={triggerActionIsDisabled ? '#b4b6ba' : '#ffffff'}
|
|
|
|
|
/>
|
|
|
|
|
),
|
2019-12-18 18:13:24 +01:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
color: 'cancel',
|
|
|
|
|
disabled: actionsAreDisabled,
|
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-10 15:17:36 +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',
|
|
|
|
|
disabled: actionsAreDisabled,
|
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,
|
|
|
|
|
},
|
|
|
|
|
actions: actions,
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-10 15:17:36 +01:00
|
|
|
const handleBlur = () => {
|
|
|
|
|
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,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
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-09 22:54:37 +01:00
|
|
|
resetError('headers');
|
2020-01-07 16:00:11 +01:00
|
|
|
};
|
|
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitForm = () => {
|
2020-01-10 15:17:36 +01:00
|
|
|
if (!isCreating) {
|
2020-01-06 11:02:11 +01:00
|
|
|
updateWebhook();
|
|
|
|
|
} else {
|
|
|
|
|
createWebhooks();
|
|
|
|
|
}
|
2020-01-06 10:48:34 +01:00
|
|
|
};
|
|
|
|
|
|
2020-01-10 15:17:36 +01:00
|
|
|
const checkFormErrors = async (submit = false) => {
|
|
|
|
|
const webhookToCheck = modifiedWebhook;
|
2020-01-07 16:00:11 +01:00
|
|
|
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,
|
|
|
|
|
});
|
|
|
|
|
|
2020-01-10 15:17:36 +01:00
|
|
|
setErrors({});
|
|
|
|
|
if (submit) submitForm();
|
2020-01-07 16:00:11 +01:00
|
|
|
} catch (err) {
|
2020-01-10 15:17:36 +01:00
|
|
|
setErrors(getYupInnerErrors(err));
|
|
|
|
|
if (submit) strapi.notification.error('notification.form.error.fields');
|
2020-01-07 16:00:11 +01:00
|
|
|
}
|
|
|
|
|
};
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-10 15:17:36 +01:00
|
|
|
const goBack = () => push('/settings/webhooks');
|
|
|
|
|
|
2020-01-08 18:28:52 +01:00
|
|
|
const resetError = name => {
|
|
|
|
|
const errors = formErrors;
|
|
|
|
|
|
|
|
|
|
if (errors[name]) {
|
|
|
|
|
delete errors[name];
|
2020-01-10 15:17:36 +01:00
|
|
|
setErrors(errors);
|
2020-01-08 18:28:52 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-07 16:00:11 +01:00
|
|
|
const setErrors = errors => {
|
2020-01-09 20:25:16 +01:00
|
|
|
const newErrors = Object.keys(errors).reduce((acc, curr) => {
|
|
|
|
|
const { id } = errors[curr];
|
|
|
|
|
|
|
|
|
|
setWith(acc, curr, id ? id : errors[curr], Object);
|
|
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
|
|
|
|
|
2020-01-07 16:00:11 +01:00
|
|
|
dispatch({
|
|
|
|
|
type: 'SET_ERRORS',
|
2020-01-09 20:25:16 +01:00
|
|
|
errors: newErrors,
|
2020-01-07 16:00:11 +01:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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-08 16:08:58 +01:00
|
|
|
strapi.notification.error('notification.form.success.fields');
|
2020-01-06 10:48:34 +01:00
|
|
|
} catch (err) {
|
|
|
|
|
strapi.notification.error('notification.error');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// utils
|
2020-01-10 15:17:36 +01:00
|
|
|
const formatWebhook = () => {
|
|
|
|
|
const webhooks = modifiedWebhook;
|
|
|
|
|
set(webhooks, 'headers', unformatHeaders(cleanHeaders()));
|
|
|
|
|
return webhooks;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const unformatHeaders = 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-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}>
|
|
|
|
|
<Inputs
|
|
|
|
|
{...form[key]}
|
2020-01-09 20:25:16 +01:00
|
|
|
error={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}
|
|
|
|
|
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;
|