Skip to content

Commit

Permalink
feat: upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
HuberTRoy committed Dec 15, 2023
1 parent 9a22890 commit 08d8572
Show file tree
Hide file tree
Showing 6 changed files with 466 additions and 96 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@sentry/react": "^7.57.0",
"@subql/apollo-links": "^1.2.3",
"@subql/components": "1.0.3-22",
"@subql/contract-sdk": "^0.100.3",
"@subql/contract-sdk": "0.111.0",
"@subql/network-clients": "^0.100.0",
"@subql/network-config": "^0.100.0",
"@subql/network-query": "0.100.3-0",
Expand Down
73 changes: 45 additions & 28 deletions src/hooks/useProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
variables: { offset: 0 },
});

const [getProject, { error: topError }] = useGetProjectLazyQuery();
const [getProject, { error: topError, loading: topLoading }] = useGetProjectLazyQuery();

const [searchKeywords, setSearchKeywords] = React.useState('');
const [filterCategories, setFilterCategories] = useState<string[]>([]);
Expand Down Expand Up @@ -121,6 +121,7 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
// filter once or twice is the same.
const nonEmptyProjects = res.data.projects?.nodes.filter(notEmpty).filter(notEmpty);
const mergered = options?.refresh ? [...nonEmptyProjects] : [...fetchedProejcts.current, ...nonEmptyProjects];
// TODO: filter by backend.
setProjects(mergered.filter((proj) => (account ? account.toLowerCase() === proj.owner.toLowerCase() : true)));
fetchedProejcts.current = mergered;
updatedLength = mergered.length;
Expand All @@ -143,8 +144,8 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
});

const topProjectItem = useMemo(() => {
if (!showTopProject) return '';
if (!inSearchMode && topProject)
if (!showTopProject || inSearchMode) return '';
if (topProject)
return (
<ProjectItem
project={topProject}
Expand All @@ -155,33 +156,53 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
/>
);

if (!inSearchMode) return <Skeleton paragraph={{ rows: 7 }} style={{ width: 236, height: 400 }} active></Skeleton>;
if (topLoading) return <Skeleton paragraph={{ rows: 7 }} style={{ width: 236, height: 400 }} active></Skeleton>;

return '';
}, [inSearchMode, topProject, showTopProject, onProjectClick]);
}, [inSearchMode, topProject, topLoading, showTopProject, onProjectClick]);

const projectListItems = useMemo(() => {
if (loading) {
return new Array(projects.length + 10 <= total ? 10 : total - projects.length).fill(0).map((_, i) => {
return <Skeleton paragraph={{ rows: 7 }} active key={i} style={{ width: 236, height: 400 }}></Skeleton>;
});
}
const loadingItems = new Array(projects.length + 10 <= total ? 10 : total - projects.length).fill(0).map((_, i) => {
return <Skeleton paragraph={{ rows: 7 }} active key={i} style={{ width: 236, height: 400 }}></Skeleton>;
});
if (projects.length) {
return projects.map((project) => (
<ProjectItem
project={project}
key={project.id}
onClick={() => {
onProjectClick?.(project.id);
}}
/>
));
return (
<>
{projects.map((project) => (
<ProjectItem
project={project}
key={project.id}
onClick={() => {
onProjectClick?.(project.id);
}}
/>
))}
{loading && loadingItems}
</>
);
} else {
if (loading) return loadingItems;
}

if (inSearchMode) return '';
// TODO: ui
return 'No Projects';
}, [inSearchMode, loading, projects]);
return '';
}, [inSearchMode, loading, projects, onProjectClick]);

const emptyResult = useMemo(() => {
if (loading || topLoading) return '';
if (inSearchMode && !projects.length)
return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Typography>No projects match your search</Typography>
</div>
);

if (!inSearchMode && !projects.length && !topProject)
return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Typography>No projects</Typography>
</div>
);
}, [loading, inSearchMode, projects, topProject, showTopProject, topLoading]);

const listsWithSearch = useMemo(() => {
return (
Expand Down Expand Up @@ -228,11 +249,7 @@ export const useProjectList = (props: UseProjectListProps = {}) => {
{projectListItems}
</div>

{inSearchMode && !loading && !projects.length && (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Typography>No projects match your search</Typography>
</div>
)}
{emptyResult}

{(error || topError) && <span>{`We have an error: ${error?.message || topError?.message}`}</span>}
</>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/explorer/Home/Home.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

.header {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
margin-bottom: 72px;
}
Expand Down
28 changes: 25 additions & 3 deletions src/pages/explorer/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router';
import { useProjectList } from '@hooks/useProjectList';
import { PublishNewProjectModal } from '@pages/studio/Home/Home';
import { Typography } from '@subql/components';
import { Button } from 'antd';

import { ROUTES } from '../../../utils';
import styles from './Home.module.css';
Expand All @@ -15,12 +17,32 @@ const { PROJECT_NAV } = ROUTES;
// TODO move to components
export const Header: React.FC = () => {
const { t } = useTranslation();
const [showPublishModal, setShowPublishModal] = React.useState(false);

return (
<div className={styles.header}>
<Typography variant="h3">{t('explorer.home.header')}</Typography>
<Typography style={{ width: 439, textAlign: 'center', marginTop: 16 }} type="secondary">
{t('explorer.home.headerDesc')}
</Typography>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Typography style={{ width: 565, marginTop: 16 }} type="secondary">
{t('explorer.home.headerDesc')}
</Typography>
<Button
type="primary"
shape="round"
size="large"
onClick={() => {
setShowPublishModal(true);
}}
>
Publish New Project
</Button>
</div>
<PublishNewProjectModal
value={showPublishModal}
onChange={(val) => {
setShowPublishModal(val);
}}
></PublishNewProjectModal>
</div>
);
};
Expand Down
112 changes: 67 additions & 45 deletions src/pages/studio/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as React from 'react';
import { useNavigate } from 'react-router';
import { useProjectList } from '@hooks/useProjectList';
import { usePropsValue } from '@hooks/usePropsValue';
import { Modal, Typography } from '@subql/components';
import { Button, Form, Input } from 'antd';
import { useForm } from 'antd/es/form/Form';
Expand All @@ -13,6 +14,67 @@ import { ROUTES } from '../../../utils';

const { STUDIO_CREATE_NAV, STUDIO_PROJECT_NAV } = ROUTES;

export const PublishNewProjectModal: React.FC<{ value: boolean; onChange: (val: boolean) => void }> = ({
value,
onChange,
}) => {
const navigate = useNavigate();
const [form] = useForm();
const [showCreateModal, setShowCreateModal] = usePropsValue<boolean>({
value,
onChange,
defaultValue: false,
});
const handleCreateProject = () => {
navigate(
`${STUDIO_CREATE_NAV}?name=${encodeURI(form.getFieldValue('projectName'))}&deploymentId=${form.getFieldValue(
'deploymentId',
)}`,
);
};

return (
<Modal
title="Publish New Project to the Decentralised Network"
width={572}
open={showCreateModal}
onCancel={() => setShowCreateModal(false)}
onOk={async () => {
await form.validateFields();

handleCreateProject();
}}
okText={'Next'}
okButtonProps={{
shape: 'round',
size: 'large',
}}
cancelButtonProps={{
style: { display: 'none' },
}}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: 24, padding: '24px 0' }}>
<Typography style={{ color: 'var(--sq-gray700)' }}>
Please enter the deployment ID of your SubQuery project below. To get the deployment ID, run subql publish
from your project code to publish it to IPFS. Learn how to publish a SubQuery project here.
</Typography>

<Form layout="vertical" form={form}>
<Form.Item label="Deployment ID" name="deploymentId" rules={[{ required: true }]}>
<Input placeholder="Deployment ID" size="large"></Input>
</Form.Item>
<div>
<Form.Item label="Project Name" name="projectName" rules={[{ required: true }]}>
<Input placeholder="Project Name" size="large"></Input>
</Form.Item>
<Typography variant="medium">Project names should be unique, you can edit this later.</Typography>
</div>
</Form>
</div>
</Modal>
);
};

const Home: React.FC = () => {
const { account } = useWeb3();
const navigate = useNavigate();
Expand All @@ -23,15 +85,7 @@ const Home: React.FC = () => {
},
});

const [form] = useForm();
const [showCreateModal, setShowCreateModal] = React.useState<boolean>(false);
const handleCreateProject = () => {
navigate(
`${STUDIO_CREATE_NAV}?name=${encodeURI(form.getFieldValue('projectName'))}&deploymentId=${form.getFieldValue(
'deploymentId',
)}`,
);
};
const enableCreateModal = () => setShowCreateModal(true);

return (
Expand All @@ -43,44 +97,12 @@ const Home: React.FC = () => {
</Button>
</div>

<Modal
title="Publish New Project to the Decentralised Network"
width={572}
open={showCreateModal}
onCancel={() => setShowCreateModal(false)}
onOk={async () => {
await form.validateFields();

handleCreateProject();
<PublishNewProjectModal
value={showCreateModal}
onChange={(val) => {
setShowCreateModal(val);
}}
okText={'Next'}
okButtonProps={{
shape: 'round',
size: 'large',
}}
cancelButtonProps={{
style: { display: 'none' },
}}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: 24, padding: '24px 0' }}>
<Typography style={{ color: 'var(--sq-gray700)' }}>
Please enter the deployment ID of your SubQuery project below. To get the deployment ID, run subql publish
from your project code to publish it to IPFS. Learn how to publish a SubQuery project here.
</Typography>

<Form layout="vertical" form={form}>
<Form.Item label="Deployment ID" name="deploymentId" rules={[{ required: true }]}>
<Input placeholder="Deployment ID" size="large"></Input>
</Form.Item>
<div>
<Form.Item label="Project Name" name="projectName" rules={[{ required: true }]}>
<Input placeholder="Project Name" size="large"></Input>
</Form.Item>
<Typography variant="medium">Project names should be unique, you can edit this later.</Typography>
</div>
</Form>
</div>
</Modal>
/>

{listsWithSearch}
</div>
Expand Down
Loading

0 comments on commit 08d8572

Please sign in to comment.