From 8742852ac0e9a0783e96695b2c8226439a5ddad3 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:09:06 +0200 Subject: [PATCH 01/20] Add labeling panel --- src/client/package-lock.json | 9 ++++ src/client/package.json | 1 + src/client/src/App.tsx | 12 +++++- src/client/src/AppTheme.ts | 22 ++++++++++ .../src/components/buttons/labelingButton.tsx | 42 +++++++++++++++++++ src/client/src/index.css | 5 +++ src/client/src/mui.theme.d.ts | 35 ++++++++++++++++ src/client/src/pages/detail/detailPage.tsx | 38 +++++++++++++---- .../pages/detail/labeling/labelingContext.tsx | 28 +++++++++++++ .../detail/labeling/labelingInterfaces.tsx | 10 +++++ .../pages/detail/labeling/labelingPanel.tsx | 17 ++++++++ 11 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 src/client/src/components/buttons/labelingButton.tsx create mode 100644 src/client/src/pages/detail/labeling/labelingContext.tsx create mode 100644 src/client/src/pages/detail/labeling/labelingInterfaces.tsx create mode 100644 src/client/src/pages/detail/labeling/labelingPanel.tsx diff --git a/src/client/package-lock.json b/src/client/package-lock.json index fd3e76bb0..2b1eee8bf 100644 --- a/src/client/package-lock.json +++ b/src/client/package-lock.json @@ -28,6 +28,7 @@ "i18next-http-backend": "^2.4.2", "immer": "^10.0.3", "lodash": "^4.17.21", + "lucide-react": "^0.438.0", "markdown-to-jsx": "^7.0.1", "moment": "^2.29.4", "oidc-client-ts": "3.0.1", @@ -7465,6 +7466,14 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.438.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.438.0.tgz", + "integrity": "sha512-uq6yCB+IzVfgIPMK8ibkecXSWTTSOMs9UjUgZigfrDCVqgdwkpIgYg1fSYnf0XXF2AoSyCJZhoZXQwzoai7VGw==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, "node_modules/markdown-to-jsx": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", diff --git a/src/client/package.json b/src/client/package.json index b5a7bde0e..ab5ea73de 100644 --- a/src/client/package.json +++ b/src/client/package.json @@ -43,6 +43,7 @@ "i18next-http-backend": "^2.4.2", "immer": "^10.0.3", "lodash": "^4.17.21", + "lucide-react": "^0.438.0", "markdown-to-jsx": "^7.0.1", "moment": "^2.29.4", "oidc-client-ts": "3.0.1", diff --git a/src/client/src/App.tsx b/src/client/src/App.tsx index ce4a70ce7..c73dcb0b3 100644 --- a/src/client/src/App.tsx +++ b/src/client/src/App.tsx @@ -19,6 +19,7 @@ import { FilterProvider } from "./pages/overview/sidePanelContent/filter/filterC import HeaderComponent from "./components/header/headerComponent.tsx"; import { AppBox } from "./components/styledComponents.ts"; import { DetailPage } from "./pages/detail/detailPage.tsx"; +import { LabelingProvider } from "./pages/detail/labeling/labelingContext.tsx"; const queryClient = new QueryClient(); @@ -64,7 +65,16 @@ class App extends React.Component { } key={0} path={"/setting"} /> - } /> + ( + + + + )} + /> { return ; diff --git a/src/client/src/AppTheme.ts b/src/client/src/AppTheme.ts index af91489c4..d8bccb663 100644 --- a/src/client/src/AppTheme.ts +++ b/src/client/src/AppTheme.ts @@ -38,6 +38,11 @@ export const theme = createTheme({ main: "#337083", secondary: "#a65462", }, + ai: { + main: "#5B21B6", + secondary: "#4F46E5", + contrastText: "#ffffff", + }, boxShadow: "#DFE4E9", background: { default: "#ffffff", @@ -188,6 +193,23 @@ export const theme = createTheme({ backgroundColor: "rgba(0, 0, 0, 0)", }, }, + colorAi: { + color: "#ffffff", + background: "linear-gradient(#5B21B6, #8B5CF6)", + "&:hover": { + background: "linear-gradient(#4F46E5, #E53940)", + }, + "&:focus-visible": { + background: "linear-gradient(#4F46E5, #E53940)", + boxShadow: "0px 0px 0px 3px #8655F6", + }, + "&:active": { + background: "linear-gradient(#4F46E5, #E53940)", + }, + "&:disabled": { + background: "linear-gradient(#4F46E5, #E53940)", + }, + }, }, }, MuiSelect: { diff --git a/src/client/src/components/buttons/labelingButton.tsx b/src/client/src/components/buttons/labelingButton.tsx new file mode 100644 index 000000000..e5d7c092c --- /dev/null +++ b/src/client/src/components/buttons/labelingButton.tsx @@ -0,0 +1,42 @@ +import { ButtonProps, IconButton } from "@mui/material"; +import { forwardRef } from "react"; +import { ChevronDown, ChevronRight, Sparkles } from "lucide-react"; + +export const LabelingButton = forwardRef((props, ref) => { + return ( + + + + ); +}); + +interface LabelingToggleButtonProps extends ButtonProps { + panelOpen: boolean; + panelPosition: "right" | "bottom"; +} + +export const LabelingToggleButton = forwardRef((props, ref) => { + return ( + + {props.panelOpen ? props.panelPosition === "right" ? : : } + + ); +}); diff --git a/src/client/src/index.css b/src/client/src/index.css index 251b756d0..84d38a5f4 100644 --- a/src/client/src/index.css +++ b/src/client/src/index.css @@ -1,3 +1,8 @@ +.lucide { + width: 20px; + height: 20px; + stroke-width: 1.5px; +} .ol-popup { position: absolute; diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index 8d1093af5..052ce0ced 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -1,6 +1,26 @@ import { Theme, ThemeOptions } from "@mui/material/styles"; +declare module "@mui/material/Button" { + interface ButtonPropsColorOverrides { + ai: true; + } +} + +declare module "@mui/material/IconButton" { + interface IconButtonPropsColorOverrides { + ai: true; + } +} + declare module "@mui/material/styles" { + interface Palette { + ai: Palette["ai"]; + } + + interface PaletteOptions { + ai?: PaletteOptions["ai"]; + } + interface CustomTheme extends Theme { palette: { action: { @@ -38,6 +58,13 @@ declare module "@mui/material/styles" { main: string; secondary: string; }; + ai: { + mainTop: string; + mainBottom: string; + activeTop: string; + activeBottom: string; + contrastText: string; + }; boxShadow: string; background: { default: string; @@ -88,6 +115,7 @@ declare module "@mui/material/styles" { }; }; } + // allow configuration using `createTheme` interface CustomThemeOptions extends ThemeOptions { palette?: { @@ -126,6 +154,13 @@ declare module "@mui/material/styles" { main: string; secondary: string; }; + ai: { + mainTop: string; + mainBottom: string; + activeTop: string; + activeBottom: string; + contrastText: string; + }; boxShadow: string; background: { default: string; diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 936349d5d..20c9f42fe 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -1,4 +1,4 @@ -import { LayoutBox, MainContentBox, SidebarBox } from "../../components/styledComponents.ts"; +import { MainContentBox, SidebarBox } from "../../components/styledComponents.ts"; import { FC, useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { useLocation } from "react-router-dom"; @@ -6,6 +6,10 @@ import { Borehole, ReduxRootState } from "../../api-lib/ReduxStateInterfaces.ts" import DetailSideNav from "./detailSideNav"; import DetailPageContent from "./detailPageContent"; import DetailHeader from "./detailHeader.tsx"; +import { Box } from "@mui/material"; +import { useLabelingContext } from "./labeling/labelingInterfaces.tsx"; +import LabelingPanel from "./labeling/labelingPanel.tsx"; +import { LabelingToggleButton } from "../../components/buttons/labelingButton.tsx"; interface DetailPageContentProps { editingEnabled: boolean; @@ -18,6 +22,7 @@ export const DetailPage: FC = () => { const borehole: Borehole = useSelector((state: ReduxRootState) => state.core_borehole); const user = useSelector((state: ReduxRootState) => state.core_user); const location = useLocation(); + const { panelPosition, panelOpen, togglePanel } = useLabelingContext(); useEffect(() => { setEditingEnabled(borehole.data.lock !== null); @@ -53,14 +58,29 @@ export const DetailPage: FC = () => { setEditingEnabled={setEditingEnabled} editableByCurrentUser={editableByCurrentUser} /> - - - - - - - - + + + + + + + + togglePanel()} /> + + + {panelOpen && panelPosition === "right" && } + + + {panelOpen && panelPosition === "bottom" && } + ); }; diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx new file mode 100644 index 000000000..5dbd50590 --- /dev/null +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -0,0 +1,28 @@ +import { LabelingContextInterface } from "./labelingInterfaces.tsx"; +import { createContext, FC, PropsWithChildren, useState } from "react"; + +export const LabelingContext = createContext({ + panelPosition: "right", + panelOpen: false, + togglePanel: () => {}, +}); + +export const LabelingProvider: FC = ({ children }) => { + const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("bottom"); + const [panelOpen, setPanelOpen] = useState(false); + + const togglePanel = () => { + setPanelOpen(!panelOpen); + }; + + return ( + + {children} + + ); +}; diff --git a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx new file mode 100644 index 000000000..896b11e45 --- /dev/null +++ b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx @@ -0,0 +1,10 @@ +import { LabelingContext } from "./labelingContext.tsx"; +import { useContext } from "react"; + +export interface LabelingContextInterface { + panelPosition: "right" | "bottom"; + panelOpen: boolean; + togglePanel: () => void; +} + +export const useLabelingContext = () => useContext(LabelingContext); diff --git a/src/client/src/pages/detail/labeling/labelingPanel.tsx b/src/client/src/pages/detail/labeling/labelingPanel.tsx new file mode 100644 index 000000000..376ed0ed9 --- /dev/null +++ b/src/client/src/pages/detail/labeling/labelingPanel.tsx @@ -0,0 +1,17 @@ +import { Box } from "@mui/material"; +import { useLabelingContext } from "./labelingInterfaces.tsx"; + +const LabelingPanel = () => { + const { panelPosition } = useLabelingContext(); + return ( + + ); +}; + +export default LabelingPanel; From 206b43d3a270ec1bd7031be098b385cef870bfde Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:10:08 +0200 Subject: [PATCH 02/20] Fix interface --- src/client/src/mui.theme.d.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index 052ce0ced..474d66608 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -59,10 +59,8 @@ declare module "@mui/material/styles" { secondary: string; }; ai: { - mainTop: string; - mainBottom: string; - activeTop: string; - activeBottom: string; + main: string; + secondary: string; contrastText: string; }; boxShadow: string; @@ -155,10 +153,8 @@ declare module "@mui/material/styles" { secondary: string; }; ai: { - mainTop: string; - mainBottom: string; - activeTop: string; - activeBottom: string; + main: string; + secondary: string; contrastText: string; }; boxShadow: string; From 2ec9f9c48741738c17c16d3f54948358a3693fcf Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:19:39 +0200 Subject: [PATCH 03/20] Fix warning --- src/client/src/components/buttons/labelingButton.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/client/src/components/buttons/labelingButton.tsx b/src/client/src/components/buttons/labelingButton.tsx index e5d7c092c..03f19fef9 100644 --- a/src/client/src/components/buttons/labelingButton.tsx +++ b/src/client/src/components/buttons/labelingButton.tsx @@ -22,21 +22,22 @@ interface LabelingToggleButtonProps extends ButtonProps { } export const LabelingToggleButton = forwardRef((props, ref) => { + const { panelOpen, panelPosition, ...defaultProps } = props; return ( - {props.panelOpen ? props.panelPosition === "right" ? : : } + {panelOpen ? panelPosition === "right" ? : : } ); }); From 8729e0b84dbd16a2a9035b6199799221ab787485 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:28:53 +0200 Subject: [PATCH 04/20] Fix interface --- src/client/src/mui.theme.d.ts | 455 +++++++++++++++++++++------------- 1 file changed, 278 insertions(+), 177 deletions(-) diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index 474d66608..ca27381ce 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -1,4 +1,5 @@ import { Theme, ThemeOptions } from "@mui/material/styles"; +import { ComponentType } from "react"; declare module "@mui/material/Button" { interface ButtonPropsColorOverrides { @@ -13,199 +14,299 @@ declare module "@mui/material/IconButton" { } declare module "@mui/material/styles" { - interface Palette { - ai: Palette["ai"]; + interface AppThemePalette { + action: { + disabled: string; + }; + primary: { + main: string; + contrastText: string; + }; + secondary: { + main: string; + contrastText: string; + background: string; + }; + success: { + main: string; + }; + warning: { + main: string; + }; + error: { + main: string; + dark: string; + contrastText: string; + background: string; + }; + neutral: { + main: string; + contrastText: string; + }; + hover: { + main: string; + }; + mapIcon: { + main: string; + secondary: string; + }; + ai: { + main: string; + secondary: string; + contrastText: string; + }; + boxShadow: string; + background: { + default: string; + lightgrey: string; + darkgrey: string; + dark: string; + menuItemActive: string; + filterItemActive: string; + }; + border: string; } - interface PaletteOptions { - ai?: PaletteOptions["ai"]; + 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: { + fontSize: string; + color: string; + lineHeight: string; + }; + body2: { + fontSize: string; + }; + fullPageMessage: { + fontSize: string; + color: string; + }; } - interface CustomTheme extends Theme { - palette: { - action: { - disabled: string; - }; - primary: { - main: string; - contrastText: string; - }; - secondary: { - main: string; - contrastText: string; - background: string; - }; - success: { - main: string; - }; - warning: { - main: string; - }; - error: { - main: string; - dark: string; - contrastText: string; - background: string; - }; - neutral: { - main: string; - contrastText: string; - }; - hover: { - main: string; - }; - mapIcon: { - main: string; - secondary: string; - }; - ai: { - main: string; - secondary: string; - contrastText: string; - }; - boxShadow: string; - background: { - default: string; - lightgrey: string; - darkgrey: string; - dark: string; - menuItemActive: string; - filterItemActive: string; - }; - border: string; - }; - typography: { - fontFamily: string; - h6: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; - }; - h5: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; - }; - h2: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; - }; - subtitle1: { - fontSize: string; - color: string; - lineHeight: string; - }; - subtitle2: { - fontSize: string; - color: string; - lineHeight: string; - }; - body2: { - fontSize: string; - }; - fullPageMessage: { - fontSize: string; - color: string; - }; + interface AppThemeBreakpoints { + values: { + xs: number; + sm: number; + md: number; + lg: number; + xl: number; }; } - // allow configuration using `createTheme` - interface CustomThemeOptions extends ThemeOptions { - palette?: { - action: { - disabled: string; - }; - primary: { - main: string; - contrastText: string; - }; - secondary: { - main: string; - contrastText: string; - background: string; - }; - success: { - main: string; - }; - warning: { - main: string; - }; - error: { - main: string; - dark: string; - contrastText: string; - background: string; - }; - neutral: { - main: string; - contrastText: string; - }; - hover: { - main: string; - }; - mapIcon: { - main: string; - secondary: string; + interface AppThemeComponents { + MuiButtonBase: { + defaultProps: { + disableRipple: boolean; }; - ai: { - main: string; - secondary: string; - contrastText: string; - }; - boxShadow: string; - background: { - default: string; - lightgrey: string; - darkgrey: string; - dark: string; - menuItemActive: string; - filterItemActive: string; + }; + 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; + }; + }; }; - border: string; - }; - typography: { - fontFamily: string; - h6: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; + }; + 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; + }; + }; }; - h5: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; + }; + MuiSelect: { + defaultProps: { + IconComponent: ComponentType; }; - h2: { - fontSize: string; - color: string; - lineHeight: string; - fontWeight: number; + }; + 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; + }; + }; }; - subtitle1: { - fontSize: string; - color: string; - lineHeight: string; + }; + MuiTab: { + styleOverrides: { + root: { + fontFamily: string; + fontWeight: string | number; + textTransform: string; + fontSize: string; + }; }; - subtitle2: { - fontSize: string; - color: string; - lineHeight: string; + }; + MuiBadge: { + styleOverrides: { + badge: { + backgroundColor: string; + color: string; + }; }; - body2: { - fontSize: string; + }; + MuiDialogContentText: { + styleOverrides: { + root: { + fontSize: string; + color: string; + }; }; - fullPageMessage: { - 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; + }; }; }; } - export function createTheme(options?: CustomThemeOptions): CustomTheme; + + interface AppTheme extends Theme { + palette: AppThemePalette; + typography: AppThemeTypography; + breakpoints: AppThemeBreakpoints; + components: AppThemeComponents; + } + + // allow configuration using `createTheme` + interface AppThemeOptions extends ThemeOptions { + palette: AppThemePalette; + typography: AppThemeTypography; + breakpoints: AppThemeBreakpoints; + components: AppThemeComponents; + } + export function createTheme(options?: AppThemeOptions): AppTheme; } From 18b5b5fdeef81ed00ab54208af398da0490b7f29 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:31:46 +0200 Subject: [PATCH 05/20] Fix type --- src/client/src/mui.theme.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index ca27381ce..4785e6318 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -1,5 +1,5 @@ import { Theme, ThemeOptions } from "@mui/material/styles"; -import { ComponentType } from "react"; +import { ComponentType, SVGProps } from "react"; declare module "@mui/material/Button" { interface ButtonPropsColorOverrides { @@ -228,7 +228,7 @@ declare module "@mui/material/styles" { }; MuiSelect: { defaultProps: { - IconComponent: ComponentType; + IconComponent: ComponentType & { title?: string | undefined }>; }; }; MuiFormControl: { From aaf2c9f47bf47791bc7312837860fc9f29aa1ca9 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 16:56:30 +0200 Subject: [PATCH 06/20] Fix default value --- src/client/src/pages/detail/labeling/labelingContext.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 5dbd50590..62844946e 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -8,7 +8,7 @@ export const LabelingContext = createContext({ }); export const LabelingProvider: FC = ({ children }) => { - const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("bottom"); + const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("right"); const [panelOpen, setPanelOpen] = useState(false); const togglePanel = () => { From 5240404d022951b8d3001533295133a9ccc29a10 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Tue, 3 Sep 2024 17:03:05 +0200 Subject: [PATCH 07/20] Temporary ignore lint warning --- src/client/src/pages/detail/labeling/labelingContext.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 62844946e..43cee46fe 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -8,6 +8,7 @@ export const LabelingContext = createContext({ }); export const LabelingProvider: FC = ({ children }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This will be used later const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("right"); const [panelOpen, setPanelOpen] = useState(false); From 022b83b245ab0ef3a9ab2c4db6bb2044fd4dcaa9 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 09:10:17 +0200 Subject: [PATCH 08/20] Add button group to toggle panel position --- src/client/src/AppTheme.ts | 22 +++++++++++++ src/client/src/index.css | 2 +- src/client/src/mui.theme.d.ts | 28 ++++++++++++---- .../pages/detail/labeling/labelingContext.tsx | 3 +- .../detail/labeling/labelingInterfaces.tsx | 1 + .../pages/detail/labeling/labelingPanel.tsx | 32 ++++++++++++++++--- 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/client/src/AppTheme.ts b/src/client/src/AppTheme.ts index d8bccb663..459703c05 100644 --- a/src/client/src/AppTheme.ts +++ b/src/client/src/AppTheme.ts @@ -212,6 +212,28 @@ export const theme = createTheme({ }, }, }, + MuiToggleButtonGroup: { + styleOverrides: { + root: { + backgroundColor: "#ffffff", + }, + }, + }, + MuiToggleButton: { + styleOverrides: { + root: { + border: "0", + borderRadius: "4px !important", + margin: "4px", + padding: "7px", + color: "#337083", + "&.Mui-selected": { + color: "#2F4356", + backgroundColor: "#D6E2E6", + }, + }, + }, + }, MuiSelect: { defaultProps: { IconComponent: ArrowDownIcon, diff --git a/src/client/src/index.css b/src/client/src/index.css index 84d38a5f4..a65696082 100644 --- a/src/client/src/index.css +++ b/src/client/src/index.css @@ -1,7 +1,7 @@ .lucide { width: 20px; height: 20px; - stroke-width: 1.5px; + stroke-width: 1.7px; } .ol-popup { diff --git a/src/client/src/mui.theme.d.ts b/src/client/src/mui.theme.d.ts index 4785e6318..f0d0e5ae1 100644 --- a/src/client/src/mui.theme.d.ts +++ b/src/client/src/mui.theme.d.ts @@ -1,12 +1,6 @@ import { Theme, ThemeOptions } from "@mui/material/styles"; import { ComponentType, SVGProps } from "react"; -declare module "@mui/material/Button" { - interface ButtonPropsColorOverrides { - ai: true; - } -} - declare module "@mui/material/IconButton" { interface IconButtonPropsColorOverrides { ai: true; @@ -226,6 +220,28 @@ declare module "@mui/material/styles" { }; }; }; + 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 }>; diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 43cee46fe..1540c32e2 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -3,12 +3,12 @@ import { createContext, FC, PropsWithChildren, useState } from "react"; export const LabelingContext = createContext({ panelPosition: "right", + setPanelPosition: () => {}, panelOpen: false, togglePanel: () => {}, }); export const LabelingProvider: FC = ({ children }) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars -- This will be used later const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("right"); const [panelOpen, setPanelOpen] = useState(false); @@ -20,6 +20,7 @@ export const LabelingProvider: FC = ({ children }) => { diff --git a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx index 896b11e45..8c23ce1b1 100644 --- a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx +++ b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx @@ -3,6 +3,7 @@ import { useContext } from "react"; export interface LabelingContextInterface { panelPosition: "right" | "bottom"; + setPanelPosition: (position: "right" | "bottom") => void; panelOpen: boolean; togglePanel: () => void; } diff --git a/src/client/src/pages/detail/labeling/labelingPanel.tsx b/src/client/src/pages/detail/labeling/labelingPanel.tsx index 376ed0ed9..272ce32f6 100644 --- a/src/client/src/pages/detail/labeling/labelingPanel.tsx +++ b/src/client/src/pages/detail/labeling/labelingPanel.tsx @@ -1,16 +1,38 @@ -import { Box } from "@mui/material"; +import { Box, ToggleButton, ToggleButtonGroup } from "@mui/material"; import { useLabelingContext } from "./labelingInterfaces.tsx"; +import { PanelBottom, PanelRight } from "lucide-react"; +import { MouseEvent } from "react"; const LabelingPanel = () => { - const { panelPosition } = useLabelingContext(); + const { panelPosition, setPanelPosition } = useLabelingContext(); + return ( + }}> + , nextPosition: "right" | "bottom") => { + setPanelPosition(nextPosition); + }} + exclusive + sx={{ + position: "absolute", + bottom: "10px", + right: "10px", + zIndex: "500", + }}> + + + + + + + + ); }; From 27773233ad2a04fd51c736bd7ca4d783fc996b68 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 09:19:19 +0200 Subject: [PATCH 09/20] Type panel position --- src/client/src/pages/detail/labeling/labelingContext.tsx | 4 ++-- src/client/src/pages/detail/labeling/labelingInterfaces.tsx | 6 ++++-- src/client/src/pages/detail/labeling/labelingPanel.tsx | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/client/src/pages/detail/labeling/labelingContext.tsx b/src/client/src/pages/detail/labeling/labelingContext.tsx index 1540c32e2..5ce55d592 100644 --- a/src/client/src/pages/detail/labeling/labelingContext.tsx +++ b/src/client/src/pages/detail/labeling/labelingContext.tsx @@ -1,4 +1,4 @@ -import { LabelingContextInterface } from "./labelingInterfaces.tsx"; +import { LabelingContextInterface, PanelPosition } from "./labelingInterfaces.tsx"; import { createContext, FC, PropsWithChildren, useState } from "react"; export const LabelingContext = createContext({ @@ -9,7 +9,7 @@ export const LabelingContext = createContext({ }); export const LabelingProvider: FC = ({ children }) => { - const [panelPosition, setPanelPosition] = useState<"right" | "bottom">("right"); + const [panelPosition, setPanelPosition] = useState("right"); const [panelOpen, setPanelOpen] = useState(false); const togglePanel = () => { diff --git a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx index 8c23ce1b1..09dbacc8d 100644 --- a/src/client/src/pages/detail/labeling/labelingInterfaces.tsx +++ b/src/client/src/pages/detail/labeling/labelingInterfaces.tsx @@ -1,9 +1,11 @@ import { LabelingContext } from "./labelingContext.tsx"; import { useContext } from "react"; +export type PanelPosition = "right" | "bottom"; + export interface LabelingContextInterface { - panelPosition: "right" | "bottom"; - setPanelPosition: (position: "right" | "bottom") => void; + panelPosition: PanelPosition; + setPanelPosition: (position: PanelPosition) => void; panelOpen: boolean; togglePanel: () => void; } diff --git a/src/client/src/pages/detail/labeling/labelingPanel.tsx b/src/client/src/pages/detail/labeling/labelingPanel.tsx index 272ce32f6..632b61b3c 100644 --- a/src/client/src/pages/detail/labeling/labelingPanel.tsx +++ b/src/client/src/pages/detail/labeling/labelingPanel.tsx @@ -1,5 +1,5 @@ import { Box, ToggleButton, ToggleButtonGroup } from "@mui/material"; -import { useLabelingContext } from "./labelingInterfaces.tsx"; +import { PanelPosition, useLabelingContext } from "./labelingInterfaces.tsx"; import { PanelBottom, PanelRight } from "lucide-react"; import { MouseEvent } from "react"; @@ -15,7 +15,7 @@ const LabelingPanel = () => { }}> , nextPosition: "right" | "bottom") => { + onChange={(event: MouseEvent, nextPosition: PanelPosition) => { setPanelPosition(nextPosition); }} exclusive From 9ddced8a98e5e4f0ed2af560b73fbadc5e739068 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 09:34:19 +0200 Subject: [PATCH 10/20] Update panel bottom position --- src/client/src/pages/detail/detailPage.tsx | 39 +++++++++------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 20c9f42fe..8f0f8a238 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -1,4 +1,4 @@ -import { MainContentBox, SidebarBox } from "../../components/styledComponents.ts"; +import { LayoutBox, MainContentBox, SidebarBox } from "../../components/styledComponents.ts"; import { FC, useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { useLocation } from "react-router-dom"; @@ -58,29 +58,22 @@ export const DetailPage: FC = () => { setEditingEnabled={setEditingEnabled} editableByCurrentUser={editableByCurrentUser} /> - - - - - - - - togglePanel()} /> - - - {panelOpen && panelPosition === "right" && } - + + + + + + + togglePanel()} /> + + + {panelOpen && } - {panelOpen && panelPosition === "bottom" && } - + ); }; From 8df25be25847ae148a4ac147a7c5b5b59c13437e Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 09:44:36 +0200 Subject: [PATCH 11/20] Add option to hide labeling button --- src/client/src/pages/detail/detailPage.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/src/pages/detail/detailPage.tsx b/src/client/src/pages/detail/detailPage.tsx index 8f0f8a238..8f9653af1 100644 --- a/src/client/src/pages/detail/detailPage.tsx +++ b/src/client/src/pages/detail/detailPage.tsx @@ -23,6 +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; useEffect(() => { setEditingEnabled(borehole.data.lock !== null); @@ -68,7 +69,9 @@ export const DetailPage: FC = () => { width: panelOpen && panelPosition === "right" ? "50%" : "100%", height: panelOpen && panelPosition === "bottom" ? "50%" : "100%", }}> - togglePanel()} /> + {showLabeling && ( + togglePanel()} /> + )} {panelOpen && } From 384c59b6bfbd54ec01d3a53e8c0262d98b0078d7 Mon Sep 17 00:00:00 2001 From: tschumpr Date: Wed, 4 Sep 2024 11:03:57 +0200 Subject: [PATCH 12/20] 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 13/20] 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 14/20] 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 15/20] 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 16/20] 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 17/20] 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 18/20] 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 19/20] 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 20/20] 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);