Skip to content

Commit

Permalink
PMM-12930 Add footer
Browse files Browse the repository at this point in the history
  • Loading branch information
matejkubinec committed Jul 30, 2024
1 parent 1a0c169 commit 0ce8c1f
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 20 deletions.
5 changes: 4 additions & 1 deletion ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SnackbarProvider } from 'notistack';
import pmmThemeOptions from 'themes/PmmTheme';
import { AuthProvider } from 'contexts/auth';
import { UserProvider } from 'contexts/user/user.provider';
import { UpdatesProvider } from 'contexts/updates';

const queryClient = new QueryClient({
defaultOptions: {
Expand Down Expand Up @@ -39,7 +40,9 @@ const App = () => (
<QueryClientProvider client={queryClient}>
<AuthProvider>
<UserProvider>
<RouterProvider router={router} />
<UpdatesProvider>
<RouterProvider router={router} />
</UpdatesProvider>
</UserProvider>
</AuthProvider>
</QueryClientProvider>
Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/page/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useUser } from 'contexts/user/user.hooks';
import { Messages } from './Page.messages';
import { PMM_HOME_URL } from 'constants';

export const Page: FC<PageProps> = ({ title, children }) => {
export const Page: FC<PageProps> = ({ title, footer, children }) => {
const { user } = useUser();

return (
Expand Down Expand Up @@ -45,6 +45,7 @@ export const Page: FC<PageProps> = ({ title, children }) => {
</CardActions>
</Card>
)}
{footer && <Stack>{footer}</Stack>}
</Stack>
);
};
3 changes: 2 additions & 1 deletion ui/src/components/page/Page.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PropsWithChildren } from 'react';
import { PropsWithChildren, ReactNode } from 'react';

export interface PageProps extends PropsWithChildren {
title?: string;
footer?: ReactNode;
}
4 changes: 4 additions & 0 deletions ui/src/contexts/updates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './updates.context';
export * from './updates.provider';
export * from './updates.context';
export * from './updates.hooks';
11 changes: 11 additions & 0 deletions ui/src/contexts/updates/updates.context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createContext } from 'react';
import { UpdatesContextProps } from './updates.context.types';
import { UpdateStatus } from 'types/updates.types';

export const UpdatesContext = createContext<UpdatesContextProps>({
isLoading: false,
inProgress: false,
status: UpdateStatus.Pending,
setStatus: () => {},
recheck: () => {},
});
10 changes: 10 additions & 0 deletions ui/src/contexts/updates/updates.context.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GetUpdatesResponse, UpdateStatus } from 'types/updates.types';

export interface UpdatesContextProps {
isLoading: boolean;
inProgress: boolean;
status: UpdateStatus;
setStatus: (status: UpdateStatus) => void;
versionInfo?: GetUpdatesResponse;
recheck: () => void;
}
4 changes: 4 additions & 0 deletions ui/src/contexts/updates/updates.hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { useContext } from 'react';
import { UpdatesContext } from './updates.context';

export const useUpdates = () => useContext(UpdatesContext);
41 changes: 41 additions & 0 deletions ui/src/contexts/updates/updates.provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FC, PropsWithChildren, useEffect, useMemo, useState } from 'react';
import { UpdatesContext } from './updates.context';
import { UpdateStatus } from 'types/updates.types';
import { useCheckUpdates } from 'hooks/api/useUpdates';

export const UpdatesProvider: FC<PropsWithChildren> = ({ children }) => {
const [status, setStatus] = useState(UpdateStatus.Pending);
const { isLoading, data, error, isRefetching, refetch } = useCheckUpdates();
const inProgress = useMemo(
() =>
status === UpdateStatus.Updating ||
status === UpdateStatus.Restarting ||
status === UpdateStatus.Completed,
[status]
);

useEffect(() => {
if (error) {
setStatus(UpdateStatus.Error);
} else if (isLoading) {
setStatus(UpdateStatus.Checking);
} else if (data && data?.installed.version === data?.latest?.version) {
setStatus(UpdateStatus.UpToDate);
}
}, [data, error, isLoading]);

return (
<UpdatesContext.Provider
value={{
isLoading: isLoading || isRefetching,
inProgress,
status,
setStatus,
versionInfo: data,
recheck: refetch,
}}
>
{children}
</UpdatesContext.Provider>
);
};
3 changes: 2 additions & 1 deletion ui/src/pages/updates/Updates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import { Messages } from './Updates.messages';
import { Page } from 'components/page';
import { useSettings } from 'hooks/api/useSettings';
import { PMM_SETTINGS_URL } from 'constants';
import { UpdateFooter } from './update-footer';

export const Updates: FC = () => {
const { data: settings } = useSettings();

return (
<Page title={Messages.title}>
<Page title={Messages.title} footer={<UpdateFooter />}>
<Card>
<CardMedia sx={{ height: 140 }} image={Welcome} title="green iguana" />
<CardContent sx={{ p: 3 }}>
Expand Down
20 changes: 5 additions & 15 deletions ui/src/pages/updates/update-card/UpdateCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Skeleton,
Alert,
} from '@mui/material';
import { FC, useMemo, useState } from 'react';
import { FC } from 'react';
import { formatTimestamp } from 'utils/formatTimestamp';
import { PMM_HOME_URL } from 'constants';
import { Messages } from './UpdateCard.messages';
Expand All @@ -22,23 +22,13 @@ import { UpdateStatus } from 'types/updates.types';
import { KeyboardDoubleArrowUp } from '@mui/icons-material';
import { UpdateInfo } from '../update-info';
import { UpdateInProgressCard } from '../update-in-progress-card';
import { useUpdates } from 'contexts/updates';

export const UpdateCard: FC = () => {
const { inProgress, status, setStatus } = useUpdates();
const { isLoading, data, error, isRefetching, refetch } = useCheckUpdates();
const { mutate: startUpdate } = useStartUpdate();
const { waitForReadiness } = useWaitForReadiness();
const [status, setStatus] = useState<UpdateStatus>(UpdateStatus.Pending);
const isUpToDate = useMemo(
() => data?.installed.version === data?.latest?.version,
[data]
);
const updateInProgress = useMemo(
() =>
status === UpdateStatus.Updating ||
status === UpdateStatus.Restarting ||
status === UpdateStatus.Completed,
[status]
);

const handleStartUpdate = async () => {
setStatus(UpdateStatus.Updating);
Expand Down Expand Up @@ -84,14 +74,14 @@ export const UpdateCard: FC = () => {
);
}

if (updateInProgress && data.latest) {
if (inProgress && data.latest) {
return <UpdateInProgressCard versionInfo={data.latest} status={status} />;
}

return (
<Card sx={{ p: 1 }}>
<CardContent>
{isUpToDate && (
{status === UpdateStatus.UpToDate && (
<Alert
severity="success"
sx={{
Expand Down
6 changes: 6 additions & 0 deletions ui/src/pages/updates/update-footer/UpdateFooter.messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const Messages = {
version: (version: string) => `PMM ${version}`,
inProgress: 'Update in progress...',
checkedOn: (date: string) => `Checked on: ${date}`,
checkNow: 'Check updates now',
};
30 changes: 30 additions & 0 deletions ui/src/pages/updates/update-footer/UpdateFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Link, Stack, Typography } from '@mui/material';
import { useUpdates } from 'contexts/updates';
import { FC } from 'react';
import { formatCheckDate } from './UpdateFooter.utils';
import { Messages } from './UpdateFooter.messages';

export const UpdateFooter: FC = () => {
const { inProgress, versionInfo, recheck } = useUpdates();

console.log({ versionInfo });
if (!versionInfo) return null;

return (
<Stack direction="row" gap={2}>
<Typography variant="body2">
{Messages.version(versionInfo.installed.version)}
</Typography>
<Typography variant="body2" color="text.disabled">
{inProgress
? Messages.inProgress
: Messages.checkedOn(formatCheckDate(versionInfo.lastCheck))}
</Typography>
{!inProgress && (
<Typography variant="body2">
<Link onClick={recheck}>{Messages.checkNow}</Link>
</Typography>
)}
</Stack>
);
};
2 changes: 2 additions & 0 deletions ui/src/pages/updates/update-footer/UpdateFooter.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const formatCheckDate = (date: string) =>
new Date(date).toLocaleDateString('en-US');
1 change: 1 addition & 0 deletions ui/src/pages/updates/update-footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './UpdateFooter';
4 changes: 3 additions & 1 deletion ui/src/types/updates.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface GetUpdatesParams {

export interface CurrentInfo {
version: string;
full_version: string;
fullVersion: string;
timestamp: string | null;
}

Expand Down Expand Up @@ -49,4 +49,6 @@ export enum UpdateStatus {
Restarting = 'restarting',
Completed = 'completed',
Error = 'error',
Checking = 'checking',
UpToDate = 'up-to-date',
}

0 comments on commit 0ce8c1f

Please sign in to comment.