@@ -287,9 +287,9 @@ export default function startReactApp( | |||
<IndexRoute | |||
component={lazyLoadComponent(() => import('../components/Landing'))} | |||
/> | |||
<RouteWithChildRoutes path="about" childRoutes={aboutRoutes} /> | |||
<Route component={GlobalContainer}> | |||
<RouteWithChildRoutes path="about" childRoutes={aboutRoutes} /> | |||
<RouteWithChildRoutes path="account" childRoutes={accountRoutes} /> | |||
<RouteWithChildRoutes path="coding_rules" childRoutes={codingRulesRoutes} /> | |||
<RouteWithChildRoutes path="documentation" childRoutes={documentationRoutes} /> |
@@ -28,7 +28,9 @@ import { addWhitePageClass, removeWhitePageClass } from 'sonar-ui-common/helpers | |||
import { searchProjects } from '../../../api/components'; | |||
import { getFacet } from '../../../api/issues'; | |||
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | |||
import GlobalContainer from '../../../app/components/GlobalContainer'; | |||
import withIndexationContext, { | |||
WithIndexationContextProps | |||
} from '../../../components/hoc/withIndexationContext'; | |||
import { | |||
getAppState, | |||
getCurrentUser, | |||
@@ -47,7 +49,7 @@ import AboutScanners from './AboutScanners'; | |||
import AboutStandards from './AboutStandards'; | |||
import EntryIssueTypes from './EntryIssueTypes'; | |||
interface Props { | |||
interface Props extends WithIndexationContextProps { | |||
currentUser: T.CurrentUser; | |||
customText?: string; | |||
fetchAboutPageSettings: () => Promise<void>; | |||
@@ -94,7 +96,9 @@ export class AboutApp extends React.PureComponent<Props, State> { | |||
loadData() { | |||
Promise.all([ | |||
this.loadProjects(), | |||
this.loadIssues().catch(() => undefined), | |||
this.props.indexationContext.status.isCompleted | |||
? this.loadIssues().catch(() => undefined) | |||
: Promise.resolve(undefined), | |||
this.loadCustomText() | |||
]).then( | |||
responses => { | |||
@@ -126,69 +130,67 @@ export class AboutApp extends React.PureComponent<Props, State> { | |||
} | |||
return ( | |||
<GlobalContainer location={this.props.location}> | |||
<div className="page page-limited about-page" id="about-page"> | |||
<A11ySkipTarget anchor="about_main" /> | |||
<div className="about-page-entry"> | |||
<div className="about-page-intro"> | |||
<h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1> | |||
{!this.props.currentUser.isLoggedIn && ( | |||
<Link className="button button-active big-spacer-right" to="/sessions/new"> | |||
{translate('layout.login')} | |||
</Link> | |||
)} | |||
<Link className="button" to="/documentation"> | |||
{translate('about_page.read_documentation')} | |||
<div className="page page-limited about-page" id="about-page"> | |||
<A11ySkipTarget anchor="about_main" /> | |||
<div className="about-page-entry"> | |||
<div className="about-page-intro"> | |||
<h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1> | |||
{!this.props.currentUser.isLoggedIn && ( | |||
<Link className="button button-active big-spacer-right" to="/sessions/new"> | |||
{translate('layout.login')} | |||
</Link> | |||
</div> | |||
<div className="about-page-instance"> | |||
<AboutProjects count={projectsCount} loading={loading} /> | |||
{issueTypes && ( | |||
<EntryIssueTypes | |||
bugs={bugs} | |||
codeSmells={codeSmells} | |||
loading={loading} | |||
vulnerabilities={vulnerabilities} | |||
/> | |||
)} | |||
</div> | |||
)} | |||
<Link className="button" to="/documentation"> | |||
{translate('about_page.read_documentation')} | |||
</Link> | |||
</div> | |||
{customText && ( | |||
<div | |||
className="about-page-section" | |||
// eslint-disable-next-line react/no-danger | |||
dangerouslySetInnerHTML={{ __html: sanitize(customText) }} | |||
/> | |||
)} | |||
<AboutLanguages /> | |||
<AboutQualityModel /> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutCleanCode /> | |||
</div> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutLeakPeriod /> | |||
</div> | |||
<div className="about-page-instance"> | |||
<AboutProjects count={projectsCount} loading={loading} /> | |||
{issueTypes && ( | |||
<EntryIssueTypes | |||
bugs={bugs} | |||
codeSmells={codeSmells} | |||
loading={loading} | |||
vulnerabilities={vulnerabilities} | |||
/> | |||
)} | |||
</div> | |||
</div> | |||
{customText && ( | |||
<div | |||
className="about-page-section" | |||
// eslint-disable-next-line react/no-danger | |||
dangerouslySetInnerHTML={{ __html: sanitize(customText) }} | |||
/> | |||
)} | |||
<AboutLanguages /> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutQualityGates /> | |||
</div> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutStandards /> | |||
</div> | |||
<AboutQualityModel /> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutCleanCode /> | |||
</div> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutLeakPeriod /> | |||
</div> | |||
</div> | |||
<AboutScanners /> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutQualityGates /> | |||
</div> | |||
<div className="flex-column flex-column-half about-page-group-boxes"> | |||
<AboutStandards /> | |||
</div> | |||
</div> | |||
</GlobalContainer> | |||
<AboutScanners /> | |||
</div> | |||
); | |||
} | |||
} | |||
@@ -204,4 +206,4 @@ const mapStateToProps = (state: Store) => { | |||
const mapDispatchToProps = { fetchAboutPageSettings } as any; | |||
export default connect(mapStateToProps, mapDispatchToProps)(AboutApp); | |||
export default withIndexationContext(connect(mapStateToProps, mapDispatchToProps)(AboutApp)); |
@@ -65,6 +65,14 @@ it('should render correctly', async () => { | |||
wrapper.unmount(); | |||
expect(removeWhitePageClass).toBeCalled(); | |||
expect( | |||
shallowRender({ | |||
indexationContext: { | |||
status: { isCompleted: false, percentCompleted: 10, hasFailures: false } | |||
} | |||
}) | |||
).toMatchSnapshot('when indexation not complete'); | |||
}); | |||
it('should load issues, projects, and custom text upon shallowing', () => { | |||
@@ -92,6 +100,9 @@ function shallowRender(props: Partial<AboutApp['props']> = {}) { | |||
customText="Lorem ipsum" | |||
fetchAboutPageSettings={jest.fn().mockResolvedValue('')} | |||
location={mockLocation()} | |||
indexationContext={{ | |||
status: { isCompleted: true, percentCompleted: 100, hasFailures: false } | |||
}} | |||
{...props} | |||
/> | |||
); |
@@ -1,108 +1,181 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<GlobalContainer | |||
location={ | |||
Object { | |||
"action": "PUSH", | |||
"hash": "", | |||
"key": "key", | |||
"pathname": "/path", | |||
"query": Object {}, | |||
"search": "", | |||
"state": Object {}, | |||
} | |||
} | |||
<div | |||
className="page page-limited about-page" | |||
id="about-page" | |||
> | |||
<A11ySkipTarget | |||
anchor="about_main" | |||
/> | |||
<div | |||
className="page page-limited about-page" | |||
id="about-page" | |||
className="about-page-entry" | |||
> | |||
<A11ySkipTarget | |||
anchor="about_main" | |||
/> | |||
<div | |||
className="about-page-entry" | |||
className="about-page-intro" | |||
> | |||
<div | |||
className="about-page-intro" | |||
<h1 | |||
className="big-spacer-bottom" | |||
> | |||
layout.sonar.slogan | |||
</h1> | |||
<Link | |||
className="button button-active big-spacer-right" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/sessions/new" | |||
> | |||
<h1 | |||
className="big-spacer-bottom" | |||
> | |||
layout.sonar.slogan | |||
</h1> | |||
<Link | |||
className="button button-active big-spacer-right" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/sessions/new" | |||
> | |||
layout.login | |||
</Link> | |||
<Link | |||
className="button" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/documentation" | |||
> | |||
about_page.read_documentation | |||
</Link> | |||
</div> | |||
<div | |||
className="about-page-instance" | |||
layout.login | |||
</Link> | |||
<Link | |||
className="button" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/documentation" | |||
> | |||
<AboutProjects | |||
count={5} | |||
loading={false} | |||
/> | |||
<EntryIssueTypes | |||
bugs={10} | |||
codeSmells={5} | |||
loading={false} | |||
vulnerabilities={0} | |||
/> | |||
</div> | |||
about_page.read_documentation | |||
</Link> | |||
</div> | |||
<div | |||
className="about-page-section" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "Lorem ipsum", | |||
} | |||
className="about-page-instance" | |||
> | |||
<AboutProjects | |||
count={5} | |||
loading={false} | |||
/> | |||
<EntryIssueTypes | |||
bugs={10} | |||
codeSmells={5} | |||
loading={false} | |||
vulnerabilities={0} | |||
/> | |||
</div> | |||
</div> | |||
<div | |||
className="about-page-section" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "Lorem ipsum", | |||
} | |||
/> | |||
<AboutLanguages /> | |||
<AboutQualityModel /> | |||
} | |||
/> | |||
<AboutLanguages /> | |||
<AboutQualityModel /> | |||
<div | |||
className="flex-columns" | |||
> | |||
<div | |||
className="flex-columns" | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutCleanCode /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutLeakPeriod /> | |||
</div> | |||
<AboutCleanCode /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutLeakPeriod /> | |||
</div> | |||
</div> | |||
<div | |||
className="flex-columns" | |||
> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutQualityGates /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutStandards /> | |||
</div> | |||
</div> | |||
<AboutScanners /> | |||
</div> | |||
`; | |||
exports[`should render correctly: when indexation not complete 1`] = ` | |||
<div | |||
className="page page-limited about-page" | |||
id="about-page" | |||
> | |||
<A11ySkipTarget | |||
anchor="about_main" | |||
/> | |||
<div | |||
className="about-page-entry" | |||
> | |||
<div | |||
className="flex-columns" | |||
className="about-page-intro" | |||
> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
<h1 | |||
className="big-spacer-bottom" | |||
> | |||
<AboutQualityGates /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
layout.sonar.slogan | |||
</h1> | |||
<Link | |||
className="button button-active big-spacer-right" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/sessions/new" | |||
> | |||
<AboutStandards /> | |||
</div> | |||
layout.login | |||
</Link> | |||
<Link | |||
className="button" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/documentation" | |||
> | |||
about_page.read_documentation | |||
</Link> | |||
</div> | |||
<div | |||
className="about-page-instance" | |||
> | |||
<AboutProjects | |||
count={0} | |||
loading={true} | |||
/> | |||
</div> | |||
</div> | |||
<div | |||
className="about-page-section" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "Lorem ipsum", | |||
} | |||
} | |||
/> | |||
<AboutLanguages /> | |||
<AboutQualityModel /> | |||
<div | |||
className="flex-columns" | |||
> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutCleanCode /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutLeakPeriod /> | |||
</div> | |||
</div> | |||
<div | |||
className="flex-columns" | |||
> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutQualityGates /> | |||
</div> | |||
<div | |||
className="flex-column flex-column-half about-page-group-boxes" | |||
> | |||
<AboutStandards /> | |||
</div> | |||
<AboutScanners /> | |||
</div> | |||
</GlobalContainer> | |||
<AboutScanners /> | |||
</div> | |||
`; |