Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f02567a
first specs
williampj Nov 26, 2020
b48b7eb
merging files
williampj Nov 26, 2020
f975a54
fast forwarded master
williampj Nov 26, 2020
1dd5d9c
adding inputs and stubs
williampj Nov 26, 2020
7481d22
more stubs
williampj Nov 26, 2020
e031a92
added more inputs
williampj Nov 26, 2020
90c5f69
stub edit
williampj Nov 26, 2020
0d341f8
ff
williampj Nov 27, 2020
4a0d157
.
williampj Nov 27, 2020
921d4f0
first tests
williampj Nov 28, 2020
6020ab8
updated tests
williampj Nov 28, 2020
1ad8ada
create bridge test
williampj Nov 29, 2020
e0d115e
added stubs
williampj Nov 29, 2020
9f7ba0d
ff
williampj Nov 29, 2020
d80a2b0
Fix williams broken spec
AndiLavera Nov 29, 2020
5be55f1
updated handlers
williampj Nov 29, 2020
4e49cf9
ff
williampj Nov 29, 2020
71b4685
cleaned stubs
williampj Nov 29, 2020
e91a168
started bridge/new spec
williampj Nov 30, 2020
666e235
payload validation in editor
williampj Nov 30, 2020
328c10c
.
williampj Nov 30, 2020
50e5826
.
williampj Nov 30, 2020
b89799a
adding payload validation
williampj Nov 30, 2020
421b688
without retries text
williampj Dec 1, 2020
018e242
random small bug fixes
AndiLavera Dec 1, 2020
78c19f9
ff
williampj Dec 1, 2020
2983c36
bridge handler
williampj Dec 1, 2020
cf69be5
.
williampj Dec 2, 2020
3286b51
further testing
williampj Dec 2, 2020
f630caa
expanded bridge.json
williampj Dec 2, 2020
61f3b5e
Merge branch 'master' of github.com:williampj/bridgeapi.js into cypre…
AndiLavera Dec 3, 2020
07c4749
Editor specs
AndiLavera Dec 4, 2020
4b55cb7
eslint fix
AndiLavera Dec 4, 2020
941b01d
Fix broken event spec for ci
AndiLavera Dec 4, 2020
764f3f8
Fix Sign up specs
AndiLavera Dec 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/Codemirror/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/fold/foldgutter.css';

function CodeMirror({
formKey, isEditView, readOnly, values, data,
formKey, isEditView, readOnly, values, data, id,
}) {
const codeRef = useRef(null);
const [mounted, setMounted] = useState(false);
Expand DownExpand Up@@ -111,7 +111,7 @@ function CodeMirror({
}, []);

return (
<div ref={codeRef} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
<div ref={codeRef} id={id} style={{ zIndex: fullScreen ? 1200 : 5, position: 'relative' }}>
{mounted
? (
<CM
Expand DownExpand Up@@ -159,6 +159,7 @@ CodeMirror.propTypes = {
testPayloadCode: PropTypes.string,
}),
data: PropTypes.shape({}),
id: PropTypes.string.isRequired,
};

CodeMirror.defaultProps = {
Expand Down
23 changes: 14 additions & 9 deletions components/Editor/ActionsDialog/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ const useStyles = makeStyles({
});

function ActionsDialog({
active, open, onClose, id,
active, open, onClose, bridgeId,
}) {
const [errorOpen, setErrorOpen] = useState(false);
const [successOpen, setSuccessOpen] = useState(false);
Expand All@@ -35,7 +35,7 @@ function ActionsDialog({

const handleAbort = () => {
api.patch('/events/abort', {
bridge_id: id,
bridge_id: bridgeId,
})
.then((res) => {
if (res.status === 200) {
Expand All@@ -51,8 +51,8 @@ function ActionsDialog({
};

const handleActivate = async () => {
await api.patch(`/bridges/${id}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${id}`);
await api.patch(`/bridges/${bridgeId}/${active ? 'deactivate' : 'activate'}`).then(() => {
router.push(`/bridge/${bridgeId}`);
setSuccessOpen(true);
setTimeout(() => {
setSuccessOpen(false);
Expand All@@ -66,7 +66,7 @@ function ActionsDialog({
};

const handleDelete = () => {
api.delete(`/bridges/${id}`).then(() => {
api.delete(`/bridges/${bridgeId}`).then(() => {
router.push('/dashboard');
}).catch(() => {
setErrorOpen(true);
Expand All@@ -82,6 +82,7 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={successOpen}
autoHideDuration={3000}
id="actions-success-message"
>
<Alert severity="success">
Success! Your bridge has been updated.
Expand All@@ -91,30 +92,34 @@ function ActionsDialog({
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={errorOpen}
autoHideDuration={3000}
id="actions-error-message"
>
<Alert severity="error">
Some error occurred. Please try again.
</Alert>
</Snackbar>

<DialogTitle id="simple-dialog-title">Bridge Actions</DialogTitle>
<List>
<ListItem button onClick={handleAbort}>
<ListItem button onClick={handleAbort} id="action-abort">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<CancelIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary="Abort Ongoing Requests" />
</ListItem>
<ListItem button onClick={handleActivate}>

<ListItem button onClick={handleActivate} id="action-deactive">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<PauseIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={`${active ? 'Deactivate' : 'Activate'} Bridge`} />
</ListItem>
<ListItem button onClick={handleDelete}>

<ListItem button onClick={handleDelete} id="action-delete">
<ListItemAvatar>
<Avatar className={classes.avatar}>
<DeleteForeverIcon />
Expand All@@ -131,7 +136,7 @@ ActionsDialog.propTypes = {
active: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
id: PropTypes.number.isRequired,
bridgeId: PropTypes.number.isRequired,
};

export default ActionsDialog;
1 change: 1 addition & 0 deletions components/Editor/BridgeTestCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,7 @@ function BridgeTestCard({ isEditView, values }) {
formKey="testPayloadCode"
isEditView={isEditView}
values={values}
id="test-payload"
/>
</Container>
</AccordionDetails>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/EnvironmentVariablesCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
name={`environmentVariables[${idx}].value`}
value={envVar.value || ''}
placeholder="Value"
id={`envVar-${idx}-value`}
fullWidth
validate={validateEnvVars}
/>
Expand All@@ -97,6 +98,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, envVar, idx); }}
id={`envVar-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -109,6 +111,7 @@ function EnvironmentVariablesCard({ environmentVariables }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="envPlusBtn"
>
+
</Button>
Expand Down
1 change: 1 addition & 0 deletions components/Editor/HeadersCard/DelayDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,7 @@ function MethodDropdown() {
select
validate={validateDelay}
className={classes.dropDown}
id="delay"
>
<MenuItem value="0">Instant</MenuItem>
<MenuItem value="15">15 Minutes</MenuItem>
Expand Down
3 changes: 3 additions & 0 deletions components/Editor/HeadersCard/HeaderTextFields.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -90,6 +90,7 @@ function HeaderTextFields({ headers }) {
name={`headers[${idx}].value`}
value={header.value || ''}
placeholder="Value"
id={`headers-${idx}-value`}
validate={validateHeaders}
fullWidth
/>
Expand All@@ -98,6 +99,7 @@ function HeaderTextFields({ headers }) {
<Button
className={classes.primary}
onClick={() => { handleDelete(arrayHelpers, header, idx); }}
id={`headers-trash-${idx}`}
>
<DeleteForeverIcon fontSize="large" />
</Button>
Expand All@@ -110,6 +112,7 @@ function HeaderTextFields({ headers }) {
variant="outlined"
className={classes.plusButton}
onClick={() => arrayHelpers.push({ key: '', value: '' })}
id="headerPlusBtn"
>
+
</Button>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/MethodDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,11 +42,12 @@ function MethodDropdown() {
<Field
component={TextField}
type="text"
name="method"
name="httpMethod"
select
validate={validateMethod}
label="Method"
className={classes.dropDown}
id="method"
>
{methods.map((method) => (
<MenuItem key={method} value={method}>{method}</MenuItem>
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/HeadersCard/RetryDropdown.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,9 +46,10 @@ function MethodDropdown() {
select
validate={validateRetries}
className={classes.dropDown}
id="retries"
>
{retries.map((retry) => (
<MenuItem key={`${retry}-retries`} value={retry}>{`${retry} Retries`}</MenuItem>
<MenuItem key={`${retry}`} value={retry}>{`${retry}`}</MenuItem>
))}
</Field>
</FormControl>
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/HeadersCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,7 +46,7 @@ function HeaderCard({ headers, outboundUrl, title }) {
let error;
if (!bridgeTitle) {
error = 'Required';
} else if (bridgeTitle.size < 3) {
} else if (bridgeTitle.length < 3) {
error = 'Title must be at least 3 characters long';
}
return error;
Expand Down
2 changes: 1 addition & 1 deletion components/Editor/PayloadCard/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ function PayloadCard({ isEditView, values }) {
</Accordion>

<Typography>Edit outbound payload</Typography>
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} />
<CodeMirror formKey="payloadCode" isEditView={isEditView} values={values} id="payload" />

</Container>
</AccordionDetails>
Expand Down
85 changes: 65 additions & 20 deletions components/Editor/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,14 +42,16 @@ function Editor({ bridge, isEditView }) {
const [open, setOpen] = useState(false);
const [actionsDialogOpen, setActionsDialogOpen] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('Some error has occurred. Please try again.');

// TODO: Custom error messages
// const [errMsg, setErrMsg] = useState('');

const {
active,
id,
outboundUrl,
method,
httpMethod,
headers,
environmentVariables,
data,
Expand All@@ -62,7 +64,7 @@ function Editor({ bridge, isEditView }) {
active,
title,
outboundUrl,
method,
httpMethod,
retries,
delay,
headers,
Expand DownExpand Up@@ -98,7 +100,7 @@ function Editor({ bridge, isEditView }) {
const generatePayload = (values) => ({
active: values.active,
title: values.title,
http_method: values.method,
http_method: values.httpMethod,
outbound_url: values.outboundUrl,
retries: values.retries,
delay: values.delay,
Expand All@@ -110,20 +112,54 @@ function Editor({ bridge, isEditView }) {
},
});

const validatePayloads = (payloadCode, testPayloadCode) => {
const erraneousPayloads = [];
const validatePayload = (payload, type) => {
try { JSON.parse(payload); } catch { erraneousPayloads.push(type); }
};
const createErrorMessage = () => {
if (erraneousPayloads.length === 1) {
setErrorMessage(`Invalid JSON for ${erraneousPayloads[0]} editor`);
} else {
setErrorMessage('Invalid JSON for Payload and Test Payload editors');
}
};

validatePayload(payloadCode, 'Payload');
validatePayload(testPayloadCode, 'Test Payload');

if (erraneousPayloads.length !== 0) {
createErrorMessage();
setErrorOpen(true);
return false;
}

return true;
};

const handleSubmit = async (values, setSubmitting) => {
if (id) {
if (validatePayloads(values.payloadCode, values.testPayloadCode)) {
// POST if new bridge, otherwise PATCH
await api
.patch(`/bridges/${id}`, generatePayload(values))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => router.push(`/bridge/${res.data.id}`))
.catch(() => setErrorOpen(true));
if (id) {
await api
.patch(`/bridges/${id}`, generatePayload(values))
.then(() => setOpen(true))
.catch(() => setErrorOpen(true));
} else {
await api
.post('/bridges', generatePayload(values))
.then((res) => {
setOpen(true);
// TODO: Should timeout so user gets a chance to read the snack
// but is 200ms the time we want?
setTimeout(() => {
router.push(`/bridge/${res.data.id}`);
}, 200);
})
.catch(() => setErrorOpen(true));
}
}

setOpen(true);
setSubmitting(false);
};

Expand All@@ -149,6 +185,7 @@ function Editor({ bridge, isEditView }) {
validateOnChange={false}
validateOnBlur={false}
className={classes.root}
id="form"
>
{({ values, submitForm }) => (
<Form className={classes.form}>
Expand All@@ -172,10 +209,18 @@ function Editor({ bridge, isEditView }) {
active={active}
open={actionsDialogOpen}
onClose={() => setActionsDialogOpen(false)}
id={id}
bridgeId={id}
/>
<Button onClick={() => setActionsDialogOpen(true)} variant="outlined" color="secondary" className={classes.action}>Actions</Button>
<Button onClick={submitForm} variant="contained" color="secondary">Save</Button>
<Button
onClick={() => setActionsDialogOpen(true)}
variant="outlined"
color="secondary"
className={classes.action}
id="actions-button"
>
Actions
</Button>
<Button id="save-btn" onClick={submitForm} variant="contained" color="secondary">Save</Button>
</Grid>
</Grid>
</Grid>
Expand All@@ -195,8 +240,8 @@ function Editor({ bridge, isEditView }) {
</Formik>
</Grid>
</Grid>
<SnackAlert open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert open={errorOpen} onClose={handleClose} severity="error" message="Some error has occured. Please try again." />
<SnackAlert id="success-alert" open={open} onClose={handleClose} severity="success" message="Bridge has been saved." />
<SnackAlert id="error-alert" open={errorOpen} onClose={handleClose} severity="error" message={errorMessage} />
</>
);
}
Expand All@@ -209,7 +254,7 @@ Editor.defaultProps = {
active: true,
title: '',
outboundUrl: '',
method: '',
httpMethod: '',
retries: '',
delay: '',
headers: [
Expand All@@ -233,7 +278,7 @@ Editor.propTypes = {
id: PropTypes.number,
title: PropTypes.string,
outboundUrl: PropTypes.string,
method: PropTypes.string,
httpMethod: PropTypes.string,
retries: PropTypes.number,
delay: PropTypes.number,
headers: PropTypes.arrayOf(
Expand Down
Loading