Skip to content

Commit

Permalink
Merge pull request #253 from bcgov/FEATURE/download-itinerary
Browse files Browse the repository at this point in the history
Feature/download itinerary
  • Loading branch information
alateefah authored Jan 23, 2023
2 parents 783cae7 + 9dc91e5 commit 3b6dce9
Show file tree
Hide file tree
Showing 9 changed files with 53,192 additions and 985 deletions.
53,986 changes: 53,019 additions & 967 deletions packages/bcer-data-portal/app/package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions packages/bcer-data-portal/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"geojson": "0.5.0",
"keycloak-js": "9.0.2",
"leaflet": "1.7.1",
"leaflet-simple-map-screenshoter": "0.5.0",
"material-table": "1.69.1",
"moment": "2.27.0",
"node-sass": "^4.14.1",
Expand Down Expand Up @@ -103,7 +104,7 @@
"webpack-merge": "^5.1.1"
},
"peerDependencies": {
"htmlparser2": "7.2.0",
"@types/htmlparser2": "3.10.3"
"@types/htmlparser2": "3.10.3",
"htmlparser2": "7.2.0"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 26 additions & 1 deletion packages/bcer-data-portal/app/src/hooks/useLeaflet.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext, useEffect, useState } from 'react';
import * as ReactDOMServer from 'react-dom/server';
import L, { Tooltip } from 'leaflet';
import { SimpleMapScreenshoter } from 'leaflet-simple-map-screenshoter';
import GeoJSON from 'geojson';
import {
BCDirectionData,
Expand All @@ -20,6 +20,9 @@ import sanitizeHtml from 'sanitize-html';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
import { useHistory } from 'react-router';
import moment from 'moment';
import ItineraryPdf from './../views/Map/ItineraryPdf';
import jsPDF from 'jspdf';
import ReactDOMServer from "react-dom/server";

// Map layer for Health Authority Boundaries
const haLayer = createHealthAuthorityLayer();
Expand Down Expand Up @@ -54,6 +57,7 @@ function useLeaflet(locationIds: string, config: LocationConfig) {
const [clickedLocation, setClickedLocation] = useState<BusinessLocation>();
const [startingLocation, setStartingLocation] =
useState<BCGeocoderAutocompleteData>();
const [downloadingItinerary, setDownloadingItinerary] = useState(false);

// Initial routing options in the map controller
const initialRoutingOptions: RouteOptions = {
Expand Down Expand Up @@ -406,6 +410,25 @@ function useLeaflet(locationIds: string, config: LocationConfig) {
}
}

const downloadItinerary = async () => {
setDownloadingItinerary(true)
const simpleMapScreenshoter = new SimpleMapScreenshoter().addTo(map);
await simpleMapScreenshoter.takeScreen('image', { mimeType: 'image/jpeg' }).then(image => {
generatePDF(image);
simpleMapScreenshoter.remove();
}).catch(e => {
simpleMapScreenshoter.remove();
setDownloadingItinerary(false)
})
}

const generatePDF = async (image: any) => {
const pdf = new jsPDF('p', 'pt', 'letter');
await pdf.html(ReactDOMServer.renderToStaticMarkup(<ItineraryPdf routeData={routeData} locations={selectedLocations} imageString = {image} />));
pdf.save(`Itinerary-${selectedLocations[0].id}`)
setDownloadingItinerary(false);
}

/**
* If there is a change in locations or options it reinitialize all the markers and
* gets fresh route data
Expand Down Expand Up @@ -493,6 +516,8 @@ function useLeaflet(locationIds: string, config: LocationConfig) {
setHealthAuthorityLocations,
clickedLocation,
setDisplayItinerary,
downloadItinerary,
downloadingItinerary
};
}

Expand Down
26 changes: 26 additions & 0 deletions packages/bcer-data-portal/app/src/util/map.util.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { BCDirectionData, BusinessLocation } from "@/constants/localInterfaces";
import React from "react";

export class MapUtil {
static formatLocationsForPDF(locations: BusinessLocation[], routeData: BCDirectionData) {
return {
locations : locations.map(({ id, addressLine1, postal, city }, index) => {
return <div key = {id} style={{paddingBottom: 10, fontSize: 10, width: '100%'}}>
<div style={{fontWeight: 'bold', color: 'black', paddingBottom: 5}}>{`Location ${index+1}`}</div>
<div style={{fontSize: 10, width: '100%', color: 'grey'}}>
{addressLine1}
<div>{`${postal}, ${city}`}</div>
</div>
</div>
}),
directions: routeData.directions.map(({ type, text}, index) => {
return <div key={index} style={{paddingBottom: 12, fontSize: 10, width: '100%'}}>
<div style={{fontWeight: 'bold', color: 'black', paddingBottom: 3}}>{type}</div>
<div style={{color: 'grey'}}>
{text}
</div>
</div>
})
};
}
}
29 changes: 18 additions & 11 deletions packages/bcer-data-portal/app/src/views/Locations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import {
import { BusinessLocation } from '@/constants/localInterfaces';
import { AppGlobalContext } from '@/contexts/AppGlobal';
import { healthAuthorityOptions} from '../constants/arrays'
import { date } from 'yup';

const useStyles = makeStyles({
loadingWrapper: {
Expand Down Expand Up @@ -514,13 +513,6 @@ export default function Locations() {
return <TextField {...props} disabled={true} />;
};

const clearAllFilter = () => {
setSearchTerms({
page:0,
pageSize: 20
})
}

return (
<div className={classes.contentWrapper}>
<div className={classes.content}>
Expand Down Expand Up @@ -578,7 +570,11 @@ export default function Locations() {
fromdate: searchTerms.fromdate ? searchTerms.fromdate : null,
todate: searchTerms.todate ? searchTerms.todate : null
}}
>
>{props => {
const {
resetForm
} = props;
return (
<Form>
<Box
alignContent="center"
Expand All @@ -603,7 +599,17 @@ export default function Locations() {
component="button"
variant="body2"
type="reset"
onClick={() => clearAllFilter()}>
onClick={() => {
resetForm({ values: {search: null,
authority: 'all', location_type: 'all',
reporting_status: 'all', underage: 'all', noi_report: 'all', product_report: 'all',
manufacturing_report: 'all', sales_report: 'all', fromdate: null, todate: null}

});
setSearchTerms({ page:0, pageSize: 20 })
}}
>

Clear all filters
</Link>
</Box>
Expand Down Expand Up @@ -737,7 +743,8 @@ export default function Locations() {
</Box>
</Grid>
</Grid>
</Form>
</Form>)
}}
</Formik>
<div>
<Typography className={classes.tableRowCount} variant="body2">
Expand Down
71 changes: 71 additions & 0 deletions packages/bcer-data-portal/app/src/views/Map/ItineraryPdf.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { BCDirectionData, BusinessLocation } from '@/constants/localInterfaces';
import { Grid, Typography, makeStyles } from '@material-ui/core';
import Box from '@material-ui/core/Box';
import React from 'react';
import logo from '../../assets/images/bc-logo.png';
import { MapUtil } from '@/util/map.util';

const useStyles = makeStyles((theme) => ({
container: {
width: 535,
padding: 40,
display: 'flex',
flexDirection: 'column',
gap: 20
},
logo: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: 15,
paddingBottom: 20
},
itinerary: {
paddingBottom: 20
},
header: {
fontSize: 14,
color: '#002C71',
fontWeight: 'bold',
},
}));

type ItineraryPdfProps = {
routeData: BCDirectionData,
locations: BusinessLocation[],
imageString: string
}

function ItineraryPdf ({ routeData, locations, imageString }: ItineraryPdfProps) {
const classes = useStyles();
const formattedData = MapUtil.formatLocationsForPDF(locations, routeData);
return (
<Box className={classes.container}>
<div className={classes.logo}>
<img src={logo} alt="BC Logo" style={{height: '70px', width: '90px'}} />
<Typography className={classes.header} style={{ fontSize: '16px'}}>E-Substances Regulation</Typography>
</div>

<div className={classes.itinerary}>
<Typography className={classes.header}>Itinerary</Typography>
<Box mt={1} />
<img src={imageString} alt="Itinerary Map" style={{ height: '330px', width: '540px'}} />
</div>

<Grid container spacing={2} >
<Grid item md={6}>
<Typography className={classes.header}>Directions</Typography>
<Box mt={1} />
{formattedData.directions}
</Grid>
<Grid item md={6}>
<Typography className={classes.header}>Business Location</Typography>
<Box mt={1} />
{formattedData.locations}
</Grid>
</Grid>
</Box>
)
}

export default ItineraryPdf
27 changes: 24 additions & 3 deletions packages/bcer-data-portal/app/src/views/Map/LeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ interface LeftPanelProps {
clickedLocation: BusinessLocation,
setDisplayItinerary: React.Dispatch<SetStateAction<boolean>>,
onRender: () => void,
downloadItinerary: () => void,
downloadingItinerary: Boolean
}

function LeftPanel({
Expand All @@ -120,6 +122,8 @@ function LeftPanel({
clickedLocation,
setDisplayItinerary,
onRender,
downloadItinerary,
downloadingItinerary
}: LeftPanelProps) {
const classes = useStyles();
const history = useHistory();
Expand Down Expand Up @@ -219,7 +223,7 @@ function LeftPanel({
<Typography className={classes.header}>Route</Typography>
<Box mt={1} />
<Grid container spacing={2}>
<Grid item xs={5}>
<Grid item xs={4}>
<StyledButton
variant="small-outlined"
size="small"
Expand All @@ -228,8 +232,7 @@ function LeftPanel({
<Hidden smDown><Box ml={1} /></Hidden> Show in Google Map
</StyledButton>
</Grid>
<Grid item xs={2}>&nbsp;</Grid>
<Grid item xs={5}>
<Grid item xs={4}>
{locations.length > 0 &&
<StyledButton
variant="small-outlined"
Expand All @@ -240,6 +243,24 @@ function LeftPanel({
<Hidden smDown><Box ml={1} /></Hidden> Display Itinerary
</StyledButton>}
</Grid>
<Grid item xs={4}>
{locations.length > 0 && routeData &&
<StyledButton
variant="small-contained"
size="small"
style={{float: 'right', padding: "4px 6px"}}
onClick={() => downloadItinerary()}
>
<DirectionsIcon fontSize="small" />
{downloadingItinerary ?
<CircularProgress size={24} /> :
<>
<DirectionsIcon fontSize="small" /> Export Itinerary to PDF
</>
}

</StyledButton>}
</Grid>
</Grid>
<Box mt={4} />

Expand Down
6 changes: 5 additions & 1 deletion packages/bcer-data-portal/app/src/views/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ function Map({asMenu, config}: MapProps) {
healthAuthorityLocations,
setHealthAuthorityLocations,
clickedLocation,
setDisplayItinerary
setDisplayItinerary,
downloadItinerary,
downloadingItinerary
} = useLeaflet(locationIds, config);

useEffect(() => {
Expand Down Expand Up @@ -97,6 +99,8 @@ function Map({asMenu, config}: MapProps) {
clickedLocation={clickedLocation}
setDisplayItinerary={setDisplayItinerary}
onRender={onRender}
downloadItinerary={downloadItinerary}
downloadingItinerary = {downloadingItinerary}
/>
</Box>
</Drawer>
Expand Down

0 comments on commit 3b6dce9

Please sign in to comment.