From d28be7b906a89bffce821c7f3b11361cbb59db32 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Wed, 1 May 2024 15:25:19 -0700 Subject: [PATCH] PSP-8324 Update area convertor in Lease and License (#3981) * Code cleanup * Show common area component on lease view * Update property-lease repository to return area unit type-code * Use common area component to update lease property areas * Test updates * Increase spacing as per UI/UX review * Update snapshots --- .../Repositories/PropertyLeaseRepository.cs | 3 +- .../src/components/measurements/AreaView.tsx | 56 ++- .../AddLeaseContainer.test.tsx.snap | 5 - .../details/PropertyInformation.test.tsx | 12 +- .../details/PropertyInformation.tsx | 20 +- .../PropertiesInformation.test.tsx.snap | 98 ++++- .../PropertyInformation.test.tsx.snap | 352 ++++++++++++++++-- source/frontend/src/features/leases/models.ts | 30 +- .../propertyPicker/LeasePropertySelector.tsx | 2 + .../SelectedPropertyHeaderRow.tsx | 1 - .../SelectedPropertyRow.test.tsx | 3 +- .../SelectedPropertyRow.tsx | 92 +++-- .../SelectedPropertyRow.test.tsx.snap | 164 ++++++-- 13 files changed, 653 insertions(+), 185 deletions(-) diff --git a/source/backend/dal/Repositories/PropertyLeaseRepository.cs b/source/backend/dal/Repositories/PropertyLeaseRepository.cs index 76b17d9639..ca23a19c63 100644 --- a/source/backend/dal/Repositories/PropertyLeaseRepository.cs +++ b/source/backend/dal/Repositories/PropertyLeaseRepository.cs @@ -58,7 +58,8 @@ public IEnumerable GetAllByPropertyId(long propertyId) /// public IEnumerable GetAllByLeaseId(long leaseId) { - return this.Context.PimsPropertyLeases.AsNoTracking() + return Context.PimsPropertyLeases.AsNoTracking() + .Include(pl => pl.AreaUnitTypeCodeNavigation) .Include(pl => pl.Property) .ThenInclude(p => p.Address) .ThenInclude(p => p.Country) diff --git a/source/frontend/src/components/measurements/AreaView.tsx b/source/frontend/src/components/measurements/AreaView.tsx index 07c0d258c0..af23d57cb3 100644 --- a/source/frontend/src/components/measurements/AreaView.tsx +++ b/source/frontend/src/components/measurements/AreaView.tsx @@ -13,37 +13,35 @@ interface IAreaViewProps { const AreaView: React.FunctionComponent = props => { const meters = convertArea(props.landArea || 0, props.unitCode || '', AreaUnitTypes.SquareMeters); const feet = convertArea(props.landArea || 0, props.unitCode || '', AreaUnitTypes.SquareFeet); - const hectars = convertArea(props.landArea || 0, props.unitCode || '', AreaUnitTypes.Hectares); + const hectares = convertArea(props.landArea || 0, props.unitCode || '', AreaUnitTypes.Hectares); const acres = convertArea(props.landArea || 0, props.unitCode || '', AreaUnitTypes.Acres); return ( - <> - - - - - {formatNumber(meters, 0, 2)} - sq. metres - - - {formatNumber(hectars, 0, 2)} - hectares - - - - - - - {formatNumber(feet, 0, 2)} - sq. feet - - - {formatNumber(acres, 0, 2)} - acres - - - - - + + + + + {formatNumber(meters, 0, 2)} + sq. metres + + + {formatNumber(hectares, 0, 2)} + hectares + + + + + + + {formatNumber(feet, 0, 2)} + sq. feet + + + {formatNumber(acres, 0, 2)} + acres + + + + ); }; diff --git a/source/frontend/src/features/leases/add/__snapshots__/AddLeaseContainer.test.tsx.snap b/source/frontend/src/features/leases/add/__snapshots__/AddLeaseContainer.test.tsx.snap index b7268d9514..69aeed5a1b 100644 --- a/source/frontend/src/features/leases/add/__snapshots__/AddLeaseContainer.test.tsx.snap +++ b/source/frontend/src/features/leases/add/__snapshots__/AddLeaseContainer.test.tsx.snap @@ -1343,11 +1343,6 @@ exports[`AddLeaseContainer component > renders as expected 1`] = ` -
- Area included -
No Properties selected diff --git a/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.test.tsx b/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.test.tsx index 16c0a388e0..aff3c25455 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.test.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.test.tsx @@ -3,10 +3,10 @@ import { createMemoryHistory } from 'history'; import noop from 'lodash/noop'; import { mockApiProperty } from '@/mocks/filterData.mock'; +import { getMockApiLease } from '@/mocks/lease.mock'; import { getEmptyPropertyLease } from '@/mocks/properties.mock'; import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease'; import { toTypeCodeNullable } from '@/utils/formUtils'; -import { getMockApiLease } from '@/mocks/lease.mock'; import { render, RenderOptions } from '@/utils/test-utils'; import PropertyInformation, { IPropertyInformationProps } from './PropertyInformation'; @@ -45,7 +45,7 @@ describe('PropertyInformation component', () => { fileProperties: [ { ...getEmptyPropertyLease(), - ...mockApiProperty, + property: { ...mockApiProperty }, areaUnitType: toTypeCodeNullable('test'), leaseArea: 123, fileId: 0, @@ -65,7 +65,7 @@ describe('PropertyInformation component', () => { fileProperties: [ { ...getEmptyPropertyLease(), - ...mockApiProperty, + property: { ...mockApiProperty }, areaUnitType: toTypeCodeNullable('test'), leaseArea: 123, fileId: 0, @@ -94,7 +94,7 @@ describe('PropertyInformation component', () => { fileProperties: [ { ...getEmptyPropertyLease(), - ...mockApiProperty, + property: { ...mockApiProperty }, leaseArea: 1, areaUnitType: toTypeCodeNullable('test'), fileId: 0, @@ -123,7 +123,7 @@ describe('PropertyInformation component', () => { fileProperties: [ { ...getEmptyPropertyLease(), - ...mockApiProperty, + property: { ...mockApiProperty }, leaseArea: 123, areaUnitType: null, fileId: 0, @@ -141,7 +141,7 @@ describe('PropertyInformation component', () => { startDate: '2020-01-01', }, }); - expect(component.getByText(/123.00/i)).toBeVisible(); + expect(component.getByText(/123/i)).toBeVisible(); expect(component.queryByDisplayValue('undefined')).toBeNull(); }); }); diff --git a/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.tsx b/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.tsx index 3b792a5986..838a9d0976 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/details/PropertyInformation.tsx @@ -3,9 +3,11 @@ import styled from 'styled-components'; import { Input } from '@/components/common/form'; import { SectionField } from '@/components/common/Section/SectionField'; +import AreaContainer from '@/components/measurements/AreaContainer'; +import { AreaUnitTypes } from '@/constants'; import { ApiGen_Base_CodeType } from '@/models/api/generated/ApiGen_Base_CodeType'; import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease'; -import { formatNumber, isValidId, isValidString, pidFormatter } from '@/utils'; +import { isValidId, pidFormatter } from '@/utils'; import { withNameSpace } from '@/utils/formUtils'; import AddressSubForm from '../AddressSubForm'; @@ -47,18 +49,14 @@ export const PropertyInformation: React.FunctionComponent< - - {formatNumber(landArea || 0, 2, 2)}{' '} - {isValidString(areaUnitType?.description) ? ( - `${areaUnitType?.description}.` - ) : ( - <> - m2 - - )} + + {!hideAddress ? ( - + renders as expected 1`] = ` font-weight: bold; } +.c6 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + +.c7 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + .c3 { margin-top: 4rem; } @@ -131,7 +145,7 @@ exports[`PropertiesInformation component > renders as expected 1`] = `
renders as expected 1`] = `
- 123.00 m - - 2 - +
+
+
+
+
+ 123 +
+
+ sq. metres +
+
+
+
+ 0.01 +
+
+ hectares +
+
+
+
+
+
+
+
+ 1,323.96 +
+
+ sq. feet +
+
+
+
+ 0.03 +
+
+ acres +
+
+
+
+
renders a complete lease as expected 1` } .c3 { - grid-column: controls; - border-left: 1px solid black !important; - padding: 0.6rem 1.2rem; - color: #495057; - font-family: 'BCSans-Bold'; + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + +.c4 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; } .c0 { @@ -76,7 +82,7 @@ exports[`PropertyInformation component > renders a complete lease as expected 1`
renders a complete lease as expected 1`
- 123.00 m - - 2 - +
+
+
+
+
+ 123 +
+
+ sq. metres +
+
+
+
+ 0.01 +
+
+ hectares +
+
+
+
+
+
+
+
+ 1,323.96 +
+
+ sq. feet +
+
+
+
+ 0.03 +
+
+ acres +
+
+
+
+
renders a complete lease as expected 1`
- -

+

+
- Address not available in PIMS -

+ +
+
+ +
+
+ +
+
+ +
+
+ +
renders a complete lease as expected 1`
+ > + test description +

@@ -162,11 +298,17 @@ exports[`PropertyInformation component > renders minimally as expected 1`] = ` } .c3 { - grid-column: controls; - border-left: 1px solid black !important; - padding: 0.6rem 1.2rem; - color: #495057; - font-family: 'BCSans-Bold'; + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + +.c4 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; } .c0 { @@ -220,7 +362,7 @@ exports[`PropertyInformation component > renders minimally as expected 1`] = `
renders minimally as expected 1`] = `
- 123.00 m - - 2 - +
+
+
+
+
+ 123 +
+
+ sq. metres +
+
+
+
+ 0.01 +
+
+ hectares +
+
+
+
+
+
+
+
+ 1,323.96 +
+
+ sq. feet +
+
+
+
+ 0.03 +
+
+ acres +
+
+
+
+
renders minimally as expected 1`] = `
- -

+

+
- Address not available in PIMS -

+ +
+
+ +
+
+ +
+
+ +
+
+ +
renders minimally as expected 1`] = `
+ > + test description +

diff --git a/source/frontend/src/features/leases/models.ts b/source/frontend/src/features/leases/models.ts index f7ff50b215..516f1287f6 100644 --- a/source/frontend/src/features/leases/models.ts +++ b/source/frontend/src/features/leases/models.ts @@ -1,5 +1,7 @@ +import isNumber from 'lodash/isNumber'; + import { IMapProperty } from '@/components/propertySelector/models'; -import { PropertyAreaUnitTypes } from '@/constants/index'; +import { AreaUnitTypes } from '@/constants/index'; import { IAutocompletePrediction } from '@/interfaces'; import { ApiGen_Concepts_ConsultationLease } from '@/models/api/generated/ApiGen_Concepts_ConsultationLease'; import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease'; @@ -8,12 +10,11 @@ import { EpochIsoDateTime } from '@/models/api/UtcIsoDateTime'; import { getEmptyBaseAudit } from '@/models/defaultInitializers'; import { ILookupCode } from '@/store/slices/lookupCodes/interfaces/ILookupCode'; import { NumberFieldValue } from '@/typings/NumberFieldValue'; -import { exists, isValidId, isValidIsoDateTime, isValidString } from '@/utils'; +import { exists, isValidId, isValidIsoDateTime } from '@/utils'; import { emptyStringtoNullable, fromTypeCode, stringToNull, - stringToUndefined, toTypeCodeNullable, } from '@/utils/formUtils'; @@ -187,13 +188,13 @@ export class FormLeaseProperty { leaseId: number | null; rowVersion?: number; name?: string; - landArea: string; + landArea: number; areaUnitTypeCode: string; private constructor(leaseId?: number | null) { this.leaseId = leaseId ?? null; - this.landArea = '0'; - this.areaUnitTypeCode = PropertyAreaUnitTypes.Meter; + this.landArea = 0; + this.areaUnitTypeCode = AreaUnitTypes.SquareMeters; } public static fromApi(apiPropertyLease: ApiGen_Concepts_PropertyLease): FormLeaseProperty { @@ -202,8 +203,8 @@ export class FormLeaseProperty { model.id = apiPropertyLease.id; model.rowVersion = apiPropertyLease.rowVersion ?? undefined; model.name = apiPropertyLease.propertyName ?? undefined; - model.landArea = apiPropertyLease.leaseArea?.toString() || '0'; - model.areaUnitTypeCode = apiPropertyLease.areaUnitType?.id || PropertyAreaUnitTypes.Meter; + model.landArea = apiPropertyLease.leaseArea ?? 0; + model.areaUnitTypeCode = apiPropertyLease.areaUnitType?.id || AreaUnitTypes.SquareMeters; return model; } @@ -214,10 +215,6 @@ export class FormLeaseProperty { } public static toApi(formLeaseProperty: FormLeaseProperty): ApiGen_Concepts_PropertyLease { - const landArea = stringToUndefined(formLeaseProperty.landArea); - const numberLeaseArea: number | undefined = isValidString(landArea) - ? Number(landArea) - : undefined; return { id: formLeaseProperty.id ?? 0, fileId: formLeaseProperty.leaseId ?? 0, @@ -225,11 +222,10 @@ export class FormLeaseProperty { property: formLeaseProperty.property?.toApi() ?? null, propertyId: formLeaseProperty.property?.id ?? 0, propertyName: formLeaseProperty.name ?? null, - leaseArea: numberLeaseArea ?? null, - areaUnitType: - numberLeaseArea !== undefined - ? toTypeCodeNullable(formLeaseProperty.areaUnitTypeCode) ?? null - : null, + leaseArea: isNumber(formLeaseProperty.landArea) ? formLeaseProperty.landArea : 0, + areaUnitType: isNumber(formLeaseProperty.landArea) + ? toTypeCodeNullable(formLeaseProperty.areaUnitTypeCode) ?? null + : null, displayOrder: null, ...getEmptyBaseAudit(formLeaseProperty.rowVersion), }; diff --git a/source/frontend/src/features/leases/shared/propertyPicker/LeasePropertySelector.tsx b/source/frontend/src/features/leases/shared/propertyPicker/LeasePropertySelector.tsx index cb84989dc9..9faefba6b9 100644 --- a/source/frontend/src/features/leases/shared/propertyPicker/LeasePropertySelector.tsx +++ b/source/frontend/src/features/leases/shared/propertyPicker/LeasePropertySelector.tsx @@ -214,11 +214,13 @@ export const LeasePropertySelector: React.FunctionComponent onRemoveClick(index)} nameSpace={`properties.${index}`} index={index} property={property} + showSeparator={index < formikProps.values.properties.length - 1} /> ); } diff --git a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyHeaderRow.tsx b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyHeaderRow.tsx index 8e5fd0b639..839e4c2614 100644 --- a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyHeaderRow.tsx +++ b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyHeaderRow.tsx @@ -16,7 +16,6 @@ export const SelectedPropertyHeaderRow: React.FunctionComponent< toolTip="Optionally - provide a user friendly description to identify the property, such as Highway 1" /> - Area included ); }; diff --git a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyRow.test.tsx b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyRow.test.tsx index 21122db275..10b658f8d6 100644 --- a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyRow.test.tsx +++ b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/SelectedPropertyRow.test.tsx @@ -25,8 +25,9 @@ describe('SelectedPropertyRow component', () => { // render component under test const component = await renderAsync( - {() => ( + {formikProps => ( void; property: PropertyForm; + formikProps: FormikProps; + showSeparator?: boolean; } -export const SelectedPropertyRow: React.FunctionComponent< - React.PropsWithChildren -> = ({ nameSpace, onRemove, index, property }) => { +export const SelectedPropertyRow: React.FunctionComponent = ({ + nameSpace, + onRemove, + index, + property, + formikProps, + showSeparator = false, +}) => { const propertyName = getPropertyName(property.toMapProperty()); let propertyIdentifier = ''; switch (propertyName.label) { @@ -35,39 +44,50 @@ export const SelectedPropertyRow: React.FunctionComponent< propertyIdentifier = ''; break; } + + const currentLeaseProperty: FormLeaseProperty = getIn( + formikProps.values, + withNameSpace(nameSpace), + ); + return ( - - - - - - - - - - - - - - - m2 - - - - - - - + <> + + + + + + + + + + + + + + + { + formikProps.setFieldValue(withNameSpace(nameSpace, 'landArea'), landArea); + formikProps.setFieldValue( + withNameSpace(nameSpace, 'areaUnitTypeCode'), + areaUnitTypeCode, + ); + }} + /> + + + {showSeparator &&
} + ); }; diff --git a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/__snapshots__/SelectedPropertyRow.test.tsx.snap b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/__snapshots__/SelectedPropertyRow.test.tsx.snap index 48b8fd7be4..d879c8407c 100644 --- a/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/__snapshots__/SelectedPropertyRow.test.tsx.snap +++ b/source/frontend/src/features/leases/shared/propertyPicker/selectedPropertyList/__snapshots__/SelectedPropertyRow.test.tsx.snap @@ -209,7 +209,7 @@ exports[`SelectedPropertyRow component > renders as expected 1`] = ` }
renders as expected 1`] = ` />
renders as expected 1`] = `
-
-
-
- -
-
-
- m - - 2 - -
-
-
-
+ .c0 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + +.c2 { + max-width: 25rem; + padding: 1rem; + border: 1px solid; + border-radius: 0.5rem; +} + +.c1 { + max-width: 9rem; +} + +
+
+
+
+
+
+
+ +
+
+ sq. metres +
+
+
+
+ +
+
+ hectares +
+
+
+
+
+
+
+
+ +
+
+ sq. feet +
+
+
+
+ +
+
+ acres +
+
+
+
+
+
+
`;