Attempt to create reports with react-pdf

- webpack config is documented here:
- https://react-pdf.org/advanced
This commit is contained in:
Vim USDS 2022-06-08 10:34:57 -07:00
parent 9882e9ba22
commit 40b9593a62
10 changed files with 1630 additions and 194 deletions

View file

@ -1,4 +1,5 @@
path = require('path'); path = require('path');
const webpack = require('webpack');
// https://github.com/maplibre/maplibre-gl-js/issues/83#issuecomment-877012839 // https://github.com/maplibre/maplibre-gl-js/issues/83#issuecomment-877012839
exports.onCreateWebpackConfig = ({stage, loaders, actions}) => { exports.onCreateWebpackConfig = ({stage, loaders, actions}) => {
@ -8,6 +9,28 @@ exports.onCreateWebpackConfig = ({stage, loaders, actions}) => {
alias: { alias: {
'mapbox-gl': 'maplibre-gl', 'mapbox-gl': 'maplibre-gl',
}, },
fallback: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
http2: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
process: require.resolve('process/browser'),
zlib: require.resolve('browserify-zlib'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
buffer: require.resolve('buffer'),
asset: require.resolve('assert'),
},
}, },
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
}),
],
}); });
}; };

1515
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -75,15 +75,20 @@
}, },
"dependencies": { "dependencies": {
"-": "^0.0.1", "-": "^0.0.1",
"@react-pdf/renderer": "^2.2.0",
"@sentry/gatsby": "^6.19.1", "@sentry/gatsby": "^6.19.1",
"@trussworks/react-uswds": "^2.9.0", "@trussworks/react-uswds": "^2.9.0",
"@turf/bbox": "^6.5.0", "@turf/bbox": "^6.5.0",
"assert": "^2.0.0",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"d3-ease": "^3.0.1", "d3-ease": "^3.0.1",
"gatsby-plugin-env-variables": "^2.2.0", "gatsby-plugin-env-variables": "^2.2.0",
"gatsby-plugin-robots-txt": "^1.7.0", "gatsby-plugin-robots-txt": "^1.7.0",
"gatsby-plugin-sitemap": "^4.10.0", "gatsby-plugin-sitemap": "^4.10.0",
"mapbox-gl": "^1.13.2", "mapbox-gl": "^1.13.2",
"maplibre-gl": "^1.14.0", "maplibre-gl": "^1.14.0",
"process": "^0.11.10",
"query-string": "^7.1.1", "query-string": "^7.1.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-device-detect": "^1.17.0", "react-device-detect": "^1.17.0",
@ -92,7 +97,9 @@
"react-intl": "^5.24.7", "react-intl": "^5.24.7",
"react-map-gl": "^6.1.19", "react-map-gl": "^6.1.19",
"react-use": "^17.3.2", "react-use": "^17.3.2",
"uswds": "^2.11.2" "stream-browserify": "^3.0.0",
"uswds": "^2.11.2",
"util": "^0.12.4"
}, },
"cypress-cucumber-preprocessor": { "cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": false "nonGlobalStepDefinitions": false

View file

@ -3,12 +3,14 @@
import React from 'react'; import React from 'react';
import {useIntl} from 'gatsby-plugin-intl'; import {useIntl} from 'gatsby-plugin-intl';
import {Accordion, Button} from '@trussworks/react-uswds'; import {Accordion, Button} from '@trussworks/react-uswds';
import {PDFDownloadLink} from '@react-pdf/renderer';
// Components: // Components:
import Category from '../Category'; import Category from '../Category';
import DisadvantageDot from '../DisadvantageDot'; import DisadvantageDot from '../DisadvantageDot';
import ExceedBurden from '../ExceedBurden'; import ExceedBurden from '../ExceedBurden';
import Indicator from '../Indicator'; import Indicator from '../Indicator';
import PDFRenderer from '../PDFRenderer';
// Styles and constants // Styles and constants
import * as styles from './areaDetail.module.scss'; import * as styles from './areaDetail.module.scss';
@ -18,6 +20,8 @@ import * as COMMON_COPY from '../../data/copy/common';
// @ts-ignore // @ts-ignore
import mailIcon from '/node_modules/uswds/dist/img/usa-icons/mail_outline.svg'; import mailIcon from '/node_modules/uswds/dist/img/usa-icons/mail_outline.svg';
// @ts-ignore
import fileDownload from '/node_modules/uswds/dist/img/usa-icons/file_download.svg';
interface IAreaDetailProps { interface IAreaDetailProps {
properties: constants.J40Properties, properties: constants.J40Properties,
@ -602,6 +606,8 @@ const AreaDetail = ({properties, hash}: IAreaDetailProps) => {
{/* <div className={styles.showThresholdExceed}> {/* <div className={styles.showThresholdExceed}>
{EXPLORE_COPY.numberOfThresholdsExceeded(properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS])} {EXPLORE_COPY.numberOfThresholdsExceeded(properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS])}
</div> */} </div> */}
{/* Send Feedback button */} {/* Send Feedback button */}
<a <a
className={styles.sendFeedbackLink} className={styles.sendFeedbackLink}
@ -629,6 +635,41 @@ const AreaDetail = ({properties, hash}: IAreaDetailProps) => {
</Button> </Button>
</a> </a>
{/* Download Report */}
{/* Todo VS: Styling names need to be made generic */}
<PDFDownloadLink className={styles.sendFeedbackLink} document={<PDFRenderer/>} fileName="document">
{({loading}) =>
loading ? (
<Button
type="button"
className={styles.sendFeedbackBtn}
>
<div className={styles.buttonContainer}>
<div className={styles.buttonText}>
{EXPLORE_COPY.COMMUNITY.DOWNLOAD_REPORT.CREATE}
</div>
</div>
</Button>
) : (
<Button
type="button"
className={styles.sendFeedbackBtn}
>
<div className={styles.buttonContainer}>
<div className={styles.buttonText}>
{EXPLORE_COPY.COMMUNITY.DOWNLOAD_REPORT.DOWNLOAD}
</div>
<img
className={styles.buttonImage}
src={fileDownload}
alt={intl.formatMessage(EXPLORE_COPY.COMMUNITY.DOWNLOAD_REPORT.IMG_ICON.ALT_TAG)}
/>
</div>
</Button>
)}
</PDFDownloadLink>
</div> </div>
{/* All category accordions in this component */} {/* All category accordions in this component */}

View file

@ -0,0 +1,171 @@
import React from 'react';
import {Page, Image, View, Text, Document, StyleSheet} from '@react-pdf/renderer';
// import {useIntl} from 'gatsby-plugin-intl';
// import {LocalizedComponent} from '../../test/testHelpers';
import cejstLogo from '../../images/cejst-logo.png';
import * as EXPLORE_COPY from '../../data/copy/explore';
const styles = StyleSheet.create({
page: {
paddingTop: 35,
paddingBottom: 65,
// paddingHorizontal: 35,
},
logo: {
width: 200,
marginLeft: 30,
},
heading1: {
fontFamily: 'Times-Roman',
fontSize: 32,
marginLeft: 22,
marginTop: 20,
maringBottom: 30,
},
heading2: {
fontFamily: 'Times-Roman',
fontSize: 24,
marginLeft: 24,
marginTop: 18,
maringBottom: 18,
},
heading3: {
fontFamily: 'Times-Roman',
fontSize: 18.72,
marginLeft: 30,
marginTop: 16,
maringBottom: 16,
},
heading4: {
fontFamily: 'Times-Roman',
fontSize: 16,
marginLeft: 24,
marginTop: 14,
maringBottom: 14,
},
paragraph: {
display: 'flex',
flexDirection: 'row',
marginLeft: 34,
marginTop: 4,
maringBottom: 4,
},
labelText: {
fontFamily: 'Times-Roman',
fontSize: 12,
fontWeight: 900,
},
text: {
fontFamily: 'Times-Roman',
fontSize: 12,
fontWeight: 'bold',
},
});
const PDFRenderer = () => {
// const intl = useIntl();
return (
// <LocalizedComponent>
<Document>
<Page style={styles.page}>
{/* Need to remove text from logo to allow for Spanish, right now hard coded */}
<Image style={styles.logo} src={cejstLogo} />
<Text style={styles.heading1}> Census tract report</Text>
<Text style={styles.heading2}> Census tract info</Text>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{/* {intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CBG_INFO.CENSUS_BLOCK_GROUP)} */}
{EXPLORE_COPY.SIDE_PANEL_CBG_INFO.CENSUS_BLOCK_GROUP.defaultMessage}
</Text>
<Text style={styles.text}>
123940813495793485
</Text>
</View>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{EXPLORE_COPY.SIDE_PANEL_CBG_INFO.COUNTY.defaultMessage}
</Text>
<Text style={styles.text}>
Kings County
</Text>
</View>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{EXPLORE_COPY.SIDE_PANEL_CBG_INFO.STATE.defaultMessage}
</Text>
<Text style={styles.text}>
New York
</Text>
</View>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{EXPLORE_COPY.SIDE_PANEL_CBG_INFO.POPULATION.defaultMessage}
</Text>
<Text style={styles.text}>
4,145
</Text>
</View>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{EXPLORE_COPY.COMMUNITY.IS_FOCUS}
</Text>
<Text style={styles.text}>
Yes
</Text>
</View>
<View style={styles.paragraph}>
<Text style={styles.text}>
Disadvantaged in 5 categories
</Text>
</View>
<Text style={styles.heading2}> Categories</Text>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLIMATE.defaultMessage}
</Text>
<View style={styles.paragraph}>
<Text style={styles.labelText}>
{EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_ONE_OR_MORE}
</Text>
<Text style={styles.text}>
No
</Text>
</View>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_ENERGY.defaultMessage}
</Text>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_TRANSPORT.defaultMessage}
</Text>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.LEG_POLLUTE.defaultMessage}
</Text>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_WATER.defaultMessage}
</Text>
<Text style={styles.heading3}>
{EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_WATER.defaultMessage}
</Text>
</Page>
</Document>
// </LocalizedComponent>
);
};
export default PDFRenderer;

View file

@ -0,0 +1,3 @@
import PDFRenderer from './PDFRenderer';
export default PDFRenderer;

View file

@ -310,6 +310,25 @@ export const COMMUNITY = {
}, },
}), }),
}, },
DOWNLOAD_REPORT: {
DOWNLOAD: <FormattedMessage
id={'explore.map.page.side.panel.download.report.title'}
defaultMessage={ 'Get report'}
description={`Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show link to download a report`}
/>,
CREATE: <FormattedMessage
id={'explore.map.page.side.panel.create.report.title'}
defaultMessage={ 'Creating report ...'}
description={`Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show link to create a report`}
/>,
IMG_ICON: defineMessages({
ALT_TAG: {
id: 'explore.map.page.side.panel.download.report.alt.img',
defaultMessage: 'icon that represents the download of a report',
description: `Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show a download report icon, this is the images alt tag`,
},
}),
},
}; };
export const numberOfCategoriesExceeded = (categoryCount:number) => <FormattedMessage export const numberOfCategoriesExceeded = (categoryCount:number) => <FormattedMessage

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -443,6 +443,18 @@
"defaultMessage": "YES", "defaultMessage": "YES",
"description": "Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show the communities the score currently is focused on" "description": "Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show the communities the score currently is focused on"
}, },
"explore.map.page.side.panel.create.report.title": {
"defaultMessage": "Creating report ...",
"description": "Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show link to create a report"
},
"explore.map.page.side.panel.download.report.alt.img": {
"defaultMessage": "icon that represents the download of a report",
"description": "Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show a download report icon, this is the images alt tag"
},
"explore.map.page.side.panel.download.report.title": {
"defaultMessage": "Get report",
"description": "Navigate to the explore the map page. When the map is in view, click on the map. The side panel will show link to download a report"
},
"explore.map.page.side.panel.exceed.burden.answer.no": { "explore.map.page.side.panel.exceed.burden.answer.no": {
"defaultMessage": "No", "defaultMessage": "No",
"description": "Navigate to the explore the map page. When the map is in view, click on the map. This will display NO if the census tract is disadvantaged" "description": "Navigate to the explore the map page. When the map is in view, click on the map. This will display NO if the census tract is disadvantaged"

31
client/src/pages/pdf.tsx Normal file
View file

@ -0,0 +1,31 @@
import * as React from 'react';
import J40MainGridContainer from '../components/J40MainGridContainer';
import Layout from '../components/layout';
import PDFRenderer from '../components/PDFRenderer/PDFRenderer';
import {PDFDownloadLink} from '@react-pdf/renderer';
interface IContactPageProps {
location: Location;
}
const ContactPage = ({location}: IContactPageProps) => {
return (
<Layout location={location} title={'test'}>
<J40MainGridContainer>
<PDFDownloadLink document={<PDFRenderer/>} fileName="document">
{({loading}) =>
loading ? (
<button>Generating Report</button>
) : (
<button>Download Report</button>
)}
</PDFDownloadLink>
{/* <PDFRenderer /> */}
</J40MainGridContainer>
</Layout>
);
};
export default ContactPage;