-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(aboutModal): ds-808 display user, status info (#488)
* aboutModal, display user and status info * viewLayout, use title image helper * viewLayoutToolbar, add about modal open, close * helpers, add ui_version, getCurrentDate, getTitleImg * useStatusApi, use status api response Relates to JIRA: DISCOVERY-808
- Loading branch information
Showing
15 changed files
with
678 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/components/aboutModal/__tests__/__snapshots__/aboutModal.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; |
Oops, something went wrong.