From 32da62638a9bc0a61e611582ae49694eb4f1c350 Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Wed, 16 Oct 2024 23:07:07 +0200 Subject: [PATCH] use shared multiselect component --- .../@planx/components/Checklist/Editor.tsx | 9 +- .../src/@planx/components/Question/Editor.tsx | 10 +- .../@planx/components/shared/FlagsSelect.tsx | 110 ++++++++---------- .../src/@planx/components/shared/index.ts | 2 +- .../components/Flow/components/Option.tsx | 7 +- 5 files changed, 62 insertions(+), 76 deletions(-) diff --git a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx index ffb5fae171..d362280b6d 100644 --- a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx @@ -24,7 +24,7 @@ import InputRow from "ui/shared/InputRow"; import InputRowItem from "ui/shared/InputRowItem"; import { BaseNodeData, Option, parseBaseNodeData } from "../shared"; -import FlagsSelect from "../shared/FlagsSelect"; +import { FlagsSelect } from "../shared/FlagsSelect"; import { ICONS } from "../ui"; import type { Category, Checklist, Group } from "./model"; import { toggleExpandableChecklist } from "./model"; @@ -91,17 +91,16 @@ const OptionEditor: React.FC<{ /> { props.onChange({ ...props.value, data: { ...props.value.data, - flag: ev.target.value as string, + flag: ev, }, }); }} - sx={{ width: { md: "160px" }, maxWidth: "160px" }} /> {typeof props.index !== "undefined" && @@ -193,7 +192,6 @@ const Options: React.FC<{ formik: FormikHookReturn }> = ({ formik }) => { text: "", description: "", val: "", - flag: "", }, }) as Option } @@ -267,7 +265,6 @@ const Options: React.FC<{ formik: FormikHookReturn }> = ({ formik }) => { text: "", description: "", val: "", - flag: "", }, }) as Option } diff --git a/editor.planx.uk/src/@planx/components/Question/Editor.tsx b/editor.planx.uk/src/@planx/components/Question/Editor.tsx index 935876320c..9660c51907 100644 --- a/editor.planx.uk/src/@planx/components/Question/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Question/Editor.tsx @@ -13,7 +13,7 @@ import InputRow from "ui/shared/InputRow"; import InputRowItem from "ui/shared/InputRowItem"; import { BaseNodeData, Option, parseBaseNodeData } from "../shared"; -import FlagsSelect from "../shared/FlagsSelect"; +import { FlagsSelect } from "../shared/FlagsSelect"; import { ICONS, InternalNotes, MoreInformation } from "../ui"; interface Props { @@ -103,21 +103,18 @@ const OptionEditor: React.FC<{ /> )} - { props.onChange({ ...props.value, data: { ...props.value.data, - flag: ev.target.value as string, + flag: ev, }, }); }} - sx={{ margin: 0 }} /> - ); @@ -218,7 +215,6 @@ export const Question: React.FC = (props) => { text: "", description: "", val: "", - flag: "", }, }) as Option } diff --git a/editor.planx.uk/src/@planx/components/shared/FlagsSelect.tsx b/editor.planx.uk/src/@planx/components/shared/FlagsSelect.tsx index bd1474bd0e..1a5baa81f0 100644 --- a/editor.planx.uk/src/@planx/components/shared/FlagsSelect.tsx +++ b/editor.planx.uk/src/@planx/components/shared/FlagsSelect.tsx @@ -1,70 +1,58 @@ -import { fallbackHttpConfig } from "@apollo/client"; -import FormControl from "@mui/material/FormControl"; -import InputLabel from "@mui/material/InputLabel"; -import ListSubheader from "@mui/material/ListSubheader"; -import MenuItem from "@mui/material/MenuItem"; -import Select, { SelectChangeEvent } from "@mui/material/Select"; +import { AutocompleteProps } from "@mui/material/Autocomplete"; +import Chip from "@mui/material/Chip"; +import ListItem from "@mui/material/ListItem"; import { Flag, flatFlags } from "@opensystemslab/planx-core/types"; -import groupBy from "lodash/groupBy"; import React from "react"; -import type { Props as SelectInputProps } from "ui/editor/SelectInput"; -import SelectInput from "ui/editor/SelectInput"; -import { SelectMultiple } from "ui/shared/SelectMultiple"; +import InputRow from "ui/shared/InputRow"; +import { CustomCheckbox, SelectMultiple } from "ui/shared/SelectMultiple"; -const flags = groupBy(flatFlags, (f) => f.category); +interface Props { + value?: string[]; + onChange: (values: string[]) => void; +} -const FlagsSelect: React.FC = (props) => { - const initialFlagValues = props?.value ? [props.value as string] : []; - const [flagValue, setFlagValue] = React.useState(initialFlagValues); +const renderOptions: AutocompleteProps< + Flag, + true, + true, + false, + "div" +>["renderOption"] = (props, flag, { selected }) => ( + + +); - const handleChange = (event: SelectChangeEvent) => { - const { - target: { value }, - } = event; - setFlagValue( - // On autofill we get a stringified value. - typeof value === 'string' ? value.split(',') : value, - ); - }; - - const flagMenuItems = Object.entries(flags).flatMap( - ([category, categoryFlags]) => [ - - {category} - , - categoryFlags.map((flag) => ( - - {flag.text} - - )), - ], - ); +const renderTags: AutocompleteProps< + Flag, + true, + true, + false, + "div" +>["renderTags"] = (value, getFlagProps) => + value.map((flag, index) => ( + + )); +export const FlagsSelect: React.FC = ({ value, onChange }) => { return ( - - Flags - - + + flag.text} + groupBy={(flag) => flag.category} + onChange={(_e, value) => onChange(value)} + value={value} + renderOption={renderOptions} + renderTags={renderTags} + /> + ); }; - -export default FlagsSelect; diff --git a/editor.planx.uk/src/@planx/components/shared/index.ts b/editor.planx.uk/src/@planx/components/shared/index.ts index a33c5040d2..37e675ca49 100644 --- a/editor.planx.uk/src/@planx/components/shared/index.ts +++ b/editor.planx.uk/src/@planx/components/shared/index.ts @@ -28,7 +28,7 @@ export interface Option { id: string; data: { description?: string; - flag?: string; + flag?: string[]; img?: string; text: string; val?: string; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Option.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Option.tsx index 8f1802dd70..e1944f193c 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Option.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Option.tsx @@ -18,8 +18,13 @@ const Option: React.FC = (props) => { let color = "#000"; try { + // If there are many flags, only show the color band for the first flag const flag = flatFlags.find(({ value }) => - [props.data?.flag, props.data?.val].filter(Boolean).includes(value), + [ + // Support both new "Options" that have array of flags and old ones with single flag + Array.isArray(props.data?.flag) ? props.data?.flag?.[0].value : props.data?.flag, + props.data?.val, + ].filter(Boolean).includes(value), ); background = flag?.bgColor || background; color = flag?.color || color;