Skip to content

Commit

Permalink
Merge pull request #62 from nismod/feature/pages
Browse files Browse the repository at this point in the history
Restructure and extend content pages
  • Loading branch information
tomalrussell authored Aug 7, 2024
2 parents e32a9ba + bbcf7d4 commit 70da200
Show file tree
Hide file tree
Showing 28 changed files with 1,135 additions and 500 deletions.
26 changes: 26 additions & 0 deletions dev-proxy/proxy-table.docker-exposed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* To configure the vite development proxy server, ensure this file is at
* ./dev-proxy/proxy-table.ts and conforms to the syntax described here:
* https://vitejs.dev/config/server-options.html#server-proxy
*
* The ports that follow are those exposed by a development docker-compose
* setup, or could be run locally on the host if preferred (see ./README.md).
*/

export const devProxy = {
'/vector': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/vector/, ''),
},
'/api': {
target: 'http://localhost:8888',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
'/extract': {
target: 'http:/localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/extract/, ''),
},
};
2 changes: 1 addition & 1 deletion dev-proxy/proxy-table.local.example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const devProxy = {
rewrite: (path) => path.replace(/^\/api/, ''),
},
'/extract': {
target: 'http:/irv-autopkg-api:8000',
target: 'http://irv-autopkg-api:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/extract/, ''),
},
Expand Down
Binary file added public/card-exposure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/card-hazard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/card-risk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/card-vulnerability.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 13 additions & 4 deletions src/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
styled,
Toolbar,
} from '@mui/material';
import { Box } from '@mui/system';
import { FC, forwardRef, useCallback, useState } from 'react';
import { NavLink as RouterNavLink } from 'react-router-dom';

Expand Down Expand Up @@ -86,9 +85,17 @@ const navItems = [
];
const secondaryNavItems = [
{
to: '/data',
to: '/about',
title: 'About',
},
{
to: '/guide',
title: 'Guide',
},
{
to: '/data',
title: 'Sources',
},
{
to: '/downloads',
title: 'Downloads',
Expand Down Expand Up @@ -177,12 +184,14 @@ export const Nav: FC<{ height: number }> = ({ height }) => {

return (
<AppBar position="fixed" elevation={0} sx={{ color: 'white' }}>
<Box height={topStripeHeight} width="100%" bgcolor="rgb(142,193,85)" />
<Toolbar
variant="dense"
sx={{
borderTopColor: 'rgb(142,193,85)',
borderTopWidth: topStripeHeight,
borderTopStyle: 'solid',
backgroundColor: 'rgb(23,38,23)',
height: height - topStripeHeight,
height: height,
}}
>
{isMobile ? <MobileNavContent height={height} /> : <DesktopNavContent />}
Expand Down
24 changes: 24 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@
background-size: cover;
background-position: center center;
}
.card h2,
.card p {
background: #172617;
transition: 0.1s;
}
.card p {
height: 105px;
}
.card:hover h2,
.card:focus h2 {
text-decoration: underline;
background: rgb(50, 78, 50);
}
.card:hover p,
.card:focus p {
background: rgb(50, 78, 50);
}
.card img {
transition: 0.1s;
}
.card:hover img,
.card:focus img {
opacity: 0.8;
}

/**
* Map and controls
Expand Down
6 changes: 5 additions & 1 deletion src/lib/nav.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinkProps, Link as MuiLink } from '@mui/material';
import { LinkProps, Button as MuiButton, Link as MuiLink } from '@mui/material';
import { ComponentProps } from 'react';
import {
Link as RouterLink,
Expand All @@ -18,6 +18,10 @@ export const AppLink = withProps(MuiLink<typeof RouterLink>, {
component: RouterLink,
});

export const AppLinkButton = withProps(MuiButton<typeof RouterLink>, {
component: RouterLink,
});

export const AppNavLink = withProps(MuiLink<typeof RouterNavLink>, {
component: RouterNavLink,
});
Expand Down
2 changes: 1 addition & 1 deletion src/modules/downloads/components/CenteredLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Container } from '@mui/material';

export const CenteredLayout = ({ children }) => {
return (
<Container maxWidth="md" sx={{ paddingTop: 2 }}>
<Container maxWidth="md" sx={{ py: 8 }}>
{children}
</Container>
);
Expand Down
21 changes: 17 additions & 4 deletions src/modules/downloads/data/jobs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Job } from '@nismod/irv-autopkg-client';
import { ApiError, Job } from '@nismod/irv-autopkg-client';
import { array, date, object, string } from '@recoiljs/refine';
import _ from 'lodash';
import { useEffect } from 'react';
Expand All @@ -23,9 +23,22 @@ export const [useJobById, fetchJobById] = makeQueryAndPrefetch(
);

export function submitJob(boundaryName: string, processors: string[]) {
return autopkgClient.jobs.submitProcessingJobV1JobsPost({
requestBody: { boundary_name: boundaryName, processors },
});
throw new ApiError(
null,
{
url: '',
status: 403,
statusText: '',
body: '',
ok: false,
},
`Failed to process ${boundaryName}: ${processors}`,
);
// Short-circuit to avoid requesting jobs.

// return autopkgClient.jobs.submitProcessingJobV1JobsPost({
// requestBody: { boundary_name: boundaryName, processors },
// });
}

export type JobParams = CamelCasedProperties<Job>;
Expand Down
8 changes: 7 additions & 1 deletion src/modules/downloads/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { H1, H2, H3, H4, H5, H6 } from '@/lib/ui/mui/typography';
export const MdLink = ({ to, title, children }) => {
const isExternal = to.startsWith('http');
return (
<AppLink to={to} title={title} children={children} target={isExternal ? '_blank' : undefined} />
<AppLink
to={to}
title={title}
children={children}
target={isExternal ? '_blank' : undefined}
rel={isExternal ? 'noopener noreferrer' : undefined}
/>
);
};

Expand Down
72 changes: 52 additions & 20 deletions src/modules/downloads/routes/downloads-index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { Stack, Typography } from '@mui/material';
import { LoaderFunctionArgs, useLoaderData } from 'react-router-dom';

import { AppLink } from '@/lib/nav';
import { AppLink, ExtLink } from '@/lib/nav';
import { LoaderData } from '@/lib/react/react-router';

import {
ArticleContainer,
ArticleContentContainer,
ArticleParagraph,
ArticleSection,
EmphasisTextContainer,
EmphasisTextParagraph,
MiniBar,
} from '@/pages/ui/ArticleContainer';
import { HeadingBox, HeadingBoxText } from '@/pages/ui/HeadingBox';

import { CenteredLayout } from '../components/CenteredLayout';
import { fetchAllRegions } from '../data/regions';
import { mdxComponents } from '../markdown';
import DownloadsIntroText from '../sections/DownloadsIntroText.mdx';
import { RegionSearchNavigation } from '../sections/RegionSearchNavigation';

export const loader = async ({ request: { signal } }: LoaderFunctionArgs) => ({
Expand All @@ -28,23 +30,53 @@ export const Component = () => {
const { regions } = useLoaderData() as LandingPageData;

return (
<CenteredLayout>
<Stack direction="column">
<ArticleContainer>
<ArticleContentContainer>
<ArticleSection>
<DownloadsIntroText components={mdxComponents} />
</ArticleSection>
</ArticleContentContainer>
</ArticleContainer>
<Stack direction="column" alignItems={'center'}>
<RegionSearchNavigation regions={regions} title="Select a country" />
<Typography textAlign="center" sx={{ my: 2 }}>
Or <AppLink to="regions">browse all countries</AppLink>
</Typography>
</Stack>
<>
<HeadingBox>
<HeadingBoxText>Data Extract Downloads</HeadingBoxText>
</HeadingBox>
<ArticleContainer>
<ArticleContentContainer>
<ArticleSection>
<EmphasisTextContainer>
<MiniBar />
<EmphasisTextParagraph>
This page provides access to extracts of the datasets presented in the tool. The
extracts are organised by country and data source.
</EmphasisTextParagraph>
</EmphasisTextContainer>
<ArticleParagraph>
Datasets are prepared individually for each country for download and available for all
users through this page.
</ArticleParagraph>

<ArticleParagraph>
Please note that some datasets are currently marked unavailable. If any of these are
of interest, please{' '}
<ExtLink href="https://github.com/nismod/irv-datapkg/issues/new">
raise an issue
</ExtLink>{' '}
or contact us.
</ArticleParagraph>

<ArticleParagraph>
For programmatic interactions with this service, please also refer to the{' '}
<ExtLink href="https://global.infrastructureresilience.org/extract/redoc">
API documentation
</ExtLink>
, <ExtLink href="https://github.com/nismod/irv-autopkg-client">Python client</ExtLink>{' '}
and <ExtLink href="https://github.com/nismod/irv-autopkg-use">usage examples</ExtLink>
.
</ArticleParagraph>
</ArticleSection>
</ArticleContentContainer>
</ArticleContainer>
<Stack direction="column" alignItems={'center'}>
<RegionSearchNavigation regions={regions} title="Select a country" />
<Typography textAlign="center" sx={{ mt: 2, mb: 8 }}>
Or <AppLink to="regions">browse all countries</AppLink>
</Typography>
</Stack>
</CenteredLayout>
</>
);
};

Expand Down
15 changes: 0 additions & 15 deletions src/modules/downloads/sections/DownloadsIntroText.mdx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,70 +1,22 @@
import { BoundarySummary, ProcessorVersionMetadata } from '@nismod/irv-autopkg-client';
import { FC, useCallback, useEffect, useState } from 'react';
import { useMutation } from 'react-query';
import { useRecoilCallback } from 'recoil';
import { FC } from 'react';

import { usePrevious } from '@/lib/hooks/use-previous';

import { SavedJob, submitJob, submittedJobsState } from '../../../data/jobs';
import { StyledChip } from './dataset-chips';
import { DatasetStatus } from './status-logic/dataset-status';

function useSubmitJob() {
const saveSubmittedJob = useRecoilCallback(({ set }) => (job: SavedJob) => {
set(submittedJobsState, (oldVal) => [...oldVal, job]);
});

const { mutate, variables, data, isSuccess } = useMutation(
({ boundaryName, pvName }: { boundaryName: string; pvName: string }) =>
submitJob(boundaryName, [pvName]),
);
const previousSuccess = usePrevious(isSuccess);

useEffect(() => {
if (isSuccess && !previousSuccess) {
const { job_id } = data;
const { boundaryName, pvName } = variables;

saveSubmittedJob({ jobId: job_id, boundaryName, processors: [pvName], inserted: new Date() });
}
}, [isSuccess, previousSuccess, data, variables, saveSubmittedJob]);

return useCallback(
(boundaryName: string, pvName: string) => {
mutate({ boundaryName, pvName });
},
[mutate],
);
}

export const RequestChip: FC<{
status: DatasetStatus.Prepare | DatasetStatus.ProcessingFailed;
boundary: BoundarySummary;
pv: ProcessorVersionMetadata;
}> = ({ status, boundary, pv }) => {
const previousFailed = status === DatasetStatus.ProcessingFailed;

const [disabled, setDisabled] = useState(false);

const submitJob = useSubmitJob();

const handleSubmitJob = useCallback(() => {
submitJob(boundary.name, pv.name);
setDisabled(true); // disable to prevent submitting twice
}, [boundary.name, pv.name, submitJob]);

}> = () => {
// See git history for handling failure/re-request. Now set directly to unavailable.
return (
<StyledChip
disabled={disabled}
color={previousFailed ? 'error' : 'info'}
title={
previousFailed
? `The processing failed. Request ${pv.data_title} again.`
: `Request ${pv.data_title}`
}
label={previousFailed ? 'FAILED' : 'PREPARE'}
disabled={true}
color="default"
title="Dataset unavailable"
label="UNAVAILABLE"
onClick={(e) => {
handleSubmitJob();
e.stopPropagation();
}}
/>
Expand Down
Loading

0 comments on commit 70da200

Please sign in to comment.