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 3c2214f2be..e31eab25b6 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 @@ -12,9 +12,11 @@ import { Link } from "react-navi"; import { useStore } from "../../../lib/store"; import { getParentId } from "../lib/utils"; +import { DataField } from "./DataField"; import Hanger from "./Hanger"; import Node from "./Node"; import { Tag } from "./Tag"; +import { Thumbnail } from "./Thumbnail"; type Props = { type: TYPES; @@ -92,9 +94,18 @@ const Checklist: React.FC = React.memo((props) => { onContextMenu={handleContext} ref={drag} > + {props.data?.img && ( + + )} {Icon && } {props.text} + {props.data?.fn && ( + + )} {props.tags?.map((tag) => )} {groupedOptions ? ( diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/DataField.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/DataField.tsx new file mode 100644 index 0000000000..86686beb4f --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/DataField.tsx @@ -0,0 +1,33 @@ +import Box from "@mui/material/Box"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React from "react"; + +export const DataField: React.FC<{ + value: string; + variant: "parent" | "child"; +}> = ({ value, variant }) => { + const showDataFields = useStore((state) => state.showDataFields); + if (!showDataFields) return null; + + return ( + ({ + fontFamily: theme.typography.data.fontFamily, + fontSize: theme.typography.data, + backgroundColor: "#f0f0f0", + borderColor: + variant === "parent" + ? theme.palette.common.black + : theme.palette.grey[400], + borderWidth: + variant === "parent" ? "0 1px 1px 1px" : "1px 0 0 0", + borderStyle: "solid", + width: "100%", + p: 0.5, + textAlign: "center", + })} + > + {value} + + ); +}; 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 8a48609f6e..8f1802dd70 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 @@ -4,8 +4,10 @@ import React from "react"; import { Link } from "react-navi"; import { useStore } from "../../../lib/store"; +import { DataField } from "./DataField"; import Hanger from "./Hanger"; import Node from "./Node"; +import { Thumbnail } from "./Thumbnail"; const Option: React.FC = (props) => { const childNodes = useStore((state) => state.childNodesOf(props.id)); @@ -14,6 +16,7 @@ const Option: React.FC = (props) => { let background = "#666"; // no flag color let color = "#000"; + try { const flag = flatFlags.find(({ value }) => [props.data?.flag, props.data?.val].filter(Boolean).includes(value), @@ -27,8 +30,15 @@ const Option: React.FC = (props) => { className={classNames("card", "option", { wasVisited: props.wasVisited })} > e.preventDefault()}> + {props.data?.img && ( + + )}
{props.data.text}
+ {props.data?.val && }
    {childNodes.map((child: any) => ( 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 a63d20827c..b2b1a20069 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 @@ -11,9 +11,11 @@ import { Link } from "react-navi"; import { useStore } from "../../../lib/store"; import { getParentId } from "../lib/utils"; +import { DataField } from "./DataField"; import Hanger from "./Hanger"; import Node from "./Node"; import { Tag } from "./Tag"; +import { Thumbnail } from "./Thumbnail"; type Props = { type: TYPES | "Error"; @@ -80,9 +82,18 @@ const Question: React.FC = React.memo((props) => { onContextMenu={handleContext} ref={drag} > + {props.data?.img && ( + + )} {Icon && } {props.text} + {props.type !== TYPES.SetValue && props.data?.fn && ( + + )} {props.tags?.map((tag) => )}
      {childNodes.map((child: any) => ( diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Thumbnail.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Thumbnail.tsx new file mode 100644 index 0000000000..7250a30c65 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Thumbnail.tsx @@ -0,0 +1,24 @@ +import Box from "@mui/material/Box"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React from "react"; + +export const Thumbnail: React.FC<{ + imageSource: string; + imageAltText?: string; +}> = ({ imageSource, imageAltText }) => { + const showImages = useStore((state) => state.showImages); + if (!showImages) return null; + + return ( + + ); +}; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleDataFieldsButton.tsx b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleDataFieldsButton.tsx new file mode 100644 index 0000000000..7bfe499d46 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleDataFieldsButton.tsx @@ -0,0 +1,35 @@ +import CodeIcon from "@mui/icons-material/Code"; +import CodeOffIcon from "@mui/icons-material/CodeOff"; +import IconButton from "@mui/material/IconButton"; +import Tooltip from "@mui/material/Tooltip"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React from "react"; + +export const ToggleDataFieldsButton: React.FC = () => { + const [showDataFields, toggleShowDataFields] = useStore((state) => [ + state.showDataFields, + state.toggleShowDataFields, + ]); + + return ( + + ({ + background: theme.palette.background.paper, + padding: theme.spacing(1), + color: showDataFields + ? theme.palette.text.primary + : theme.palette.text.disabled, + "&:hover": { + background: theme.palette.common.white, + }, + })} + > + {showDataFields ? : } + + + ); +}; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleImagesButton.tsx b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleImagesButton.tsx new file mode 100644 index 0000000000..4e1a958804 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleImagesButton.tsx @@ -0,0 +1,35 @@ +import ImageOffIcon from "@mui/icons-material/HideImage"; +import ImageIcon from "@mui/icons-material/Image"; +import IconButton from "@mui/material/IconButton"; +import Tooltip from "@mui/material/Tooltip"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React from "react"; + +export const ToggleImagesButton: React.FC = () => { + const [showImages, toggleShowImages] = useStore((state) => [ + state.showImages, + state.toggleShowImages, + ]); + + return ( + + ({ + background: theme.palette.background.paper, + padding: theme.spacing(1), + color: showImages + ? theme.palette.text.primary + : theme.palette.text.disabled, + "&:hover": { + background: theme.palette.common.white, + }, + })} + > + {showImages ? : } + + + ); +}; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleTagsButton.tsx b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleTagsButton.tsx index 18a01e24a8..068563981a 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleTagsButton.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/FlowEditor/ToggleTagsButton.tsx @@ -1,6 +1,5 @@ import LabelIcon from "@mui/icons-material/Label"; import LabelOffIcon from "@mui/icons-material/LabelOff"; -import Box from "@mui/material/Box"; import IconButton from "@mui/material/IconButton"; import Tooltip from "@mui/material/Tooltip"; import { useStore } from "pages/FlowEditor/lib/store"; @@ -13,32 +12,24 @@ export const ToggleTagsButton: React.FC = () => { ]); return ( - ({ - position: "fixed", - bottom: theme.spacing(2), - left: theme.spacing(7), - zIndex: theme.zIndex.appBar, - border: `1px solid ${theme.palette.border.main}`, - borderRadius: "3px", - background: theme.palette.background.paper, - })} - > - - ({ - padding: theme.spacing(1), - color: showTags - ? theme.palette.text.primary - : theme.palette.text.disabled, - })} - > - {showTags ? : } - - - + + ({ + background: theme.palette.background.paper, + padding: theme.spacing(1), + color: showTags + ? theme.palette.text.primary + : theme.palette.text.disabled, + "&:hover": { + background: theme.palette.common.white, + }, + })} + > + {showTags ? : } + + ); }; diff --git a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss index 5998350e7b..561d37248a 100644 --- a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss +++ b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss @@ -251,7 +251,7 @@ $fontMonospace: "Source Code Pro", monospace; flex-direction: column; padding: 0; min-width: 60px; - max-width: 200px; + max-width: fit-content; } .band { width: 100%; diff --git a/editor.planx.uk/src/pages/FlowEditor/index.tsx b/editor.planx.uk/src/pages/FlowEditor/index.tsx index 167b517006..f582340893 100644 --- a/editor.planx.uk/src/pages/FlowEditor/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/index.tsx @@ -1,12 +1,15 @@ import "./floweditor.scss"; import Box from "@mui/material/Box"; +import ButtonGroup from "@mui/material/ButtonGroup"; import { styled } from "@mui/material/styles"; import { HEADER_HEIGHT_EDITOR } from "components/Header"; import React, { useRef } from "react"; import { useCurrentRoute } from "react-navi"; import Flow from "./components/Flow"; +import { ToggleDataFieldsButton } from "./components/FlowEditor/ToggleDataFieldsButton"; +import { ToggleImagesButton } from "./components/FlowEditor/ToggleImagesButton"; import { ToggleTagsButton } from "./components/FlowEditor/ToggleTagsButton"; import Sidebar from "./components/Sidebar"; import { useStore } from "./lib/store"; @@ -24,6 +27,18 @@ const EditorContainer = styled(Box, { : `calc(100vh - ${HEADER_HEIGHT_EDITOR}px)`, })); +const EditorVisualControls = styled(ButtonGroup)(({ theme }) => ({ + position: "fixed", + bottom: theme.spacing(2.5), + left: theme.spacing(7.5), + zIndex: theme.zIndex.appBar, + border: `1px solid ${theme.palette.border.main}`, + borderRadius: "3px", + background: theme.palette.border.main, + gap: "1px", + overflow: "hidden", +})); + const FlowEditor = () => { const [flow, ...breadcrumbs] = useCurrentRoute().url.pathname.split("/").at(-1)?.split(",") || []; @@ -50,7 +65,14 @@ const FlowEditor = () => { > - + + + + + 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 02db9a6b77..b12d7f920e 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts @@ -3,7 +3,6 @@ import { getPathForNode, sortFlow } from "@opensystemslab/planx-core"; import { ComponentType, FlowGraph, - IndexedNode, NodeId, OrderedFlow, } from "@opensystemslab/planx-core/types"; @@ -52,6 +51,10 @@ export interface EditorUIStore { hideTestEnvBanner: () => void; showTags: boolean; toggleShowTags: () => void; + showImages: boolean; + toggleShowImages: () => void; + showDataFields: boolean; + toggleShowDataFields: () => void; } export const editorUIStore: StateCreator< @@ -76,12 +79,22 @@ export const editorUIStore: StateCreator< showTags: false, toggleShowTags: () => set({ showTags: !get().showTags }), + + showImages: false, + + toggleShowImages: () => set({ showImages: !get().showImages }), + + showDataFields: false, + + toggleShowDataFields: () => set({ showDataFields: !get().showDataFields }), }), { name: "editorUIStore", partialize: (state) => ({ showSidebar: state.showSidebar, showTags: state.showTags, + showImages: state.showImages, + showDataFields: state.showDataFields, }), }, );