From 5963fd5866a4b8fc2026758e6a1e97129c71e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Mon, 7 Oct 2024 16:46:18 +0100 Subject: [PATCH 01/13] feat: Use zustand middleware to persist to local storage (#3767) --- .../FlowEditor/components/Sidebar/index.tsx | 232 +++++++++--------- .../src/pages/FlowEditor/index.tsx | 3 +- .../src/pages/FlowEditor/lib/store/editor.ts | 29 ++- 3 files changed, 133 insertions(+), 131 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Sidebar/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Sidebar/index.tsx index 00cb7d09f0..ea7475c23e 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Sidebar/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Sidebar/index.tsx @@ -5,6 +5,7 @@ import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import OpenInNewOffIcon from "@mui/icons-material/OpenInNewOff"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; +import Collapse from "@mui/material/Collapse"; import Container from "@mui/material/Container"; import Link from "@mui/material/Link"; import { styled } from "@mui/material/styles"; @@ -29,25 +30,18 @@ type SidebarTabs = "PreviewBrowser" | "History" | "Search" | "Console"; const SIDEBAR_WIDTH = "500px"; const SIDEBAR_WIDTH_MINIMISED = "20px"; -const Root = styled(Box)<{ isMinimised: boolean }>( - ({ theme, isMinimised }) => ({ - position: "relative", - top: "0", - right: "0", - bottom: "0", - width: isMinimised ? SIDEBAR_WIDTH_MINIMISED : SIDEBAR_WIDTH, - display: "flex", - flexShrink: 0, - flexDirection: "column", - borderLeft: `1px solid ${theme.palette.border.main}`, - background: theme.palette.background.paper, - zIndex: 1, - transition: "width 200ms ease-in-out", - "& iframe": { - flex: 1, - }, - }), -); +const Root = styled(Box)(({ theme }) => ({ + position: "relative", + top: "0", + right: "0", + bottom: "0", + display: "flex", + flexShrink: 0, + flexDirection: "column", + borderLeft: `1px solid ${theme.palette.border.main}`, + background: theme.palette.background.paper, + zIndex: 1, +})); const SidebarContainer = styled(Box)(() => ({ overflow: "auto", @@ -62,7 +56,7 @@ const SidebarWrapper = styled(Box)(() => ({ flexDirection: "column", flexShrink: 0, flexGrow: 1, - maxHeight: "100%", + height: "100%", })); const StyledToggleButton = styled(ToggleButton)(({ theme }) => ({ @@ -132,16 +126,14 @@ const TabList = styled(Box)(({ theme }) => ({ })); const Sidebar: React.FC = React.memo(() => { - const [resetPreview, isFlowPublished] = useStore((state) => [ + const [resetPreview, isFlowPublished, toggleSidebar, showSidebar] = useStore((state) => [ state.resetPreview, state.isFlowPublished, + state.toggleSidebar, + state.showSidebar, ]); const [activeTab, setActiveTab] = useState("PreviewBrowser"); - const [isSidebarMinimised, setIsSidebarMinimised] = useState(() => { - const savedState = localStorage.getItem("isSidebarMinimised"); - return savedState === "true"; - }); const handleChange = ( _event: React.SyntheticEvent, @@ -150,14 +142,6 @@ const Sidebar: React.FC = React.memo(() => { setActiveTab(newValue); }; - const togglePreview = () => { - setIsSidebarMinimised((prev) => { - const newState = !prev; - localStorage.setItem("isSidebarMinimised", JSON.stringify(newState)); - return newState; - }); - }; - const baseUrl = `${window.location.origin}${rootFlowPath(false)}`; const urls = { @@ -167,102 +151,114 @@ const Sidebar: React.FC = React.memo(() => { }; return ( - - - - {isSidebarMinimised ? : } - -
- - - - - - - - - - + + + + + {showSidebar + ? + : + } + +
+ + - - - - - + + + + + + + - {isFlowPublished ? ( - + - + - ) : ( - - - + + {isFlowPublished ? ( + + - - - )} - - -
- - - - - - - - - {activeTab === "PreviewBrowser" && ( - - { - resetPreview(); - }} - > - - Restart - - - - )} - {activeTab === "History" && ( - - - - - - )} - {activeTab === "Search" && ( - - - - )} - {activeTab === "Console" && ( - - - - )} -
+ + ) : ( + + + + + + + + )} +
+ +
+ + + + + + + + + {activeTab === "PreviewBrowser" && ( + + { + resetPreview(); + }} + > + + Restart + + + + )} + {activeTab === "History" && ( + + + + + + )} + {activeTab === "Search" && ( + + + + )} + {activeTab === "Console" && ( + + + + )} +
+
); }); diff --git a/editor.planx.uk/src/pages/FlowEditor/index.tsx b/editor.planx.uk/src/pages/FlowEditor/index.tsx index 7524b59e3c..b5130f0f24 100644 --- a/editor.planx.uk/src/pages/FlowEditor/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/index.tsx @@ -29,7 +29,6 @@ const FlowEditor = () => { const scrollContainerRef = useRef(null); useScrollControlsAndRememberPosition(scrollContainerRef); - const showSidebar = useStore((state) => state.showSidebar); const isTestEnvBannerVisible = useStore( (state) => state.isTestEnvBannerVisible, @@ -52,7 +51,7 @@ const FlowEditor = () => { - {showSidebar && } + ); }; diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts b/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts index bae0c5f446..d46f351c3c 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts @@ -26,6 +26,7 @@ import { customAlphabet } from "nanoid-good"; import en from "nanoid-good/locale/en"; import { type } from "ot-json0"; import type { StateCreator } from "zustand"; +import { persist } from 'zustand/middleware' import { FlowLayout } from "../../components/Flow"; import { connectToDB, getConnection } from "./../sharedb"; @@ -45,7 +46,7 @@ const send = (ops: Array) => { export interface EditorUIStore { flowLayout: FlowLayout; showSidebar: boolean; - togglePreview: () => void; + toggleSidebar: () => void; isTestEnvBannerVisible: boolean; hideTestEnvBanner: () => void; } @@ -53,21 +54,27 @@ export interface EditorUIStore { export const editorUIStore: StateCreator< SharedStore & EditorUIStore, [], - [], + [["zustand/persist", unknown]], EditorUIStore -> = (set, get) => ({ - flowLayout: FlowLayout.TOP_DOWN, +> = persist( + (set, get) => ({ + flowLayout: FlowLayout.TOP_DOWN, - showSidebar: true, + showSidebar: true, - togglePreview: () => { - set({ showSidebar: !get().showSidebar }); - }, + toggleSidebar: () => { + set({ showSidebar: !get().showSidebar }); + }, - isTestEnvBannerVisible: !window.location.href.includes(".uk"), + isTestEnvBannerVisible: !window.location.href.includes(".uk"), - hideTestEnvBanner: () => set({ isTestEnvBannerVisible: false }), -}); + hideTestEnvBanner: () => set({ isTestEnvBannerVisible: false }), + }), + { + name: "editorUIStore", + partialize: (state) => ({ showSidebar: state.showSidebar }), + } +); interface PublishFlowResponse { alteredNodes: Store.Node[]; From 6b363985b7d23eace8fc9dd80c03f2afe0b95d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Tue, 8 Oct 2024 09:40:16 +0100 Subject: [PATCH 02/13] feat(ui): Node tags (#3762) --- .../@planx/components/AddressInput/Editor.tsx | 16 +------ .../@planx/components/Calculate/Editor.tsx | 16 +------ .../@planx/components/Checklist/Editor.tsx | 16 ++----- .../@planx/components/ContactInput/Editor.tsx | 16 +------ .../src/@planx/components/Content/Editor.tsx | 16 +------ .../@planx/components/DateInput/Editor.tsx | 16 +------ .../@planx/components/DrawBoundary/Editor.tsx | 16 +------ .../@planx/components/FileUpload/Editor.tsx | 16 ++----- .../components/FileUploadAndLabel/Editor.tsx | 16 +------ .../SelectMultipleFileTypes.tsx | 2 +- .../@planx/components/FindProperty/Editor.tsx | 16 +------ .../src/@planx/components/List/Editor.tsx | 16 ++----- .../@planx/components/MapAndLabel/Editor.tsx | 16 ++----- .../@planx/components/NextSteps/Editor.tsx | 16 +------ .../src/@planx/components/Notice/Editor.tsx | 8 ++++ .../@planx/components/NumberInput/Editor.tsx | 16 +------ .../src/@planx/components/Page/Editor.tsx | 16 ++----- .../src/@planx/components/Pay/Editor.tsx | 5 ++ .../components/PlanningConstraints/Editor.tsx | 9 ++-- .../components/PropertyInformation/Editor.tsx | 16 +------ .../src/@planx/components/Question/Editor.tsx | 5 ++ .../src/@planx/components/Review/Editor.tsx | 9 ++-- .../src/@planx/components/Section/Editor.tsx | 9 ++-- .../src/@planx/components/SetValue/Editor.tsx | 9 ++-- .../src/@planx/components/TaskList/Editor.tsx | 16 +------ .../@planx/components/TextInput/Editor.tsx | 18 ++----- .../src/@planx/components/shared/index.ts | 2 +- .../components/Flow/components/Checklist.tsx | 30 +++++++----- .../components/Flow/components/Node.tsx | 1 + .../components/Flow/components/Question.tsx | 9 +++- .../components/Flow/components/Tag.tsx | 35 ++++++++++++++ .../src/pages/FlowEditor/floweditor.scss | 1 + .../src/ui/editor/ComponentTagSelect.tsx | 47 +++++++++++++++++++ editor.planx.uk/src/ui/editor/ModalFooter.tsx | 45 ++++++++++++++++++ .../src/ui/shared/SelectMultiple.tsx | 1 + 35 files changed, 230 insertions(+), 287 deletions(-) create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Tag.tsx create mode 100644 editor.planx.uk/src/ui/editor/ComponentTagSelect.tsx create mode 100644 editor.planx.uk/src/ui/editor/ModalFooter.tsx diff --git a/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx b/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx index d41fc325b6..a118beeafe 100644 --- a/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx @@ -2,11 +2,10 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -66,18 +65,7 @@ export default function AddressInputComponent(props: Props): FCReturn { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/Calculate/Editor.tsx b/editor.planx.uk/src/@planx/components/Calculate/Editor.tsx index 065d8a554e..c1c0239ab5 100644 --- a/editor.planx.uk/src/@planx/components/Calculate/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Calculate/Editor.tsx @@ -6,12 +6,11 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import InputGroup from "ui/editor/InputGroup"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import Input from "ui/shared/Input"; @@ -195,18 +194,7 @@ export default function Component(props: Props) {

- - + ); } diff --git a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx index 29bfe2b3ff..094a2e48f6 100644 --- a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx @@ -14,6 +14,7 @@ import { FormikHookReturn } from "types"; import ImgInput from "ui/editor/ImgInput"; import InputGroup from "ui/editor/InputGroup"; import ListManager from "ui/editor/ListManager"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -24,7 +25,7 @@ import InputRowItem from "ui/shared/InputRowItem"; import { BaseNodeData, Option, parseBaseNodeData } from "../shared"; import PermissionSelect from "../shared/PermissionSelect"; -import { ICONS, InternalNotes, MoreInformation } from "../ui"; +import { ICONS } from "../ui"; import type { Category, Checklist, Group } from "./model"; import { toggleExpandableChecklist } from "./model"; @@ -427,18 +428,7 @@ export const ChecklistComponent: React.FC = (props) => { - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/ContactInput/Editor.tsx b/editor.planx.uk/src/@planx/components/ContactInput/Editor.tsx index 8bd7a6632c..fc9049b38d 100644 --- a/editor.planx.uk/src/@planx/components/ContactInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/ContactInput/Editor.tsx @@ -2,11 +2,10 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -66,18 +65,7 @@ export default function ContactInputComponent(props: Props): FCReturn { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/Content/Editor.tsx b/editor.planx.uk/src/@planx/components/Content/Editor.tsx index 270f40011d..6286052fa6 100644 --- a/editor.planx.uk/src/@planx/components/Content/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Content/Editor.tsx @@ -4,12 +4,11 @@ import { parseContent } from "@planx/components/Content/model"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import ColorPicker from "ui/editor/ColorPicker"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -49,18 +48,7 @@ const ContentComponent: React.FC = (props) => { /> - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/DateInput/Editor.tsx b/editor.planx.uk/src/@planx/components/DateInput/Editor.tsx index 69f1aff7d0..926fb10136 100644 --- a/editor.planx.uk/src/@planx/components/DateInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/DateInput/Editor.tsx @@ -9,11 +9,10 @@ import { parseDateInput } from "@planx/components/DateInput/model"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -97,18 +96,7 @@ const DateInputComponent: React.FC = (props) => { - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/DrawBoundary/Editor.tsx b/editor.planx.uk/src/@planx/components/DrawBoundary/Editor.tsx index 38492b893c..913be645dc 100644 --- a/editor.planx.uk/src/@planx/components/DrawBoundary/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/DrawBoundary/Editor.tsx @@ -4,12 +4,11 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import InputGroup from "ui/editor/InputGroup"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -119,18 +118,7 @@ function DrawBoundaryComponent(props: Props) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/FileUpload/Editor.tsx b/editor.planx.uk/src/@planx/components/FileUpload/Editor.tsx index 3871181b47..f7ed9d2999 100644 --- a/editor.planx.uk/src/@planx/components/FileUpload/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/FileUpload/Editor.tsx @@ -1,7 +1,8 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { ICONS, InternalNotes, MoreInformation } from "@planx/components/ui"; +import { ICONS } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -72,18 +73,7 @@ function Component(props: any) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Editor.tsx b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Editor.tsx index 6c93ce179d..28fbface52 100644 --- a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/Editor.tsx @@ -10,8 +10,6 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import { lowerCase, merge, upperFirst } from "lodash"; @@ -20,6 +18,7 @@ import ImgInput from "ui/editor/ImgInput"; import ListManager, { EditorProps as ListManagerEditorProps, } from "ui/editor/ListManager"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import { ModalSubtitle } from "ui/editor/ModalSubtitle"; @@ -122,18 +121,7 @@ function FileUploadAndLabelComponent(props: Props) { /> - - + ); } diff --git a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/SelectMultipleFileTypes.tsx b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/SelectMultipleFileTypes.tsx index d99a8cf1f8..ee6c9c94d9 100644 --- a/editor.planx.uk/src/@planx/components/FileUploadAndLabel/SelectMultipleFileTypes.tsx +++ b/editor.planx.uk/src/@planx/components/FileUploadAndLabel/SelectMultipleFileTypes.tsx @@ -163,7 +163,7 @@ export const SelectMultipleFileTypes = (props: SelectMultipleProps) => { }; return ( - + option.name} groupBy={(option) => option.category} id={`select-multiple-file-tags-${uploadedFile.id}`} diff --git a/editor.planx.uk/src/@planx/components/FindProperty/Editor.tsx b/editor.planx.uk/src/@planx/components/FindProperty/Editor.tsx index 6430de1285..29aa0be76e 100644 --- a/editor.planx.uk/src/@planx/components/FindProperty/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/FindProperty/Editor.tsx @@ -4,12 +4,11 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import InputGroup from "ui/editor/InputGroup"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -114,18 +113,7 @@ function FindPropertyComponent(props: Props) { )} - - + ); } diff --git a/editor.planx.uk/src/@planx/components/List/Editor.tsx b/editor.planx.uk/src/@planx/components/List/Editor.tsx index 52aeef7bf9..d8d923cf00 100644 --- a/editor.planx.uk/src/@planx/components/List/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/List/Editor.tsx @@ -2,6 +2,7 @@ import MenuItem from "@mui/material/MenuItem"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -12,7 +13,7 @@ import InputRow from "ui/shared/InputRow"; import InputRowItem from "ui/shared/InputRowItem"; import InputRowLabel from "ui/shared/InputRowLabel"; -import { EditorProps, ICONS, InternalNotes, MoreInformation } from "../ui"; +import { EditorProps, ICONS } from "../ui"; import { List, parseContent, validationSchema } from "./model"; import { ProposedAdvertisements } from "./schemas/Adverts"; import { NonResidentialFloorspace } from "./schemas/Floorspace"; @@ -153,18 +154,7 @@ function ListComponent(props: Props) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/MapAndLabel/Editor.tsx b/editor.planx.uk/src/@planx/components/MapAndLabel/Editor.tsx index 2c8b6e0c8f..86a5c31e72 100644 --- a/editor.planx.uk/src/@planx/components/MapAndLabel/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/MapAndLabel/Editor.tsx @@ -7,6 +7,7 @@ import { useFormik } from "formik"; import React from "react"; import ColorPicker from "ui/editor/ColorPicker"; import InputGroup from "ui/editor/InputGroup"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -17,7 +18,7 @@ import InputRow from "ui/shared/InputRow"; import InputRowItem from "ui/shared/InputRowItem"; import BasicRadio from "../shared/Radio/BasicRadio"; -import { EditorProps, ICONS, InternalNotes, MoreInformation } from "../ui"; +import { EditorProps, ICONS } from "../ui"; import { MapAndLabel, parseContent } from "./model"; import { Trees } from "./schemas/Trees"; @@ -177,18 +178,7 @@ function MapAndLabelComponent(props: Props) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/NextSteps/Editor.tsx b/editor.planx.uk/src/@planx/components/NextSteps/Editor.tsx index ebe8b31d59..d60609b2c6 100644 --- a/editor.planx.uk/src/@planx/components/NextSteps/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/NextSteps/Editor.tsx @@ -5,14 +5,13 @@ import { parseNextSteps } from "@planx/components/NextSteps/model"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React, { ChangeEvent } from "react"; import ListManager, { EditorProps as ListManagerEditorProps, } from "ui/editor/ListManager"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -118,18 +117,7 @@ const NextStepsComponent: React.FC = (props) => { /> - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/Notice/Editor.tsx b/editor.planx.uk/src/@planx/components/Notice/Editor.tsx index 6be6eb1658..318844ebd4 100644 --- a/editor.planx.uk/src/@planx/components/Notice/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Notice/Editor.tsx @@ -7,6 +7,7 @@ import { ICONS, InternalNotes, MoreInformation } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import ColorPicker from "ui/editor/ColorPicker"; +import { ComponentTagSelect } from "ui/editor/ComponentTagSelect"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -105,6 +106,13 @@ const NoticeEditor: React.FC = (props) => { }} value={props.value.notes} /> + props.onChange({ + ...props.value, + tags: value, + })} + value={props.value.tags} + /> ); }; diff --git a/editor.planx.uk/src/@planx/components/NumberInput/Editor.tsx b/editor.planx.uk/src/@planx/components/NumberInput/Editor.tsx index b0a7425d52..7155859abf 100644 --- a/editor.planx.uk/src/@planx/components/NumberInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/NumberInput/Editor.tsx @@ -6,11 +6,10 @@ import { parseNumberInput } from "@planx/components/NumberInput/model"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -94,18 +93,7 @@ export default function NumberInputComponent(props: Props): FCReturn { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/Page/Editor.tsx b/editor.planx.uk/src/@planx/components/Page/Editor.tsx index fd5eb2cadb..c1c7e7f5a0 100644 --- a/editor.planx.uk/src/@planx/components/Page/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Page/Editor.tsx @@ -2,6 +2,7 @@ import MenuItem from "@mui/material/MenuItem"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -11,7 +12,7 @@ import InputRow from "ui/shared/InputRow"; import InputRowItem from "ui/shared/InputRowItem"; import InputRowLabel from "ui/shared/InputRowLabel"; -import { EditorProps, ICONS, InternalNotes, MoreInformation } from "../ui"; +import { EditorProps, ICONS } from "../ui"; import { Page, parsePage } from "./model"; import { ProposedAdvertisements } from "./schema/AdvertConsent"; @@ -89,18 +90,7 @@ function PageComponent(props: Props) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/Pay/Editor.tsx b/editor.planx.uk/src/@planx/components/Pay/Editor.tsx index 417ef34b18..3f7671be93 100644 --- a/editor.planx.uk/src/@planx/components/Pay/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Pay/Editor.tsx @@ -23,6 +23,7 @@ import { import { Form, Formik, useFormikContext } from "formik"; import { useStore } from "pages/FlowEditor/lib/store"; import React from "react"; +import { ComponentTagSelect } from "ui/editor/ComponentTagSelect"; import ListManager, { EditorProps as ListManagerEditorProps, } from "ui/editor/ListManager"; @@ -449,6 +450,10 @@ const Component: React.FC = (props: Props) => { onChange={handleChange} value={values.notes} /> + setFieldValue("tags", value)} + value={values.tags} + /> )} diff --git a/editor.planx.uk/src/@planx/components/PlanningConstraints/Editor.tsx b/editor.planx.uk/src/@planx/components/PlanningConstraints/Editor.tsx index 03423b9ce8..42d4aa0e77 100644 --- a/editor.planx.uk/src/@planx/components/PlanningConstraints/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/PlanningConstraints/Editor.tsx @@ -8,11 +8,12 @@ import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Typography from "@mui/material/Typography"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { EditorProps, ICONS, InternalNotes } from "@planx/components/ui"; +import { EditorProps, ICONS } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; import { FONT_WEIGHT_BOLD } from "theme"; import InputGroup from "ui/editor/InputGroup"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -166,11 +167,7 @@ function PlanningConstraintsComponent(props: Props) { - + ); } diff --git a/editor.planx.uk/src/@planx/components/PropertyInformation/Editor.tsx b/editor.planx.uk/src/@planx/components/PropertyInformation/Editor.tsx index c3faea4bbb..4f4a25f267 100644 --- a/editor.planx.uk/src/@planx/components/PropertyInformation/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/PropertyInformation/Editor.tsx @@ -4,11 +4,10 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -74,18 +73,7 @@ function PropertyInformationComponent(props: Props) { - - + ); } diff --git a/editor.planx.uk/src/@planx/components/Question/Editor.tsx b/editor.planx.uk/src/@planx/components/Question/Editor.tsx index b108ef2a51..5d4d4438cb 100644 --- a/editor.planx.uk/src/@planx/components/Question/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Question/Editor.tsx @@ -1,6 +1,7 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { useFormik } from "formik"; import React, { useEffect, useRef } from "react"; +import { ComponentTagSelect } from "ui/editor/ComponentTagSelect"; import ImgInput from "ui/editor/ImgInput"; import InputGroup from "ui/editor/InputGroup"; import ListManager from "ui/editor/ListManager"; @@ -239,6 +240,10 @@ export const Question: React.FC = (props) => { onChange={formik.handleChange} value={formik.values.notes} /> + formik.setFieldValue("tags", value)} + /> ); }; diff --git a/editor.planx.uk/src/@planx/components/Review/Editor.tsx b/editor.planx.uk/src/@planx/components/Review/Editor.tsx index 38cec10acd..0ece7df2e4 100644 --- a/editor.planx.uk/src/@planx/components/Review/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Review/Editor.tsx @@ -1,13 +1,14 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; import Input from "ui/shared/Input"; import InputRow from "ui/shared/InputRow"; -import { EditorProps, ICONS, InternalNotes } from "../ui"; +import { EditorProps, ICONS } from "../ui"; import { parseContent, Review } from "./model"; type Props = EditorProps; @@ -46,11 +47,7 @@ function Component(props: Props) { - + ); } diff --git a/editor.planx.uk/src/@planx/components/Section/Editor.tsx b/editor.planx.uk/src/@planx/components/Section/Editor.tsx index 84294365dc..ae366c66f8 100644 --- a/editor.planx.uk/src/@planx/components/Section/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Section/Editor.tsx @@ -1,7 +1,8 @@ import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { EditorProps, ICONS, InternalNotes } from "@planx/components/ui"; +import { EditorProps, ICONS } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -49,11 +50,7 @@ function SectionComponent(props: Props) { - + ); } diff --git a/editor.planx.uk/src/@planx/components/SetValue/Editor.tsx b/editor.planx.uk/src/@planx/components/SetValue/Editor.tsx index b36c1e37f0..cc82ddfbb3 100644 --- a/editor.planx.uk/src/@planx/components/SetValue/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/SetValue/Editor.tsx @@ -3,9 +3,10 @@ import RadioGroup from "@mui/material/RadioGroup"; import Typography from "@mui/material/Typography"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import BasicRadio from "@planx/components/shared/Radio/BasicRadio"; -import { EditorProps, InternalNotes } from "@planx/components/ui"; +import { EditorProps } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import Input from "ui/shared/Input"; @@ -138,11 +139,7 @@ function SetValueComponent(props: Props) { - + ); } diff --git a/editor.planx.uk/src/@planx/components/TaskList/Editor.tsx b/editor.planx.uk/src/@planx/components/TaskList/Editor.tsx index f869005888..f8f3b7a297 100644 --- a/editor.planx.uk/src/@planx/components/TaskList/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/TaskList/Editor.tsx @@ -5,14 +5,13 @@ import { parseTaskList } from "@planx/components/TaskList/model"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React, { ChangeEvent } from "react"; import ListManager, { EditorProps as ListManagerEditorProps, } from "ui/editor/ListManager"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -104,18 +103,7 @@ const TaskListComponent: React.FC = (props) => { /> - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/TextInput/Editor.tsx b/editor.planx.uk/src/@planx/components/TextInput/Editor.tsx index 4f0eb7f051..f48ffba379 100644 --- a/editor.planx.uk/src/@planx/components/TextInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/TextInput/Editor.tsx @@ -5,11 +5,10 @@ import BasicRadio from "@planx/components/shared/Radio/BasicRadio"; import { EditorProps, ICONS, - InternalNotes, - MoreInformation, } from "@planx/components/ui"; import { useFormik } from "formik"; import React from "react"; +import { ModalFooter } from "ui/editor/ModalFooter"; import ModalSection from "ui/editor/ModalSection"; import ModalSectionContent from "ui/editor/ModalSectionContent"; import RichTextInput from "ui/editor/RichTextInput"; @@ -21,7 +20,7 @@ import { parseTextInput, TextInput } from "./model"; export type Props = EditorProps; const TextInputComponent: React.FC = (props) => { - const formik = useFormik({ + const formik = useFormik({ initialValues: parseTextInput(props.node?.data), onSubmit: (newValues) => { if (props.handleSubmit) { @@ -95,18 +94,7 @@ const TextInputComponent: React.FC = (props) => { - - + ); }; diff --git a/editor.planx.uk/src/@planx/components/shared/index.ts b/editor.planx.uk/src/@planx/components/shared/index.ts index 0d1a5756f8..a33c5040d2 100644 --- a/editor.planx.uk/src/@planx/components/shared/index.ts +++ b/editor.planx.uk/src/@planx/components/shared/index.ts @@ -21,7 +21,7 @@ export const parseBaseNodeData = ( howMeasured: data?.howMeasured, policyRef: data?.policyRef, info: data?.info, - tags: data?.tags, + tags: data?.tags || [], }); export interface Option { diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Checklist.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Checklist.tsx index 86c1b003eb..3c2214f2be 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Checklist.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Checklist.tsx @@ -1,4 +1,8 @@ -import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; +import Box from "@mui/material/Box"; +import { + ComponentType as TYPES, + NodeTags, +} from "@opensystemslab/planx-core/types"; import { ICONS } from "@planx/components/ui"; import classNames from "classnames"; import mapAccum from "ramda/src/mapAccum"; @@ -10,12 +14,13 @@ import { useStore } from "../../../lib/store"; import { getParentId } from "../lib/utils"; import Hanger from "./Hanger"; import Node from "./Node"; +import { Tag } from "./Tag"; type Props = { type: TYPES; [key: string]: any; wasVisited?: boolean; -}; +} & NodeTags; const Checklist: React.FC = React.memo((props) => { const [isClone, childNodes, copyNode] = useStore((state) => [ @@ -80,15 +85,18 @@ const Checklist: React.FC = React.memo((props) => { wasVisited: props.wasVisited, })} > - - {Icon && } - {props.text} - + + + {Icon && } + {props.text} + + {props.tags?.map((tag) => )} + {groupedOptions ? (
    {groupedOptions.map(({ title, children }, i) => ( diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Node.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Node.tsx index bf35c17078..2537272cb3 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Node.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Node.tsx @@ -21,6 +21,7 @@ const Node: React.FC = (props) => { const allProps = { ...props, wasVisited, + tags: node.data?.tags, }; const type = props.type as TYPES; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Question.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Question.tsx index 2de72feecb..a63d20827c 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Question.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Question.tsx @@ -1,5 +1,8 @@ import ErrorIcon from "@mui/icons-material/Error"; -import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; +import { + ComponentType as TYPES, + NodeTags, +} from "@opensystemslab/planx-core/types"; import { ICONS } from "@planx/components/ui"; import classNames from "classnames"; import React from "react"; @@ -10,12 +13,13 @@ import { useStore } from "../../../lib/store"; import { getParentId } from "../lib/utils"; import Hanger from "./Hanger"; import Node from "./Node"; +import { Tag } from "./Tag"; type Props = { type: TYPES | "Error"; [key: string]: any; wasVisited?: boolean; -}; +} & NodeTags; const Question: React.FC = React.memo((props) => { const [isClone, childNodes, copyNode] = useStore((state) => [ @@ -79,6 +83,7 @@ const Question: React.FC = React.memo((props) => { {Icon && } {props.text} + {props.tags?.map((tag) => )}
      {childNodes.map((child: any) => ( diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Tag.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Tag.tsx new file mode 100644 index 0000000000..7dbca109bb --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Tag.tsx @@ -0,0 +1,35 @@ +import Box from "@mui/material/Box"; +import { visuallyHidden } from "@mui/utils"; +import { NodeTag } from "@opensystemslab/planx-core/types"; +import React from "react"; +import { FONT_WEIGHT_SEMI_BOLD } from "theme"; + +export const TAG_DISPLAY_VALUES: Record< + NodeTag, + { color: string; displayName: string } +> = { + placeholder: { + color: "#FAE1B7", + displayName: "Placeholder", + }, +} as const; + +export const Tag: React.FC<{ tag: NodeTag }> = ({ tag }) => ( + +); diff --git a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss index 8f51ad279b..9640df4a60 100644 --- a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss +++ b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss @@ -137,6 +137,7 @@ $fontMonospace: "Source Code Pro", monospace; border: $nodeBorderWidth dashed red; } + & > div > a, & > a { position: relative; display: flex; diff --git a/editor.planx.uk/src/ui/editor/ComponentTagSelect.tsx b/editor.planx.uk/src/ui/editor/ComponentTagSelect.tsx new file mode 100644 index 0000000000..d47440a766 --- /dev/null +++ b/editor.planx.uk/src/ui/editor/ComponentTagSelect.tsx @@ -0,0 +1,47 @@ +import BookmarksIcon from "@mui/icons-material/Bookmarks"; +import { AutocompleteProps } from "@mui/material/Autocomplete"; +import ListItem from "@mui/material/ListItem"; +import { NODE_TAGS, NodeTag } from "@opensystemslab/planx-core/types"; +import { TAG_DISPLAY_VALUES } from "pages/FlowEditor/components/Flow/components/Tag"; +import React from "react"; +import ModalSection from "ui/editor/ModalSection"; +import ModalSectionContent from "ui/editor/ModalSectionContent"; +import InputRow from "ui/shared/InputRow"; +import { CustomCheckbox, SelectMultiple } from "ui/shared/SelectMultiple"; + +interface Props { + value?: NodeTag[]; + onChange: (values: NodeTag[]) => void; +}; + +const renderOption: AutocompleteProps< + NodeTag, + true, + true, + false, + "div" +>["renderOption"] = (props, tag, { selected }) => ( + + +); + +export const ComponentTagSelect: React.FC = ({ value, onChange }) => { + return ( + + + + TAG_DISPLAY_VALUES[tag].displayName} + options={NODE_TAGS} + onChange={(_e, value) => onChange(value)} + value={value} + renderOption={renderOption} + /> + + + + ) +} \ No newline at end of file diff --git a/editor.planx.uk/src/ui/editor/ModalFooter.tsx b/editor.planx.uk/src/ui/editor/ModalFooter.tsx new file mode 100644 index 0000000000..07fb31f349 --- /dev/null +++ b/editor.planx.uk/src/ui/editor/ModalFooter.tsx @@ -0,0 +1,45 @@ +import { BaseNodeData } from "@planx/components/shared"; +import { InternalNotes, MoreInformation } from "@planx/components/ui"; +import { useFormik } from "formik"; +import React from "react"; + +import { ComponentTagSelect } from "./ComponentTagSelect"; + +interface Props { + formik: ReturnType>; + showMoreInformation?: boolean; + showInternalNotes?: boolean; + showTags?: boolean; +} + +export const ModalFooter = ({ + formik, + showMoreInformation = true, + showInternalNotes = true, + showTags = true, +}: Props) => ( + <> + {showMoreInformation && ( + + )} + {showInternalNotes && ( + + )} + {showTags && ( + formik.setFieldValue("tags", value)} + /> + )} + +); diff --git a/editor.planx.uk/src/ui/shared/SelectMultiple.tsx b/editor.planx.uk/src/ui/shared/SelectMultiple.tsx index 8d3624b86e..30d32f277b 100644 --- a/editor.planx.uk/src/ui/shared/SelectMultiple.tsx +++ b/editor.planx.uk/src/ui/shared/SelectMultiple.tsx @@ -64,6 +64,7 @@ const StyledTextField = styled(TextField)(({ theme }) => ({ backgroundColor: theme.palette.background.paper, [`& .${outlinedInputClasses.root}, input`]: { cursor: "pointer", + backgroundColor: theme.palette.background.default, }, [`& .${inputLabelClasses.root}`]: { textDecoration: "underline", From 3262ef854db9d2624cdd760fb763265ef690feb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Tue, 8 Oct 2024 10:21:38 +0100 Subject: [PATCH 03/13] chore: Fix React `:nth-child` warnings (#3768) --- editor.planx.uk/src/@planx/components/Content/Public.tsx | 2 +- editor.planx.uk/src/pages/FlowEditor/floweditor.scss | 6 +++--- editor.planx.uk/src/ui/editor/RichTextInput.tsx | 2 +- editor.planx.uk/src/ui/shared/InputRow.tsx | 2 +- editor.planx.uk/src/ui/shared/InputRowLabel.tsx | 3 --- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/editor.planx.uk/src/@planx/components/Content/Public.tsx b/editor.planx.uk/src/@planx/components/Content/Public.tsx index 7c8584c09e..d8232f954a 100644 --- a/editor.planx.uk/src/@planx/components/Content/Public.tsx +++ b/editor.planx.uk/src/@planx/components/Content/Public.tsx @@ -30,7 +30,7 @@ const Content = styled(Box, { "& a": { color: getContrastTextColor(color || "#fff", theme.palette.link.main), }, - "& *:nth-child(1)": { + "& *:nth-of-type(1)": { marginTop: 0, }, })); diff --git a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss index 9640df4a60..dfe02405c3 100644 --- a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss +++ b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss @@ -169,7 +169,7 @@ $fontMonospace: "Source Code Pro", monospace; opacity: 0.6; } - > span:not(:nth-child(1)) { + > span:not(:first-child) { margin-left: 6px; } } @@ -477,7 +477,7 @@ $fontMonospace: "Source Code Pro", monospace; $lineWidth; background-repeat: no-repeat, repeat-x, repeat-x; - &:nth-child(1) { + &:nth-of-type(1) { background-position: top center, top right, @@ -517,7 +517,7 @@ $fontMonospace: "Source Code Pro", monospace; $lineWidth 100%, 2px 100%; - &:nth-child(1) { + &:nth-of-type(1) { background-position: left center, left bottom, diff --git a/editor.planx.uk/src/ui/editor/RichTextInput.tsx b/editor.planx.uk/src/ui/editor/RichTextInput.tsx index c455cad5c4..5b8d4312f6 100644 --- a/editor.planx.uk/src/ui/editor/RichTextInput.tsx +++ b/editor.planx.uk/src/ui/editor/RichTextInput.tsx @@ -97,7 +97,7 @@ export const RichContentContainer = styled(Box)(({ theme }) => ({ }, }, // Styles for placeholder text, to match ui/Input.tsx - "& p.is-editor-empty:nth-child(1)::before": { + "& p.is-editor-empty:first-child::before": { color: theme.palette.text.placeholder, opacity: 1, content: `attr(data-placeholder)`, diff --git a/editor.planx.uk/src/ui/shared/InputRow.tsx b/editor.planx.uk/src/ui/shared/InputRow.tsx index ff8eab5798..0c4f5798f3 100644 --- a/editor.planx.uk/src/ui/shared/InputRow.tsx +++ b/editor.planx.uk/src/ui/shared/InputRow.tsx @@ -13,7 +13,7 @@ const Root = styled(Box, { "& > *": { flexGrow: 1, marginRight: 5, - "&:nth-child(1)": { + "&:first:child": { marginLeft: 0, }, "&:last-child": { diff --git a/editor.planx.uk/src/ui/shared/InputRowLabel.tsx b/editor.planx.uk/src/ui/shared/InputRowLabel.tsx index f8799618ba..e69634e424 100644 --- a/editor.planx.uk/src/ui/shared/InputRowLabel.tsx +++ b/editor.planx.uk/src/ui/shared/InputRowLabel.tsx @@ -7,9 +7,6 @@ const Label = styled(Typography)(({ theme }) => ({ flexGrow: 0, paddingRight: theme.spacing(2), alignSelf: "center", - "&:not(:nth-child(1))": { - paddingLeft: theme.spacing(2), - }, })) as typeof Typography; export default function InputRowLabel({ children }: { children: ReactNode }) { From 97f4bf6b2f1bca4b017f60db84a13cc2f60d8c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Tue, 8 Oct 2024 13:13:04 +0100 Subject: [PATCH 04/13] fix: Restore loading bar and `FlowEditor` state on Editor-only routes (#3772) --- editor.planx.uk/src/routes/index.tsx | 74 ++++++++++++++++------------ 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/editor.planx.uk/src/routes/index.tsx b/editor.planx.uk/src/routes/index.tsx index c1cad20ee9..73c77abf78 100644 --- a/editor.planx.uk/src/routes/index.tsx +++ b/editor.planx.uk/src/routes/index.tsx @@ -57,38 +57,48 @@ const editorRoutes = mount({ ), }); -const mountPayRoutes = () => - map(async () => { - compose(withView(loadingView)); - return lazy(() => import("./pay")); - }); +const loadPayRoutes = () => + compose( + withView(loadingView), + lazy(() => import("./pay")), + ); -export default isPreviewOnlyDomain - ? compose( - withView(loadingView), +const loadPublishedRoutes = () => + compose( + withView(loadingView), + lazy(() => import("./published")), + ); + +const loadPreviewRoutes = () => + compose( + withView(loadingView), + lazy(() => import("./preview")), + ); - mount({ - "/:team/:flow/published": lazy(() => import("./published")), // XXX: keeps old URL working, but only for the team listed in the domain. - "/:flow": lazy(() => import("./published")), - "/:flow/pay": mountPayRoutes(), - // XXX: We're not sure where to redirect `/` to so for now we'll just return the default 404 - // "/": redirect("somewhere?"), - }), - ) - : compose( - withView(loadingView), +const loadDraftRoutes = () => + compose( + withView(loadingView), + lazy(() => import("./draft")), + ); - mount({ - "/:team/:flow/published": lazy(() => import("./published")), // loads current published flow if exists, or throws Not Found if unpublished - "/canterbury/find-out-if-you-need-planning-permission/preview": map( - async (req) => - redirect( - `/canterbury/find-out-if-you-need-planning-permission/published${req?.search}`, - ), - ), // temporary redirect while Canterbury works with internal IT to update advertised service links - "/:team/:flow/preview": lazy(() => import("./preview")), // loads current draft flow and latest published external portals, or throws Not Found if any external portal is unpublished - "/:team/:flow/draft": lazy(() => import("./draft")), // loads current draft flow and draft external portals - "/:team/:flow/pay": mountPayRoutes(), - "*": editorRoutes, - }), - ); +export default isPreviewOnlyDomain + ? mount({ + "/:team/:flow/published": loadPublishedRoutes(), // XXX: keeps old URL working, but only for the team listed in the domain. + "/:flow": loadPublishedRoutes(), + "/:flow/pay": loadPayRoutes(), + // XXX: We're not sure where to redirect `/` to so for now we'll just return the default 404 + // "/": redirect("somewhere?"), + }) + : mount({ + "/:team/:flow/published": loadPublishedRoutes(), // loads current published flow if exists, or throws Not Found if unpublished + "/canterbury/find-out-if-you-need-planning-permission/preview": map( + async (req) => + redirect( + `/canterbury/find-out-if-you-need-planning-permission/published${req?.search}`, + ), + ), // temporary redirect while Canterbury works with internal IT to update advertised service links + "/:team/:flow/preview": loadPreviewRoutes(), // loads current draft flow and latest published external portals, or throws Not Found if any external portal is unpublished + "/:team/:flow/draft": loadDraftRoutes(), // loads current draft flow and draft external portals + "/:team/:flow/pay": loadPayRoutes(), + "*": editorRoutes, + }); From dc85fa818ad161489cef1e908ce54890282bcf24 Mon Sep 17 00:00:00 2001 From: Ian Jones <51156018+ianjon3s@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:40:04 +0100 Subject: [PATCH 05/13] refactor: Better handling of print CSS styles (#3774) --- editor.planx.uk/src/components/Header.tsx | 9 ++++---- .../src/pages/layout/PublicLayout.tsx | 21 +++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/editor.planx.uk/src/components/Header.tsx b/editor.planx.uk/src/components/Header.tsx index 242d2d9ef2..d4c1b46886 100644 --- a/editor.planx.uk/src/components/Header.tsx +++ b/editor.planx.uk/src/components/Header.tsx @@ -141,16 +141,15 @@ const Logo = styled("img")(() => ({ maxWidth: 140, maxHeight: HEADER_HEIGHT_PUBLIC - 20, objectFit: "contain", + "@media print": { + filter: "invert(1)", + }, })); -const LogoLink = styled(Link)(({ theme }) => ({ +const LogoLink = styled(Link)(() => ({ display: "flex", alignItems: "center", "&:focus-visible": borderedFocusStyle, - "@media print": { - backgroundColor: theme.palette.common.black, - padding: "0.25em", - }, })); const SkipLink = styled("a")(({ theme }) => ({ diff --git a/editor.planx.uk/src/pages/layout/PublicLayout.tsx b/editor.planx.uk/src/pages/layout/PublicLayout.tsx index f7b21a23b1..72860758dc 100644 --- a/editor.planx.uk/src/pages/layout/PublicLayout.tsx +++ b/editor.planx.uk/src/pages/layout/PublicLayout.tsx @@ -29,6 +29,13 @@ const MainContainer = styled(Box)(({ theme }) => ({ position: "relative", })); +const OglLogo = styled("img")(({ theme }) => ({ + paddingRight: theme.spacing(2), + "@media print": { + filter: "invert(1)", + }, +})); + const PublicFooter: React.FC = () => { const { data } = useCurrentRoute(); const [flowSettings, globalSettings] = useStore((state) => [ @@ -68,19 +75,7 @@ const PublicFooter: React.FC = () => {