Skip to content

Commit

Permalink
Merge pull request #636 from subquery/feat/rpc-playground
Browse files Browse the repository at this point in the history
feat: rpc playground
  • Loading branch information
HuberTRoy authored Jan 18, 2024
2 parents 1d22c33 + fe07f6b commit c051b3f
Show file tree
Hide file tree
Showing 22 changed files with 308 additions and 73 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"@subql/contract-sdk": "0.112.0",
"@subql/network-clients": "^0.112.1-1",
"@subql/network-config": "^0.112.0",
"@subql/network-query": "0.112.1-0",
"@subql/react-hooks": "^0.112.1-2",
"@subql/network-query": "0.112.1-1",
"@subql/react-hooks": "^0.112.1-3",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
Expand Down
13 changes: 1 addition & 12 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,14 @@ export interface AppNavigation {
export const Header: React.FC = () => {
const { address: account } = useAccount();
const navigate = useNavigate();
const calEntryLinks = React.useMemo(() => {
return entryLinks.map((entry) => {
if (entry.key === 'explorer') {
return {
...entry,
dropdown: undefined,
};
}
return entry;
});
}, []);

return (
<div className={styles.header}>
<SubqlHeader
navigate={(link) => {
navigate(link);
}}
appNavigation={calEntryLinks}
appNavigation={entryLinks}
dropdownLinks={{ label: 'Kepler', links: externalAppLinks }}
rightElement={
<>
Expand Down
2 changes: 2 additions & 0 deletions src/components/IndexerDetails/IndexerDetails.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@
color: #fff;
font-size: 18px;
margin-bottom: 8px;
display: flex;
align-items: center;
}

&LimitInfo {
Expand Down
6 changes: 4 additions & 2 deletions src/components/IndexerDetails/IndexerDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { EmptyList } from '@components/EmptyList';
import { ProjectDetailsQuery } from '@hooks/useProjectFromQuery';
import { Spinner, TableTitle, Typography } from '@subql/components';
import { ServiceStatus } from '@subql/network-query';
import { renderAsync, useGetDeploymentIndexersLazyQuery, useGetIndexerDeploymentLazyQuery } from '@subql/react-hooks';
Expand All @@ -16,6 +17,7 @@ import Row from './Row';

type Props = {
deploymentId: string | undefined;
project: ProjectDetailsQuery;
};

const NoIndexers: React.FC = () => {
Expand All @@ -31,7 +33,7 @@ const NoIndexers: React.FC = () => {
);
};

const IndexerDetails: React.FC<Props> = ({ deploymentId }) => {
const IndexerDetails: React.FC<Props> = ({ deploymentId, project }) => {
const { t } = useTranslation();

const [loadIndexersLazy, asyncIndexers] = useGetDeploymentIndexersLazyQuery();
Expand Down Expand Up @@ -156,7 +158,7 @@ const IndexerDetails: React.FC<Props> = ({ deploymentId }) => {
.filter(notEmpty)
.sort((indexer) => (indexer.status === ServiceStatus.READY ? -1 : 1))
.map((indexer) => (
<Row indexer={indexer} key={indexer.indexerId} deploymentId={deploymentId} />
<Row type={project.type} indexer={indexer} key={indexer.indexerId} deploymentId={deploymentId} />
))}
</>
<div className={styles.indexersPagination}>
Expand Down
37 changes: 31 additions & 6 deletions src/components/IndexerDetails/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
import { BsChevronDown, BsChevronUp, BsInfoSquare } from 'react-icons/bs';
import { useNavigate } from 'react-router';
import { LazyQueryResult } from '@apollo/client';
import RpcPlayground from '@components/RpcPlayground/RpcPlayground';
import { WalletRoute } from '@components/WalletRoute';
import { useIsLogin } from '@hooks/useIsLogin';
import { useRequestServiceAgreementToken } from '@hooks/useRequestServiceAgreementToken';
Expand All @@ -14,6 +15,7 @@ import { GraphiQL } from '@subql/components/dist/common/GraphiQL';
import {
GetDeploymentIndexersQuery,
PlansNodeFieldsFragment as Plan,
ProjectType,
ServiceStatus as DeploymentStatus,
} from '@subql/network-query';
import { useGetDeploymentPlansLazyQuery } from '@subql/react-hooks';
Expand All @@ -25,6 +27,7 @@ import clsx from 'clsx';
import { t } from 'i18next';
import { useAccount } from 'wagmi';

import RpcPlaygroundIcon from 'src/images/rpcPlayground';
import { useWeb3Store } from 'src/stores';
import { useProjectStore } from 'src/stores/project';

Expand Down Expand Up @@ -77,7 +80,8 @@ export interface QueryLimit {
const ConnectedRow: React.FC<{
indexer: ExcludeNull<ExcludeNull<GetDeploymentIndexersQuery['indexerDeployments']>['nodes'][number]>;
deploymentId?: string;
}> = ({ indexer, deploymentId }) => {
type: ProjectType;
}> = ({ indexer, deploymentId, type }) => {
const { t } = useTranslation();
const { address: account } = useAccount();
const navigate = useNavigate();
Expand Down Expand Up @@ -175,7 +179,6 @@ const ConnectedRow: React.FC<{
</>
),
},

{
width: '13%',
render: () => {
Expand Down Expand Up @@ -211,7 +214,16 @@ const ConnectedRow: React.FC<{
setShowReqTokenConfirmModal(true);
}}
>
<PlaygroundIcon color="var(--sq-blue600)" width={14} height={14} style={{ marginRight: '5px' }} />
{type === ProjectType.SUBQUERY ? (
<PlaygroundIcon color="var(--sq-blue600)" width={14} height={14} style={{ marginRight: '5px' }} />
) : (
<RpcPlaygroundIcon
color="var(--sq-blue600)"
width={14}
height={14}
style={{ marginRight: '5px', marginTop: 3 }}
></RpcPlaygroundIcon>
)}
Playground
</Typography>
);
Expand Down Expand Up @@ -332,7 +344,13 @@ const ConnectedRow: React.FC<{
>
<WalletRoute
componentMode
element={<Typography>{t('explorer.flexPlans.requestToken')}</Typography>}
element={
<Typography>
{t('explorer.flexPlans.requestToken', {
type: type === ProjectType.RPC ? 'JSON' : 'Graphql',
})}
</Typography>
}
></WalletRoute>
</Modal>

Expand All @@ -344,7 +362,11 @@ const ConnectedRow: React.FC<{
>
<div className={styles.playgroundModalHeader}>
<Typography className={styles.playgroundModalTitle}>
<PlaygroundIcon style={{ marginRight: '8px' }} />
{type === ProjectType.SUBQUERY ? (
<PlaygroundIcon style={{ marginRight: '8px' }} />
) : (
<RpcPlaygroundIcon style={{ marginRight: '8px' }}></RpcPlaygroundIcon>
)}
{t('myFlexPlans.playground')}
</Typography>
<Typography className={styles.playgroundModalLimitInfo}>
Expand All @@ -361,7 +383,10 @@ const ConnectedRow: React.FC<{
</span>
</Typography>
</div>
{queryUrl && trailToken && <GraphiQL url={queryUrl} bearToken={trailToken} theme="dark"></GraphiQL>}
{type === ProjectType.SUBQUERY && queryUrl && trailToken && (
<GraphiQL url={queryUrl} bearToken={trailToken} theme="dark"></GraphiQL>
)}
{type === ProjectType.RPC && <RpcPlayground url={queryUrl} trailToken={trailToken}></RpcPlayground>}
</AntdModal>
</>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/ProjectHeader/ProjectHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ const ProjectHeader: React.FC<Props> = ({
{isUnsafeDeployment && <UnsafeWarn></UnsafeWarn>}
<VersionDropdown />
<span style={{ flex: 1 }}></span>
<Button type="primary" shape="round" size="large">
{/* TODO: finish this */}
{/* <Button type="primary" shape="round" size="large">
Get RPC Endpoint
</Button>
</Button> */}
</div>
<Address address={project.owner} size="small" />

Expand Down
98 changes: 98 additions & 0 deletions src/components/RpcPlayground/RpcPlayground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2020-2022 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React, { FC, useMemo, useState } from 'react';
import { Typography } from '@subql/components';
import { getAuthReqHeader } from '@utils';
import { Button, Input } from 'antd';
import { fetchJson } from 'ethers/lib/utils';

import styles from './index.module.less';

interface IProps {
url?: string;
trailToken: string;
}

const RpcPlayground: FC<IProps> = ({ url, trailToken }) => {
const [val, setVal] = useState('');
const [loading, setLoading] = useState(false);
const enteredRows = useMemo(() => {
return val.split('\n').length;
}, [val]);

const [responseData, setResponseData] = useState('');

const fetchRpc = async () => {
if (!url) return;
try {
setLoading(true);
const res = await fetchJson(
{
url,
headers: {
...getAuthReqHeader(trailToken),
},
},
val,
);

setResponseData(JSON.stringify(res));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
setResponseData(`${e.toString()}`);
} finally {
setLoading(false);
}
};

return (
<div className={styles.rpcPlayground}>
<div className={styles.rpcPlaygroundEditor}>
<Typography style={{ color: '#fff', marginBottom: 8 }} weight={500}>
Request
</Typography>
<div style={{ display: 'flex', gap: 8 }}>
<div className={styles.rows}>
{new Array(enteredRows).fill(0).map((_, index) => (
<span key={index}>{index + 1}</span>
))}
</div>
<Input.TextArea
rows={30}
value={val}
onChange={(e) => {
setVal(e.target.value);
}}
style={{ resize: 'none' }}
placeholder="JSON RPC playground is a simple tool to help you test queries, click to enter you requests."
></Input.TextArea>
</div>

<div style={{ display: 'flex', justifyContent: 'flex-end', position: 'sticky', bottom: 32 }}>
<Button
loading={loading}
shape="round"
size="large"
type="primary"
onClick={() => {
fetchRpc();
}}
>
Send Request
</Button>
</div>
</div>

<div className={styles.rpcPlaygroundResponse}>
<Typography style={{ color: '#fff', marginBottom: 8 }} weight={500}>
Response
</Typography>
<div style={{ overflowWrap: 'anywhere', wordBreak: 'break-all', color: 'var(--sq-gray500)' }}>
{responseData}
</div>
</div>
</div>
);
};
export default RpcPlayground;
46 changes: 46 additions & 0 deletions src/components/RpcPlayground/index.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.rpcPlayground {
display: flex;
padding: 16px;
border-radius: 0px 0px 16px 16px;
background: #2A3546;

&Editor {
flex: 1;
padding: 16px;
background: #1F2A3B;
border-radius: 10px;
position: relative;

.rows {
display: flex;
flex-direction: column;
color: var(--sq-gray600);
font-size: 14px;
line-height: 1.5714285714285714;
padding-top: 2px;
}

:global {
.ant-input {
background: #1F2A3B;
border: 1px solid #1F2A3B;
color: var(--sq-gray500);
padding: 0;
font-family: var(--sq-font-family);
&:focus {
box-shadow: none;
}

&::placeholder {
color: var(--sq-gary500);
}
}
}
}

&Response {
flex: 1;
padding: 16px;

}
}
7 changes: 2 additions & 5 deletions src/components/Spinner/Spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import * as React from 'react';
import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
import { Spin } from 'antd';
import { Spinner as SubqlSpinner } from '@subql/components';

import styles from './Spinner.module.css';

Expand All @@ -12,11 +11,9 @@ type Props = {
};

const Spinner: React.FC<Props> = ({ size }) => {
const antIcon = <LoadingOutlined style={{ fontSize: size }} spin />;

return (
<div className={styles.spinner}>
<Spin indicator={antIcon} />
<SubqlSpinner></SubqlSpinner>
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useProjectList.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

.typeFilter {
display: flex;
justify-content: center;
// justify-content: center;
margin-bottom: 40px;

:global {
Expand Down
Loading

0 comments on commit c051b3f

Please sign in to comment.