Skip to content

Commit

Permalink
chore: optimise planning constraints requests (#3740)
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicamcinchak authored Oct 2, 2024
1 parent 013f0a8 commit 55dc78b
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 244 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import classifiedRoadsNegativeResponseMock from "./mocks/classifiedRoadsNegative
import classifiedRoadsResponseMock from "./mocks/classifiedRoadsResponseMock";
import digitalLandNegativeResponseMock from "./mocks/digitalLandNegativeResponseMock";
import digitalLandResponseMock from "./mocks/digitalLandResponseMock";
import Public, {
PlanningConstraintsContent,
PlanningConstraintsContentProps,
} from "./Public";
import { Presentational, PresentationalProps } from "./Presentational";
import Public from "./Public";

/**
* PlanningConstraints fetches data about constraints from DLUHC's planning.data.gov.uk & data about classified roads from the Ordnance Survey Features API.
Expand All @@ -27,7 +25,7 @@ export default {
component: Public,
} satisfies Meta<typeof Public>;

const propsWithIntersections: PlanningConstraintsContentProps = {
const propsWithIntersections: PresentationalProps = {
title: "Planning constraints",
description:
"Planning constraints might limit how you can develop or use the property",
Expand All @@ -48,7 +46,7 @@ const propsWithIntersections: PlanningConstraintsContentProps = {
setInaccurateConstraints: () => {},
};

const propsWithoutIntersections: PlanningConstraintsContentProps = {
const propsWithoutIntersections: PresentationalProps = {
title: "Planning constraints",
description:
"Planning constraints might limit how you can develop or use the property",
Expand All @@ -70,11 +68,11 @@ const propsWithoutIntersections: PlanningConstraintsContentProps = {
};

export const WithIntersections = {
render: () => <PlanningConstraintsContent {...propsWithIntersections} />,
render: () => <Presentational {...propsWithIntersections} />,
};

export const WithoutIntersections = {
render: () => <PlanningConstraintsContent {...propsWithoutIntersections} />,
render: () => <Presentational {...propsWithoutIntersections} />,
};

export const WithEditor = () => <Wrapper Editor={Editor} Public={Public} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import ErrorOutline from "@mui/icons-material/ErrorOutline";
import Typography from "@mui/material/Typography";
import type { Constraint, GISResponse } from "@opensystemslab/planx-core/types";
import Card from "@planx/components/shared/Preview/Card";
import CardHeader from "@planx/components/shared/Preview/CardHeader";
import capitalize from "lodash/capitalize";
import { HandleSubmit } from "pages/Preview/Node";
import React from "react";
import ReactMarkdownOrHtml from "ui/shared/ReactMarkdownOrHtml";

import { ErrorSummaryContainer } from "../shared/Preview/ErrorSummaryContainer";
import SimpleExpand from "../shared/Preview/SimpleExpand";
import { WarningContainer } from "../shared/Preview/WarningContainer";
import ConstraintsList from "./List";
import { DEFAULT_PLANNING_CONDITIONS_DISCLAIMER } from "./model";
import { InaccurateConstraints } from "./Public";

export type PresentationalProps = {
title: string;
description: string;
fn: string;
disclaimer: string;
constraints: GISResponse["constraints"];
metadata: GISResponse["metadata"];
handleSubmit: () => void;
refreshConstraints: () => void;
inaccurateConstraints: InaccurateConstraints;
setInaccurateConstraints: (
value: React.SetStateAction<InaccurateConstraints>,
) => void;
};

export function Presentational(props: PresentationalProps) {
const {
title,
description,
constraints,
metadata,
disclaimer,
inaccurateConstraints,
setInaccurateConstraints,
} = props;

const error = constraints.error || undefined;
const showError = error || !Object.values(constraints)?.length;
if (showError) return <ConstraintsFetchError error={error} {...props} />;

const positiveConstraints = Object.values(constraints).filter(
(v: Constraint) => v.text && v.value,
);
const negativeConstraints = Object.values(constraints).filter(
(v: Constraint) => v.text && !v.value,
);

return (
<Card handleSubmit={props.handleSubmit}>
<CardHeader title={title} description={description} />
{positiveConstraints.length > 0 && (
<>
<Typography variant="h3" component="h2" mt={3}>
These are the planning constraints we think apply to this property
</Typography>
<ConstraintsList
data={positiveConstraints}
metadata={metadata}
inaccurateConstraints={inaccurateConstraints}
setInaccurateConstraints={setInaccurateConstraints}
/>
{negativeConstraints.length > 0 && (
<SimpleExpand
id="negative-constraints-list"
data-testid="negative-constraints-list"
buttonText={{
open: "Constraints that don't apply to this property",
closed: "Hide constraints that don't apply",
}}
>
<ConstraintsList
data={negativeConstraints}
metadata={metadata}
inaccurateConstraints={inaccurateConstraints}
setInaccurateConstraints={setInaccurateConstraints}
/>
</SimpleExpand>
)}
<Disclaimer text={disclaimer} />
</>
)}
{positiveConstraints.length === 0 && negativeConstraints.length > 0 && (
<>
<Typography variant="h3" component="h2" gutterBottom mt={3}>
It looks like there are no constraints on this property
</Typography>
<Typography variant="body1" gutterBottom>
Based on the information you've given it looks like there are no
planning constraints on your property that might limit what you can
do.
</Typography>
<Typography variant="body1" gutterBottom>
Continue with your application to tell us more about your project.
</Typography>
<SimpleExpand
id="negative-constraints-list"
buttonText={{
open: "Show the things we checked",
closed: "Hide constraints that don't apply",
}}
>
<ConstraintsList
data={negativeConstraints}
metadata={metadata}
inaccurateConstraints={inaccurateConstraints}
setInaccurateConstraints={setInaccurateConstraints}
/>
</SimpleExpand>
<Disclaimer text={disclaimer} />
</>
)}
</Card>
);
}

const Disclaimer = (props: { text: string }) => (
<WarningContainer>
<ErrorOutline />
<Typography variant="body1" component="div" ml={2} mb={1}>
<ReactMarkdownOrHtml
source={props.text || DEFAULT_PLANNING_CONDITIONS_DISCLAIMER}
openLinksOnNewTab
/>
</Typography>
</WarningContainer>
);

interface ConstraintsFetchErrorProps {
error: any;
title: string;
description: string;
refreshConstraints: () => void;
handleSubmit?: HandleSubmit;
}

const ConstraintsFetchError = (props: ConstraintsFetchErrorProps) => (
<Card handleSubmit={props.handleSubmit} isValid>
<CardHeader title={props.title} description={props.description} />
<ErrorSummaryContainer role="status" data-testid="error-summary-no-info">
<Typography variant="h4" component="h2" gutterBottom>
No information available
</Typography>
{props.error &&
typeof props.error === "string" &&
props.error.endsWith("local authority") ? (
<Typography variant="body2">{capitalize(props.error)}</Typography>
) : (
<>
<Typography variant="body2">
We couldn't find any information about your property. Click search
again to try again. You can continue your application without this
information but it might mean we ask additional questions about your
project.
</Typography>
<button onClick={props.refreshConstraints}>Search again</button>
</>
)}
</ErrorSummaryContainer>
</Card>
);
Loading

0 comments on commit 55dc78b

Please sign in to comment.