Skip to content

Commit

Permalink
feat: add contaminant data and implementation ideas to cccv pdf
Browse files Browse the repository at this point in the history
  • Loading branch information
wtcarter-gw committed Jun 25, 2024
1 parent 44c961b commit c48df9c
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export function getObjectiveDescription(contaminant: Contaminant, contaminant_le
export const level_codes = (level: string | undefined) => (level ?? '').trim().match(/\b[A-E]\b/g)?.sort();

export const byWhen = (contaminant: Contaminant) => {
console.log(contaminant.byWhen);
const mciYear = Array.from((contaminant.byWhen ?? '').matchAll(/([0-9]+) for MCI/g), match => match[1]);

if (contaminantTitle(contaminant).includes('MCI') && mciYear?.length)
Expand Down
72 changes: 34 additions & 38 deletions packages/cccv/src/components/Contaminants/Contaminants.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,54 @@
import React, {useState} from "react";
import {ContaminantList} from "@components/FreshwaterManagementUnit/utils.ts";
import {ChevronUpIcon, ChevronDownIcon} from '@heroicons/react/20/solid';
import React, { useState } from "react";
import { ContaminantList } from "@components/FreshwaterManagementUnit/utils.ts";
import { ChevronUpIcon, ChevronDownIcon } from '@heroicons/react/20/solid';
import {
getObjectiveDescription,
contaminantTitle,
byWhen
} from "@components/Contaminants/ContaminantObjectiveDescription";


export const Contaminants: React.FC<{ contaminants: ContaminantList }> = ({contaminants}) => {
export const Contaminants: React.FC<{ contaminants: ContaminantList }> = ({ contaminants }) => {
const [expandedRows, setExpandedRows] = useState<{ [key: string]: boolean }>({});

const handleRowClick = (title: string) => {
setExpandedRows(prevState => ({...prevState, [title]: !prevState[title]}));
setExpandedRows(prevState => ({ ...prevState, [title]: !prevState[title] }));
};

return (
<div>
{contaminants.map((contaminant, index) => (
<table className="min-w-full mb-4" key={index}>
<thead>
<tr className="pb-0">
<th colSpan={1} />
<th colSpan={2} className="px-4 text-left text-sm font-semibold">{contaminantTitle(contaminant)}</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr onClick={() => handleRowClick(contaminant.title)} className="cursor-pointer border-b border-gray-200">
<th className="px-1 text-left text-sm font-medium text-gray-600">
{expandedRows[contaminant.title] ? <ChevronUpIcon className="h-6 w-6 text-blue-500"/> :
<ChevronDownIcon className="h-6 w-6 text-blue-500"/>}
</th>
<th className="px-4 text-left text-sm font-medium text-gray-600">
Base Rating (2018) <span className="font-bold">{contaminant.base || "None"}</span></th>
<th className="px-4 text-left text-sm font-medium text-gray-600">Objective
{contaminant.byWhen ? ` (${byWhen(contaminant)})` : ''} <span className="font-bold">{contaminant.objective || 'None'}</span></th>
</tr>
<div className={`min-w-full border-b border-gray-300 pb-3`} key={index}>
<div className="grid mb-1 mt-3 items-center" style={{ gridTemplateColumns: "20px 4fr" }}>
<div className="pl-0 text-left text-md font-medium text-gray-600 cursor-pointer" onClick={() => handleRowClick(contaminant.title)}>
{expandedRows[contaminant.title] ? <ChevronUpIcon className="h-6 w-6 text-blue-500" /> : <ChevronDownIcon className="h-6 w-6 text-blue-500" />}
</div>
<div className="pl-4 text-left text-md font-semibold">
{index.toString()+" "+contaminants.length+" "+contaminantTitle(contaminant)}
</div>
<div></div>
</div>
<div className={`grid mb-2 items-top`} style={{ gridTemplateColumns: "20px 2fr 2fr" }}>
<div className="pl-1"></div>
<div className="pl-4 text-left text-sm font-medium text-gray-600">
Base Rating (2018) <span className="font-bold">{contaminant.base || "None"}</span>
</div>
<div className="pl-4 text-left text-sm font-medium text-gray-600">
Objective {contaminant.byWhen ? ` (${byWhen(contaminant)})` : ''} <span className="font-bold">{contaminant.objective || 'None'}</span>
</div>
</div>
{expandedRows[contaminant.title] && (
<tr>
<td className="px-0 pt-2 text-xs text-left align-text-top">
</td>
<td className="px-4 pt-2 text-xs text-left align-text-top">
<div dangerouslySetInnerHTML={{__html: getObjectiveDescription(contaminant, contaminant.base) ?? ''}}/>
</td>
<td className="px-4 pt-2 text-xs text-left align-text-top">
<div
dangerouslySetInnerHTML={{__html: getObjectiveDescription(contaminant, contaminant.objective) ?? ''}}/>
</td>
</tr>
<div className="grid" style={{ gridTemplateColumns: "20px 2fr 2fr" }}>
<div className="pl-1 text-xs text-left align-text-top"></div>
<div className="pl-4 text-xs text-left align-text-top">
<div dangerouslySetInnerHTML={{ __html: getObjectiveDescription(contaminant, contaminant.base) ?? '' }} />
</div>
<div className="pl-4 text-left text-xs align-text-top">
<div dangerouslySetInnerHTML={{ __html: getObjectiveDescription(contaminant, contaminant.objective) ?? '' }} />
</div>
</div>
)}
</tbody>
</table>
</div>
))}
</div>
);

};
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {Document, Font, Image, Page, Text, View} from '@react-pdf/renderer';
import purify from 'dompurify';
import {
contaminants as fmuContaminants,
ContaminantList
Expand All @@ -11,6 +10,11 @@ import gwrcLogo from "@images/printLogo_500x188px.png";
import {tw as predefinedTw} from "@lib/pdfTailwindStyles.ts";
import fonts from "@src/fonts.ts";
import React from "react";
import {
getObjectiveDescription,
contaminantTitle,
byWhen
} from "@components/Contaminants/ContaminantObjectiveDescription";

Font.register(fonts.inter);

Expand All @@ -28,19 +32,28 @@ const twContext = createTw({
const tw = (input: string) => twContext(predefinedTw(input))

const Contaminants: React.FC<{ contaminants: ContaminantList }> = ({contaminants}) => (
<View style={tw('w-full body mt-2')}>
<View style={tw('w-full body mt-4')}>
<View style={tw('flex flex-row border-b border-gray-300')}>
<Text style={tw('w-1/4 p-2 font-bold')}></Text>
<Text style={tw('w-1/4 p-2')}>Base</Text>
<Text style={tw('w-1/4 p-2')}>Objective</Text>
<Text style={tw('w-1/4 p-2')}>By</Text>
<Text style={tw('w-1/5 p-2 font-bold')}></Text>
<Text style={tw('w-2/5 p-2')}>Base</Text>
<Text style={tw('w-2/5 p-2')}>Objective</Text>
</View>
{contaminants.map((contaminant, index) => (
<View key={index} style={tw('flex flex-row border-b border-gray-300')}>
<Text style={tw('w-1/4 p-2 font-bold')}>{contaminant.title}</Text>
<Text style={tw('w-1/4 p-2')}>{contaminant.base}</Text>
<Text style={tw('w-1/4 p-2')}>{contaminant.objective}</Text>
<Text style={tw('w-1/4 p-2')}>{contaminant.byWhen}</Text>
<View>
<View key={index} style={tw('flex flex-row mt-2')}>
<Text style={tw('w-1/5 p-2 font-bold')}>{contaminantTitle(contaminant)}</Text>
<Text style={tw('w-2/5 p-2')}>{contaminant.base}</Text>
<Text style={tw('w-2/5 p-2')}>{`${contaminant.objective}${contaminant.byWhen ? ` (${byWhen(contaminant)})` : ''}`}</Text>
</View>
<View style={tw('flex flex-row pb-4 border-b border-gray-300')}>
<Text style={tw('w-1/5 text-left align-text-top')}></Text>
<Text style={tw('w-2/5 pl-2 text-left align-text-top')}>
<Text>{getObjectiveDescription(contaminant, contaminant.base) ?? ''}</Text>
</Text>
<Text style={tw('w-2/5 pl-2 text-left align-text-top')}>
<Text>{getObjectiveDescription(contaminant, contaminant.objective) ?? ''}</Text>
</Text>
</View>
</View>
))}
</View>
Expand All @@ -63,6 +76,7 @@ export const FreshwaterManagementUnitPDF = (details: FmuFullDetails) => {
id,
fmuName1,
catchmentDescription,
implementationIdeas,
} = details.freshwaterManagementUnit;

const tangataWhenuaSites = details.tangataWhenuaSites;
Expand Down Expand Up @@ -90,8 +104,8 @@ export const FreshwaterManagementUnitPDF = (details: FmuFullDetails) => {
{catchmentDescription ? (<>
<Text style={tw("h2 mb-2")}>Overview</Text>
<Text
style={tw("body mb-4")}>{purify.sanitize(catchmentDescription || 'No overview available').replace(/<[^>]+>/g, '')}</Text>
</>) : null}
style={tw("body mb-4")}>{(catchmentDescription ?? '').replace(/<[^>]+>/g, '')}</Text>

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.
</>) : <View><Text style={tw("body mb4")}>No overview available</Text></View>}
</View>

<View style={tw("mb-6")}>
Expand All @@ -112,7 +126,14 @@ export const FreshwaterManagementUnitPDF = (details: FmuFullDetails) => {

<BulletList items={tangataWhenuaSites?.map(s => s.location)}/>
</View>
) : null}
) : <View/>}

{implementationIdeas ? (
<View style={tw("mb-4")} wrap={false}>
<Text style={tw("h2")}>Implementation Ideas</Text>
<BulletList items={implementationIdeas}/>
</View>
) : <View/>}

<View style={tw("mb-4")} wrap={false}>
<Text style={tw("h2 mb-2")}>About this Information</Text>
Expand All @@ -130,7 +151,7 @@ export const FreshwaterManagementUnitPDF = (details: FmuFullDetails) => {
<Text style={tw('text-xs')}>CCCV details for {fmuName1}</Text>
<Text
style={tw('text-xs')}
render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`}
render={({pageNumber, totalPages}) => `Page ${pageNumber} of ${totalPages}`}
/>
</View>
</Page>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const FreshwaterManagementUnit = (details: FmuFullDetails) => {
<div className="tangata-whenua-sites">
<ul className={"mt-2"}>
{tangataWhenuaSites?.map((site: { location: string }, index: Key | null | undefined) => <li
className="list-disc" key={index}>{site?.location}</li>)}
className="list-disc my-0" key={index}>{site?.location}</li>)}
</ul>
</div>
</div>
Expand All @@ -69,14 +69,19 @@ const FreshwaterManagementUnit = (details: FmuFullDetails) => {
{implementationIdeas ? (
<div className="implementation-ideas mt-6">
<h2>Implementation Ideas</h2>
<div
dangerouslySetInnerHTML={{__html: purify.sanitize(implementationIdeas)}}/>
<div className="implementation-ideas">
<ul className={"mt-2"}>
{implementationIdeas?.map((idea: string, index) => <li
className="list-disc my-0" key={index}>{idea}</li>)}
</ul>
</div>
</div>
) : <div></div>}

<div className={`about-this-information mt-6`}>
<h3>About this information</h3>
<p>The content, data, and information used in this app comes from multiple sources, including Greater Wellington’s <a>Natural Resources Plan</a> (2018) and Whaitua Implementation Plans.</p>
<p>The content, data, and information used in this app comes from multiple sources, including Greater
Wellington’s <a>Natural Resources Plan</a> (2018) and Whaitua Implementation Plans.</p>
<div className="mt-6 flex justify-center">
<EmailLink>Contact us for more information</EmailLink>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const FeatureHighlight: React.FC<FeatureHighlightProps> = ({
moveToolTip();
if (mapRef?.current) {
const map = mapRef.current.getMap();
map.on('mouseup', moveToolTip);
map.on('drag', moveToolTip);
map.on('move', moveToolTip);
return () => {
map.off('move', moveToolTip);
Expand Down
2 changes: 1 addition & 1 deletion packages/cccv/src/models/FreshwaterManagementUnit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default interface FreshwaterManagementUnit {
atoxObj?: string
ntoxBase?: string
ntoxObj?: string
implementationIdeas?: string
implementationIdeas?: string[]
catchmentDescription?: string
tangataWhenua?: { iwi: string[], sites: { name: string }[] }
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cccv/src/pages/MapPage/MapPage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ $gapSize: 12px;

.info-panel {
position: absolute;
grid-column: 9 / span 4;
grid-column: 8 / span 5;
overflow: auto;
grid-row: 1;
height: 100%;
Expand Down
12 changes: 6 additions & 6 deletions packages/cccv/src/services/FreshwaterManagementUnitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ const service = {
return record;
}
if (record.freshwaterManagementUnit.fmuName1 == 'Parkvale Stream' && !record.freshwaterManagementUnit.implementationIdeas) {
record.freshwaterManagementUnit.implementationIdeas = "<ul>\n" +
"<li>Consider wetlands for water quality treatment before discharges reach the stream</li>" +
"<li>Setbacks from depressions and waterways should be necessary for intensive land uses including winter grazing and winter cropping</li>" +
"<li>Riparian planting should be undertaken in strategic spots, including to provide shade to help improve periphytn and macrophyte problems</li>" +
"<li>Good management of stock access to streambanks and of winter grazing may prove important in this catchment</li>" +
"</ul>";
record.freshwaterManagementUnit.implementationIdeas = [
"Consider wetlands for water quality treatment before discharges reach the stream",
"Setbacks from depressions and waterways should be necessary for intensive land uses including winter grazing and winter cropping",
"Riparian planting should be undertaken in strategic spots, including to provide shade to help improve periphytn and macrophyte problems",
"Good management of stock access to streambanks and of winter grazing may prove important in this catchment"
];
}
return record;
}
Expand Down

0 comments on commit c48df9c

Please sign in to comment.