From c3df513e8cb2e70c8d858d22310efffff50da04a Mon Sep 17 00:00:00 2001 From: Vincent T Date: Wed, 29 Nov 2023 14:56:21 -0500 Subject: [PATCH] frontend Detail Drawer: Add detail drawer mode Signed-off-by: Vincent T --- frontend/package.json | 2 +- frontend/src/components/App/Layout.tsx | 6 + .../App/Settings/DrawerModeButton.tsx | 59 +++++++++ .../src/components/App/Settings/Settings.tsx | 5 + .../__snapshots__/Settings.stories.storyshot | 46 +++++++ .../common/DetailDrawer/DetailDrawer.tsx | 121 ++++++++++++++++++ .../common/DetailDrawer/DetailDrawerFrame.tsx | 17 +++ frontend/src/components/common/Link.tsx | 33 ++++- .../ActionsNotifier.stories.storyshot | 10 +- frontend/src/components/pod/Details.tsx | 24 +++- frontend/src/components/pod/List.tsx | 71 ++++++++-- frontend/src/i18n/locales/de/translation.json | 1 + frontend/src/i18n/locales/en/translation.json | 1 + frontend/src/i18n/locales/es/translation.json | 1 + frontend/src/i18n/locales/fr/translation.json | 1 + frontend/src/i18n/locales/pt/translation.json | 1 + frontend/src/lib/router.tsx | 6 + frontend/src/redux/drawerModeSlice.ts | 35 +++++ frontend/src/redux/reducers/reducers.tsx | 2 + 19 files changed, 414 insertions(+), 28 deletions(-) create mode 100644 frontend/src/components/App/Settings/DrawerModeButton.tsx create mode 100644 frontend/src/components/common/DetailDrawer/DetailDrawer.tsx create mode 100644 frontend/src/components/common/DetailDrawer/DetailDrawerFrame.tsx create mode 100644 frontend/src/redux/drawerModeSlice.ts diff --git a/frontend/package.json b/frontend/package.json index 8a611927d72..08d58754801 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -103,7 +103,7 @@ "storybook": "start-storybook -p 6006 -s public", "build-typedoc": "npx typedoc", "build-storybook": "build-storybook -s public -o ../docs/development/storybook", - "i18n": "npx --no-install i18next ./src/**/ts* ./src/**/**/*.ts* ./src/**/**/**/*.ts* -c ./src/i18n/i18next-parser.config.js", + "i18n": "npx --no-install i18next ./src/**/*.ts* ./src/**/**/*.ts* ./src/**/**/**/*.ts* -c ./src/i18n/i18next-parser.config.js", "tsc": "tsc", "make-version": "node ./make-env.js", "postinstall": "patch-package" diff --git a/frontend/src/components/App/Layout.tsx b/frontend/src/components/App/Layout.tsx index 43dd210327b..94c4d6d0706 100644 --- a/frontend/src/components/App/Layout.tsx +++ b/frontend/src/components/App/Layout.tsx @@ -17,6 +17,7 @@ import { useTypedSelector } from '../../redux/reducers/reducers'; import store from '../../redux/stores/store'; import ActionsNotifier from '../common/ActionsNotifier'; import AlertNotification from '../common/AlertNotification'; +// import DetailDrawer from '../common/DetailDrawer/DetailDrawer'; import Sidebar, { NavigationTabs } from '../Sidebar'; import RouteSwitcher from './RouteSwitcher'; import TopBar from './TopBar'; @@ -93,6 +94,10 @@ export default function Layout({}: LayoutProps) { const { t } = useTranslation(); const clusterInURL = getCluster(); + // DETAIL DRAWER MODE + // const isDetailDrawerEnabled = useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled); + // console.log('LAY - isDetailDrawerEnabled', isDetailDrawerEnabled); + useEffect(() => { window.clusterConfigFetchHandler = setInterval( () => { @@ -197,6 +202,7 @@ export default function Layout({}: LayoutProps) { )} + {/* {isDetailDrawerEnabled && } */} diff --git a/frontend/src/components/App/Settings/DrawerModeButton.tsx b/frontend/src/components/App/Settings/DrawerModeButton.tsx new file mode 100644 index 00000000000..aa2a3104cae --- /dev/null +++ b/frontend/src/components/App/Settings/DrawerModeButton.tsx @@ -0,0 +1,59 @@ +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() { + const dispatch = useDispatch(); + const { t } = useTranslation('translation'); + // This will fix the problem of the project refreshing the state away from needed position + + // DETAIL DRAWER MODE + const isDetailDrawerEnabled = useTypedSelector(state => state.drawerMode.isDetailDrawerEnabled); + // const localDetailDrawerEnabled = localStorage.getItem('detailDrawerEnabled'); + const [isDrawerEnabled, changeDetailDrawerEnabled] = useState(isDetailDrawerEnabled); + + if (isDetailDrawerEnabled) { + console.log('THE LOCAL STORAGE IS TRUE'); + dispatch(setDetailDrawerEnabled(true)); + console.log('READING FROM DISPATCHED STATE', isDetailDrawerEnabled); + } else { + console.log(" THE LOCAL STORAGE IS NULL, UNDEFINED, OR 'FALSE' "); + dispatch(setDetailDrawerEnabled(false)); + console.log('READING FROM DISPATCHED STATE', isDetailDrawerEnabled); + } + + console.log('BUTTON - isDetailDrawerEnabled', isDetailDrawerEnabled); + + // the useEffect will run everytime the isDrawerEnabled state changes, which is everytime the user clicks the switch button because the switch button changes the state of isDrawerEnabled + useEffect(() => { + dispatch(setDetailDrawerEnabled(isDrawerEnabled)); + console.log('ON SETTINGS'); + console.log(localStorage.getItem('detailDrawerEnabled')); + }, [isDrawerEnabled]); + + // 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(!isDrawerEnabled); + } + + // NOTICE THAT WE DO NOT USE isDrawerEnabled 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 ( + + } + // will need to replace label + label={t('translation|Drawer Mode')} + /> + ); +} diff --git a/frontend/src/components/App/Settings/Settings.tsx b/frontend/src/components/App/Settings/Settings.tsx index 73b1bce3e48..f461e4c4faf 100644 --- a/frontend/src/components/App/Settings/Settings.tsx +++ b/frontend/src/components/App/Settings/Settings.tsx @@ -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'; @@ -69,6 +70,10 @@ export default function Settings() { name: t('translation|Theme'), value: , }, + { + name: t('translation|Details on list view'), + value: , + }, { name: t('translation|Number of rows for tables'), value: ( diff --git a/frontend/src/components/App/Settings/__snapshots__/Settings.stories.storyshot b/frontend/src/components/App/Settings/__snapshots__/Settings.stories.storyshot index 09b91fde7a7..52b65bbd660 100644 --- a/frontend/src/components/App/Settings/__snapshots__/Settings.stories.storyshot +++ b/frontend/src/components/App/Settings/__snapshots__/Settings.stories.storyshot @@ -158,6 +158,52 @@ exports[`Storyshots Settings General 1`] = ` +
+ Drawer Mode +
+
+ +
diff --git a/frontend/src/components/common/DetailDrawer/DetailDrawer.tsx b/frontend/src/components/common/DetailDrawer/DetailDrawer.tsx new file mode 100644 index 00000000000..dd57fb4a645 --- /dev/null +++ b/frontend/src/components/common/DetailDrawer/DetailDrawer.tsx @@ -0,0 +1,121 @@ +// PUT BACK LATER ♦ +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 { useLocation } from 'react-router-dom'; +// import { useParams } from 'react-router-dom'; +import { setDetailDrawerOpen } from '../../../redux/drawerModeSlice'; +import { useTypedSelector } from '../../../redux/reducers/reducers'; +// PUT BACK LATER ♦ +import DetailDrawerFrame from './DetailDrawerFrame'; + +export interface DetailDrawerProps { + // isOpen: boolean; + onClose?: () => void; + children?: React.ReactNode; +} + +// DELETE OR FIND A WAY TO USE CHILDREN LIKE IN CONSOLE LOG ♦ +// export default function DetailDrawer({ children }: DetailDrawerProps) { ♦ +export default function DetailDrawer({ children }: DetailDrawerProps) { + const dispatch = useDispatch(); + + // DELETE LATER - CONSOLE LOG ♦ + console.log(children); + + const isDetailDrawerOpen = useTypedSelector(state => state.drawerMode.isDetailDrawerOpen); + console.log('OFF SETTINGS isDetailDrawerOpen', isDetailDrawerOpen); + + // USE CHANGEOPENDETAILDRAWER OR JUST OPEN DETAIL DRAWER ♦ + const [openDetailDrawer, changeOpenDetailDrawer] = useState(isDetailDrawerOpen); + // const [openDetailDrawer] = useState(isDetailDrawerOpen); + console.log('openDetailDrawer', openDetailDrawer); + + useEffect(() => { + console.log('Toggle Open Drawer', openDetailDrawer); + dispatch(setDetailDrawerOpen(openDetailDrawer)); + }, [openDetailDrawer]); + + // * Trying to find a way to get the path and params to determine if it should be rendered within the iframe + const location = window.location.pathname; + const url = window.location.href; + + console.log('WINDOW', window.location); + + const pathDetails = ['/pods/']; + + useEffect(() => { + for (let i = 0; i < pathDetails.length; i++) { + if (location.includes(pathDetails[i])) { + console.log('URL PAIR MATCHED', pathDetails[i], location); + } + } + }, [window.location.href]); + + // * DOES NOT WORK, WILL PRINT '{}' WHEN CONSOLE LOG params + // const location = useLocation(); + // const params = useParams(); + + useEffect(() => { + console.log('location changed'); + console.log('LOCATION', location); + + // console.log('PARAMS', params); + }, [location]); + + function toggleOpenDrawer() { + changeOpenDetailDrawer(!openDetailDrawer); + } + + return ( + <> + {/* {!openDetailDrawer && ( + <> + + + Open Drawer + + + + )} */} + + {openDetailDrawer && ( + <> + + + + + {children} + + + + )} + + {!openDetailDrawer && ( + <> + + + {children} + + + )} + + ); +} + +// * 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/components/common/DetailDrawer/DetailDrawerFrame.tsx b/frontend/src/components/common/DetailDrawer/DetailDrawerFrame.tsx new file mode 100644 index 00000000000..cd02d1f1398 --- /dev/null +++ b/frontend/src/components/common/DetailDrawer/DetailDrawerFrame.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import PodDetails from '../../pod/Details'; + +export interface DetailDrawerFrameProps { + title?: string; + source?: string; +} + +export default function DetailDrawerFrame({ title }: DetailDrawerFrameProps) { + return ( + <> +

{title}

+ {/* */} + + + ); +} diff --git a/frontend/src/components/common/Link.tsx b/frontend/src/components/common/Link.tsx index ecbe7248e62..d3719b6c4b3 100644 --- a/frontend/src/components/common/Link.tsx +++ b/frontend/src/components/common/Link.tsx @@ -1,6 +1,6 @@ import MuiLink from '@mui/material/Link'; import React from 'react'; -import { Link as RouterLink } from 'react-router-dom'; +import { Link as RouterLink, useHistory } from 'react-router-dom'; import { makeKubeObject } from '../../lib/k8s/cluster'; import { createRouteURL, RouteURLProps } from '../../lib/router'; import { LightTooltip } from './Tooltip'; @@ -21,6 +21,7 @@ export interface LinkProps extends LinkBaseProps { state?: { [prop: string]: any; }; + drawerEnabled?: boolean; } export interface LinkObjectProps extends LinkBaseProps { @@ -30,11 +31,33 @@ export interface LinkObjectProps extends LinkBaseProps { function PureLink(props: React.PropsWithChildren) { if ((props as LinkObjectProps).kubeObject) { - const { kubeObject, ...otherProps } = props as LinkObjectProps; + const { kubeObject, drawerEnabled, ...otherProps } = props as LinkObjectProps; + + const history = useHistory(); + return ( - - {props.children || kubeObject.getName()} - + <> + {drawerEnabled === true ? ( + { + event.preventDefault(); + alert('Drawer'); + history.push(kubeObject.getDetailsLink() + '/drawer'); + alert('woof'); + }} + // onClick={() => history.push(kubeObject.getDetailsLink() + '/drawer')} + > + {props.children || kubeObject.getName()} + + ) : ( + + {props.children || kubeObject.getName()} + + )} + ); } diff --git a/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot b/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot index e8cc3287b01..135224ef764 100644 --- a/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot +++ b/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot @@ -5,7 +5,7 @@ exports[`Storyshots ActionsNotifier None 1`] = `
`; exports[`Storyshots ActionsNotifier Some 1`] = `