Merge pull request #135 from meienberger/feature/update-alert

Display update available in SideMenu
This commit is contained in:
Nicolas Meienberger 2022-07-25 16:57:07 +00:00 committed by GitHub
commit bca8c08e5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 37 deletions

View file

@ -6,6 +6,7 @@ import { FiChevronRight } from 'react-icons/fi';
import Header from './Header';
import Menu from './SideMenu';
import MenuDrawer from './MenuDrawer';
// import UpdateBanner from './UpdateBanner';
interface IProps {
loading?: boolean;
@ -15,6 +16,7 @@ interface IProps {
const Layout: React.FC<IProps> = ({ children, loading, breadcrumbs }) => {
const { isOpen, onClose, onOpen } = useDisclosure();
const menubg = useColorModeValue('#F1F3F4', '#202736');
const bg = useColorModeValue('white', '#1a202c');
@ -49,7 +51,6 @@ const Layout: React.FC<IProps> = ({ children, loading, breadcrumbs }) => {
<Head>
<title>Tipi</title>
</Head>
<Flex height="100vh" direction="column">
<MenuDrawer isOpen={isOpen} onClose={onClose}>
<Menu />
@ -60,6 +61,7 @@ const Layout: React.FC<IProps> = ({ children, loading, breadcrumbs }) => {
<Menu />
</Flex>
<Box bg={bg} className="flex-1 px-4 py-4 md:px-10 md:py-8">
{/* <UpdateBanner /> */}
{renderBreadcrumbs()}
{renderContent()}
</Box>

View file

@ -2,20 +2,23 @@ import { AiOutlineDashboard, AiOutlineSetting, AiOutlineAppstore } from 'react-i
import { FaAppStore, FaRegMoon } from 'react-icons/fa';
import { FiLogOut } from 'react-icons/fi';
import Package from '../../../package.json';
import { Box, Divider, Flex, List, ListItem, Switch, useColorMode } from '@chakra-ui/react';
import { Badge, Box, Divider, Flex, List, ListItem, Switch, useColorMode } from '@chakra-ui/react';
import React from 'react';
import Link from 'next/link';
import clsx from 'clsx';
import { useRouter } from 'next/router';
import { IconType } from 'react-icons';
import { useLogoutMutation } from '../../generated/graphql';
import { useLogoutMutation, useVersionQuery } from '../../generated/graphql';
const SideMenu: React.FC = () => {
const router = useRouter();
const { colorMode, setColorMode } = useColorMode();
const [logout] = useLogoutMutation({ refetchQueries: ['Me'] });
const versionQuery = useVersionQuery();
const path = router.pathname.split('/')[1];
const isLatest = versionQuery.data?.version.latest === versionQuery.data?.version.current;
const renderMenuItem = (title: string, name: string, Icon: IconType) => {
const selected = path === name;
@ -65,6 +68,11 @@ const SideMenu: React.FC = () => {
</div>
</List>
<div className="pb-1 text-center text-sm text-gray-400 mt-5">Tipi version {Package.version}</div>
{!isLatest && (
<Badge className="self-center mt-1" colorScheme="green">
New version available
</Badge>
)}
</Box>
);
};

View file

@ -0,0 +1,38 @@
import { Alert, AlertDescription, AlertIcon, AlertTitle, Box, CloseButton } from '@chakra-ui/react';
import React from 'react';
import { useVersionQuery } from '../../generated/graphql';
const UpdateBanner = () => {
const { data, loading } = useVersionQuery();
const isLatest = data?.version.latest === data?.version.current;
if (isLatest || (loading && !data?.version)) {
return null;
}
console.log(data);
const onClose = () => {};
return (
<div>
<Alert status="info" className="flex mb-3">
<AlertIcon />
<Box className="flex-1">
<AlertTitle>New version available!</AlertTitle>
<AlertDescription>
There is a new version of Tipi available ({data?.version.latest}). Visit{' '}
<a className="text-blue-600" target="_blank" rel="noreferrer" href={'https://github.com/meienberger/runtipi/releases/latest'}>
Github
</a>{' '}
for update instructions.
</AlertDescription>
</Box>
<CloseButton alignSelf="flex-start" position="relative" right={-1} top={-1} onClick={onClose} />
</Alert>
</div>
);
};
export default UpdateBanner;

View file

@ -1,45 +1,11 @@
import create from 'zustand';
import api from '../core/api';
type Store = {
cpuLoad: number;
internalIp: string;
disk: { total: number; used: number; available: number };
memory: { total: number; used: number; available: number };
fetchDiskSpace: () => void;
fetchCpuLoad: () => void;
fetchMemoryLoad: () => void;
setInternalIp: (internalIp: string) => void;
};
export const useSytemStore = create<Store>((set) => ({
cpuLoad: 0,
internalIp: '',
setInternalIp: (internalIp: string) => set((state) => ({ ...state, internalIp })),
memory: { total: 0, used: 0, available: 0 },
disk: { total: 0, used: 0, available: 0 },
fetchDiskSpace: async () => {
const response = await api.fetch<any>({
endpoint: '/system/disk',
method: 'get',
});
set({ disk: response });
},
fetchCpuLoad: async () => {
const response = await api.fetch<any>({
endpoint: '/system/cpu',
method: 'get',
});
set({ cpuLoad: response.load });
},
fetchMemoryLoad: async () => {
const response = await api.fetch<any>({
endpoint: '/system/memory',
method: 'get',
});
set({ memory: response });
},
}));