From 468ce6b5e4101670c0fc7a41f51886008e2eba63 Mon Sep 17 00:00:00 2001 From: Christoph Jerolimov Date: Tue, 10 Dec 2024 23:34:38 +0100 Subject: [PATCH] feat(settings): hide detailed build version information and show them on demand (#2064) Signed-off-by: Christoph Jerolimov --- .../components/UserSettings/GeneralPage.tsx | 6 +- .../components/UserSettings/InfoCard.test.tsx | 20 +++ .../src/components/UserSettings/InfoCard.tsx | 132 ++++++++++++++++-- .../components/UserSettings/SettingsPages.tsx | 4 +- 4 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 packages/app/src/components/UserSettings/InfoCard.test.tsx diff --git a/packages/app/src/components/UserSettings/GeneralPage.tsx b/packages/app/src/components/UserSettings/GeneralPage.tsx index a0a8438064..a8e2452258 100644 --- a/packages/app/src/components/UserSettings/GeneralPage.tsx +++ b/packages/app/src/components/UserSettings/GeneralPage.tsx @@ -6,9 +6,9 @@ import { import Grid from '@mui/material/Grid'; -import { infoCard } from './InfoCard'; +import { InfoCard } from './InfoCard'; -export const generalPage = ( +export const GeneralPage = () => ( @@ -20,7 +20,7 @@ export const generalPage = ( - {infoCard} + ); diff --git a/packages/app/src/components/UserSettings/InfoCard.test.tsx b/packages/app/src/components/UserSettings/InfoCard.test.tsx new file mode 100644 index 0000000000..a8bc659658 --- /dev/null +++ b/packages/app/src/components/UserSettings/InfoCard.test.tsx @@ -0,0 +1,20 @@ +import { renderInTestApp } from '@backstage/test-utils'; + +import { userEvent } from '@testing-library/user-event'; + +import { InfoCard } from './InfoCard'; + +describe('InfoCard', () => { + it('should render essential versions by default', async () => { + const renderResult = await renderInTestApp(); + expect(renderResult.getByText(/RHDH Version/)).toBeInTheDocument(); + expect(renderResult.getByText(/Backstage Version/)).toBeInTheDocument(); + }); + + it('should hide the build time by default and show it on click', async () => { + const renderResult = await renderInTestApp(); + expect(renderResult.queryByText(/Last Commit/)).toBeNull(); + await userEvent.click(renderResult.getByText(/RHDH Version/)); + expect(renderResult.getByText(/Last Commit/)).toBeInTheDocument(); + }); +}); diff --git a/packages/app/src/components/UserSettings/InfoCard.tsx b/packages/app/src/components/UserSettings/InfoCard.tsx index a3977cc8e9..5abbb1eb5c 100644 --- a/packages/app/src/components/UserSettings/InfoCard.tsx +++ b/packages/app/src/components/UserSettings/InfoCard.tsx @@ -1,20 +1,122 @@ -import { InfoCard as BSInfoCard } from '@backstage/core-components'; +import React from 'react'; -import Grid from '@mui/material/Grid'; +import { + InfoCard as BSInfoCard, + CopyTextButton, +} from '@backstage/core-components'; + +import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; +import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; +import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import buildMetadata from '../../build-metadata.json'; -export const infoCard = ( - - - {buildMetadata.card.map(text => ( - - - {text} - - - ))} - - -); +export const InfoCard = () => { + const [showBuildInformation, setShowBuildInformation] = + React.useState( + () => + localStorage.getItem('rhdh-infocard-show-build-information') === 'true', + ); + + const toggleBuildInformation = () => { + setShowBuildInformation(!showBuildInformation); + try { + if (showBuildInformation) { + localStorage.removeItem('rhdh-infocard-show-build-information'); + } else { + localStorage.setItem('rhdh-infocard-show-build-information', 'true'); + } + } catch (e) { + // ignore + } + }; + + let clipboardText = buildMetadata.title; + if (buildMetadata.card?.length) { + clipboardText += '\n\n'; + buildMetadata.card.forEach(text => { + clipboardText += `${text}\n`; + }); + } + + const filteredCards = showBuildInformation + ? buildMetadata.card + : buildMetadata.card.filter( + text => + text.startsWith('RHDH Version') || + text.startsWith('Backstage Version'), + ); + // Ensure that we show always some information + const versionInfo = + filteredCards.length > 0 ? filteredCards.join('\n') : buildMetadata.card[0]; + + /** + * Show all build information and automatically select them + * when the user selects the version with the mouse. + */ + const onMouseUp = (event: React.MouseEvent) => { + if (!showBuildInformation) { + setShowBuildInformation(true); + window.getSelection()?.selectAllChildren(event.target as Node); + } + }; + + /** + * Show all build information and automatically select them + * when the user selects the version with the keyboard (tab) + * and presses the space key or the Ctrl+C key combination. + */ + const onKeyDown = (event: React.KeyboardEvent) => { + if ( + event.key === ' ' || + (event.key === 'c' && event.ctrlKey) || + (event.key === 'C' && event.ctrlKey) + ) { + setShowBuildInformation(true); + window.getSelection()?.selectAllChildren(event.target as Node); + } + }; + + return ( + +
+ + + {showBuildInformation ? : } + +
+ + } + > + + {versionInfo} + +
+ ); +}; diff --git a/packages/app/src/components/UserSettings/SettingsPages.tsx b/packages/app/src/components/UserSettings/SettingsPages.tsx index 3b9b2963a4..2d04ae111e 100644 --- a/packages/app/src/components/UserSettings/SettingsPages.tsx +++ b/packages/app/src/components/UserSettings/SettingsPages.tsx @@ -3,12 +3,12 @@ import { UserSettingsAuthProviders, } from '@backstage/plugin-user-settings'; -import { generalPage } from './GeneralPage'; +import { GeneralPage } from './GeneralPage'; export const settingsPage = ( - {generalPage} +