mirror of
https://github.com/strapi/strapi.git
synced 2025-12-26 14:44:31 +00:00
clean code
This commit is contained in:
parent
177fdb6c5d
commit
d98215c10b
@ -14,11 +14,11 @@ const EventRow = ({
|
||||
);
|
||||
const hasSomeCheckboxSelected = events.some(e => inputValue.indexOf(e) >= 0);
|
||||
|
||||
const handleChangeMultiple = ({ target: { name } }) => {
|
||||
const onChangeAll = ({ target: { name } }) => {
|
||||
const valueToSet = !areAllCheckboxesSelected;
|
||||
|
||||
handleChangeAll({
|
||||
target: { name: name, value: valueToSet },
|
||||
target: { name, value: valueToSet },
|
||||
});
|
||||
};
|
||||
|
||||
@ -27,7 +27,7 @@ const EventRow = ({
|
||||
<td>
|
||||
<Checkbox
|
||||
name={name}
|
||||
onChange={handleChangeMultiple}
|
||||
onChange={onChangeAll}
|
||||
message={name}
|
||||
someChecked={hasSomeCheckboxSelected && !areAllCheckboxesSelected}
|
||||
value={areAllCheckboxesSelected}
|
||||
|
||||
@ -17,22 +17,22 @@ const Wrapper = styled.div`
|
||||
tr {
|
||||
&:before {
|
||||
content: '-';
|
||||
display: inline-block;
|
||||
line-height: 1.1em;
|
||||
color: transparent;
|
||||
background-color: #f6f6f6;
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
display: inline-block;
|
||||
width: calc(100% - 40px);
|
||||
height: 1px;
|
||||
margin-top: -1px;
|
||||
line-height: 1.1em;
|
||||
color: transparent;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
&:first-of-type:before {
|
||||
background-color: #fafafb;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
background-color: #fafafb;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
thead {
|
||||
@ -48,14 +48,13 @@ const Wrapper = styled.div`
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
box-shadow: inset 0px 0px 0px 1px #f6f6f6;
|
||||
|
||||
td {
|
||||
height: 54px;
|
||||
padding-bottom: 3px;
|
||||
&:first-of-type {
|
||||
width: 200px;
|
||||
padding-left: 30px;
|
||||
text-transform: capitalize;
|
||||
width: 200px;
|
||||
label {
|
||||
width: fit-content;
|
||||
margin-top: -1px;
|
||||
@ -64,9 +63,9 @@ const Wrapper = styled.div`
|
||||
}
|
||||
}
|
||||
&:not(:first-of-type) > div {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
width: fit-content;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,44 +19,35 @@ const EventInput = ({ onChange, name: inputName, value: inputValue }) => {
|
||||
media: ['media.create', 'media.update', 'media.delete'],
|
||||
};
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
let newValue = inputValue;
|
||||
|
||||
const formatValue = (name, value, newValue = inputValue) => {
|
||||
if (value) {
|
||||
if (!inputValue.includes(name)) {
|
||||
if (!newValue.includes(name)) {
|
||||
newValue.push(name);
|
||||
}
|
||||
} else {
|
||||
if (inputValue.includes(name)) {
|
||||
const index = inputValue.indexOf(name);
|
||||
if (newValue.includes(name)) {
|
||||
const index = newValue.indexOf(name);
|
||||
if (index > -1) {
|
||||
newValue.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newValue;
|
||||
};
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
const newValue = formatValue(name, value);
|
||||
onChange({ target: { name: inputName, value: newValue } });
|
||||
};
|
||||
|
||||
const handleChangeAll = ({ target: { name, value } }) => {
|
||||
let newValue = inputValue;
|
||||
|
||||
if (value) {
|
||||
events[name].map(event => {
|
||||
if (!inputValue.includes(event)) {
|
||||
newValue.push(event);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
events[name].map(event => {
|
||||
const index = inputValue.indexOf(event);
|
||||
if (index > -1) {
|
||||
newValue.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
events[name].map(event => {
|
||||
newValue = formatValue(event, value, newValue);
|
||||
});
|
||||
|
||||
onChange({ target: { name: inputName, value: newValue } });
|
||||
onChange({ target: { name: inputName, value: inputValue } });
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -7,19 +7,19 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
background-color: #fafafb;
|
||||
padding: 23px 24px 26px 24px;
|
||||
margin-top: 12px;
|
||||
padding: 23px 24px 26px 24px;
|
||||
background-color: #fafafb;
|
||||
border-radius: 3px;
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
& + button {
|
||||
padding: 0;
|
||||
color: #007eff;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
svg,
|
||||
span {
|
||||
@ -40,8 +40,8 @@ const Wrapper = styled.div`
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
> section {
|
||||
width: 50%;
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
vertical-align: top;
|
||||
&:nth-child(odd) {
|
||||
padding-right: 15px;
|
||||
|
||||
@ -7,19 +7,23 @@ import { CircleButton } from 'strapi-helper-plugin';
|
||||
import { InputText } from '@buffetjs/core';
|
||||
import { Plus } from '@buffetjs/icons';
|
||||
|
||||
import keys from './keys';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
import keys from './keys';
|
||||
|
||||
const HeadersInput = ({
|
||||
errors,
|
||||
name,
|
||||
onBlur,
|
||||
onClick,
|
||||
onChange,
|
||||
name,
|
||||
value,
|
||||
onRemove,
|
||||
errors,
|
||||
value,
|
||||
}) => {
|
||||
const optionFormat = value => ({ value: value, label: value });
|
||||
const options = keys.map(key => optionFormat(key));
|
||||
|
||||
const handleBlur = () => onBlur({ target: { name, value } });
|
||||
|
||||
const handleChangeKey = (selected, name) => {
|
||||
if (selected === null) {
|
||||
onChange({ target: { name, value: '' } });
|
||||
@ -29,24 +33,11 @@ const HeadersInput = ({
|
||||
}
|
||||
};
|
||||
|
||||
const optionFormat = value => {
|
||||
return { value: value, label: value };
|
||||
};
|
||||
|
||||
const options = keys.map(key => {
|
||||
return optionFormat(key);
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
onClick(name);
|
||||
};
|
||||
const handleClick = () => onClick(name);
|
||||
|
||||
const handleRemoveItem = index => {
|
||||
if (index === 0 && value.length === 1) {
|
||||
onRemove({ event: 'clear', index });
|
||||
} else {
|
||||
onRemove({ event: 'remove', index });
|
||||
}
|
||||
const event = index === 0 && value.length === 1 ? 'clear' : 'remove';
|
||||
onRemove({ event, index });
|
||||
};
|
||||
|
||||
const customStyles = hasError => {
|
||||
@ -95,10 +86,6 @@ const HeadersInput = ({
|
||||
};
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
onBlur({ target: { name, value } });
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<ul>
|
||||
@ -125,20 +112,19 @@ const HeadersInput = ({
|
||||
isClearable
|
||||
onBlur={handleBlur}
|
||||
onChange={e => handleChangeKey(e, `${name}.${index}.key`)}
|
||||
options={options}
|
||||
name={`${name}.${index}.key`}
|
||||
value={optionFormat(key)}
|
||||
options={options}
|
||||
styles={customStyles(entryErrors && entryErrors.key)}
|
||||
value={optionFormat(key)}
|
||||
/>
|
||||
</section>
|
||||
<section>
|
||||
<InputText
|
||||
onBlur={handleBlur}
|
||||
className={entryErrors && entryErrors.value && 'bordered'}
|
||||
error={entryErrors && entryErrors.value}
|
||||
value={value}
|
||||
name={`${name}.${index}.value`}
|
||||
onChange={onChange}
|
||||
name={`${name}.${index}.value`}
|
||||
value={value}
|
||||
/>
|
||||
</section>
|
||||
<div>
|
||||
|
||||
@ -16,13 +16,13 @@ const Wrapper = styled.div`
|
||||
}
|
||||
> p {
|
||||
width 100%;
|
||||
margin-bottom: -8px;
|
||||
padding-top: 10px;
|
||||
font-size: 13px;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
${({ error }) =>
|
||||
!!error &&
|
||||
|
||||
@ -5,102 +5,103 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { ErrorMessage, Label } from '@buffetjs/styles';
|
||||
import { Error, InputText } from '@buffetjs/core';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import HeadersInput from '../HeadersInput';
|
||||
import EventInput from '../EventInput';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
function Inputs({
|
||||
error: inputError,
|
||||
label,
|
||||
name,
|
||||
onChange,
|
||||
onBlur: handleBlur,
|
||||
onBlur,
|
||||
onClick,
|
||||
onRemove,
|
||||
type,
|
||||
validations,
|
||||
value,
|
||||
}) {
|
||||
if (type === 'headers') {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Label htmlFor={name}>{label}</Label>
|
||||
<HeadersInput
|
||||
value={value}
|
||||
name={name}
|
||||
onBlur={handleBlur}
|
||||
onClick={onClick}
|
||||
onChange={onChange}
|
||||
onRemove={onRemove}
|
||||
errors={inputError}
|
||||
/>
|
||||
{inputError && <ErrorMessage>This value is required</ErrorMessage>}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Error
|
||||
inputError={inputError}
|
||||
name={name}
|
||||
type="text"
|
||||
validations={validations}
|
||||
>
|
||||
{({ canCheck, error, dispatch }) => {
|
||||
const hasError = error && error !== null;
|
||||
<Wrapper>
|
||||
<Label htmlFor={name}>{label}</Label>
|
||||
{type === 'headers' ? (
|
||||
<>
|
||||
<HeadersInput
|
||||
errors={inputError}
|
||||
name={name}
|
||||
onBlur={onBlur}
|
||||
onClick={onClick}
|
||||
onChange={onChange}
|
||||
onRemove={onRemove}
|
||||
value={value}
|
||||
/>
|
||||
{inputError && (
|
||||
<ErrorMessage>
|
||||
<FormattedMessage id="components.Input.error.validation.required" />
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Error
|
||||
inputError={inputError}
|
||||
name={name}
|
||||
type="text"
|
||||
validations={validations}
|
||||
>
|
||||
{({ canCheck, error, dispatch }) => {
|
||||
const hasError = error && error !== null;
|
||||
|
||||
const handleChange = e => {
|
||||
if (!canCheck) {
|
||||
dispatch({
|
||||
type: 'SET_CHECK',
|
||||
});
|
||||
}
|
||||
const handleChange = e => {
|
||||
if (!canCheck) {
|
||||
dispatch({
|
||||
type: 'SET_CHECK',
|
||||
});
|
||||
}
|
||||
dispatch({
|
||||
type: 'SET_ERROR',
|
||||
error: null,
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'SET_ERROR',
|
||||
error: null,
|
||||
});
|
||||
onChange(e);
|
||||
};
|
||||
onChange(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Label htmlFor={name}>{label}</Label>
|
||||
|
||||
{type === 'events' ? (
|
||||
<EventInput
|
||||
value={value}
|
||||
name={name}
|
||||
onChange={e => {
|
||||
handleChange(e);
|
||||
handleBlur(e);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<InputText
|
||||
error={hasError}
|
||||
onBlur={handleBlur}
|
||||
onChange={handleChange}
|
||||
value={value}
|
||||
name={name}
|
||||
/>
|
||||
)}
|
||||
|
||||
{hasError && <ErrorMessage>{error}</ErrorMessage>}
|
||||
</Wrapper>
|
||||
);
|
||||
}}
|
||||
</Error>
|
||||
return (
|
||||
<>
|
||||
{type === 'events' ? (
|
||||
<EventInput
|
||||
name={name}
|
||||
onChange={e => {
|
||||
handleChange(e);
|
||||
onBlur(e);
|
||||
}}
|
||||
value={value}
|
||||
/>
|
||||
) : (
|
||||
<InputText
|
||||
error={hasError}
|
||||
name={name}
|
||||
onBlur={onBlur}
|
||||
onChange={handleChange}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
{hasError && <ErrorMessage>{error}</ErrorMessage>}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Error>
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
Inputs.defaultProps = {
|
||||
error: null,
|
||||
label: '',
|
||||
onBlur: () => {},
|
||||
onClick: () => {},
|
||||
onRemove: () => {},
|
||||
type: 'text',
|
||||
@ -110,7 +111,7 @@ Inputs.defaultProps = {
|
||||
|
||||
Inputs.propTypes = {
|
||||
error: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
label: PropTypes.oneOfType([PropTypes.string]),
|
||||
label: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
@ -118,11 +119,7 @@ Inputs.propTypes = {
|
||||
onRemove: PropTypes.func,
|
||||
type: PropTypes.string,
|
||||
validations: PropTypes.object,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
]),
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
||||
};
|
||||
|
||||
export default Inputs;
|
||||
|
||||
@ -16,8 +16,8 @@ const StyledListRow = styled(Row)`
|
||||
white-space: nowrap;
|
||||
}
|
||||
&:first-of-type {
|
||||
padding-left: 30px;
|
||||
width: 65px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
max-width: 158px;
|
||||
|
||||
@ -28,9 +28,7 @@ function ListRow({
|
||||
const links = [
|
||||
{
|
||||
icon: 'pencil',
|
||||
onClick: e => {
|
||||
handleEditClick(e);
|
||||
},
|
||||
onClick: () => handleEditClick(),
|
||||
},
|
||||
{
|
||||
icon: 'trash',
|
||||
@ -43,17 +41,12 @@ function ListRow({
|
||||
|
||||
const isChecked = itemsToDelete.includes(id);
|
||||
|
||||
const handleEditClick = () => {
|
||||
onEditClick(id);
|
||||
};
|
||||
const handleEditClick = () => onEditClick(id);
|
||||
|
||||
const handleEnabledChange = ({ target: { value } }) => {
|
||||
const handleEnabledChange = ({ target: { value } }) =>
|
||||
onEnabledChange(value, id);
|
||||
};
|
||||
|
||||
const handleCheckChange = ({ target: { value } }) => {
|
||||
onCheckChange(value, id);
|
||||
};
|
||||
const handleCheckChange = ({ target: { value } }) => onCheckChange(value, id);
|
||||
|
||||
const handleDeleteConfirm = () => {
|
||||
onDeleteCLick(id);
|
||||
@ -61,44 +54,42 @@ function ListRow({
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledListRow onClick={handleEditClick}>
|
||||
<td>
|
||||
<Checkbox
|
||||
<StyledListRow onClick={handleEditClick}>
|
||||
<td>
|
||||
<Checkbox
|
||||
name={name}
|
||||
value={isChecked}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={handleCheckChange}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<p>{name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p title={url}>{url}</p>
|
||||
</td>
|
||||
<td>
|
||||
<div onClick={e => e.stopPropagation()}>
|
||||
<Switch
|
||||
name={name}
|
||||
value={isChecked}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={handleCheckChange}
|
||||
value={isEnabled}
|
||||
onChange={handleEnabledChange}
|
||||
></Switch>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<IconLinks links={links} />
|
||||
<div className="popup-wrapper">
|
||||
<PopUpWarning
|
||||
isOpen={showModal}
|
||||
toggleModal={() => setShowModal(!showModal)}
|
||||
popUpWarningType="danger"
|
||||
onConfirm={handleDeleteConfirm}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<p>{name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p title={url}>{url}</p>
|
||||
</td>
|
||||
<td>
|
||||
<div onClick={e => e.stopPropagation()}>
|
||||
<Switch
|
||||
name={name}
|
||||
value={isEnabled}
|
||||
onChange={handleEnabledChange}
|
||||
></Switch>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<IconLinks links={links} />
|
||||
<div className="popup-wrapper">
|
||||
<PopUpWarning
|
||||
isOpen={showModal}
|
||||
toggleModal={() => setShowModal(!showModal)}
|
||||
popUpWarningType="danger"
|
||||
onConfirm={handleDeleteConfirm}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</StyledListRow>
|
||||
</>
|
||||
</div>
|
||||
</td>
|
||||
</StyledListRow>
|
||||
);
|
||||
}
|
||||
|
||||
@ -111,8 +102,6 @@ ListRow.defaultProps = {
|
||||
onEditClick: () => {},
|
||||
onEnabledChange: () => {},
|
||||
url: null,
|
||||
headers: {},
|
||||
hooks: [],
|
||||
};
|
||||
|
||||
ListRow.propTypes = {
|
||||
@ -125,8 +114,6 @@ ListRow.propTypes = {
|
||||
onEditClick: PropTypes.func,
|
||||
onEnabledChange: PropTypes.func,
|
||||
url: PropTypes.string,
|
||||
headers: PropTypes.object,
|
||||
hooks: PropTypes.instanceOf(Array),
|
||||
};
|
||||
|
||||
export default ListRow;
|
||||
|
||||
@ -11,10 +11,10 @@ const Toggle = styled.input`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
`;
|
||||
|
||||
|
||||
@ -9,29 +9,28 @@ import styled from 'styled-components';
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
.button {
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
margin-right: 12px;
|
||||
.button-rect {
|
||||
position: relative;
|
||||
z-index: -2;
|
||||
margin-top: 3px;
|
||||
width: 30px;
|
||||
height: 12px;
|
||||
background-color: #faa684;
|
||||
border-radius: 6px;
|
||||
margin-top: 3px;
|
||||
z-index: -2;
|
||||
}
|
||||
.button-circle {
|
||||
background-color: #f1f1f1;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -1px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
border-radius: 9px;
|
||||
|
||||
background-color: #f1f1f1;
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
||||
@ -19,9 +19,9 @@ function Switch({ name, value, onChange }) {
|
||||
<Toggle
|
||||
checked={value}
|
||||
name={name}
|
||||
onChange={e => {
|
||||
onChange({ target: { name, value: e.target.checked } });
|
||||
}}
|
||||
onChange={({ target: { checked } }) =>
|
||||
onChange({ target: { name, value: checked } })
|
||||
}
|
||||
/>
|
||||
<div className="button">
|
||||
<div className="button-rect"></div>
|
||||
|
||||
@ -29,10 +29,8 @@ const Wrapper = styled.div`
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
svg {
|
||||
& + span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
svg + span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
&.success-label {
|
||||
svg {
|
||||
@ -46,8 +44,8 @@ const Wrapper = styled.div`
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
text-align: right;
|
||||
max-width: 400px;
|
||||
text-align: right;
|
||||
button {
|
||||
color: #b4b6ba;
|
||||
&,
|
||||
|
||||
@ -17,13 +17,16 @@ const TriggerContainer = ({ isPending, onCancel, response }) => {
|
||||
<td>
|
||||
<p>Test-trigger</p>
|
||||
</td>
|
||||
|
||||
{isPending ? (
|
||||
<>
|
||||
<td>
|
||||
<p>
|
||||
<Pending fill="#6DBB1A" width="15px" height="15px" />
|
||||
<span>Pending...</span>
|
||||
<span>
|
||||
{formatMessage({
|
||||
id: `Settings.webhooks.trigger.pending`,
|
||||
})}
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
@ -38,11 +41,19 @@ const TriggerContainer = ({ isPending, onCancel, response }) => {
|
||||
<td>
|
||||
<p className="success-label">
|
||||
<Success fill="#6DBB1A" width="19px" height="19px" />
|
||||
<span>Success!</span>
|
||||
<span>
|
||||
{formatMessage({
|
||||
id: `Settings.webhooks.trigger.success`,
|
||||
})}
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>Trigger succeded</p>
|
||||
<p>
|
||||
{formatMessage({
|
||||
id: `Settings.webhooks.trigger.success.label`,
|
||||
})}
|
||||
</p>
|
||||
</td>
|
||||
</>
|
||||
) : (
|
||||
@ -68,6 +79,7 @@ const TriggerContainer = ({ isPending, onCancel, response }) => {
|
||||
TriggerContainer.defaultProps = {
|
||||
isPending: false,
|
||||
onCancel: () => {},
|
||||
response: {},
|
||||
};
|
||||
|
||||
TriggerContainer.propTypes = {
|
||||
|
||||
@ -17,18 +17,18 @@ const Wrapper = styled.div`
|
||||
}
|
||||
.header-title + div {
|
||||
button: first-of-type {
|
||||
margin-right: 30px;
|
||||
position: relative;
|
||||
margin-right: 30px;
|
||||
overflow: initial;
|
||||
&::after {
|
||||
content: '-';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: -20px;
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background-color: #e9eaeb;
|
||||
color: transparent;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: -20px;
|
||||
}
|
||||
span svg {
|
||||
margin-top: -2px;
|
||||
@ -39,17 +39,17 @@ const Wrapper = styled.div`
|
||||
padding-top: 4px;
|
||||
}
|
||||
.form-card {
|
||||
margin-bottom: 30px;
|
||||
padding: 21px 25px 0px 25px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 4px 0 #e3e9f3;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.row {
|
||||
> div {
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
z-index: 0;
|
||||
margin-bottom: 4px;
|
||||
&:nth-of-type(3) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
import React, { useEffect, useReducer, useCallback, useState } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { cloneDeep, get, isEmpty, isEqual, set, setWith } from 'lodash';
|
||||
import { get, isEmpty, isEqual, set, setWith } from 'lodash';
|
||||
import { Header } from '@buffetjs/custom';
|
||||
import { Play } from '@buffetjs/icons';
|
||||
import {
|
||||
@ -18,7 +18,7 @@ import {
|
||||
|
||||
import reducer, { initialState } from './reducer';
|
||||
import form from './utils/form';
|
||||
import { createYupSchema, createYupSchemaEntry } from './utils/schema';
|
||||
import createYupSchema from './utils/schema';
|
||||
|
||||
import Inputs from '../../../components/Inputs';
|
||||
import TriggerContainer from '../../../components/TriggerContainer';
|
||||
@ -29,7 +29,7 @@ function EditView() {
|
||||
const [submittedOnce, setSubmittedOnce] = useState(false);
|
||||
const [reducerState, dispatch] = useReducer(reducer, initialState);
|
||||
const location = useLocation();
|
||||
const { goBack, push } = useHistory();
|
||||
const { push } = useHistory();
|
||||
|
||||
const {
|
||||
formErrors,
|
||||
@ -43,17 +43,17 @@ function EditView() {
|
||||
const { name } = modifiedWebhook;
|
||||
|
||||
const id = location.pathname.split('/')[3];
|
||||
const isCreatingWebhook = id === 'create';
|
||||
const isCreating = id === 'create';
|
||||
|
||||
const abortController = new AbortController();
|
||||
|
||||
const { signal } = abortController;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isCreatingWebhook || (!isCreatingWebhook && shouldRefetchData)) {
|
||||
if (!isCreating || (!isCreating && shouldRefetchData)) {
|
||||
fetchData();
|
||||
}
|
||||
}, [fetchData, isCreatingWebhook, shouldRefetchData]);
|
||||
}, [fetchData, isCreating, shouldRefetchData]);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
try {
|
||||
@ -72,8 +72,7 @@ function EditView() {
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
// Header props
|
||||
const headerTitle = isCreatingWebhook
|
||||
const headerTitle = isCreating
|
||||
? formatMessage({
|
||||
id: `Settings.webhooks.create`,
|
||||
})
|
||||
@ -84,7 +83,7 @@ function EditView() {
|
||||
Object.keys(formErrors).length > 0;
|
||||
|
||||
const triggerActionIsDisabled =
|
||||
isCreatingWebhook || (!isCreatingWebhook && !actionsAreDisabled);
|
||||
isCreating || (!isCreating && !actionsAreDisabled);
|
||||
|
||||
const handleTrigger = async () => {
|
||||
dispatch({
|
||||
@ -116,17 +115,15 @@ function EditView() {
|
||||
});
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
const handleReset = () =>
|
||||
dispatch({
|
||||
type: 'RESET',
|
||||
});
|
||||
};
|
||||
|
||||
const actions = [
|
||||
{
|
||||
color: 'primary',
|
||||
disabled: triggerActionIsDisabled,
|
||||
type: 'button',
|
||||
label: formatMessage({
|
||||
id: `Settings.webhooks.trigger`,
|
||||
}),
|
||||
@ -134,14 +131,14 @@ function EditView() {
|
||||
handleTrigger();
|
||||
},
|
||||
style: {
|
||||
paddingRight: 15,
|
||||
paddingLeft: 15,
|
||||
padding: '0 15px',
|
||||
},
|
||||
title: triggerActionIsDisabled
|
||||
? formatMessage({
|
||||
id: `Settings.webhooks.trigger.save`,
|
||||
})
|
||||
: null,
|
||||
type: 'button',
|
||||
icon: (
|
||||
<Play
|
||||
width="6px"
|
||||
@ -151,30 +148,27 @@ function EditView() {
|
||||
),
|
||||
},
|
||||
{
|
||||
onClick: () => {
|
||||
handleReset();
|
||||
},
|
||||
color: 'cancel',
|
||||
disabled: actionsAreDisabled,
|
||||
type: 'button',
|
||||
label: formatMessage({
|
||||
id: `app.components.Button.reset`,
|
||||
}),
|
||||
onClick: () => handleReset(),
|
||||
style: {
|
||||
paddingRight: 20,
|
||||
paddingLeft: 20,
|
||||
padding: '0 20px',
|
||||
},
|
||||
type: 'button',
|
||||
},
|
||||
{
|
||||
color: 'success',
|
||||
disabled: actionsAreDisabled,
|
||||
type: 'submit',
|
||||
label: formatMessage({
|
||||
id: `app.components.Button.save`,
|
||||
}),
|
||||
style: {
|
||||
minWidth: 140,
|
||||
},
|
||||
type: 'submit',
|
||||
},
|
||||
];
|
||||
|
||||
@ -185,8 +179,8 @@ function EditView() {
|
||||
actions: actions,
|
||||
};
|
||||
|
||||
const handleBlur = ({ target }) => {
|
||||
if (submittedOnce) checkFormError(target);
|
||||
const handleBlur = () => {
|
||||
if (submittedOnce) checkFormErrors();
|
||||
};
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
@ -216,34 +210,19 @@ function EditView() {
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
setSubmittedOnce(true);
|
||||
checkFormErrors();
|
||||
checkFormErrors(true);
|
||||
};
|
||||
|
||||
const submitForm = () => {
|
||||
if (!isCreatingWebhook) {
|
||||
if (!isCreating) {
|
||||
updateWebhook();
|
||||
} else {
|
||||
createWebhooks();
|
||||
}
|
||||
};
|
||||
|
||||
const checkFormError = async target => {
|
||||
const { name, value } = target;
|
||||
const { type, validations } = form[name];
|
||||
|
||||
try {
|
||||
await createYupSchemaEntry(type, validations).validate(value, {
|
||||
abortEarly: false,
|
||||
});
|
||||
|
||||
resetError(name);
|
||||
} catch (err) {
|
||||
setError(err, name);
|
||||
}
|
||||
};
|
||||
|
||||
const checkFormErrors = async () => {
|
||||
const webhookToCheck = cloneDeep(modifiedWebhook);
|
||||
const checkFormErrors = async (submit = false) => {
|
||||
const webhookToCheck = modifiedWebhook;
|
||||
set(webhookToCheck, 'headers', cleanHeaders());
|
||||
|
||||
try {
|
||||
@ -251,13 +230,11 @@ function EditView() {
|
||||
abortEarly: false,
|
||||
});
|
||||
|
||||
resetErrors();
|
||||
submitForm();
|
||||
setErrors({});
|
||||
if (submit) submitForm();
|
||||
} catch (err) {
|
||||
strapi.notification.error('notification.form.error.fields');
|
||||
|
||||
const errors = getYupInnerErrors(err);
|
||||
setErrors(errors);
|
||||
setErrors(getYupInnerErrors(err));
|
||||
if (submit) strapi.notification.error('notification.form.error.fields');
|
||||
}
|
||||
};
|
||||
|
||||
@ -271,43 +248,17 @@ function EditView() {
|
||||
return headers;
|
||||
};
|
||||
|
||||
const goBack = () => push('/settings/webhooks');
|
||||
|
||||
const resetError = name => {
|
||||
const errors = formErrors;
|
||||
|
||||
if (errors[name]) {
|
||||
delete errors[name];
|
||||
resetErrors(errors);
|
||||
setErrors(errors);
|
||||
}
|
||||
};
|
||||
|
||||
const resetErrors = (errors = {}) => {
|
||||
dispatch({
|
||||
type: 'SET_ERRORS',
|
||||
errors: errors,
|
||||
});
|
||||
};
|
||||
|
||||
const setError = (errors, name) => {
|
||||
const err =
|
||||
name === 'headers'
|
||||
? getYupInnerErrors(errors)
|
||||
: { [name]: errors.message };
|
||||
|
||||
const formattedErrors = formErrors;
|
||||
|
||||
const newErrors = Object.keys(err).reduce((acc, curr) => {
|
||||
const path = name === 'headers' ? `${name}${curr}` : name;
|
||||
|
||||
setWith(acc, path, err[curr], Object);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
set(formattedErrors, name, newErrors[name]);
|
||||
|
||||
setErrors(formattedErrors);
|
||||
};
|
||||
|
||||
const setErrors = errors => {
|
||||
const newErrors = Object.keys(errors).reduce((acc, curr) => {
|
||||
const { id } = errors[curr];
|
||||
@ -323,12 +274,6 @@ function EditView() {
|
||||
});
|
||||
};
|
||||
|
||||
const formatWebhook = () => {
|
||||
const webhooks = cloneDeep(modifiedWebhook);
|
||||
set(webhooks, 'headers', unformatLayout(cleanHeaders()));
|
||||
return webhooks;
|
||||
};
|
||||
|
||||
const createWebhooks = async () => {
|
||||
try {
|
||||
await request(`/admin/webhooks`, {
|
||||
@ -363,7 +308,13 @@ function EditView() {
|
||||
};
|
||||
|
||||
// utils
|
||||
const unformatLayout = headers => {
|
||||
const formatWebhook = () => {
|
||||
const webhooks = modifiedWebhook;
|
||||
set(webhooks, 'headers', unformatHeaders(cleanHeaders()));
|
||||
return webhooks;
|
||||
};
|
||||
|
||||
const unformatHeaders = headers => {
|
||||
return headers.reduce((obj, item) => {
|
||||
const { key, value } = item;
|
||||
return {
|
||||
@ -375,7 +326,7 @@ function EditView() {
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<BackHeader onClick={() => push('/settings/webhooks')} />
|
||||
<BackHeader onClick={goBack} />
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Header {...headerProps} />
|
||||
{(isTriggering || !isEmpty(triggerResponse)) && (
|
||||
|
||||
@ -29,7 +29,6 @@ const reducer = (state, action) => {
|
||||
return { key: key, value: headers[key] };
|
||||
})
|
||||
);
|
||||
|
||||
set(data, ['headers'], newHeaders);
|
||||
} else {
|
||||
set(data, ['headers'], get(initialWebhook, 'headers'));
|
||||
@ -40,19 +39,16 @@ const reducer = (state, action) => {
|
||||
.update('modifiedWebhook', () => fromJS(data))
|
||||
.update('shouldRefetchData', () => false);
|
||||
}
|
||||
case 'TRIGGER_SUCCEEDED': {
|
||||
case 'TRIGGER_SUCCEEDED':
|
||||
return state
|
||||
.update('triggerResponse', () => fromJS(action.response))
|
||||
.update('isTriggering', () => false);
|
||||
}
|
||||
case 'ON_TRIGGER': {
|
||||
case 'ON_TRIGGER':
|
||||
return state.update('isTriggering', () => true);
|
||||
}
|
||||
case 'ON_TRIGGER_CANCELED': {
|
||||
case 'ON_TRIGGER_CANCELED':
|
||||
return state
|
||||
.update('isTriggering', () => false)
|
||||
.update('triggerResponse', () => {});
|
||||
}
|
||||
case 'ON_CHANGE':
|
||||
return state.updateIn(
|
||||
['modifiedWebhook', ...action.keys],
|
||||
@ -74,17 +70,14 @@ const reducer = (state, action) => {
|
||||
);
|
||||
}
|
||||
}
|
||||
case 'RESET': {
|
||||
case 'RESET':
|
||||
return state.update('modifiedWebhook', () =>
|
||||
fromJS(state.get('initialWebhook'))
|
||||
);
|
||||
}
|
||||
case 'SET_ERRORS': {
|
||||
case 'SET_ERRORS':
|
||||
return state.update('formErrors', () => fromJS(action.errors));
|
||||
}
|
||||
case 'SUBMIT_SUCCEEDED': {
|
||||
case 'SUBMIT_SUCCEEDED':
|
||||
return state.update('shouldRefetchData', () => true);
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -7,8 +7,8 @@ const translatedErrors = {
|
||||
string: 'This is not a string',
|
||||
};
|
||||
|
||||
const createYupSchema = form => {
|
||||
const validation = yup.object().shape(
|
||||
const createYupSchema = form =>
|
||||
yup.object().shape(
|
||||
Object.keys(form).reduce((acc, current) => {
|
||||
const { type, validations } = form[current];
|
||||
acc[current] = createYupSchemaEntry(type, validations);
|
||||
@ -17,9 +17,6 @@ const createYupSchema = form => {
|
||||
}, {})
|
||||
);
|
||||
|
||||
return validation;
|
||||
};
|
||||
|
||||
const createYupSchemaEntry = (type, validations) => {
|
||||
let schema = yup.mixed();
|
||||
|
||||
@ -38,6 +35,7 @@ const createYupSchemaEntry = (type, validations) => {
|
||||
)
|
||||
.nullable();
|
||||
}
|
||||
|
||||
if (['events'].includes(type)) {
|
||||
schema = yup.array();
|
||||
}
|
||||
@ -59,4 +57,4 @@ const createYupSchemaEntry = (type, validations) => {
|
||||
return schema;
|
||||
};
|
||||
|
||||
export { createYupSchema, createYupSchemaEntry };
|
||||
export default createYupSchema;
|
||||
|
||||
@ -13,11 +13,10 @@ const reducer = (state, action) => {
|
||||
.update('shouldRefetchData', () => false);
|
||||
case 'SET_WEBHOOK_ENABLED':
|
||||
return state.updateIn(['webhooks', ...action.keys], () => action.value);
|
||||
case 'WEBHOOK_DELETED': {
|
||||
case 'WEBHOOK_DELETED':
|
||||
return state.update('webhooks', webhooks =>
|
||||
webhooks.splice(action.index, 1)
|
||||
);
|
||||
}
|
||||
case 'WEBHOOKS_DELETED':
|
||||
return state.update('shouldRefetchData', v => !v);
|
||||
default:
|
||||
|
||||
@ -238,6 +238,9 @@
|
||||
"Settings.webhooks.trigger": "Trigger",
|
||||
"Settings.webhooks.trigger.title": "Save before Trigger",
|
||||
"Settings.webhooks.trigger.cancel": "Cancel trigger",
|
||||
"Settings.webhooks.trigger.pending": "Pending…",
|
||||
"Settings.webhooks.trigger.success": "Success!",
|
||||
"Settings.webhooks.trigger.success.label": "Trigger succeded",
|
||||
"Settings.webhooks.trigger.save": "Please save to trigger",
|
||||
"Settings.webhooks.events.create": "Create",
|
||||
"Settings.webhooks.events.edit": "Edit",
|
||||
|
||||
@ -20,10 +20,10 @@ function LeftMenuHeader({ count, search, searchable, setSearch, title }) {
|
||||
|
||||
const getTitle = () => {
|
||||
if (searchable) {
|
||||
return count > 1 ? (
|
||||
<FormattedMessage id={`${title.id}plural`} />
|
||||
) : (
|
||||
<FormattedMessage id={`${title.id}singular`} />
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={`${title.id}${count > 1 ? 'plural' : 'singular'}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,13 @@ import styled from 'styled-components';
|
||||
|
||||
const ListButton = styled.div`
|
||||
button {
|
||||
background-color: #e6f0fb;
|
||||
width: 100%;
|
||||
height: 54px;
|
||||
border-top: 1px solid #aed4fb;
|
||||
color: #007eff;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
background-color: #e6f0fb;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 2px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user