Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC Assessment Popup #2236

Merged
merged 16 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions frontend/src/components/bcAssessment/BCADialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
Stack,
Typography,
} from '@mui/material';
import { HeaderDivider } from 'features/mapSideBar/components/tabs/HeaderDivider';
import { tabStyles } from 'features/mapSideBar/components/tabs/TabStyles';
import React, { Dispatch, SetStateAction } from 'react';
import formatCurrency from 'utils/formatCurrency';

export interface IBCAData {
GEN_NET_IMPROVEMENT_VALUE: number;
GEN_NET_LAND_VALUE: number;
GEN_GROSS_LAND_VALUE: number;
GEN_GROSS_IMPROVEMENT_VALUE: number;
FOLIO_ID: string;
ROLL_NUMBER: string;
}

interface IBCADialogProps {
bcaInfoOpen: boolean;
setBcaInfoOpen: Dispatch<SetStateAction<boolean>>;
bcaData: IBCAData;
}

export const BCADialog = (props: IBCADialogProps) => {
const { bcaInfoOpen, setBcaInfoOpen, bcaData } = props;
const { leftColumnWidth, rightColumnWidth, boldFontWeight, fontSize, headerColour } = tabStyles;
const noInfoParagraphStyle = {
display: 'flex',
margin: '1em',
color: 'GrayText',
fontSize: '11pt',
};
return (
<Dialog
open={bcaInfoOpen}
scroll={'body'}
aria-labelledby="scroll-dialog-title"
aria-describedby="scroll-dialog-description"
maxWidth={'md'}
>
<DialogTitle id="scroll-dialog-title">BC Assessment Information</DialogTitle>
<DialogContent>
{bcaData.FOLIO_ID ? (
<div className="title">
<Box sx={{ p: 2, background: 'white' }}>
{/* HEADER */}
<Stack direction="row" spacing={1}>
<Typography
text-align="left"
sx={{ fontWeight: boldFontWeight, color: headerColour }}
>
Details
</Typography>
</Stack>
<HeaderDivider />

{/* CONTENT */}
<Grid container sx={{ textAlign: 'left' }} rowSpacing={0.5}>
<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Folio ID:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>{bcaData?.FOLIO_ID}</Typography>
</Grid>

<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Roll Number:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>{bcaData?.ROLL_NUMBER}</Typography>
</Grid>

<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Net Improvement Value:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>
{formatCurrency(bcaData.GEN_NET_IMPROVEMENT_VALUE)}
</Typography>
</Grid>

<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Net Land Value:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>
{formatCurrency(bcaData?.GEN_NET_LAND_VALUE)}
</Typography>
</Grid>

<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Gross Improvement Value:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>
{formatCurrency(bcaData?.GEN_GROSS_IMPROVEMENT_VALUE)}
</Typography>
</Grid>

<Grid item xs={leftColumnWidth}>
<Typography fontSize={fontSize}>Gross Land Value:</Typography>
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>
{formatCurrency(bcaData?.GEN_GROSS_LAND_VALUE)}
</Typography>
</Grid>
</Grid>
</Box>
</div>
) : (
<>
<p style={noInfoParagraphStyle}>
No BC Assessment information available for this PID or information still loading.
</p>
</>
)}
</DialogContent>
<DialogActions>
<Button
onClick={() => {
setBcaInfoOpen(false);
}}
sx={{
backgroundColor: '#003366',
color: '#F2F2F2',
fontWeight: 600,
'&:hover': {
backgroundColor: '#1A5A96',
},
}}
>
Close
</Button>
</DialogActions>
</Dialog>
);
};
26 changes: 2 additions & 24 deletions frontend/src/components/ltsa/TitleDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ILTSAOrderModel } from 'actions/parcelsActions';
import { HeaderDivider } from 'features/mapSideBar/components/tabs/HeaderDivider';
import { tabStyles } from 'features/mapSideBar/components/tabs/TabStyles';
import React from 'react';
import formatCurrency from 'utils/formatCurrency';

interface ITitleDetailsProps {
ltsa?: ILTSAOrderModel;
Expand All @@ -12,27 +13,6 @@ export const TitleDetails = (props: ITitleDetailsProps) => {
const { ltsa } = props;
const { leftColumnWidth, rightColumnWidth, boldFontWeight, fontSize, headerColour } = tabStyles;

const calculateCurrency = (value: number | string | undefined) => {
if (!value) {
return '';
}

let cleanedValue = 0;
if (typeof value === 'string') {
cleanedValue = parseFloat(value.replace(',', '').replace('$', ''));
if (Number.isNaN(cleanedValue)) {
return '';
}
} else if (typeof value === 'number') {
cleanedValue = value;
}

return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'CAD',
}).format(cleanedValue);
};

return (
<div className="title">
<Box sx={{ p: 2, background: 'white' }}>
Expand Down Expand Up @@ -80,9 +60,7 @@ export const TitleDetails = (props: ITitleDetailsProps) => {
</Grid>
<Grid item xs={rightColumnWidth}>
<Typography fontSize={fontSize}>
{calculateCurrency(
ltsa?.order.orderedProduct.fieldedData.tombstone.marketValueAmount,
)}
{formatCurrency(ltsa?.order.orderedProduct.fieldedData.tombstone.marketValueAmount)}
</Typography>
</Grid>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ILTSAOrderModel } from 'actions/parcelsActions';
import { BCADialog, IBCAData } from 'components/bcAssessment/BCADialog';
import { LTSADialog } from 'components/ltsa/LTSADialog';
import { useApi } from 'hooks/useApi';
import { LatLng, LatLngBounds } from 'leaflet';
Expand Down Expand Up @@ -70,6 +71,7 @@ export const LayerPopupContent: React.FC<IPopupContentProps> = ({ data, config,

// Get LTSA information
const [ltsaInfoOpen, setLtsaInfoOpen] = React.useState<boolean>(false);
const [bcaInfoOpen, setBcaInfoOpen] = React.useState<boolean>(false);
const [ltsa, setLtsa] = useState<ILTSAOrderModel | undefined>(undefined);
const api = useApi();

Expand Down Expand Up @@ -121,6 +123,23 @@ export const LayerPopupContent: React.FC<IPopupContentProps> = ({ data, config,
</StyledLink>
<LTSADialog pid={data.PID} {...{ ltsa, ltsaInfoOpen, setLtsaInfoOpen }} />
</Col>
{data.FOLIO_ID && (
<Col>
<StyledLink
to={{ ...location }}
onClick={() => {
setBcaInfoOpen(true);
}}
>
BCA Info
</StyledLink>
<BCADialog
bcaData={data as unknown as IBCAData}
bcaInfoOpen={bcaInfoOpen}
setBcaInfoOpen={setBcaInfoOpen}
/>
</Col>
)}
</MenuRow>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ export const MUNICIPALITY_LAYER_URL =
'https://openmaps.gov.bc.ca/geo/pub/WHSE_LEGAL_ADMIN_BOUNDARIES.ABMS_MUNICIPALITIES_SP/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.3.0&outputFormat=application/json&typeNames=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.ABMS_MUNICIPALITIES_SP';
export const PARCELS_PUBLIC_LAYER_URL =
'https://openmaps.gov.bc.ca/geo/pub/WHSE_CADASTRE.PMBC_PARCEL_FABRIC_POLY_SVW/wfs?service=WFS&REQUEST=GetFeature&VERSION=1.3.0&outputFormat=application/json&typeNames=pub:WHSE_CADASTRE.PMBC_PARCEL_FABRIC_POLY_SVW';
export const BCA_PRIVATE_LAYER_URL = window.location.href.includes('pims.gov.bc.ca')
? 'https://apps.gov.bc.ca/ext/sgw/geo.bca?REQUEST=GetFeature&SERVICE=WFS&VERSION=2.0.0&typeName=geo.bca:WHSE_HUMAN_CULTURAL_ECONOMIC.BCA_FOLIO_GNRL_PROP_VALUES_SV&outputFormat=application/json'
: 'https://test.apps.gov.bc.ca/ext/sgw/geo.bca?REQUEST=GetFeature&SERVICE=WFS&VERSION=2.0.0&typeName=geo.bca:WHSE_HUMAN_CULTURAL_ECONOMIC.BCA_FOLIO_GNRL_PROP_VALUES_SV&outputFormat=application/json';

export const parcelLayerPopupConfig = {
PARCEL_NAME: { label: 'Parcel Name:', display: (data: any) => data.PARCEL_NAME },
Expand Down Expand Up @@ -32,6 +35,32 @@ export const parcelLayerPopupConfig = {
</>
),
},
// GEN_GROSS_LAND_VALUE: {
// label: 'Gross Land Value:',
// display: (data: any) => (
// <>{data.GEN_GROSS_LAND_VALUE ? `$${data.GEN_GROSS_LAND_VALUE}` : `N/A`}</>
// ),
// },
// GEN_GROSS_IMPROVEMENT_VALUE: {
// label: 'Gross Improvement Value:',
// display: (data: any) => (
// <>{data.GEN_GROSS_IMPROVEMENT_VALUE ? `$${data.GEN_GROSS_IMPROVEMENT_VALUE}` : `N/A`}</>
// ),
// },
// GEN_NET_LAND_VALUE: {
// label: 'Net Land Value:',
// display: (data: any) => <>{data.GEN_NET_LAND_VALUE ? `$${data.GEN_NET_LAND_VALUE}` : `N/A`}</>,
// },
// GEN_NET_IMPROVEMENT_VALUE: {
// label: 'Net Improvement Value:',
// display: (data: any) => (
// <>{data.GEN_NET_IMPROVEMENT_VALUE ? `$${data.GEN_NET_IMPROVEMENT_VALUE}` : `N/A`}</>
// ),
// },
// FOLIO_ID: {
// label: 'Folio ID:',
// display: (data: any) => <>{data.FOLIO_ID ? `${data.FOLIO_ID}` : `N/A`}</>,
// },
Comment on lines +38 to +63
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with leaving this here. Easy to uncomment if we want it back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I felt there was a non-zero chance we might move the information around so I figured I would leave it there for now.

};

export const municipalityLayerPopupConfig = {
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/components/maps/leaflet/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import FilterBackdrop from './FilterBackdrop';
import InfoSlideOut from './InfoSlideOut/InfoSlideOut';
import { InventoryLayer } from './InventoryLayer';
import {
BCA_PRIVATE_LAYER_URL,
MUNICIPALITY_LAYER_URL,
municipalityLayerPopupConfig,
parcelLayerPopupConfig,
Expand Down Expand Up @@ -186,6 +187,7 @@ const Map: React.FC<MapProps> = ({
const [triggerFilterChanged, setTriggerFilterChanged] = React.useState(true);
const municipalitiesService = useLayerQuery(MUNICIPALITY_LAYER_URL);
const parcelsService = useLayerQuery(PARCELS_PUBLIC_LAYER_URL);
const bcaWMSLayerService = useLayerQuery(BCA_PRIVATE_LAYER_URL ?? '');
const { setChanged } = useFilterContext();
const popUpContext = React.useContext(PropertyPopUpContext);
const parcelLayerFeature = useAppSelector((store) => store.parcelLayerData?.parcelLayerFeature);
Expand Down Expand Up @@ -313,6 +315,7 @@ const Map: React.FC<MapProps> = ({
!!onMapClick && onMapClick(event);
const municipality = await municipalitiesService.findOneWhereContains(event.latlng);
const parcel = await parcelsService.findOneWhereContains(event.latlng);
const bca = await bcaWMSLayerService.findOneWhereContains(event.latlng);
let properties = {};
let center: LatLng | undefined;
let bounds: LatLngBounds | undefined;
Expand All @@ -337,6 +340,26 @@ const Map: React.FC<MapProps> = ({
center = bounds?.getCenter();
feature = parcel.features[0];
}
if (bca && bca.features?.length >= 1) {
const bcaProps = bca.features[0].properties!;
const {
GEN_NET_IMPROVEMENT_VALUE,
GEN_NET_LAND_VALUE,
GEN_GROSS_LAND_VALUE,
GEN_GROSS_IMPROVEMENT_VALUE,
FOLIO_ID,
ROLL_NUMBER,
} = bcaProps;
properties = {
...properties,
GEN_NET_IMPROVEMENT_VALUE,
GEN_NET_LAND_VALUE,
GEN_GROSS_LAND_VALUE,
GEN_GROSS_IMPROVEMENT_VALUE,
FOLIO_ID,
ROLL_NUMBER,
};
}

if (!isEmpty(properties)) {
setLayerPopup({
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/utils/formatCurrency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* formatCurrency - transform a string or number to the local Canadian currency string format.
* Ex: 1234: number -> CA$1,234: string
* @param value a number or string formatted number
* @returns {string}
*/
const formatCurrency = (value: number | string | undefined): string => {
if (value == null) {
return '';
}

let cleanedValue = 0;
if (typeof value === 'string') {
cleanedValue = parseFloat(value.replace(',', '').replace('$', ''));
if (Number.isNaN(cleanedValue)) {
return '';
}
} else if (typeof value === 'number') {
cleanedValue = value;
}

return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'CAD',
}).format(cleanedValue);
};

export default formatCurrency;
3 changes: 2 additions & 1 deletion frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"jsx": "react-jsx",
"downlevelIteration": true,
"noFallthroughCasesInSwitch": true,
"typeRoots": ["src/types", "node_modules/@types"]
"typeRoots": ["src/types", "node_modules/@types", "./node_modules"],
"types": ["vite/client"]
},
"include": ["src"]
}
5 changes: 0 additions & 5 deletions openshift/templates/app-dc-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,6 @@ objects:
value: /api
- name: RealIpFrom
value: 172.51.0.0/16
- name: VITE_BCA_LAYER_URL
valueFrom:
configMapKeyRef:
name: pims-app-env
key: BCA_LAYER_URL
ports:
- containerPort: 8080
protocol: TCP
Expand Down
Loading