Skip to content

Commit

Permalink
feat: play ground
Browse files Browse the repository at this point in the history
  • Loading branch information
HuberTRoy committed Jan 17, 2024
1 parent 1d22c33 commit 3df3f0c
Show file tree
Hide file tree
Showing 16 changed files with 264 additions and 63 deletions.
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
88 changes: 88 additions & 0 deletions src/components/RpcPlayground/RpcPlayground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 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));
} 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>
<Input.TextArea
rows={30}
value={val}
onChange={(e) => {
setVal(e.target.value);
}}
placeholder="JSON RPC playground is a simple tool to help you test queries, click to enter you requests."
></Input.TextArea>

<Button
loading={loading}
shape="round"
size="large"
type="primary"
style={{ position: 'absolute', right: 16, bottom: 32 }}
onClick={() => {
fetchRpc();
}}
>
Send Request
</Button>
</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;
37 changes: 37 additions & 0 deletions src/components/RpcPlayground/index.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.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;

: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;

}
}
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
21 changes: 20 additions & 1 deletion src/hooks/useProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import React, { useMemo, useState } from 'react';
import SearchOutlined from '@ant-design/icons/SearchOutlined';
import { ProjectCard } from '@components';
import { useProjectMetadata } from '@containers';
import { PublishNewProjectModal } from '@pages/studio/Home/Home';
import { SubqlCheckbox } from '@subql/components';
import { ProjectFieldsFragment, ProjectsOrderBy, ProjectType } from '@subql/network-query';
import { useAsyncMemo, useGetProjectLazyQuery, useGetProjectsLazyQuery } from '@subql/react-hooks';
import { categoriesOptions, notEmpty, rpcCategoriesOptions } from '@utils';
import { useInfiniteScroll, useMount } from 'ahooks';
import { Input, Radio, Skeleton, Typography } from 'antd';
import { Button, Input, Radio, Skeleton, Typography } from 'antd';

import { useGetDeploymentManifest } from './useGetDeploymentManifest';
import { useLocalProjects } from './useLocalProjects';
Expand Down Expand Up @@ -63,6 +64,7 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
// assum there at lease have 11 projects
const [total, setTotal] = React.useState(10);
const [inSearchMode, setInSearchMode] = React.useState(false);
const [showPublishModal, setShowPublishModal] = React.useState(false);

const { getProjectBySearch } = useLocalProjects();

Expand Down Expand Up @@ -236,6 +238,23 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
buttonStyle="solid"
size="large"
/>
<span style={{ flex: 1 }}></span>
<Button
type="primary"
shape="round"
size="large"
onClick={() => {
setShowPublishModal(true);
}}
>
Publish New Project
</Button>
<PublishNewProjectModal
value={showPublishModal}
onChange={(val) => {
setShowPublishModal(val);
}}
></PublishNewProjectModal>
</div>
<div style={{ display: 'flex', marginBottom: 32 }}>
<div>
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/en/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const translation = {
indexer: 'indexer',
validityPeriod: 'Validity Period',
non: 'There are no flex plans for this project yet.',
requestToken: 'To start testing your queries in the GraphQL playground, simply request a trial token.',
requestToken: 'To start testing your queries in the {{type}} playground, simply request a trial token.',
remainLimit: 'Remain requests limit: {{limit}}',
expireTime: 'Token expires in {{time}}',
},
Expand Down
Loading

0 comments on commit 3df3f0c

Please sign in to comment.