From 8fe0d76a341cc839c38d435f7b367406f2aa79cd Mon Sep 17 00:00:00 2001 From: Matej Kubinec <32638572+matejkubinec@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:20:08 +0200 Subject: [PATCH] PMM-12930 Update status, log & clients (#3039) * PMM-11231 Setup PMM UI * PMM-11231 Update working directory for node setup * PMM-11231 Adjust setup node step * PMM-11231 Add build & cleanup makefile * PMM-11231 Use correct UI directory * PMM-11231 Adjust pmm-ui build directory * PMM-11231 Add install commands * PMM-11231 Add pmm ui directory to files section * PMM-11231 Copy correct build files * PMM-11231 Handle token rotation * PMM-11231 Simplify spec file * PMM-11231 Update dependencies * PMM-11231 Allow use of eslints non flat config * PMM-11231 Align version fetch logic with previous * PMM-11231 Refactor fetching icon * PMM-11231 Update compose file * PMM-11231 Use /pmm-ui as path * PMM-11231 Allow specifying pmm server image through env variable * PMM-12930 Show update status * PMM-11231 Switch to tanstack query * PMM-12930 Fix lint * PMM-11231 Update dev configuration * PMM-11231 Use correct naming & switch to hooks * PMM-11231 Use different name for update image * PMM-12930 Improve update process * PMM-11231 Disable auth_request for pmm-ui * PMM-11231 Rework redirect to login * PMM-11231 Update api response * PMM-11231 Add link to support * PMM-11231 Fix support url redirect * PMM-11231 Fix lint * PMM-11231 Fix typings * PMM-12930 Fix version typings * PMM-11231 Add admin & auth check * PMM-12930 Make page component responsive * PMM-12930 Add Page unit tests * PMM-12930 Make page component responsive * PMM-12930 Add Page unit tests * PMM-11231 Update api endpoints * PMM-12930 Add upgrade docs link * PMM-12930 Update types & readyz url * PMM-12930 Remove temporary error handling * PMM-12930 Add footer * PMM-12930 Refactor footer * PMM-12930 Refactor user context imports * PMM-12930 Add doc comnent * PMM-12930 Update progress bar color * PMM-12930 Update progress bar * PMM-12930 Bump packages * PMM-12930 Fix updates check * PMM-12934 Add page for client updates * PMM-12934 Extend page & remove mocks * PMM-12934 Update table loading * PMM-12934 Use custom filter component * PMM-12933 Add update log modal * PMM-12934 Add next button * PMM-12930 Add unit tests * PMM-12930 Downgrade eslint version * PMM-12934 Add check for pending client update * PMM-12934 Adjust styling * PMM-12930 Fix before CR * PMM-12930 Remove empty file * PMM-12930 Simplify initial auth check * PMM-12930 Make appbar sticky * PMM-12930 Fix font loading * PMM-12930 Adjust section spacing * PMM-12930 Bump axios version * PMM-7 fix proto validation error * PMM-12930 Use table from ui-lib * PMM-12930 Update dev nginx file * PMM-12930 Use shortened links * PMM-12930 Add pmm home button, rework dialog & add test * PMM-12930 Improve clients update check * PMM-12930 Highligh only Release Notes --- ui/package.json | 25 +- ui/pmm-dev.conf | 3 + ui/src/App.tsx | 7 +- ui/src/api/__mocks__/agents.ts | 10 + ui/src/api/agents.ts | 9 + ui/src/api/ready.ts | 6 + ui/src/api/updates.ts | 11 +- ui/src/components/app-bar/AppBar.tsx | 16 +- ui/src/components/breadcrumbs/Breadcrumbs.tsx | 6 +- ui/src/components/footer/Footer.messages.ts | 5 + ui/src/components/footer/Footer.test.tsx | 32 + ui/src/components/footer/Footer.tsx | 24 + ui/src/components/footer/Footer.utils.ts | 7 + ui/src/components/footer/index.ts | 1 + ui/src/components/home-link/HomeLink.test.tsx | 66 + ui/src/components/home-link/HomeLink.tsx | 39 + .../clients-modal/ClientsModal.messages.ts | 9 + .../clients-modal/ClientsModal.test.tsx | 36 + .../home-link/clients-modal/ClientsModal.tsx | 60 + .../clients-modal/ClientsModal.types.ts | 4 + .../home-link/clients-modal/index.ts | 1 + ui/src/components/home-link/index.ts | 1 + ui/src/components/main/Main.test.tsx | 2 +- ui/src/components/modal/Modal.test.tsx | 35 + ui/src/components/modal/Modal.tsx | 70 + ui/src/components/modal/Modal.types.ts | 6 + ui/src/components/modal/index.ts | 1 + ui/src/components/page/Page.test.tsx | 2 +- ui/src/components/page/Page.tsx | 9 +- ui/src/components/page/Page.types.ts | 3 +- .../text-select/TextSelect.messages.ts | 4 + .../text-select/TextSelect.test.tsx | 93 + ui/src/components/text-select/TextSelect.tsx | 83 + .../text-select/TextSelect.types.ts | 11 + ui/src/components/text-select/index.ts | 1 + ui/src/constants.ts | 5 +- ui/src/contexts/auth/auth.provider.tsx | 9 +- ui/src/contexts/auth/index.ts | 1 + ui/src/contexts/updates/index.ts | 5 + ui/src/contexts/updates/updates.context.tsx | 12 + .../contexts/updates/updates.context.types.ts | 13 + ui/src/contexts/updates/updates.hooks.ts | 4 + ui/src/contexts/updates/updates.provider.tsx | 51 + ui/src/contexts/updates/updates.utils.ts | 12 + ui/src/contexts/user/index.ts | 4 + ui/src/hooks/api/useAgents.ts | 8 + ui/src/hooks/api/useReadiness.ts | 19 + ui/src/hooks/api/useUpdates.tsx | 34 +- ui/src/hooks/utils/useBootstrap.ts | 2 +- .../update-clients/UpdateClients.constants.ts | 18 + .../update-clients/UpdateClients.messages.ts | 37 + .../update-clients/UpdateClients.test.tsx | 139 ++ ui/src/pages/update-clients/UpdateClients.tsx | 162 ++ .../update-clients/UpdateClients.types.ts | 5 + .../update-clients/UpdateClients.utils.ts | 17 + .../severity-chip/SeverityChip.tsx | 46 + .../severity-chip/SeverityChip.types.ts | 5 + .../update-clients/severity-chip/index.ts | 1 + ui/src/pages/updates/Updates.tsx | 8 + .../update-card/UpdateCard.messages.ts | 5 + .../pages/updates/update-card/UpdateCard.tsx | 111 +- .../updates/update-card/UpdateCard.utils.ts | 2 +- .../UpdateInProgressCard.messages.ts | 6 + .../UpdateInProgressCard.tsx | 65 + .../UpdateInProgressCard.types.tsx | 7 + .../updates/update-in-progress-card/index.ts | 1 + .../UpdateProgress.messages.ts | 5 + .../update-progress/UpdateProgress.tsx | 78 + .../update-progress/UpdateProgress.types.ts | 5 + .../update-info/UpdateInfo.messages.ts | 9 + .../pages/updates/update-info/UpdateInfo.tsx | 34 + ui/src/pages/updates/update-info/index.ts | 1 + .../updates/update-log/UpdateLog.hooks.ts | 34 + .../updates/update-log/UpdateLog.messages.ts | 5 + ui/src/pages/updates/update-log/UpdateLog.tsx | 47 + .../updates/update-log/UpdateLog.types.ts | 3 + ui/src/pages/updates/update-log/index.ts | 1 + .../update-log-content/UpdateLogContent.tsx | 26 + .../UpdateLogContent.types.ts | 3 + .../update-log/update-log-content/index.ts | 1 + ui/src/router.tsx | 5 + ui/src/themes/PmmTheme.tsx | 51 +- ui/src/types/agent.types.ts | 18 + ui/src/types/api.types.ts | 5 + ui/src/types/updates.types.ts | 33 +- ui/src/utils/testUtils.tsx | 54 + ui/src/utils/testWrapper.tsx | 24 +- ui/yarn.lock | 1546 +++++++---------- 88 files changed, 2534 insertions(+), 966 deletions(-) create mode 100644 ui/src/api/__mocks__/agents.ts create mode 100644 ui/src/api/agents.ts create mode 100644 ui/src/api/ready.ts create mode 100644 ui/src/components/footer/Footer.messages.ts create mode 100644 ui/src/components/footer/Footer.test.tsx create mode 100644 ui/src/components/footer/Footer.tsx create mode 100644 ui/src/components/footer/Footer.utils.ts create mode 100644 ui/src/components/footer/index.ts create mode 100644 ui/src/components/home-link/HomeLink.test.tsx create mode 100644 ui/src/components/home-link/HomeLink.tsx create mode 100644 ui/src/components/home-link/clients-modal/ClientsModal.messages.ts create mode 100644 ui/src/components/home-link/clients-modal/ClientsModal.test.tsx create mode 100644 ui/src/components/home-link/clients-modal/ClientsModal.tsx create mode 100644 ui/src/components/home-link/clients-modal/ClientsModal.types.ts create mode 100644 ui/src/components/home-link/clients-modal/index.ts create mode 100644 ui/src/components/home-link/index.ts create mode 100644 ui/src/components/modal/Modal.test.tsx create mode 100644 ui/src/components/modal/Modal.tsx create mode 100644 ui/src/components/modal/Modal.types.ts create mode 100644 ui/src/components/modal/index.ts create mode 100644 ui/src/components/text-select/TextSelect.messages.ts create mode 100644 ui/src/components/text-select/TextSelect.test.tsx create mode 100644 ui/src/components/text-select/TextSelect.tsx create mode 100644 ui/src/components/text-select/TextSelect.types.ts create mode 100644 ui/src/components/text-select/index.ts create mode 100644 ui/src/contexts/updates/index.ts create mode 100644 ui/src/contexts/updates/updates.context.tsx create mode 100644 ui/src/contexts/updates/updates.context.types.ts create mode 100644 ui/src/contexts/updates/updates.hooks.ts create mode 100644 ui/src/contexts/updates/updates.provider.tsx create mode 100644 ui/src/contexts/updates/updates.utils.ts create mode 100644 ui/src/contexts/user/index.ts create mode 100644 ui/src/hooks/api/useAgents.ts create mode 100644 ui/src/hooks/api/useReadiness.ts create mode 100644 ui/src/pages/update-clients/UpdateClients.constants.ts create mode 100644 ui/src/pages/update-clients/UpdateClients.messages.ts create mode 100644 ui/src/pages/update-clients/UpdateClients.test.tsx create mode 100644 ui/src/pages/update-clients/UpdateClients.tsx create mode 100644 ui/src/pages/update-clients/UpdateClients.types.ts create mode 100644 ui/src/pages/update-clients/UpdateClients.utils.ts create mode 100644 ui/src/pages/update-clients/severity-chip/SeverityChip.tsx create mode 100644 ui/src/pages/update-clients/severity-chip/SeverityChip.types.ts create mode 100644 ui/src/pages/update-clients/severity-chip/index.ts create mode 100644 ui/src/pages/updates/update-in-progress-card/UpdateInProgressCard.messages.ts create mode 100644 ui/src/pages/updates/update-in-progress-card/UpdateInProgressCard.tsx create mode 100644 ui/src/pages/updates/update-in-progress-card/UpdateInProgressCard.types.tsx create mode 100644 ui/src/pages/updates/update-in-progress-card/index.ts create mode 100644 ui/src/pages/updates/update-in-progress-card/update-progress/UpdateProgress.messages.ts create mode 100644 ui/src/pages/updates/update-in-progress-card/update-progress/UpdateProgress.tsx create mode 100644 ui/src/pages/updates/update-in-progress-card/update-progress/UpdateProgress.types.ts create mode 100644 ui/src/pages/updates/update-info/UpdateInfo.messages.ts create mode 100644 ui/src/pages/updates/update-info/UpdateInfo.tsx create mode 100644 ui/src/pages/updates/update-info/index.ts create mode 100644 ui/src/pages/updates/update-log/UpdateLog.hooks.ts create mode 100644 ui/src/pages/updates/update-log/UpdateLog.messages.ts create mode 100644 ui/src/pages/updates/update-log/UpdateLog.tsx create mode 100644 ui/src/pages/updates/update-log/UpdateLog.types.ts create mode 100644 ui/src/pages/updates/update-log/index.ts create mode 100644 ui/src/pages/updates/update-log/update-log-content/UpdateLogContent.tsx create mode 100644 ui/src/pages/updates/update-log/update-log-content/UpdateLogContent.types.ts create mode 100644 ui/src/pages/updates/update-log/update-log-content/index.ts create mode 100644 ui/src/types/agent.types.ts create mode 100644 ui/src/types/api.types.ts create mode 100644 ui/src/utils/testUtils.tsx diff --git a/ui/package.json b/ui/package.json index 29e4248d44..fa5581d694 100644 --- a/ui/package.json +++ b/ui/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "ESLINT_USE_FLAT_CONFIG=false eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "format": "prettier . --write", "preview": "vite preview", "test": "vitest run", @@ -15,13 +15,16 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", + "@fontsource/poppins": "^5.0.15", + "@fontsource/roboto": "^5.0.14", + "@fontsource/roboto-mono": "^5.0.18", "@mui/icons-material": "^5.15.18", "@mui/material": "^5.15.18", "@mui/x-date-pickers": "^7.5.0", "@percona/design": "^1.0.0", "@percona/ui-lib": "^1.0.0", "@tanstack/react-query": "^5.45.1", - "axios": "^1.7.0", + "axios": "^1.7.4", "axios-case-converter": "^1.1.1", "date-fns": "^2.30.0", "react": "^18.3.1", @@ -32,23 +35,27 @@ "@percona/eslint-config-react": "^1.0.0", "@percona/prettier-config": "^1.0.0", "@percona/tsconfig": "^1.0.0", - "@testing-library/jest-dom": "^6.4.5", + "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^15.0.7", "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.9.0", "@typescript-eslint/parser": "^7.9.0", - "@vitejs/plugin-react-swc": "^3.6.0", - "eslint": "^9.3.0", + "@vitejs/plugin-react-swc": "^3.7.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", - "jsdom": "^24.0.0", + "jsdom": "^24.1.1", "prettier": "^3.2.5", "typescript": "^5.4.5", - "vite": "^5.2.11", + "vite": "^5.3.5", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.6.0" + "vitest": "^2.0.5" + }, + "resolutions": { + "braces": "^3.0.3", + "vite": "^5.3.5" }, "prettier": "@percona/prettier-config" -} +} \ No newline at end of file diff --git a/ui/pmm-dev.conf b/ui/pmm-dev.conf index 47a5af63dc..5e5f8b6b7d 100644 --- a/ui/pmm-dev.conf +++ b/ui/pmm-dev.conf @@ -16,5 +16,8 @@ server { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + + # duplicate so http_host is correctly set + rewrite ^/$ $scheme://$http_host/graph/; } } diff --git a/ui/src/App.tsx b/ui/src/App.tsx index bd4f98d963..ac7b3a7cef 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -8,7 +8,8 @@ import { NotistackMuiSnackbar } from '@percona/ui-lib'; import { SnackbarProvider } from 'notistack'; import pmmThemeOptions from 'themes/PmmTheme'; import { AuthProvider } from 'contexts/auth'; -import { UserProvider } from 'contexts/user/user.provider'; +import { UserProvider } from 'contexts/user'; +import { UpdatesProvider } from 'contexts/updates'; const queryClient = new QueryClient({ defaultOptions: { @@ -39,7 +40,9 @@ const App = () => ( - + + + diff --git a/ui/src/api/__mocks__/agents.ts b/ui/src/api/__mocks__/agents.ts new file mode 100644 index 0000000000..ec3d950fef --- /dev/null +++ b/ui/src/api/__mocks__/agents.ts @@ -0,0 +1,10 @@ +import { AgentUpdateSeverity, GetAgentVersionItem } from 'types/agent.types'; + +export const getAgentVersions = async (): Promise => [ + { + agentId: 'pmm-server', + version: '3.0.0', + nodeName: 'pmm-server', + severity: AgentUpdateSeverity.UP_TO_DATE, + }, +]; diff --git a/ui/src/api/agents.ts b/ui/src/api/agents.ts new file mode 100644 index 0000000000..74b7ebcfff --- /dev/null +++ b/ui/src/api/agents.ts @@ -0,0 +1,9 @@ +import { GetAgentVersionsResponse } from 'types/agent.types'; +import { api } from './api'; + +export const getAgentVersions = async () => { + const res = await api.get( + '/management/agents/versions' + ); + return res.data.agentVersions; +}; diff --git a/ui/src/api/ready.ts b/ui/src/api/ready.ts new file mode 100644 index 0000000000..7d40dfa3ce --- /dev/null +++ b/ui/src/api/ready.ts @@ -0,0 +1,6 @@ +import { api } from './api'; + +export const getReadiness = async () => { + const res = await api.get>('/server/readyz'); + return res.data; +}; diff --git a/ui/src/api/updates.ts b/ui/src/api/updates.ts index 14ab16216d..db6c3d05d9 100644 --- a/ui/src/api/updates.ts +++ b/ui/src/api/updates.ts @@ -4,6 +4,7 @@ import { GetUpdateStatusResponse, GetUpdatesParams, GetUpdatesResponse, + StartUpdateBody, StartUpdateResponse, } from 'types/updates.types'; import { api } from './api'; @@ -17,11 +18,11 @@ export const checkForUpdates = async ( return res.data; }; -export const startUpdate = async () => { - const res = await api.post>( - '/server/updates:start', - {} - ); +export const startUpdate = async (body: StartUpdateBody) => { + const res = await api.post< + StartUpdateBody, + AxiosResponse + >('/server/updates:start', body); return res.data; }; diff --git a/ui/src/components/app-bar/AppBar.tsx b/ui/src/components/app-bar/AppBar.tsx index 333329fc25..29717712da 100644 --- a/ui/src/components/app-bar/AppBar.tsx +++ b/ui/src/components/app-bar/AppBar.tsx @@ -8,26 +8,26 @@ import { } from '@mui/material'; import { HelpFilledIcon, PmmRoundedIcon } from 'icons'; import { Breadcrumbs } from 'components/breadcrumbs'; -import { PMM_HOME_URL, PMM_SUPPORT_URL } from 'constants'; +import { PMM_SUPPORT_URL } from 'constants'; import { Messages } from './AppBar.messages'; +import { HomeLink } from 'components/home-link'; export const AppBar = () => ( - + - ({ - marginRight: theme.spacing(2), - })} + sx={{ + mr: 2, + }} data-testid="appbar-pmm-link" > {Messages.title} - + { const theme = useTheme(); @@ -19,9 +19,9 @@ export const Breadcrumbs: FC = () => { color="text" separator={} > - + {Messages.home} - + `PMM ${version}`, + inProgress: 'Update in progress...', + checkedOn: (date: string) => `Checked on: ${date}`, +}; diff --git a/ui/src/components/footer/Footer.test.tsx b/ui/src/components/footer/Footer.test.tsx new file mode 100644 index 0000000000..a9073e66cf --- /dev/null +++ b/ui/src/components/footer/Footer.test.tsx @@ -0,0 +1,32 @@ +import { screen, render } from '@testing-library/react'; +import { Footer } from './Footer'; +import { Messages } from './Footer.messages'; +import { wrapWithUpdatesProvider } from 'utils/testUtils'; + +describe('Footer', () => { + it("doesnt't show when version info is not available", () => { + render( + wrapWithUpdatesProvider(