From 384c59b6bfbd54ec01d3a53e8c0262d98b0078d7 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 11:03:57 +0200 Subject: [PATCH 1/9] Save panel position in cache --- .../src/pages/detail/labeling/labelingContext.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 5ce55d592..8d3ab6287 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -1,5 +1,5 @@ import { LabelingContextInterface, PanelPosition } from "./labelingInterfaces.tsx"; -import { createContext, FC, PropsWithChildren, useState } from "react"; +import { createContext, FC, PropsWithChildren, useEffect, useLayoutEffect, useState } from "react"; export const LabelingContext = createContext({ panelPosition: "right", @@ -12,6 +12,17 @@ export const LabelingProvider: FC = ({ children }) => { const [panelPosition, setPanelPosition] = useState("right"); const [panelOpen, setPanelOpen] = useState(false); + useLayoutEffect(() => { + const storedPosition = localStorage.getItem("panelPosition") as PanelPosition; + if (storedPosition) { + setPanelPosition(storedPosition); + } + }, []); + + useEffect(() => { + localStorage.setItem("panelPosition", panelPosition); + }, [panelPosition]); + const togglePanel = () => { setPanelOpen(!panelOpen); }; From 6bdb8f924741e52c8d01df50f4069c3d1c0b4d03 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 11:04:57 +0200 Subject: [PATCH 2/9] Save panel position in cache --- src/client/src/pages/detail/labeling/labelingContext.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 8d3ab6287..ff007be8a 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -12,15 +12,16 @@ export const LabelingProvider: FC = ({ children }) => { const [panelPosition, setPanelPosition] = useState("right"); const [panelOpen, setPanelOpen] = useState(false); + const panelPositionStorageName = "labelingPanelPosition"; useLayoutEffect(() => { - const storedPosition = localStorage.getItem("panelPosition") as PanelPosition; + const storedPosition = localStorage.getItem(panelPositionStorageName) as PanelPosition; if (storedPosition) { setPanelPosition(storedPosition); } }, []); useEffect(() => { - localStorage.setItem("panelPosition", panelPosition); + localStorage.setItem(panelPositionStorageName, panelPosition); }, [panelPosition]); const togglePanel = () => { From 5fbd6c1e6e64fb372b435a0429dc49bc4adc448e Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 11:11:29 +0200 Subject: [PATCH 3/9] Only show labeling tool in edit mode --- src/client/src/pages/detail/detailPage.tsx | 8 ++++++-- src/client/src/pages/detail/labeling/labelingContext.tsx | 8 ++++++-- .../src/pages/detail/labeling/labelingInterfaces.tsx | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 8f9653af1..d784da95d 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -30,6 +30,10 @@ export const DetailPage: FC = () => { }, [borehole.data.lock]); useEffect(() => { + if (!editingEnabled) { + togglePanel(false); + } + if (borehole.data.lock !== null && borehole.data.lock.id !== user.data.id) { setEditableByCurrentUser(false); return; @@ -69,12 +73,12 @@ export const DetailPage: FC = () => { width: panelOpen && panelPosition === "right" ? "50%" : "100%", height: panelOpen && panelPosition === "bottom" ? "50%" : "100%", }}> - {showLabeling && ( + {editingEnabled && showLabeling && ( togglePanel()} /> )} - {panelOpen && } + {editingEnabled && panelOpen && } diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index ff007be8a..5efbfd9a4 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -24,8 +24,12 @@ export const LabelingProvider: FC = ({ children }) => { localStorage.setItem(panelPositionStorageName, panelPosition); }, [panelPosition]); - const togglePanel = () => { - setPanelOpen(!panelOpen); + const togglePanel = (isOpen?: boolean) => { + if (isOpen !== undefined) { + setPanelOpen(isOpen); + } else { + setPanelOpen(!panelOpen); + } }; return ( diff --git a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx index 09dbacc8d..011ebed52 100644 --- a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx +++ b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx @@ -7,7 +7,7 @@ export interface LabelingContextInterface { panelPosition: PanelPosition; setPanelPosition: (position: PanelPosition) => void; panelOpen: boolean; - togglePanel: () => void; + togglePanel: (isOpen?: boolean) => void; } export const useLabelingContext = () => useContext(LabelingContext); From 2fcb254d3b0c0ddb7d286384dcf0754736623619 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 13:03:04 +0200 Subject: [PATCH 4/9] Simplify theme interface --- src/client/src/mui.theme.d.ts | 281 +++++----------------------------- 1 file changed, 38 insertions(+), 243 deletions(-) diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index f0d0e5ae1..c89ce9d7d 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -1,5 +1,8 @@ import { Theme, ThemeOptions } from "@mui/material/styles"; -import { ComponentType, SVGProps } from "react"; +import { Breakpoints } from "@mui/system"; +import { BreakpointsOptions } from "@mui/system/createTheme/createBreakpoints"; +import { Typography } from "@mui/material"; +import { TypographyOptions } from "@mui/material/styles/createTypography"; declare module "@mui/material/IconButton" { interface IconButtonPropsColorOverrides { @@ -61,268 +64,60 @@ declare module "@mui/material/styles" { border: string; } - interface AppThemeTypography { - fontFamily: string; - h6: { - fontSize: string; - lineHeight: string; - fontWeight: number | string; - color: string; - }; - h5: { - fontSize: string; - lineHeight: string; - fontWeight: number | string; - color: string; - }; - h2: { - fontSize: string; - lineHeight: string; - fontWeight: number | string; - color: string; - }; - subtitle1: { - fontSize: string; - color: string; - lineHeight: string; - }; - subtitle2: { + interface AppThemeTypography extends Typography { + fullPageMessage: { fontSize: string; color: string; - lineHeight: string; - }; - body2: { - fontSize: string; }; - fullPageMessage: { + } + + interface AppThemeTypographyOptions extends TypographyOptions { + fullPageMessage?: { fontSize: string; color: string; }; } - interface AppThemeBreakpoints { - values: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; + interface AppThemeComponents extends Components { + MuiButtonBase: object; + MuiButton: object; + MuiIconButton: object; + MuiToggleButtonGroup: object; + MuiToggleButton: object; + MuiSelect: object; + MuiFormControl: object; + MuiTab: object; + MuiBadge: object; + MuiDialogContentText: object; + MuiTableCell: object; } - interface AppThemeComponents { - MuiButtonBase: { - defaultProps: { - disableRipple: boolean; - }; - }; - MuiButton: { - styleOverrides: { - root: { - fontFamily: string; - fontWeight: string | number; - textTransform: string; - whiteSpace: string; - minWidth: string; - marginLeft: string; - padding: string; - borderRadius: string; - boxShadow: string; - "&:hover": { - boxShadow: string; - }; - }; - contained: { - backgroundColor: string; - "&:hover": { - backgroundColor: string; - }; - "&:focus-visible": { - backgroundColor: string; - boxShadow: string; - }; - "&:active": { - backgroundColor: string; - }; - "&:disabled": { - backgroundColor: string; - }; - }; - outlined: { - color: string; - backgroundColor: string; - "&:hover": { - color: string; - backgroundColor: string; - }; - "&:focus-visible": { - color: string; - backgroundColor: string; - boxShadow: string; - }; - "&:active": { - color: string; - backgroundColor: string; - }; - "&:disabled": { - backgroundColor: string; - color: string; - }; - }; - }; - }; - MuiIconButton: { - styleOverrides: { - root: { - "& .MuiTouchRipple-root": { - display: string; - }; - }; - colorPrimary: { - backgroundColor: string; - color: string; - "&:hover": { - backgroundColor: string; - }; - "&:focus-visible": { - backgroundColor: string; - boxShadow: string; - }; - "&:active": { - backgroundColor: string; - }; - "&:disabled": { - backgroundColor: string; - }; - }; - colorError: { - "&:hover": { - color: string; - backgroundColor: string; - }; - }; - colorAi: { - color: string; - background: string; - "&:hover": { - background: string; - }; - "&:focus-visible": { - background: string; - boxShadow: string; - }; - "&:active": { - background: string; - }; - "&:disabled": { - background: string; - }; - }; - }; - }; - MuiToggleButtonGroup: { - styleOverrides: { - root: { - backgroundColor: string; - }; - }; - }; - MuiToggleButton: { - styleOverrides: { - root: { - border: string; - borderRadius: string; - margin: string; - padding: string; - color: string; - "&.Mui-selected": { - color: string; - backgroundColor: string; - }; - }; - }; - }; - MuiSelect: { - defaultProps: { - IconComponent: ComponentType & { title?: string | undefined }>; - }; - }; - MuiFormControl: { - styleOverrides: { - root: { - "& .MuiFilledInput-root": { - backgroundColor: string; - }; - "& .MuiFilledInput-root:hover:not(.Mui-disabled, .Mui-error):before": { - borderColor: string; - }; - "& .MuiFilledInput-root:not(.Mui-error):before": { - borderColor: string; - }; - "& .MuiFilledInput-root:not(.Mui-error):after": { - borderColor: string; - }; - }; - }; - }; - MuiTab: { - styleOverrides: { - root: { - fontFamily: string; - fontWeight: string | number; - textTransform: string; - fontSize: string; - }; - }; - }; - MuiBadge: { - styleOverrides: { - badge: { - backgroundColor: string; - color: string; - }; - }; - }; - MuiDialogContentText: { - styleOverrides: { - root: { - fontSize: string; - color: string; - }; - }; - }; - MuiTableCell: { - styleOverrides: { - head: { - fontSize: string; - fontWeight: number | string; - padding: string; - flex: number | string; - verticalAlign: string; - }; - body: { - paddingRight: string; - paddingLeft: string; - flex: number | string; - fontSize: string; - }; - }; - }; + interface AppThemeComponentsOptions extends ComponentsOptions { + MuiButtonBase: object; + MuiButton: object; + MuiIconButton: object; + MuiToggleButtonGroup: object; + MuiToggleButton: object; + MuiSelect: object; + MuiFormControl: object; + MuiTab: object; + MuiBadge: object; + MuiDialogContentText: object; + MuiTableCell: object; } interface AppTheme extends Theme { palette: AppThemePalette; typography: AppThemeTypography; - breakpoints: AppThemeBreakpoints; + breakpoints: Breakpoints; components: AppThemeComponents; } - // allow configuration using `createTheme` interface AppThemeOptions extends ThemeOptions { palette: AppThemePalette; - typography: AppThemeTypography; - breakpoints: AppThemeBreakpoints; - components: AppThemeComponents; + typography: AppThemeTypographyOptions; + breakpoints: BreakpointsOptions; + components: AppThemeComponentsOptions; } export function createTheme(options?: AppThemeOptions): AppTheme; } From f4ef05fbe4cc9a6184008d2e8fff0f836ae12bdb Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 13:22:39 +0200 Subject: [PATCH 5/9] Add test --- src/client/cypress/e2e/editor/labeling.cy.js | 35 +++++++++++++++++++ .../src/components/buttons/labelingButton.tsx | 3 +- src/client/src/pages/detail/detailPage.tsx | 2 +- .../pages/detail/labeling/labelingPanel.tsx | 7 ++-- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/client/cypress/e2e/editor/labeling.cy.js diff --git a/src/client/cypress/e2e/editor/labeling.cy.js b/src/client/cypress/e2e/editor/labeling.cy.js new file mode 100644 index 000000000..484161fbe --- /dev/null +++ b/src/client/cypress/e2e/editor/labeling.cy.js @@ -0,0 +1,35 @@ +import { newUneditableBorehole, startBoreholeEditing, stopBoreholeEditing } from "../helpers/testHelpers.js"; + +describe("Test labeling tool", () => { + it("can show labeling panel", () => { + newUneditableBorehole().as("borehole_id"); + // only show in editing mode + cy.get('[data-cy="labeling-toggle-button"]').should("not.exist"); + + // panel is closed by default + startBoreholeEditing(); + cy.get('[data-cy="labeling-toggle-button"]').should("exist"); + cy.get('[data-cy="labeling-panel"]').should("not.exist"); + + // panel can be opened and closed + cy.get('[data-cy="labeling-toggle-button"]').click(); + cy.get('[data-cy="labeling-panel"]').should("exist"); + cy.get('[data-cy="labeling-toggle-button"]').click(); + cy.get('[data-cy="labeling-panel"]').should("not.exist"); + + // panel open state should be reset when editing is stopped, panel position should be preserved + cy.get('[data-cy="labeling-toggle-button"]').click(); + cy.get('[data-cy="labeling-panel"]').should("exist"); + cy.get('[data-cy="labeling-panel-position-right"]').should("have.class", "Mui-selected"); + cy.get('[data-cy="labeling-panel-position-bottom"]').click(); + cy.get('[data-cy="labeling-panel-position-right"]').should("not.have.class", "Mui-selected"); + cy.get('[data-cy="labeling-panel-position-bottom"]').should("have.class", "Mui-selected"); + + stopBoreholeEditing(); + cy.get('[data-cy="labeling-panel"]').should("not.exist"); + startBoreholeEditing(); + cy.get('[data-cy="labeling-panel"]').should("not.exist"); + cy.get('[data-cy="labeling-toggle-button"]').click(); + cy.get('[data-cy="labeling-panel-position-bottom"]').should("have.class", "Mui-selected"); + }); +}); diff --git a/src/client/src/components/buttons/labelingButton.tsx b/src/client/src/components/buttons/labelingButton.tsx index 03f19fef9..a4932c448 100644 --- a/src/client/src/components/buttons/labelingButton.tsx +++ b/src/client/src/components/buttons/labelingButton.tsx @@ -36,7 +36,8 @@ export const LabelingToggleButton = forwardRef + }} + data-cy="labeling-toggle-button"> {panelOpen ? panelPosition === "right" ? : : } ); diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index d784da95d..7c2f49e9a 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -23,7 +23,7 @@ export const DetailPage: FC = () => { const user = useSelector((state: ReduxRootState) => state.core_user); const location = useLocation(); const { panelPosition, panelOpen, togglePanel } = useLabelingContext(); - const showLabeling = false; + const showLabeling = true; useEffect(() => { setEditingEnabled(borehole.data.lock !== null); diff --git a/src/client/src/pages/detail/labeling/labelingPanel.tsx b/src/client/src/pages/detail/labeling/labelingPanel.tsx index 632b61b3c..3c6eb917a 100644 --- a/src/client/src/pages/detail/labeling/labelingPanel.tsx +++ b/src/client/src/pages/detail/labeling/labelingPanel.tsx @@ -12,7 +12,8 @@ const LabelingPanel = () => { backgroundColor: "#46596B", height: panelPosition === "bottom" ? "50%" : "100%", width: panelPosition === "right" ? "50%" : "100%", - }}> + }} + data-cy="labeling-panel"> , nextPosition: PanelPosition) => { @@ -25,10 +26,10 @@ const LabelingPanel = () => { right: "10px", zIndex: "500", }}> - + - + From b240dabdc9ee158b311ec202ff865b77a092d10c Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 13:24:58 +0200 Subject: [PATCH 6/9] Add colors to theme --- src/client/src/AppTheme.ts | 5 ++++- src/client/src/mui.theme.d.ts | 5 ++++- src/client/src/pages/detail/labeling/labelingPanel.tsx | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/client/src/AppTheme.ts b/src/client/src/AppTheme.ts index 459703c05..3539f9fd3 100644 --- a/src/client/src/AppTheme.ts +++ b/src/client/src/AppTheme.ts @@ -39,8 +39,11 @@ export const theme = createTheme({ secondary: "#a65462", }, ai: { + background: "#46596B", main: "#5B21B6", - secondary: "#4F46E5", + mainEnd: "#8B5CF6", + active: "#4F46E5", + activeEnd: "#E53940", contrastText: "#ffffff", }, boxShadow: "#DFE4E9", diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index c89ce9d7d..cc495b607 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -48,8 +48,11 @@ declare module "@mui/material/styles" { secondary: string; }; ai: { + background: string; main: string; - secondary: string; + mainEnd: string; + active: string; + activeEnd: string; contrastText: string; }; boxShadow: string; diff --git a/src/client/src/pages/detail/labeling/labelingPanel.tsx b/src/client/src/pages/detail/labeling/labelingPanel.tsx index 3c6eb917a..a82732beb 100644 --- a/src/client/src/pages/detail/labeling/labelingPanel.tsx +++ b/src/client/src/pages/detail/labeling/labelingPanel.tsx @@ -2,6 +2,7 @@ import { Box, ToggleButton, ToggleButtonGroup } from "@mui/material"; import { PanelPosition, useLabelingContext } from "./labelingInterfaces.tsx"; import { PanelBottom, PanelRight } from "lucide-react"; import { MouseEvent } from "react"; +import { theme } from "../../../AppTheme.ts"; const LabelingPanel = () => { const { panelPosition, setPanelPosition } = useLabelingContext(); @@ -9,7 +10,7 @@ const LabelingPanel = () => { return ( Date: Wed, 4 Sep 2024 13:27:23 +0200 Subject: [PATCH 7/9] Add missing dependency --- src/client/src/pages/detail/detailPage.tsx | 2 +- .../src/pages/detail/labeling/labelingContext.tsx | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 7c2f49e9a..6be0259be 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -49,7 +49,7 @@ export const DetailPage: FC = () => { const isBoreholeInEditWorkflow = borehole?.data.workflow?.role === "EDIT"; setEditableByCurrentUser(userRoleMatches && (isStatusPage || isBoreholeInEditWorkflow)); - }, [editingEnabled, user, borehole, location]); + }, [editingEnabled, user, borehole, location, togglePanel]); const props: DetailPageContentProps = { editingEnabled: editingEnabled, diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 5efbfd9a4..f8a72503d 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -1,5 +1,5 @@ import { LabelingContextInterface, PanelPosition } from "./labelingInterfaces.tsx"; -import { createContext, FC, PropsWithChildren, useEffect, useLayoutEffect, useState } from "react"; +import { createContext, FC, PropsWithChildren, useCallback, useEffect, useLayoutEffect, useState } from "react"; export const LabelingContext = createContext({ panelPosition: "right", @@ -24,13 +24,9 @@ export const LabelingProvider: FC = ({ children }) => { localStorage.setItem(panelPositionStorageName, panelPosition); }, [panelPosition]); - const togglePanel = (isOpen?: boolean) => { - if (isOpen !== undefined) { - setPanelOpen(isOpen); - } else { - setPanelOpen(!panelOpen); - } - }; + const togglePanel = useCallback((isOpen?: boolean) => { + setPanelOpen(prevState => (isOpen !== undefined ? isOpen : !prevState)); + }, []); return ( Date: Wed, 4 Sep 2024 13:42:52 +0200 Subject: [PATCH 8/9] Fix interface --- src/client/src/mui.theme.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index cc495b607..9daed25a1 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -68,6 +68,7 @@ declare module "@mui/material/styles" { } interface AppThemeTypography extends Typography { + fontFamily: string; fullPageMessage: { fontSize: string; color: string; @@ -75,6 +76,7 @@ declare module "@mui/material/styles" { } interface AppThemeTypographyOptions extends TypographyOptions { + fontFamily: string; fullPageMessage?: { fontSize: string; color: string; From 4037b42eca1c240c1773d1b8c97b955cd02f59f7 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 14:39:35 +0200 Subject: [PATCH 9/9] Hide labeling tool for merge --- src/client/cypress/e2e/editor/labeling.cy.js | 2 +- src/client/src/pages/detail/detailPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/cypress/e2e/editor/labeling.cy.js b/src/client/cypress/e2e/editor/labeling.cy.js index 484161fbe..eec0da34e 100644 --- a/src/client/cypress/e2e/editor/labeling.cy.js +++ b/src/client/cypress/e2e/editor/labeling.cy.js @@ -1,6 +1,6 @@ import { newUneditableBorehole, startBoreholeEditing, stopBoreholeEditing } from "../helpers/testHelpers.js"; -describe("Test labeling tool", () => { +describe.skip("Test labeling tool", () => { it("can show labeling panel", () => { newUneditableBorehole().as("borehole_id"); // only show in editing mode diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 6be0259be..316fe6d51 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -23,7 +23,7 @@ export const DetailPage: FC = () => { const user = useSelector((state: ReduxRootState) => state.core_user); const location = useLocation(); const { panelPosition, panelOpen, togglePanel } = useLabelingContext(); - const showLabeling = true; + const showLabeling = false; useEffect(() => { setEditingEnabled(borehole.data.lock !== null);