Skip to content

Commit

Permalink
frontend: Add detail drawer mode
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent T <[email protected]>
  • Loading branch information
vyncent-t committed Oct 11, 2023
1 parent 341aad9 commit 3f7e7c1
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 0 deletions.
12 changes: 12 additions & 0 deletions frontend/src/components/App/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -90,6 +91,16 @@ function ClusterNotFoundPopup() {
export default function Layout({}: LayoutProps) {
const classes = useStyle();
const arePluginsLoaded = useTypedSelector(state => state.plugins.loaded);

const isDetailDrawerEnabled = localStorage.getItem('detailDrawerEnabled')
? Boolean(localStorage.getItem('detailDrawerEnabled'))
: useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled);
console.log('A - isDetailDrawerEnabled', isDetailDrawerEnabled);
const isDetailDrawerOpen = localStorage.getItem('detailDrawerOpen')
? Boolean(localStorage.getItem('detailDrawerOpen'))
: useTypedSelector(state => state.drawerMode.isDetailDrawerOpen);
console.log('A - isDetailDrawerOpen', isDetailDrawerOpen);

const dispatch = useDispatch();
const clusters = useTypedSelector(state => state.config.clusters);
const { t } = useTranslation('frequent');
Expand Down Expand Up @@ -177,6 +188,7 @@ export default function Layout({}: LayoutProps) {
<CssBaseline />
<TopBar />
<Sidebar />
{isDetailDrawerEnabled && <DetailsDrawer open={isDetailDrawerOpen} />}
<main id="main" className={classes.content}>
{clusters && !!clusterInURL && !Object.keys(clusters).includes(getCluster() || '') ? (
<ClusterNotFoundPopup />
Expand Down
56 changes: 56 additions & 0 deletions frontend/src/components/App/Settings/DrawerModeButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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';

export default function DrawerModeButton() {
// This will fix the problem of the project refreshing the state away from needed position

// we initate a const that sets the state for the drawerMode, it will read whatever state is on and then set it to local storage through the setDetailDrawerEnabled function later
const isDetailDrawerEnabled = useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled);

// localStorage.getItem('detailDrawerEnabled') will return a string, so we need to convert it to a boolean
// ex. localStorage.getItem('detailDrawerEnabled') = 'true' or 'false'
const localDetailDrawerEnabled = Boolean(localStorage.getItem('detailDrawerEnabled'));

// we need to create a state for the current changes to the drawerMode, so we create a new state called newDrawerEnabled and set it to the localDetailDrawerEnabled
// we use newDrawerEnabled to take in a change of state, send it to the setDetailDrawerEnabled function which the function then sets sets the state to the new change and ALSO sets it to local storage

const [newDrawerEnabled, changeDetailDrawerEnabled] = useState(localDetailDrawerEnabled);

const dispatch = useDispatch();
const { t } = useTranslation('frequent');

// the useEffect will run everytime the newDrawerEnabled state changes, which is everytime the user clicks the switch button because the switch button changes the state of newDrawerEnabled
useEffect(() => {
dispatch(setDetailDrawerEnabled(newDrawerEnabled));
console.log('ON SETTINGS');
console.log(localStorage.getItem('detailDrawerEnabled'));
}, [newDrawerEnabled]);

// this function takes in the current changes and updates it, this kicks off the useEffect that is listening for changes to newDrawerEnabled
function drawerModeToggle() {
console.log('drawerModeToggle');
changeDetailDrawerEnabled(!newDrawerEnabled);
}

// NOTICE THAT WE DO NOT USE NewDrawerEnabled TO DETERMINE HOW THE SWITCH IS RENDERED UNDER THE CHECKED PROP, THIS IS BECAUSE THE USEEFFECT WILL RERENDER THE COMPONENT WITH THE NEW STATE
return (
<FormControlLabel
control={
<Switch
checked={isDetailDrawerEnabled}
onClick={() => drawerModeToggle()}
name="drawerMode"
color="primary"
/>
}
label={
isDetailDrawerEnabled ? t('Disable Detail Drawer Mode') : t('Enable Detail Drawer Mode')
}
/>
);
}
5 changes: 5 additions & 0 deletions frontend/src/components/App/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { setAppSettings } from '../../../redux/configSlice';
import { defaultTableRowsPerPageOptions } from '../../../redux/configSlice';
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';
Expand Down Expand Up @@ -69,6 +70,10 @@ export default function Settings() {
name: t('frequent|Theme'),
value: <ThemeChangeButton showBothIcons />,
},
{
name: t('frequent|Drawer mode'),
value: <DrawerModeButton />,
},
{
name: t('settings|Number of rows for tables'),
value: (
Expand Down
71 changes: 71 additions & 0 deletions frontend/src/components/common/DetailsDrawer/DetailDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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) {
// 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'));
console.log('LOCAL B OFF SETTINGS BEFORE localDetailDrawerEnabled', localDetailDrawerEnabled);

if (!localDetailDrawerEnabled) {
useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled);
}
console.log('LOCAL B OFF SETTINGS localDetailDrawerEnabled', localDetailDrawerEnabled);

// const isDetailDrawerOpen = localStorage.getItem('detialDrawerOpen') ? Boolean(localStorage.getItem('detailDrawerOpen')) : useTypedSelector(state => state.drawerMode.isDetailDrawerOpen);
const isDetailDrawerOpen = open;
console.log('OFF SETTINGS isDetailDrawerOpen', isDetailDrawerOpen);
// localDetailDrawerOpen is a string of either 'true' or 'false', if it does not exist yet it needs to be created
// const localDetailDrawerOpen = Boolean(localStorage.getItem('detailDrawerOpen'))

const [openDetailDrawer, changeOpenDetailDrawer] = useState(isDetailDrawerOpen);
console.log('openDetailDrawer', openDetailDrawer);
const dispatch = useDispatch();

useEffect(() => {
console.log('Toggle Open Drawer', openDetailDrawer);
dispatch(setDetailDrawerOpen(openDetailDrawer));
}, [openDetailDrawer]);

function toggleOpenDrawer() {
changeOpenDetailDrawer(!openDetailDrawer);
}

return (
<>
{!openDetailDrawer && (
<>
<Drawer anchor="right" open onClose={onClose}>
<Box width={200} p={2}>
<Button onClick={() => toggleOpenDrawer()}>Open</Button>
</Box>
</Drawer>
</>
)}
{openDetailDrawer && (
<>
<Drawer anchor="right" open onClose={() => toggleOpenDrawer()}>
<Box width={600} p={2}>
<Button onClick={() => toggleOpenDrawer()}>Close</Button>
{children}
</Box>
</Drawer>
</>
)}
</>
);
}

// * the drawer is not opening in minimized mode? persistent drawer fix maybe - https://mui.com/material-ui/react-drawer/#persistent-drawer
29 changes: 29 additions & 0 deletions frontend/src/redux/drawerModeSlice.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>) => {
state.isDetailDrawerEnabled = action.payload;
localStorage.setItem('detailDrawerEnabled', `${action.payload}`);
},
setDetailDrawerOpen: (state, action: PayloadAction<boolean>) => {
state.isDetailDrawerOpen = action.payload;
localStorage.setItem('detailDrawerOpen', `${action.payload}`);
},
},
});

export const { setDetailDrawerEnabled, setDetailDrawerOpen } = drawerModeSlice.actions;
export default drawerModeSlice.reducer;
2 changes: 2 additions & 0 deletions frontend/src/redux/reducers/reducers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import pluginsReducer from '../../plugin/pluginsSlice';
import actionButtons from '../actionButtonsSlice';
import configReducer from '../configSlice';
import detailsViewSectionsSlice from '../detailsViewSectionsSlice';
import drawerModeSlice from '../drawerModeSlice';
import clusterAction from './clusterAction';
import filter from './filter';
import uiReducer from './ui';
Expand All @@ -16,6 +17,7 @@ const reducers = combineReducers({
plugins: pluginsReducer,
actionButtons: actionButtons,
detailsViewSections: detailsViewSectionsSlice,
drawerMode: drawerModeSlice,
});

export type RootState = ReturnType<typeof reducers>;
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/redux/reducers/ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export interface UIState {
};
tableColumnsProcessors: TableColumnsProcessor[];
};
drawerMode: {
isDetailDrawerEnabled: boolean;
isDetailDrawerOpen: boolean;
};
theme: {
name: string;
};
Expand Down Expand Up @@ -115,6 +119,10 @@ export const INITIAL_STATE: UIState = {
},
tableColumnsProcessors: [],
},
drawerMode: {
isDetailDrawerEnabled: false,
isDetailDrawerOpen: false,
},
theme: {
name: '',
},
Expand Down

0 comments on commit 3f7e7c1

Please sign in to comment.