From d115bb227eb050db891714794e49a78497e78961 Mon Sep 17 00:00:00 2001 From: Vincent T Date: Mon, 9 Oct 2023 16:47:41 -0400 Subject: [PATCH] frontend: Add detail drawer mode Signed-off-by: Vincent T --- frontend/src/components/App/Layout.tsx | 6 ++ .../App/Settings/DrawerModeButton.tsx | 57 +++++++++++++++++ .../src/components/App/Settings/Settings.tsx | 5 ++ .../common/DetailsDrawer/DetailDrawer.tsx | 62 +++++++++++++++++++ frontend/src/redux/drawerModeSlice.ts | 29 +++++++++ frontend/src/redux/reducers/reducers.tsx | 2 + frontend/src/redux/reducers/ui.tsx | 8 +++ 7 files changed, 169 insertions(+) create mode 100644 frontend/src/components/App/Settings/DrawerModeButton.tsx create mode 100644 frontend/src/components/common/DetailsDrawer/DetailDrawer.tsx create mode 100644 frontend/src/redux/drawerModeSlice.ts diff --git a/frontend/src/components/App/Layout.tsx b/frontend/src/components/App/Layout.tsx index f55ed0755a3..709fc4065ca 100644 --- a/frontend/src/components/App/Layout.tsx +++ b/frontend/src/components/App/Layout.tsx @@ -16,6 +16,7 @@ import { useTypedSelector } from '../../redux/reducers/reducers'; import store from '../../redux/stores/store'; import ActionsNotifier from '../common/ActionsNotifier'; import AlertNotification from '../common/AlertNotification'; +import DetailsDrawer from '../common/DetailsDrawer/DetailDrawer'; import Sidebar, { drawerWidthClosed, NavigationTabs } from '../Sidebar'; import RouteSwitcher from './RouteSwitcher'; import TopBar from './TopBar'; @@ -90,6 +91,10 @@ function ClusterNotFoundPopup() { export default function Layout({}: LayoutProps) { const classes = useStyle(); const arePluginsLoaded = useTypedSelector(state => state.plugins.loaded); + const isDetailDrawerEnabled = useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled); + console.log('isDetailDrawerEnabled', isDetailDrawerEnabled); + const isDetailDrawerOpen = useTypedSelector(state => state.drawerMode.isDetailDrawerOpen); + console.log('isDetailDrawerOpen', isDetailDrawerOpen); const dispatch = useDispatch(); const clusters = useTypedSelector(state => state.config.clusters); const { t } = useTranslation('frequent'); @@ -177,6 +182,7 @@ export default function Layout({}: LayoutProps) { + {isDetailDrawerEnabled && }
{clusters && !!clusterInURL && !Object.keys(clusters).includes(getCluster() || '') ? ( diff --git a/frontend/src/components/App/Settings/DrawerModeButton.tsx b/frontend/src/components/App/Settings/DrawerModeButton.tsx new file mode 100644 index 00000000000..6b14bab3cc1 --- /dev/null +++ b/frontend/src/components/App/Settings/DrawerModeButton.tsx @@ -0,0 +1,57 @@ +import { FormControlLabel, Switch } from '@material-ui/core'; +import React from 'react'; +import { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; +import { setDetailDrawerEnabled } from '../../../redux/drawerModeSlice'; +import { useTypedSelector } from '../../../redux/reducers/reducers'; + +// const useStyles = makeStyles((theme: Theme) => ({ +// buttonGroup: { +// '& button': { +// boxShadow: 'none', +// borderRadius: '4px', +// padding: '0.8rem 1.5rem', +// }, +// '& .MuiButton-contained': { +// backgroundColor: theme.palette.type === 'dark' ? '' : 'rgba(0, 0, 0, 0.45)', +// color: theme.palette.type === 'dark' ? '' : 'rgb(255, 255, 255)', +// }, +// }, +// })); + +export default function DrawerModeButton() { + const isDetailDrawerEnabled = useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled); + // localDetailDrawerEnabled is a string of either 'true' or 'false', if it does not exist yet it needs to be created + const localDetailDrawerEnabled = Boolean(localStorage.getItem('detailDrawerEnabled')); + + const [newDrawerEnabled, changeDetailDrawerEnabled] = useState(localDetailDrawerEnabled); + + const dispatch = useDispatch(); + const { t } = useTranslation('frequent'); + + useEffect(() => { + dispatch(setDetailDrawerEnabled(newDrawerEnabled)); + }, [newDrawerEnabled]); + + function drawerModeToggle() { + console.log('drawerModeToggle'); + changeDetailDrawerEnabled(!localDetailDrawerEnabled); + } + + return ( + drawerModeToggle()} + name="drawerMode" + color="primary" + /> + } + label={ + isDetailDrawerEnabled ? t('Disable Detail Drawer Mode') : t('Enable Detail Drawer Mode') + } + /> + ); +} diff --git a/frontend/src/components/App/Settings/Settings.tsx b/frontend/src/components/App/Settings/Settings.tsx index 8a4c36db4f1..9da1d333579 100644 --- a/frontend/src/components/App/Settings/Settings.tsx +++ b/frontend/src/components/App/Settings/Settings.tsx @@ -8,6 +8,7 @@ import { setAppSettings, setVersionDialogOpen } from '../../../redux/actions/act import { defaultTableRowsPerPageOptions } from '../../../redux/reducers/config'; import { ActionButton, NameValueTable, SectionBox } from '../../common'; import TimezoneSelect from '../../common/TimezoneSelect'; +import DrawerModeButton from './DrawerModeButton'; import { useSettings } from './hook'; import NumRowsInput from './NumRowsInput'; import ThemeChangeButton from './ThemeChangeButton'; @@ -68,6 +69,10 @@ export default function Settings() { name: t('frequent|Theme'), value: , }, + { + name: t('frequent|Drawer mode'), + value: , + }, { name: t('settings|Number of rows for tables'), value: ( diff --git a/frontend/src/components/common/DetailsDrawer/DetailDrawer.tsx b/frontend/src/components/common/DetailsDrawer/DetailDrawer.tsx new file mode 100644 index 00000000000..72fb102a27a --- /dev/null +++ b/frontend/src/components/common/DetailsDrawer/DetailDrawer.tsx @@ -0,0 +1,62 @@ +import { Button } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Drawer from '@material-ui/core/Drawer'; +import React from 'react'; +import { useState } from 'react'; +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { setDetailDrawerOpen } from '../../../redux/drawerModeSlice'; +import { useTypedSelector } from '../../../redux/reducers/reducers'; + +export interface DetailDrawerProps { + open: boolean; + onClose?: () => void; + children?: React.ReactNode; +} + +export default function DetailDrawer({ open, onClose, children }: DetailDrawerProps) { + const isDetailDrawerOpen = useTypedSelector(state => state.drawerMode.isDetailDrawerOpen); + const [openDetailDrawer, changeOpenDetailDrawer] = useState(isDetailDrawerOpen); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(setDetailDrawerOpen(openDetailDrawer)); + }, [openDetailDrawer]); + + function toggleOpenDrawer() { + changeOpenDetailDrawer(!openDetailDrawer); + } + + return ( + <> + {!isDetailDrawerOpen && ( + <> + + + + + + + )} + {isDetailDrawerOpen && ( + <> + toggleOpenDrawer()}> + + + {children} + + + + )} + + ); +} + +// FIX +// * console log prints that the state resets? localStorage fix maybe +// - maybe by adding the local storage save in the useEffect? +// - if no local storage key exists, create one +// * CREATE A LOCAL STORAGE FOR OPEN DRAWER SAME AS ENABLED DRAWER + +// * the drawer is not opening in minimized mode? persistent drawer fix maybe - https://mui.com/material-ui/react-drawer/#persistent-drawer diff --git a/frontend/src/redux/drawerModeSlice.ts b/frontend/src/redux/drawerModeSlice.ts new file mode 100644 index 00000000000..ee89ff7381b --- /dev/null +++ b/frontend/src/redux/drawerModeSlice.ts @@ -0,0 +1,29 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +interface DrawerModeState { + isDetailDrawerEnabled: boolean; + isDetailDrawerOpen: boolean; +} + +const initialState: DrawerModeState = { + isDetailDrawerEnabled: false, + isDetailDrawerOpen: false, +}; + +const drawerModeSlice = createSlice({ + name: 'drawerMode', + initialState, + reducers: { + setDetailDrawerEnabled: (state, action: PayloadAction) => { + state.isDetailDrawerEnabled = action.payload; + localStorage.setItem('detailDrawerEnabled', `${action.payload}`); + }, + setDetailDrawerOpen: (state, action: PayloadAction) => { + state.isDetailDrawerOpen = action.payload; + localStorage.setItem('detailDrawerOpen', `${action.payload}`); + }, + }, +}); + +export const { setDetailDrawerEnabled, setDetailDrawerOpen } = drawerModeSlice.actions; +export default drawerModeSlice.reducer; diff --git a/frontend/src/redux/reducers/reducers.tsx b/frontend/src/redux/reducers/reducers.tsx index c6ddf048ea3..34fab4e440d 100644 --- a/frontend/src/redux/reducers/reducers.tsx +++ b/frontend/src/redux/reducers/reducers.tsx @@ -3,6 +3,7 @@ import { combineReducers } from 'redux'; import pluginsReducer from '../../plugin/pluginsSlice'; import actionButtons from '../actionButtonsSlice'; import detailsViewSectionsSlice from '../detailsViewSectionsSlice'; +import drawerModeSlice from '../drawerModeSlice'; import clusterAction from './clusterAction'; import config from './config'; import filter from './filter'; @@ -16,6 +17,7 @@ const reducers = combineReducers({ plugins: pluginsReducer, actionButtons: actionButtons, detailsViewSections: detailsViewSectionsSlice, + drawerMode: drawerModeSlice, }); export type RootState = ReturnType; diff --git a/frontend/src/redux/reducers/ui.tsx b/frontend/src/redux/reducers/ui.tsx index 73a09b5dd78..3cf3670dc2f 100644 --- a/frontend/src/redux/reducers/ui.tsx +++ b/frontend/src/redux/reducers/ui.tsx @@ -58,6 +58,10 @@ export interface UIState { }; tableColumnsProcessors: TableColumnsProcessor[]; }; + drawerMode: { + isDetailDrawerEnabled: boolean; + isDetailDrawerOpen: boolean; + }; theme: { name: string; }; @@ -115,6 +119,10 @@ export const INITIAL_STATE: UIState = { }, tableColumnsProcessors: [], }, + drawerMode: { + isDetailDrawerEnabled: false, + isDetailDrawerOpen: false, + }, theme: { name: '', },