diff --git a/ui/apps/everest/src/App.tsx b/ui/apps/everest/src/App.tsx index 5d85ed797..e813c64f6 100644 --- a/ui/apps/everest/src/App.tsx +++ b/ui/apps/everest/src/App.tsx @@ -13,6 +13,7 @@ import { useEffect, useState } from 'react'; import { EverestConfig } from 'shared-types/configs.types'; import { getEverestConfigs } from 'api/everestConfigs'; import LoadingPageSkeleton from 'components/loading-page-skeleton/LoadingPageSkeleton'; +import UpgradeEverestProvider from 'contexts/upgrade-everest/upgrade-everest.provider'; const queryClient = new QueryClient({ defaultOptions: { @@ -80,7 +81,9 @@ const App = () => { }} > - + + + diff --git a/ui/apps/everest/src/components/app-bar/help-icon/HelpIcon.tsx b/ui/apps/everest/src/components/app-bar/help-icon/HelpIcon.tsx index 04eb4cd0e..e495ccaf4 100644 --- a/ui/apps/everest/src/components/app-bar/help-icon/HelpIcon.tsx +++ b/ui/apps/everest/src/components/app-bar/help-icon/HelpIcon.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useContext, useState } from 'react'; import { Divider, IconButton, @@ -8,11 +8,11 @@ import { Typography, } from '@mui/material'; import HelpIcon from '@mui/icons-material/Help'; -import { useVersion } from 'hooks/api/version/useVersion'; +import { UpgradeEverestContext } from 'contexts/upgrade-everest'; const AppBarHelpIcon = () => { const [anchorEl, setAnchorEl] = useState(null); - const { data: versionData } = useVersion(); + const { currentVersion } = useContext(UpgradeEverestContext); const handleMenu = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); @@ -44,7 +44,7 @@ const AppBarHelpIcon = () => { > - {`Everest ${versionData?.version}`} + {`Everest ${currentVersion}`} diff --git a/ui/apps/everest/src/components/know-more-button/index.ts b/ui/apps/everest/src/components/know-more-button/index.ts new file mode 100644 index 000000000..fae9aa147 --- /dev/null +++ b/ui/apps/everest/src/components/know-more-button/index.ts @@ -0,0 +1 @@ +export { default } from './know-more-button'; diff --git a/ui/apps/everest/src/components/know-more-button/know-more-button.tsx b/ui/apps/everest/src/components/know-more-button/know-more-button.tsx new file mode 100644 index 000000000..7c15770a7 --- /dev/null +++ b/ui/apps/everest/src/components/know-more-button/know-more-button.tsx @@ -0,0 +1,26 @@ +import { Box, Button } from '@mui/material'; +import NorthEastIcon from '@mui/icons-material/NorthEast'; + +interface KnowMoreButtonProps { + href: string; +} +const KnowMoreButton = ({ href }: KnowMoreButtonProps) => { + return ( + + + + ); +}; + +export default KnowMoreButton; diff --git a/ui/apps/everest/src/components/main/Main.tsx b/ui/apps/everest/src/components/main/Main.tsx index 31688849f..8fd8c9688 100644 --- a/ui/apps/everest/src/components/main/Main.tsx +++ b/ui/apps/everest/src/components/main/Main.tsx @@ -20,6 +20,8 @@ import { Drawer } from '../drawer/Drawer'; import { WelcomeDialog } from '../welcome-dialog/welcome-dialog'; import { Messages } from './Main.messages'; import LoadingPageSkeleton from 'components/loading-page-skeleton/LoadingPageSkeleton'; +import UpgradeEverestReloadDialog from 'modals/upgrade-reload-everest-dialog'; +import { UpgradeEverestContext } from 'contexts/upgrade-everest'; export const Main = () => { const theme = useTheme(); @@ -28,6 +30,9 @@ export const Main = () => { true ); const { activeBreakpoint } = useContext(DrawerContext); + const { apiVersion, openReloadDialog, setOpenReloadDialog } = useContext( + UpgradeEverestContext + ); const { isFetching, isError, refetch } = useKubernetesClusterInfo([ 'initial-k8-info', ]); @@ -86,6 +91,11 @@ export const Main = () => { closeDialog={handleCloseWelcomeDialog} /> )} + setOpenReloadDialog(false)} + version={apiVersion || ''} + /> diff --git a/ui/apps/everest/src/contexts/upgrade-everest/index.ts b/ui/apps/everest/src/contexts/upgrade-everest/index.ts new file mode 100644 index 000000000..ad659e7bc --- /dev/null +++ b/ui/apps/everest/src/contexts/upgrade-everest/index.ts @@ -0,0 +1,2 @@ +export { default as UpgradeEverestContext } from './upgrade-everest.context'; +export { default as UpgradeEverestProvider } from './upgrade-everest.provider'; diff --git a/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.tsx b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.tsx new file mode 100644 index 000000000..1c7055bf9 --- /dev/null +++ b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.tsx @@ -0,0 +1,12 @@ +import { createContext } from 'react'; +import { UpgradeEverestContextProps } from './upgrade-everest.context.types'; + +const UpgradeEverestContext = createContext({ + openReloadDialog: false, + toggleOpenReloadDialog: () => {}, + setOpenReloadDialog: () => {}, + currentVersion: null, + apiVersion: '', +}); + +export default UpgradeEverestContext; diff --git a/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.types.ts b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.types.ts new file mode 100644 index 000000000..17211a246 --- /dev/null +++ b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.context.types.ts @@ -0,0 +1,9 @@ +import { Dispatch, SetStateAction } from 'react'; + +export interface UpgradeEverestContextProps { + openReloadDialog: boolean; + toggleOpenReloadDialog: () => void; + setOpenReloadDialog: Dispatch>; + currentVersion: null | string; + apiVersion?: string; +} diff --git a/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.provider.tsx b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.provider.tsx new file mode 100644 index 000000000..51309f389 --- /dev/null +++ b/ui/apps/everest/src/contexts/upgrade-everest/upgrade-everest.provider.tsx @@ -0,0 +1,47 @@ +import { useEffect, useRef, useState } from 'react'; +import UpgradeEverestContext from './upgrade-everest.context'; +import { useVersion } from 'hooks'; + +const UpgradeEverestProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + const commitVersion = useRef(null); + const { data: apiVersion } = useVersion(); + const [currentVersion, setCurrentVersion] = useState(''); + + const [openReloadEverestDialog, setOpenReloadEverestDialog] = useState(false); + + useEffect(() => { + if (commitVersion.current === null && apiVersion?.fullCommit) { + commitVersion.current = apiVersion?.fullCommit; + setCurrentVersion(apiVersion?.version); + } + if ( + commitVersion.current !== null && + commitVersion.current !== apiVersion?.fullCommit + ) { + setOpenReloadEverestDialog(true); + } + }, [apiVersion?.fullCommit]); + + const toggleOpenReloadDialog = () => + setOpenReloadEverestDialog((val) => !val); + + return ( + + {children} + + ); +}; + +export default UpgradeEverestProvider; diff --git a/ui/apps/everest/src/hooks/api/version/useVersion.ts b/ui/apps/everest/src/hooks/api/version/useVersion.ts index 07960dc27..c1bb6259e 100644 --- a/ui/apps/everest/src/hooks/api/version/useVersion.ts +++ b/ui/apps/everest/src/hooks/api/version/useVersion.ts @@ -7,5 +7,6 @@ export const useVersion = (options?: PerconaQueryOptions) => useQuery({ queryKey: ['everest-version'], queryFn: getVersionFn, + refetchInterval: 5000, ...options, }); diff --git a/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/index.ts b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/index.ts new file mode 100644 index 000000000..29ac1b59d --- /dev/null +++ b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/index.ts @@ -0,0 +1 @@ +export { default } from './upgrade-reload-everest-dialog'; diff --git a/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.messages.ts b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.messages.ts new file mode 100644 index 000000000..49bd39b58 --- /dev/null +++ b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.messages.ts @@ -0,0 +1,8 @@ +export const Messages = { + headerMessage: 'Reload Percona Everest', + successfullyUpgraded: (version: string) => + `Percona Everest has been successfully upgraded to ${version}.`, + clickToReload: + 'Click the reload button to discover and start using all the new features.', + cancelMessage: 'Reload', +}; diff --git a/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.tsx b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.tsx new file mode 100644 index 000000000..78c5120fb --- /dev/null +++ b/ui/apps/everest/src/modals/upgrade-reload-everest-dialog/upgrade-reload-everest-dialog.tsx @@ -0,0 +1,52 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + Typography, +} from '@mui/material'; +import { DialogTitle } from '@percona/ui-lib'; +import { Messages } from './upgrade-reload-everest-dialog.messages'; +import KnowMoreButton from 'components/know-more-button/know-more-button'; + +interface UpgradeEverestReloadDialogProps { + isOpen: boolean; + closeModal: () => void; + version: string; +} +const UpgradeEverestReloadDialog = ({ + isOpen, + closeModal, + version, +}: UpgradeEverestReloadDialogProps) => { + return ( + + {Messages.headerMessage} + + + {Messages.successfullyUpgraded(version)} + + + {Messages.clickToReload} + + + + + + ); +}; + +export default UpgradeEverestReloadDialog;