From ead0e6aec2d198a12d01b446e02bcc395927fd1f Mon Sep 17 00:00:00 2001 From: Kevin Zheng Date: Thu, 29 Feb 2024 03:17:15 +1100 Subject: [PATCH] Minor UI changes --- .../BreakpointListEditor.tsx | 2 +- client/src/components/generic/ListEditor.tsx | 4 +-- client/src/components/generic/Snackbar.tsx | 7 +++-- .../src/components/inspector/Placeholder.tsx | 27 ++++++++++++++++--- .../components/inspector/TraceRenderer.tsx | 6 ++++- .../settings-editor/RendererEditor.tsx | 13 ++++++++- .../settings-editor/RendererListEditor.tsx | 1 - .../settings-editor/ServerEditor.tsx | 15 ++++++++--- .../settings-editor/ServerListEditor.tsx | 1 - client/src/pages/DebugPage.tsx | 6 ++++- client/src/pages/InfoPage.tsx | 14 ++++++++-- client/src/pages/LayersPage.tsx | 1 + client/src/pages/SettingsPage.tsx | 24 ++++++++++------- client/src/pages/StepsPage.tsx | 15 ++++++++--- client/src/pages/TreePage.tsx | 6 ++++- client/src/public/manifest.json | 4 +-- client/src/slices/log.ts | 19 +++++++++---- 17 files changed, 125 insertions(+), 40 deletions(-) diff --git a/client/src/components/breakpoint-editor/BreakpointListEditor.tsx b/client/src/components/breakpoint-editor/BreakpointListEditor.tsx index e221ab59..54ce746c 100644 --- a/client/src/components/breakpoint-editor/BreakpointListEditor.tsx +++ b/client/src/components/breakpoint-editor/BreakpointListEditor.tsx @@ -66,7 +66,7 @@ export function BreakpointListEditor({ handleBreakpointsChange(updatedBreakpoints) } addItemLabel="Breakpoint" - placeholder="No breakpoints." + placeholder="Get started by adding a breakpoint." /> diff --git a/client/src/components/generic/ListEditor.tsx b/client/src/components/generic/ListEditor.tsx index b61a8012..c97946b0 100644 --- a/client/src/components/generic/ListEditor.tsx +++ b/client/src/components/generic/ListEditor.tsx @@ -413,7 +413,7 @@ export default function Editor(props: Props) { - + {extras} - + ); diff --git a/client/src/components/generic/Snackbar.tsx b/client/src/components/generic/Snackbar.tsx index cbe2a613..4256c747 100644 --- a/client/src/components/generic/Snackbar.tsx +++ b/client/src/components/generic/Snackbar.tsx @@ -66,8 +66,11 @@ export function SnackbarProvider({ children }: { children?: ReactNode }) { }, ]); appendLog(() => ({ - content: filter([message, secondary]).join(", "), - timestamp: `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`, + action: "append", + log: { + content: filter([message, secondary]).join(", "), + timestamp: `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`, + }, })); if (options.error) { console.error(`${message}, ${secondary}`); diff --git a/client/src/components/inspector/Placeholder.tsx b/client/src/components/inspector/Placeholder.tsx index db4878b7..dd4703f0 100644 --- a/client/src/components/inspector/Placeholder.tsx +++ b/client/src/components/inspector/Placeholder.tsx @@ -1,26 +1,45 @@ import { WidgetsOutlined } from "@mui/icons-material"; import { Typography as Type } from "@mui/material"; import { Flex, FlexProps } from "components/generic/Flex"; -import { cloneElement, ReactElement, ReactNode } from "react"; +import { ReactElement, ReactNode } from "react"; export function Placeholder({ label, icon = , + secondary, ...rest -}: { label?: ReactNode; icon?: ReactElement } & FlexProps) { +}: { + label?: ReactNode; + icon?: ReactElement; + secondary?: ReactNode; +} & FlexProps) { return ( `repeating-linear-gradient( + 45deg, + ${t.palette.background.default}, + ${t.palette.background.paper} 1px, + ${t.palette.background.paper} 7px, + ${t.palette.background.default} 8px + )`, + }} textAlign="center" vertical pt={6} {...rest} > - {cloneElement(icon, { sx: { mb: 2 }, fontSize: "large" })} + {icon} {label} + {!!secondary && ( + + {secondary} + + )} ); } diff --git a/client/src/components/inspector/TraceRenderer.tsx b/client/src/components/inspector/TraceRenderer.tsx index 5fe3eb8b..a2085df3 100644 --- a/client/src/components/inspector/TraceRenderer.tsx +++ b/client/src/components/inspector/TraceRenderer.tsx @@ -110,6 +110,9 @@ function TraceRendererCircularProgress() { ); } +const VIEWPORT_PAGE_DESCRIPTION = + "When you create a layer, you'll see it visualised here."; + export function TraceRenderer({ width, height, @@ -194,9 +197,10 @@ export function TraceRenderer({ ) : ( } - label="No layers to render" + label="Viewport" width={width} height={height} + secondary={VIEWPORT_PAGE_DESCRIPTION} /> )} diff --git a/client/src/components/settings-editor/RendererEditor.tsx b/client/src/components/settings-editor/RendererEditor.tsx index 117cdda8..919b2ff6 100644 --- a/client/src/components/settings-editor/RendererEditor.tsx +++ b/client/src/components/settings-editor/RendererEditor.tsx @@ -50,7 +50,18 @@ export function RendererEditor({ value, onValueChange }: RendererEditorProps) { return ( <> - + *": { + overflow: "hidden", + whiteSpace: "nowrap", + textOverflow: "ellipsis", + }, + }} + > {current ? `${current.renderer.meta.name} ${current.renderer.meta.version}` diff --git a/client/src/components/settings-editor/RendererListEditor.tsx b/client/src/components/settings-editor/RendererListEditor.tsx index cf8d3529..5da0b841 100644 --- a/client/src/components/settings-editor/RendererListEditor.tsx +++ b/client/src/components/settings-editor/RendererListEditor.tsx @@ -27,7 +27,6 @@ export function RendererListEditor() { addItemExtras={ } - sx={{ ml: 2 }} onClick={() => setSettings(() => ({ renderer: defaultRenderers }))} > Reset to Defaults diff --git a/client/src/components/settings-editor/ServerEditor.tsx b/client/src/components/settings-editor/ServerEditor.tsx index f87c007c..edcf7524 100644 --- a/client/src/components/settings-editor/ServerEditor.tsx +++ b/client/src/components/settings-editor/ServerEditor.tsx @@ -15,9 +15,7 @@ import { ManagedModal as Dialog, AppBarTitle as Title, } from "components/generic/Modal"; -import { OverlineDot as Dot } from "components/generic/Overline"; import { SelectField as Select } from "components/generic/Select"; -import { Space } from "components/generic/Space"; import { useConnection } from "hooks/useConnectionResolver"; import { useConnectionStatus } from "hooks/useConnectionStatus"; import { entries, omit, startCase } from "lodash"; @@ -54,7 +52,18 @@ export function ServerEditor({ value, onValueChange }: ServerEditorProps) { return ( <> - + *": { + overflow: "hidden", + whiteSpace: "nowrap", + textOverflow: "ellipsis", + }, + }} + > {connection ? `${connection.name} ${connection.version}` diff --git a/client/src/components/settings-editor/ServerListEditor.tsx b/client/src/components/settings-editor/ServerListEditor.tsx index 31f7282f..6ff68b94 100644 --- a/client/src/components/settings-editor/ServerListEditor.tsx +++ b/client/src/components/settings-editor/ServerListEditor.tsx @@ -27,7 +27,6 @@ export function ServerListEditor() { addItemExtras={ } - sx={{ ml: 2 }} onClick={() => setSettings(() => ({ remote: defaultRemotes }))} > Reset to Defaults diff --git a/client/src/pages/DebugPage.tsx b/client/src/pages/DebugPage.tsx index de0e7d31..4a19a831 100644 --- a/client/src/pages/DebugPage.tsx +++ b/client/src/pages/DebugPage.tsx @@ -87,7 +87,11 @@ export function DebugPage({ template: Page }: PageContentProps) { ) : ( - } label="Debugger" /> + } + label="Debugger" + secondary="Configure breakpoints and other debugging options here. First, you'll need to load a trace." + /> )} {controls} diff --git a/client/src/pages/InfoPage.tsx b/client/src/pages/InfoPage.tsx index 3478c173..94fc2449 100644 --- a/client/src/pages/InfoPage.tsx +++ b/client/src/pages/InfoPage.tsx @@ -1,5 +1,6 @@ -import { ListOutlined } from "@mui/icons-material"; +import { CloseOutlined, ListOutlined } from "@mui/icons-material"; import { Divider, List, ListItem, ListItemText } from "@mui/material"; +import { FeaturePickerButton } from "components/app-bar/FeaturePickerButton"; import { Flex } from "components/generic/Flex"; import { Scroll } from "components/generic/Scrollbars"; import { Placeholder } from "components/inspector/Placeholder"; @@ -11,10 +12,19 @@ import { PageContentProps } from "./PageMeta"; export function InfoPage({ template: Page }: PageContentProps) { const { controls, onChange, state, dragHandle } = useViewTreeContext(); - const [log] = useLog(); + const [log, setLog] = useLog(); return ( {dragHandle} + + } + onClick={() => setLog(() => ({ action: "clear" }))} + > + Clear + + {log.length ? ( diff --git a/client/src/pages/LayersPage.tsx b/client/src/pages/LayersPage.tsx index d04e7b6e..87b819e4 100644 --- a/client/src/pages/LayersPage.tsx +++ b/client/src/pages/LayersPage.tsx @@ -4,6 +4,7 @@ import { Scroll } from "components/generic/Scrollbars"; import { useViewTreeContext } from "components/inspector/ViewTree"; import { LayerListEditor } from "components/layer-editor/LayerListEditor"; import { PageContentProps } from "./PageMeta"; + export function LayersPage({ template: Page }: PageContentProps) { const { controls, onChange, state, dragHandle } = useViewTreeContext(); diff --git a/client/src/pages/SettingsPage.tsx b/client/src/pages/SettingsPage.tsx index 905dbdea..b56f9cba 100644 --- a/client/src/pages/SettingsPage.tsx +++ b/client/src/pages/SettingsPage.tsx @@ -47,7 +47,15 @@ export function SettingsPage({ template: Page }: PageContentProps) { } function renderLabel(label: ReactNode) { return ( - + {label} ); @@ -71,9 +79,8 @@ export function SettingsPage({ template: Page }: PageContentProps) { {renderHeading("Playback")} - + {renderLabel("Playback Rate")} - ({ @@ -94,9 +101,8 @@ export function SettingsPage({ template: Page }: PageContentProps) { /> {renderHeading("Appearance")} - + {renderLabel("Acrylic")} - @@ -104,7 +110,7 @@ export function SettingsPage({ template: Page }: PageContentProps) { } /> - + {renderLabel("Dark Mode")} - + {renderLabel("Accent")} - ({ @@ -134,9 +139,8 @@ export function SettingsPage({ template: Page }: PageContentProps) { /> {renderHeading("Behaviour")} - + {renderLabel("Show Explore Panel on Start-up")} - diff --git a/client/src/pages/StepsPage.tsx b/client/src/pages/StepsPage.tsx index ae4f4aa4..47ac2ead 100644 --- a/client/src/pages/StepsPage.tsx +++ b/client/src/pages/StepsPage.tsx @@ -1,5 +1,4 @@ import { - DragIndicatorOutlined, FiberManualRecordOutlined, LayersOutlined as LayersIcon, SegmentOutlined, @@ -100,6 +99,11 @@ function useStepsPageState( }; } +const getStepsPageDescription = (s?: string) => + s + ? `${s} contains 0 steps.` + : "When you load a trace, you'll see its steps here."; + export function StepsPage({ template: Page }: PageContentProps) { const { spacing } = useTheme(); const paper = usePaper(); @@ -250,11 +254,16 @@ export function StepsPage({ template: Page }: PageContentProps) { ) : ( } - label={`${inferLayerName(layer)}`} + label="Steps" + secondary={getStepsPageDescription(inferLayerName(layer))} /> ) ) : ( - } label="Steps" /> + } + label="Steps" + secondary={getStepsPageDescription()} + /> )} {!!steps?.length && ( diff --git a/client/src/pages/TreePage.tsx b/client/src/pages/TreePage.tsx index d3482737..076da391 100644 --- a/client/src/pages/TreePage.tsx +++ b/client/src/pages/TreePage.tsx @@ -161,7 +161,11 @@ export function TreePage({ template: Page }: PageContentProps) { )} ) : ( - } label="Tree" /> + } + label="Tree" + secondary="When you load a trace that has tree-like data, you'll see it as a decision tree here." + /> )} {" "} diff --git a/client/src/public/manifest.json b/client/src/public/manifest.json index beabe13a..6a5cc34e 100644 --- a/client/src/public/manifest.json +++ b/client/src/public/manifest.json @@ -1,9 +1,9 @@ { "short_name": "Visualiser", "name": "Visualiser", - "version": "1.1.11-1", + "version": "1.1.11-2", "description": "Visualise pathfinding search and more", - "version_name": "1.1.11-1; late February 2024", + "version_name": "1.1.11-2; late February 2024", "repository": "https://github.com/path-visualiser/app", "docs": "https://github.com/path-visualiser/app/blob/master/docs", "homepage": "https://path-visualiser.github.io/", diff --git a/client/src/slices/log.ts b/client/src/slices/log.ts index 604b33cd..122013b4 100644 --- a/client/src/slices/log.ts +++ b/client/src/slices/log.ts @@ -1,5 +1,5 @@ -import { createSlice } from "./createSlice"; - +import { createSlice } from "./createSlice"; + type LogEntry = { content: string; timestamp?: string; @@ -7,6 +7,15 @@ type LogEntry = { type Log = LogEntry[]; -export const [useLog, LogProvider] = createSlice([], { - reduce: (prev, next) => [next, ...prev], -}); \ No newline at end of file +type LogAction = { action: "append"; log: LogEntry } | { action: "clear" }; + +export const [useLog, LogProvider] = createSlice([], { + reduce: (prev, next) => { + switch (next.action) { + case "append": + return [next.log, ...prev]; + case "clear": + return []; + } + }, +});