Skip to content

Commit

Permalink
feat(settings): hide detailed build version information and show them…
Browse files Browse the repository at this point in the history
… on demand (#2064)

Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
  • Loading branch information
christoph-jerolimov authored Dec 10, 2024
1 parent 486e002 commit 468ce6b
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 20 deletions.
6 changes: 3 additions & 3 deletions packages/app/src/components/UserSettings/GeneralPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<Grid container direction="row" spacing={3}>
<Grid item xs={12} md={6}>
<UserSettingsProfileCard />
Expand All @@ -20,7 +20,7 @@ export const generalPage = (
<UserSettingsIdentityCard />
</Grid>
<Grid item xs={12} md={6}>
{infoCard}
<InfoCard />
</Grid>
</Grid>
);
20 changes: 20 additions & 0 deletions packages/app/src/components/UserSettings/InfoCard.test.tsx
Original file line number Diff line number Diff line change
@@ -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(<InfoCard />);
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(<InfoCard />);
expect(renderResult.queryByText(/Last Commit/)).toBeNull();
await userEvent.click(renderResult.getByText(/RHDH Version/));
expect(renderResult.getByText(/Last Commit/)).toBeInTheDocument();
});
});
132 changes: 117 additions & 15 deletions packages/app/src/components/UserSettings/InfoCard.tsx
Original file line number Diff line number Diff line change
@@ -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 = (
<BSInfoCard title={buildMetadata.title}>
<Grid container spacing={1}>
{buildMetadata.card.map(text => (
<Grid item xs={12} key={text}>
<Typography variant="subtitle1" gutterBottom>
{text}
</Typography>
</Grid>
))}
</Grid>
</BSInfoCard>
);
export const InfoCard = () => {
const [showBuildInformation, setShowBuildInformation] =
React.useState<boolean>(
() =>
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<HTMLSpanElement>) => {
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<HTMLSpanElement>) => {
if (
event.key === ' ' ||
(event.key === 'c' && event.ctrlKey) ||
(event.key === 'C' && event.ctrlKey)
) {
setShowBuildInformation(true);
window.getSelection()?.selectAllChildren(event.target as Node);
}
};

return (
<BSInfoCard
title={buildMetadata.title}
action={
// This is a workaround to ensure that the buttons doesn't increase the header size.
<div style={{ position: 'relative' }}>
<div
style={{ position: 'absolute', top: -2, right: 0, display: 'flex' }}
>
<CopyTextButton
text={clipboardText}
tooltipText="Metadata copied to clipboard"
arial-label="Copy metadata to your clipboard"
/>
<IconButton
title={showBuildInformation ? 'Show less' : 'Show more'}
onClick={toggleBuildInformation}
style={{ width: 48 }}
>
{showBuildInformation ? <UnfoldLessIcon /> : <UnfoldMoreIcon />}
</IconButton>
</div>
</div>
}
>
<Typography
variant="subtitle1"
// Allow the user to select the text with the keyboard.
tabIndex={0}
onMouseUp={onMouseUp}
onKeyDown={onKeyDown}
style={{
whiteSpace: 'pre-line',
wordWrap: 'break-word',
lineHeight: '2.1rem',
}}
>
{versionInfo}
</Typography>
</BSInfoCard>
);
};
4 changes: 2 additions & 2 deletions packages/app/src/components/UserSettings/SettingsPages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
UserSettingsAuthProviders,
} from '@backstage/plugin-user-settings';

import { generalPage } from './GeneralPage';
import { GeneralPage } from './GeneralPage';

export const settingsPage = (
<SettingsLayout>
<SettingsLayout.Route path="general" title="General">
{generalPage}
<GeneralPage />
</SettingsLayout.Route>
<SettingsLayout.Route
path="auth-providers"
Expand Down

0 comments on commit 468ce6b

Please sign in to comment.