Skip to content

Commit

Permalink
feat: List component - First iteration of a residential units schema (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr committed Jun 1, 2024
1 parent 69ead78 commit 0c3cce6
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 12 deletions.
5 changes: 3 additions & 2 deletions editor.planx.uk/src/@planx/components/List/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import InputRowLabel from "ui/shared/InputRowLabel";

import { EditorProps, ICONS, InternalNotes, MoreInformation } from "../ui";
import { List, parseContent } from "./model";
import { ResidentialUnits } from "./schemas/ResidentialUnits";
import { Zoo } from "./schemas/Zoo";

type Props = EditorProps<TYPES.List, List>;

export const SCHEMAS = [
{ name: "Zoo", schema: Zoo },
// TODO: Residential units
{ name: "Residential Units (alpha)", schema: ResidentialUnits },
{ name: "Zoo (test)", schema: Zoo },
// TODO: Residential units (GLA)
];

Expand Down
42 changes: 32 additions & 10 deletions editor.planx.uk/src/@planx/components/List/Public/Fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import MenuItem from "@mui/material/MenuItem";
import RadioGroup from "@mui/material/RadioGroup";
import { Option } from "@planx/components/shared";
import { getIn } from "formik";
import React from "react";
import SelectInput from "ui/editor/SelectInput";
Expand All @@ -26,7 +27,10 @@ export const TextFieldInput: React.FC<Props<TextField>> = ({
const { formik, activeIndex } = useListContext();

return (
<InputLabel label={data.title} htmlFor={id}>
<InputLabel
label={required === false ? data.title + " (optional)" : data.title}
htmlFor={id}
>
<Input
type={((type) => {
if (type === "email") return "email";
Expand Down Expand Up @@ -70,7 +74,10 @@ export const NumberFieldInput: React.FC<Props<NumberField>> = ({
const { formik, activeIndex } = useListContext();

return (
<InputLabel label={data.title} htmlFor={id}>
<InputLabel
label={required === false ? data.title + " (optional)" : data.title}
htmlFor={id}
>
<Box sx={{ display: "flex", alignItems: "baseline" }}>
<Input
required={required}
Expand Down Expand Up @@ -104,6 +111,7 @@ export const NumberFieldInput: React.FC<Props<NumberField>> = ({
export const RadioFieldInput: React.FC<Props<QuestionField>> = ({
id,
data,
required,
}) => {
const { formik, activeIndex } = useListContext();

Expand All @@ -119,7 +127,7 @@ export const RadioFieldInput: React.FC<Props<QuestionField>> = ({
},
})}
>
{data.title}
{required === false ? data.title + " (optional)" : data.title}
</FormLabel>
<ErrorWrapper
id={`${id}-error`}
Expand All @@ -145,15 +153,25 @@ export const RadioFieldInput: React.FC<Props<QuestionField>> = ({
);
};

export const SelectFieldInput: React.FC<Props<QuestionField>> = ({
id,
data,
required,
}) => {
export const SelectFieldInput: React.FC<Props<QuestionField>> = (props) => {
const { formik, activeIndex } = useListContext();
const { id, data, required } = props;

const isDisabled = (option: Option) => {
if (!props.unique) return false;

const existingValues = formik.values.userData
.map((response) => response[data.fn])
.filter((value) => value === option.data.text);

return existingValues.includes(option.data.text);
};

return (
<InputLabel label={data.title} id={`select-label-${id}`}>
<InputLabel
label={required === false ? data.title + " (optional)" : data.title}
id={`select-label-${id}`}
>
<ErrorWrapper
id={`${id}-error`}
error={getIn(formik.errors, `userData[${activeIndex}][${data.fn}]`)}
Expand All @@ -168,7 +186,11 @@ export const SelectFieldInput: React.FC<Props<QuestionField>> = ({
name={`userData[${activeIndex}][${data.fn}]`}
>
{data.options.map((option) => (
<MenuItem key={option.id} value={option.data.text}>
<MenuItem
key={option.id}
value={option.data.text}
disabled={isDisabled(option)}
>
{option.data.text}
</MenuItem>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ describe("Form validation and error handling", () => {
test.todo("text fields use existing validation schemas");
test.todo("number fields use existing validation schemas");
test.todo("question fields use validation schema");
test.todo("unique constraints are enforced on question where this is set");
test.todo("an error displays if the minimum number of items is not met");
test.todo("an error displays if the maximum number of items is exceeded");
test.todo(
Expand Down
1 change: 1 addition & 0 deletions editor.planx.uk/src/@planx/components/List/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export type NumberField = {
export type QuestionField = {
type: "question";
required?: boolean;
unique?: boolean;
data: QuestionInput & { fn: string };
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Schema } from "../model";

export const ResidentialUnits: Schema = {
type: "Residential Units",
fields: [
{
type: "question",
data: {
title: "What type of change are you making?",
fn: "changeType",
options: [
{ id: "proposed", data: { text: "Proposed" } },
{ id: "existing", data: { text: "Existing" } },
],
},
},
{
type: "question",
unique: true,
data: {
title: "What is the tenure type?",
fn: "tenureType",
options: [
{ id: "marketHousing", data: { text: "Market housing" } },
{
id: "socialAffordableRent",
data: { text: "Social and affordable rent" },
},
{
id: "affordableHomeOwnership",
data: { text: "Affordable home ownership" },
},
{ id: "starterHome", data: { text: "Starter homes" } },
{ id: "selfBuild", data: { text: "Self build" } },
],
},
},
{
type: "question",
data: {
title: "What is the unit type?",
fn: "unitType",
options: [
{ id: "houses", data: { text: "Houses" } },
{ id: "flats", data: { text: "Flats" } },
{ id: "bedsits", data: { text: "Bedsits" } },
{ id: "starterHome", data: { text: "Starter homes" } },
{ id: "shelteredHousing", data: { text: "Sheltered housing" } },
{ id: "clusteredFlats", data: { text: "Clustered flats" } },
{ id: "other", data: { text: "Other" } },
],
},
},
{
type: "number",
data: {
title: "How many bedrooms are there?",
fn: "numberBedrooms",
allowNegatives: false,
},
},
{
type: "number",
required: false,
data: {
title: "How many identical units of this type are there?",
fn: "numberIdenticalUnits",
allowNegatives: false,
},
},
],
min: 1,
} as const;

0 comments on commit 0c3cce6

Please sign in to comment.