Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate the WebSocket API page (https://xrpl.org/websocket-api-tool.html) #2265

Closed
wants to merge 12 commits into from
Closed
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__
out/
yarn-error.log
/.idea
*.iml
.venv/

# PHP
Expand Down
9 changes: 9 additions & 0 deletions content/resources/dev-tools/components/Loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';
import { useTranslate } from "@portal/hooks";

export const Loader = () => {
const { translate } = useTranslate();

return <img className="throbber" src="/img/xrp-loader-96.png" alt={translate("(loading)")} />

}
81 changes: 81 additions & 0 deletions content/resources/dev-tools/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { JSX, ReactElement, ReactNode } from 'react';
import { useTranslate } from '@portal/hooks';

interface ModalProps {
id: string // used for targeting animations
title: string,
children: ReactNode,
footer?: ReactNode,
onClose: () => void;
}

/**
* Reusable component that leverages bootstrap's jquery library
*/
export const Modal = ({title, footer, children, onClose, id}: ModalProps) => {
return <div
className="modal fade"
id={id}
tabIndex={-1}
role="dialog"
aria-hidden="true"
>
<div className="modal-dialog modal-dialog-centered" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{title}</h5>
<button
type="button"
className="close"
aria-label="Close"
onClick={onClose}
data-dismiss="modal"
>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div className="modal-body">
{children}
</div>
<div className="modal-footer">
{ footer ? footer : (
<ModalCloseBtn onClick={onClose} />
)}
</div>
</div>
</div>
</div>
}

export const ModalCloseBtn = ({onClick}) => {
const { translate } = useTranslate();

return <button
type="button"
className="btn btn-outline-secondary"
data-dismiss="modal"
onClick={onClick}
>
{translate('Close')}
</button>
}

export const ModalClipboardBtn = ({textareaRef}) => {
const { translate } = useTranslate();

return <button
title={translate('Copy to clipboard')}
className="btn btn-outline-secondary clipboard-btn"
onClick={() => copyToClipboard(textareaRef)}
>
<i className="fa fa-clipboard"></i>
</button>
}

const copyToClipboard = async (textareaRef) => {
if (textareaRef.current) {
textareaRef.current.select();
textareaRef.current.focus();
await navigator.clipboard.writeText(textareaRef.current.value);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useTranslate } from "@portal/hooks";
import { Connection } from './types';
import { ChangeEvent } from 'react';
import { Modal } from '../Modal';

interface ConnectionButtonProps {
selectedConnection: Connection;
setSelectedConnection: (value: Connection) => void;
connections: Connection[];
}

interface ConnectionProps extends ConnectionButtonProps {
closeConnectionModal: any;
}

export const ConnectionModal: React.FC<ConnectionProps> = ({
selectedConnection,
setSelectedConnection,
closeConnectionModal,
connections,
}) => {
const { translate } = useTranslate();
const handleConnectionChange = (event: ChangeEvent<HTMLInputElement>) => {
const selectedValue = event.target.value;
const foundConnection = connections.find(
(conn) => conn.id === selectedValue
);

setSelectedConnection(foundConnection);
};

return (
<Modal id="wstool-1-connection-settings" title={translate('Connection Settings')} onClose={closeConnectionModal}>
{connections.map((conn) => (
<div className="form-check" key={conn.id}>
<input
className="form-check-input"
type="radio"
name="wstool-1-connection"
id={conn.id}
value={conn.id}
checked={selectedConnection.id === conn.id}
onChange={handleConnectionChange}
/>
<label className="form-check-label" htmlFor={conn.id}>
<div dangerouslySetInnerHTML={{ __html: conn.longname }} />
</label>
</div>
))}
</Modal>
);
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { useTranslate } from "@portal/hooks";
import { Connection } from './types';
import { useRef, useState } from 'react';
import { Modal, ModalClipboardBtn, ModalCloseBtn } from '../Modal';

interface CurlButtonProps {
currentBody: any;
selectedConnection: Connection;
}

interface CurlProps extends CurlButtonProps{
closeCurlModal: () => void;
}

const getCurl = function (currentBody, selectedConnection: Connection) {
let body;
try {
// change WS to JSON-RPC syntax
const params = JSON.parse(currentBody);
delete params.id;
const method = params.command;
delete params.command;
const body_json = { method: method, params: [params] };
body = JSON.stringify(body_json, null, null);
} catch (e) {
alert("Can't provide curl format of invalid JSON syntax");
return;
}

const server = selectedConnection.jsonrpc_url;

return `curl -H 'Content-Type: application/json' -d '${body}' ${server}`;
};

export const CurlModal: React.FC<CurlProps> = ({
currentBody,
selectedConnection,
}) => {
const curlRef = useRef(null);
const { translate } = useTranslate();
const footer = <>
<ModalClipboardBtn textareaRef={curlRef} />
<ModalCloseBtn onClick={() => {}} />
</>

return (
<Modal
id="wstool-1-curl"
title={translate("cURL Syntax")}
onClose={() => {}}
footer={footer}
>
<form>
<div className="form-group">
<label htmlFor="curl-box-1">
Use the following syntax to make the equivalent JSON-RPC
request using <a href="https://curl.se/">cURL</a> from a
commandline interface:
</label>
<textarea
id="curl-box-1"
className="form-control"
rows={8}
ref={curlRef}
>
{getCurl(currentBody, selectedConnection)}
</textarea>
</div>
</form>
</Modal>
);
};

export const CurlButton = ({selectedConnection, currentBody}: CurlButtonProps) => {
return <>
<button
className="btn btn-outline-secondary curl"
data-toggle="modal"
data-target="#wstool-1-curl"
title="cURL syntax"
>
<i className="fa fa-terminal"></i>
</button>
<CurlModal
closeCurlModal={() => {}}
currentBody={currentBody}
selectedConnection={selectedConnection}
/>
</>
}
Loading