Skip to content

Commit

Permalink
feat(aboutModal): ds-808 display user, status info (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcabrera authored Oct 16, 2024
1 parent 65cbc5d commit 761344b
Show file tree
Hide file tree
Showing 15 changed files with 678 additions and 185 deletions.
8 changes: 8 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{
"about": {
"browser-os": "Browser OS",
"browser-version": "Browser Version",
"copyright": "Copyright (c) {{year}} Red Hat Inc.",
"server-version": "Server Version",
"ui-version": "UI Version",
"username": "Username"
},
"form-dialog": {
"confirmation_heading_delete-scan": "Are you sure you want to delete the scan <0>{{name}}</0>?",
"confirmation_heading_delete-credential": "Are you sure you want to delete the credential {{name}}?",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AboutModal Component should attempt to display username, status data: username and status 1`] = `
<AboutModal
aria-label="Quipucords"
backgroundImageSrc="aboutBg.png"
brandImageAlt="Quipucords"
brandImageSrc="title.svg"
isOpen={true}
onClose={[Function]}
trademark="t([
"about.copyright",
{
"year": "2024"
}
])"
>
<TextContent
className=""
>
<TextList
component="dl"
>
<React.Fragment>
<TextListItem
component="dt"
>
t([
"about.username"
])
</TextListItem>
<TextListItem
component="dd"
>
lorem ipsum
</TextListItem>
</React.Fragment>
<React.Fragment>
<TextListItem
component="dt"
>
t([
"about.ui-version"
])
</TextListItem>
<TextListItem
component="dd"
>
0.0.0.0000000
</TextListItem>
</React.Fragment>
<React.Fragment>
<TextListItem
className=""
component="dt"
>
t([
"about.server-version"
])
</TextListItem>
<TextListItem
className=""
component="dd"
>
0.0.0.12345678
</TextListItem>
</React.Fragment>
</TextList>
</TextContent>
</AboutModal>
`;

exports[`AboutModal Component should render a basic component: basic 1`] = `
<AboutModal
aria-label="Quipucords"
backgroundImageSrc="aboutBg.png"
brandImageAlt="Quipucords"
brandImageSrc="title.svg"
isOpen={false}
onClose={[Function]}
trademark="t([
"about.copyright",
{
"year": "2024"
}
])"
>
<TextContent
className="fadein"
>
<TextList
component="dl"
>
<React.Fragment>
<TextListItem
component="dt"
>
t([
"about.ui-version"
])
</TextListItem>
<TextListItem
component="dd"
>
0.0.0.0000000
</TextListItem>
</React.Fragment>
</TextList>
</TextContent>
</AboutModal>
`;
45 changes: 45 additions & 0 deletions src/components/aboutModal/__tests__/aboutModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { shallowComponent } from '../../../../config/jest.setupTests';
import { AboutModal } from '../aboutModal';

describe('AboutModal Component', () => {
it('should render a basic component', async () => {
const props = {};
const component = await shallowComponent(<AboutModal {...props} />);
expect(component).toMatchSnapshot('basic');
});

it('should attempt to display username, status data', async () => {
const mockGetStatus = jest.fn().mockResolvedValue({ server_version: '0.0.0.12345678' });
const mockUseStatusApi = jest.fn().mockReturnValue({ getStatus: mockGetStatus });
const mockGetUser = jest.fn().mockResolvedValue('lorem ipsum');
const mockUseUserApi = jest.fn().mockReturnValue({ getUser: mockGetUser });
const props = {
isOpen: true,
useUser: mockUseUserApi,
useStatus: mockUseStatusApi
};

const component = await shallowComponent(<AboutModal {...props} />);
expect(component).toMatchSnapshot('username and status');
});

it('should call onClose', async () => {
const mockOnClose = jest.fn();
const props = {
isOpen: true,
useUser: jest.fn().mockReturnValue({ getUser: jest.fn().mockResolvedValue('lorem ipsum') }),
useStatus: jest.fn().mockReturnValue({ getStatus: jest.fn().mockResolvedValue({}) }),
onClose: mockOnClose
};

render(<AboutModal {...props} />);

const user = userEvent.setup();
await user.click(screen.getByLabelText('Close Dialog'));

expect(mockOnClose).toHaveBeenCalledTimes(1);
});
});
102 changes: 102 additions & 0 deletions src/components/aboutModal/aboutModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { AboutModal as PfAboutModal, TextContent, TextList, TextListItem } from '@patternfly/react-core';
import { detect } from 'detect-browser';
import moment from 'moment/moment';
import { helpers } from '../../helpers';
import { useUserApi } from '../../hooks/useLoginApi';
import { useStatusApi, type ApiStatusSuccessType } from '../../hooks/useStatusApi';
import backgroundImageSrc from '../../images/aboutBg.png';

interface AboutModalProps {
currentYear?: string;
isOpen?: boolean;
onClose?: () => void;
titleImg?: string;
uiName?: string;
uiVersion?: string;
useStatus?: typeof useStatusApi;
useUser?: typeof useUserApi;
}

const AboutModal: React.FC<AboutModalProps> = ({
currentYear = moment.utc(helpers.getCurrentDate()).format('YYYY'),
isOpen = false,
onClose = Function.prototype,
titleImg = helpers.getTitleImg(),
uiName = helpers.UI_NAME,
uiVersion = helpers.UI_VERSION,
useStatus = useStatusApi,
useUser = useUserApi
}) => {
const { t } = useTranslation();
const { getStatus } = useStatus();
const { getUser } = useUser();
const [userName, setUserName] = useState<string>();
const [stats, setStats] = useState<ApiStatusSuccessType>();
const browser = detect();
const loadingClassName = (!stats && 'fadein') || '';

useEffect(() => {
if (isOpen && !stats) {
getUser().then(username => setUserName(username));
getStatus().then(
data => setStats(data),
error => console.error(`About status error: ${error} `)
);
}
}, [isOpen, getStatus, getUser, stats]);

return (
<PfAboutModal
aria-label={uiName}
backgroundImageSrc={backgroundImageSrc as string}
brandImageAlt={uiName}
brandImageSrc={titleImg}
isOpen={isOpen}
onClose={() => onClose()}
trademark={t('about.copyright', { year: currentYear })}
>
<TextContent className={loadingClassName}>
<TextList component="dl">
{userName && (
<React.Fragment>
<TextListItem component="dt">{t('about.username')}</TextListItem>
<TextListItem component="dd">{userName}</TextListItem>
</React.Fragment>
)}
{browser && (
<React.Fragment>
<TextListItem component="dt">{t('about.browser-version')}</TextListItem>
<TextListItem component="dd">{`${browser.name} ${browser.version}`}</TextListItem>
</React.Fragment>
)}
{browser && (
<React.Fragment>
<TextListItem component="dt">{t('about.browser-os')}</TextListItem>
<TextListItem component="dd">{browser.os || ''}</TextListItem>
</React.Fragment>
)}
{uiVersion && (
<React.Fragment>
<TextListItem component="dt">{t('about.ui-version')}</TextListItem>
<TextListItem component="dd">{uiVersion}</TextListItem>
</React.Fragment>
)}
{stats?.server_version && (
<React.Fragment>
<TextListItem className={loadingClassName} component="dt">
{t('about.server-version')}
</TextListItem>
<TextListItem className={loadingClassName} component="dd">
{stats.server_version}
</TextListItem>
</React.Fragment>
)}
</TextList>
</TextContent>
</PfAboutModal>
);
};

export { AboutModal as default, AboutModal, type AboutModalProps };
Loading

0 comments on commit 761344b

Please sign in to comment.