Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Simply editor visual settings button group #3810

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -92,9 +94,18 @@ const Checklist: React.FC<Props> = React.memo((props) => {
onContextMenu={handleContext}
ref={drag}
>
{props.data?.img && (
<Thumbnail
imageSource={props.data?.img}
imageAltText={props.data?.text}
/>
)}
{Icon && <Icon />}
<span>{props.text}</span>
</Link>
{props.data?.fn && (
<DataField value={props.data.fn} variant="parent" />
)}
{props.tags?.map((tag) => <Tag tag={tag} key={tag} />)}
</Box>
{groupedOptions ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<Box
sx={(theme) => ({
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}
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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<any> = (props) => {
const childNodes = useStore((state) => state.childNodesOf(props.id));
Expand All @@ -14,6 +16,7 @@ const Option: React.FC<any> = (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),
Expand All @@ -27,8 +30,15 @@ const Option: React.FC<any> = (props) => {
className={classNames("card", "option", { wasVisited: props.wasVisited })}
>
<Link href={href} prefetch={false} onClick={(e) => e.preventDefault()}>
{props.data?.img && (
<Thumbnail
imageSource={props.data?.img}
imageAltText={props.data.text}
/>
)}
<div className="band" style={{ background, color }}></div>
<div className="text">{props.data.text}</div>
{props.data?.val && <DataField value={props.data.val} variant="child" />}
</Link>
<ol className="decisions">
{childNodes.map((child: any) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -80,9 +82,18 @@ const Question: React.FC<Props> = React.memo((props) => {
onContextMenu={handleContext}
ref={drag}
>
{props.data?.img && (
<Thumbnail
imageSource={props.data?.img}
imageAltText={props.data?.text}
/>
)}
{Icon && <Icon titleAccess={iconTitleAccess} />}
<span>{props.text}</span>
</Link>
{props.type !== TYPES.SetValue && props.data?.fn && (
<DataField value={props.data.fn} variant="parent" />
)}
{props.tags?.map((tag) => <Tag tag={tag} key={tag} />)}
<ol className="options">
{childNodes.map((child: any) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<Box
sx={{
maxWidth: "220px",
maxHeight: "220px",
margin: "auto",
}}
component="img"
src={imageSource}
alt={imageAltText}
/>
);
};
Original file line number Diff line number Diff line change
@@ -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 (
<Tooltip title="Toggle data fields" placement="right">
<IconButton
aria-label="Toggle data fields"
onClick={toggleShowDataFields}
size="large"
sx={(theme) => ({
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 ? <CodeIcon /> : <CodeOffIcon />}
</IconButton>
</Tooltip>
);
};
Original file line number Diff line number Diff line change
@@ -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 (
<Tooltip title="Toggle images" placement="right">
<IconButton
aria-label="Toggle images"
onClick={toggleShowImages}
size="large"
sx={(theme) => ({
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 ? <ImageIcon /> : <ImageOffIcon />}
</IconButton>
</Tooltip>
);
};
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -13,32 +12,24 @@ export const ToggleTagsButton: React.FC = () => {
]);

return (
<Box
sx={(theme) => ({
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,
})}
>
<Tooltip title="Toggle tags" placement="right">
<IconButton
aria-label="Toggle tags"
onClick={toggleShowTags}
size="large"
sx={(theme) => ({
padding: theme.spacing(1),
color: showTags
? theme.palette.text.primary
: theme.palette.text.disabled,
})}
>
{showTags ? <LabelIcon /> : <LabelOffIcon />}
</IconButton>
</Tooltip>
</Box>
<Tooltip title="Toggle tags" placement="right">
<IconButton
aria-label="Toggle tags"
onClick={toggleShowTags}
size="large"
sx={(theme) => ({
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 ? <LabelIcon /> : <LabelOffIcon />}
</IconButton>
</Tooltip>
);
};
2 changes: 1 addition & 1 deletion editor.planx.uk/src/pages/FlowEditor/floweditor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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%;
Expand Down
24 changes: 23 additions & 1 deletion editor.planx.uk/src/pages/FlowEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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(",") || [];
Expand All @@ -50,7 +65,14 @@ const FlowEditor = () => {
>
<Box id="editor" ref={scrollContainerRef} sx={{ position: "relative" }}>
<Flow flow={flow} breadcrumbs={breadcrumbs} />
<ToggleTagsButton />
<EditorVisualControls
orientation="vertical"
aria-label="Toggle node attributes"
>
<ToggleImagesButton />
<ToggleDataFieldsButton />
<ToggleTagsButton />
</EditorVisualControls>
</Box>
</Box>
<Sidebar />
Expand Down
15 changes: 14 additions & 1 deletion editor.planx.uk/src/pages/FlowEditor/lib/store/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { getPathForNode, sortFlow } from "@opensystemslab/planx-core";
import {
ComponentType,
FlowGraph,
IndexedNode,
NodeId,
OrderedFlow,
} from "@opensystemslab/planx-core/types";
Expand Down Expand Up @@ -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<
Expand All @@ -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,
}),
},
);
Expand Down
Loading