@@ -99,3 +99,8 @@ table > thead > tr.code-components-header > th { | |||
height: 8px; | |||
width: 4px; | |||
} | |||
.code-components .no-file .h1 { | |||
position: fixed; | |||
top: 50%; | |||
} |
@@ -71,7 +71,7 @@ interface State { | |||
total: number; | |||
} | |||
export class App extends React.PureComponent<Props, State> { | |||
export class AppCode extends React.PureComponent<Props, State> { | |||
mounted = false; | |||
state: State; | |||
@@ -255,6 +255,8 @@ export class App extends React.PureComponent<Props, State> { | |||
const showSearch = searchResults !== undefined; | |||
const hasNoFile = components.length === 0 && searchResults === undefined; | |||
const shouldShowBreadcrumbs = breadcrumbs.length > 1 && !showSearch; | |||
const shouldShowComponentList = | |||
sourceViewer === undefined && components.length > 0 && !showSearch; | |||
@@ -278,14 +280,26 @@ export class App extends React.PureComponent<Props, State> { | |||
/> | |||
<A11ySkipTarget anchor="code_main" /> | |||
<Search | |||
branchLike={branchLike} | |||
component={component} | |||
onSearchClear={this.handleSearchClear} | |||
onSearchResults={this.handleSearchResults} | |||
/> | |||
{!hasNoFile && ( | |||
<Search | |||
branchLike={branchLike} | |||
component={component} | |||
onSearchClear={this.handleSearchClear} | |||
onSearchResults={this.handleSearchResults} | |||
/> | |||
)} | |||
<div className="code-components"> | |||
{hasNoFile && ( | |||
<div className="display-flex-center display-flex-column no-file"> | |||
<span className="h1 text-muted"> | |||
{translate( | |||
'code_viewer.no_source_code_displayed_due_to_empty_analysis', | |||
component.qualifier | |||
)} | |||
</span> | |||
</div> | |||
)} | |||
{shouldShowBreadcrumbs && ( | |||
<Breadcrumbs | |||
branchLike={branchLike} | |||
@@ -360,4 +374,4 @@ const mapDispatchToProps: DispatchToProps = { | |||
export default connect<StateToProps, DispatchToProps, Props>( | |||
mapStateToProps, | |||
mapDispatchToProps | |||
)(App); | |||
)(AppCode); |
@@ -1,108 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||
import { mockIssue, mockRouter } from '../../../../helpers/testMocks'; | |||
import { retrieveComponent } from '../../utils'; | |||
import { App } from '../App'; | |||
jest.mock('../../utils', () => ({ | |||
retrieveComponent: jest.fn().mockResolvedValue({ | |||
breadcrumbs: [], | |||
component: { qualifier: 'APP' }, | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}), | |||
retrieveComponentChildren: () => Promise.resolve() | |||
})); | |||
const METRICS = { | |||
coverage: { id: '2', key: 'coverage', type: 'PERCENT', name: 'Coverage', domain: 'Coverage' }, | |||
new_bugs: { id: '4', key: 'new_bugs', type: 'INT', name: 'New Bugs', domain: 'Reliability' } | |||
}; | |||
beforeEach(() => { | |||
(retrieveComponent as jest.Mock<any>).mockClear(); | |||
}); | |||
it('should have correct title for APP based component', async () => { | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.find('Helmet')).toMatchSnapshot(); | |||
}); | |||
it('should have correct title for portfolio base component', async () => { | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component: { qualifier: 'VW' }, | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.find('Helmet')).toMatchSnapshot(); | |||
}); | |||
it('should have correct title for project component', async () => { | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component: { qualifier: 'TRK' }, | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.find('Helmet')).toMatchSnapshot(); | |||
}); | |||
it('should refresh branch status if issues are updated', async () => { | |||
const fetchBranchStatus = jest.fn(); | |||
const branchLike = mockPullRequest(); | |||
const wrapper = shallowRender({ branchLike, fetchBranchStatus }); | |||
const instance = wrapper.instance(); | |||
await waitAndUpdate(wrapper); | |||
instance.handleIssueChange(mockIssue()); | |||
expect(fetchBranchStatus).toBeCalledWith(branchLike, 'foo'); | |||
}); | |||
function shallowRender(props: Partial<App['props']> = {}) { | |||
return shallow<App>( | |||
<App | |||
component={{ | |||
breadcrumbs: [], | |||
name: 'foo', | |||
key: 'foo', | |||
qualifier: 'FOO' | |||
}} | |||
fetchBranchStatus={jest.fn()} | |||
fetchMetrics={jest.fn()} | |||
location={{ query: { branch: 'b', id: 'foo', line: '7' } }} | |||
metrics={METRICS} | |||
router={mockRouter()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,198 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||
import { | |||
mockComponent, | |||
mockComponentMeasure, | |||
mockIssue, | |||
mockRouter | |||
} from '../../../../helpers/testMocks'; | |||
import { ComponentQualifier } from '../../../../types/component'; | |||
import { loadMoreChildren, retrieveComponent } from '../../utils'; | |||
import { AppCode } from '../AppCode'; | |||
jest.mock('../../utils', () => ({ | |||
loadMoreChildren: jest.fn().mockResolvedValue({}), | |||
retrieveComponent: jest.fn().mockResolvedValue({ | |||
breadcrumbs: [], | |||
component: { qualifier: 'APP' }, | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}), | |||
retrieveComponentChildren: () => Promise.resolve() | |||
})); | |||
const METRICS = { | |||
coverage: { id: '2', key: 'coverage', type: 'PERCENT', name: 'Coverage', domain: 'Coverage' }, | |||
new_bugs: { id: '4', key: 'new_bugs', type: 'INT', name: 'New Bugs', domain: 'Reliability' } | |||
}; | |||
beforeEach(() => { | |||
(retrieveComponent as jest.Mock<any>).mockClear(); | |||
}); | |||
it.each([ | |||
[ComponentQualifier.Application], | |||
[ComponentQualifier.Project], | |||
[ComponentQualifier.Portfolio], | |||
[ComponentQualifier.SubPortfolio] | |||
])('should render correclty when no sub component for %s', async qualifier => { | |||
const component = { breadcrumbs: [], name: 'foo', key: 'foo', qualifier }; | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component, | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}); | |||
const wrapper = shallowRender({ component }); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper).toMatchSnapshot(); | |||
wrapper.instance().handleSearchResults([]); | |||
expect(wrapper).toMatchSnapshot('no search'); | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component, | |||
components: [mockComponent({ qualifier: ComponentQualifier.File })], | |||
page: 0, | |||
total: 1 | |||
}); | |||
wrapper.instance().loadComponent(component.key); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper).toMatchSnapshot('with sub component'); | |||
}); | |||
it('should refresh branch status if issues are updated', async () => { | |||
const fetchBranchStatus = jest.fn(); | |||
const branchLike = mockPullRequest(); | |||
const wrapper = shallowRender({ branchLike, fetchBranchStatus }); | |||
const instance = wrapper.instance(); | |||
await waitAndUpdate(wrapper); | |||
instance.handleIssueChange(mockIssue()); | |||
expect(fetchBranchStatus).toBeCalledWith(branchLike, 'foo'); | |||
}); | |||
it('should load more behave correctly', async () => { | |||
const component1 = mockComponent(); | |||
const component2 = mockComponent(); | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component: mockComponent(), | |||
components: [component1], | |||
page: 0, | |||
total: 1 | |||
}); | |||
let wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
(loadMoreChildren as jest.Mock<any>).mockResolvedValueOnce({ | |||
components: [component2], | |||
page: 0, | |||
total: 1 | |||
}); | |||
wrapper.instance().handleLoadMore(); | |||
expect(wrapper.state().components).toContainEqual(component1); | |||
expect(wrapper.state().components).toContainEqual(component2); | |||
(retrieveComponent as jest.Mock<any>).mockRejectedValueOnce({}); | |||
wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
wrapper.instance().handleLoadMore(); | |||
expect(wrapper.state().components).toBeUndefined(); | |||
}); | |||
it('should handle go to parent correctly', async () => { | |||
const router = mockRouter(); | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [], | |||
component: mockComponent(), | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}); | |||
let wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
wrapper.instance().handleGoToParent(); | |||
expect(wrapper.state().highlighted).toBeUndefined(); | |||
const breadcrumb = { key: 'key2', name: 'name2', qualifier: ComponentQualifier.Directory }; | |||
(retrieveComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
breadcrumbs: [ | |||
{ key: 'key1', name: 'name1', qualifier: ComponentQualifier.Directory }, | |||
breadcrumb | |||
], | |||
component: mockComponent(), | |||
components: [], | |||
page: 0, | |||
total: 1 | |||
}); | |||
wrapper = shallowRender({ router }); | |||
await waitAndUpdate(wrapper); | |||
wrapper.instance().handleGoToParent(); | |||
expect(wrapper.state().highlighted).toBe(breadcrumb); | |||
expect(router.push).toHaveBeenCalledWith({ | |||
pathname: '/code', | |||
query: { id: 'foo', line: undefined, selected: 'key1' } | |||
}); | |||
}); | |||
it('should handle select correctly', () => { | |||
const router = mockRouter(); | |||
const wrapper = shallowRender({ router }); | |||
wrapper.setState({ highlighted: mockComponentMeasure() }); | |||
wrapper.instance().handleSelect(mockComponentMeasure(true, { refKey: 'test' })); | |||
expect(router.push).toHaveBeenCalledWith({ | |||
pathname: '/dashboard', | |||
query: { branch: undefined, id: 'test' } | |||
}); | |||
expect(wrapper.state().highlighted).toBeUndefined(); | |||
wrapper.instance().handleSelect(mockComponentMeasure()); | |||
expect(router.push).toHaveBeenCalledWith({ | |||
pathname: '/dashboard', | |||
query: { branch: undefined, id: 'test' } | |||
}); | |||
}); | |||
function shallowRender(props: Partial<AppCode['props']> = {}) { | |||
return shallow<AppCode>( | |||
<AppCode | |||
component={{ | |||
breadcrumbs: [], | |||
name: 'foo', | |||
key: 'foo', | |||
qualifier: 'FOO' | |||
}} | |||
fetchBranchStatus={jest.fn()} | |||
fetchMetrics={jest.fn()} | |||
location={{ query: { branch: 'b', id: 'foo', line: '7' } }} | |||
metrics={METRICS} | |||
router={mockRouter()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -1,25 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should have correct title for APP based component 1`] = ` | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
`; | |||
exports[`should have correct title for portfolio base component 1`] = ` | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
`; | |||
exports[`should have correct title for project component 1`] = ` | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="code.page" | |||
/> | |||
`; |
@@ -0,0 +1,765 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correclty when no sub component for APP 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="display-flex-center display-flex-column no-file" | |||
> | |||
<span | |||
className="h1 text-muted" | |||
> | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.APP | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for APP: no search 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "APP", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top search-results" | |||
> | |||
<withKeyboardNavigation(Components) | |||
components={Array []} | |||
metrics={Object {}} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "APP", | |||
} | |||
} | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for APP: with sub component 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "APP", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top" | |||
> | |||
<withKeyboardNavigation(Components) | |||
baseComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "APP", | |||
} | |||
} | |||
components={ | |||
Array [ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
] | |||
} | |||
cycle={true} | |||
metrics={ | |||
Object { | |||
"coverage": Object { | |||
"domain": "Coverage", | |||
"id": "2", | |||
"key": "coverage", | |||
"name": "Coverage", | |||
"type": "PERCENT", | |||
}, | |||
"new_bugs": Object { | |||
"domain": "Reliability", | |||
"id": "4", | |||
"key": "new_bugs", | |||
"name": "New Bugs", | |||
"type": "INT", | |||
}, | |||
} | |||
} | |||
onEndOfList={[Function]} | |||
onGoToParent={[Function]} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "APP", | |||
} | |||
} | |||
/> | |||
</div> | |||
<ListFooter | |||
count={1} | |||
loadMore={[Function]} | |||
total={1} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for SVW 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="display-flex-center display-flex-column no-file" | |||
> | |||
<span | |||
className="h1 text-muted" | |||
> | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.SVW | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for SVW: no search 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "SVW", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top search-results" | |||
> | |||
<withKeyboardNavigation(Components) | |||
components={Array []} | |||
metrics={Object {}} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "SVW", | |||
} | |||
} | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for SVW: with sub component 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "SVW", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top" | |||
> | |||
<withKeyboardNavigation(Components) | |||
baseComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "SVW", | |||
} | |||
} | |||
components={ | |||
Array [ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
] | |||
} | |||
cycle={true} | |||
metrics={ | |||
Object { | |||
"coverage": Object { | |||
"domain": "Coverage", | |||
"id": "2", | |||
"key": "coverage", | |||
"name": "Coverage", | |||
"type": "PERCENT", | |||
}, | |||
"new_bugs": Object { | |||
"domain": "Reliability", | |||
"id": "4", | |||
"key": "new_bugs", | |||
"name": "New Bugs", | |||
"type": "INT", | |||
}, | |||
} | |||
} | |||
onEndOfList={[Function]} | |||
onGoToParent={[Function]} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "SVW", | |||
} | |||
} | |||
/> | |||
</div> | |||
<ListFooter | |||
count={1} | |||
loadMore={[Function]} | |||
total={1} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for TRK 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="code.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="display-flex-center display-flex-column no-file" | |||
> | |||
<span | |||
className="h1 text-muted" | |||
> | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.TRK | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for TRK: no search 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="code.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "TRK", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top search-results" | |||
> | |||
<withKeyboardNavigation(Components) | |||
components={Array []} | |||
metrics={Object {}} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "TRK", | |||
} | |||
} | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for TRK: with sub component 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="code.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "TRK", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top" | |||
> | |||
<withKeyboardNavigation(Components) | |||
baseComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "TRK", | |||
} | |||
} | |||
components={ | |||
Array [ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
] | |||
} | |||
cycle={true} | |||
metrics={ | |||
Object { | |||
"coverage": Object { | |||
"domain": "Coverage", | |||
"id": "2", | |||
"key": "coverage", | |||
"name": "Coverage", | |||
"type": "PERCENT", | |||
}, | |||
"new_bugs": Object { | |||
"domain": "Reliability", | |||
"id": "4", | |||
"key": "new_bugs", | |||
"name": "New Bugs", | |||
"type": "INT", | |||
}, | |||
} | |||
} | |||
onEndOfList={[Function]} | |||
onGoToParent={[Function]} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "TRK", | |||
} | |||
} | |||
/> | |||
</div> | |||
<ListFooter | |||
count={1} | |||
loadMore={[Function]} | |||
total={1} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for VW 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="display-flex-center display-flex-column no-file" | |||
> | |||
<span | |||
className="h1 text-muted" | |||
> | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.VW | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for VW: no search 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "VW", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top search-results" | |||
> | |||
<withKeyboardNavigation(Components) | |||
components={Array []} | |||
metrics={Object {}} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "VW", | |||
} | |||
} | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correclty when no sub component for VW: with sub component 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<Suggestions | |||
suggestions="code" | |||
/> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
title="projects.page" | |||
/> | |||
<A11ySkipTarget | |||
anchor="code_main" | |||
/> | |||
<withRouter(Search) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "VW", | |||
} | |||
} | |||
onSearchClear={[Function]} | |||
onSearchResults={[Function]} | |||
/> | |||
<div | |||
className="code-components" | |||
> | |||
<div | |||
className="boxed-group spacer-top" | |||
> | |||
<withKeyboardNavigation(Components) | |||
baseComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "VW", | |||
} | |||
} | |||
components={ | |||
Array [ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
] | |||
} | |||
cycle={true} | |||
metrics={ | |||
Object { | |||
"coverage": Object { | |||
"domain": "Coverage", | |||
"id": "2", | |||
"key": "coverage", | |||
"name": "Coverage", | |||
"type": "PERCENT", | |||
}, | |||
"new_bugs": Object { | |||
"domain": "Reliability", | |||
"id": "4", | |||
"key": "new_bugs", | |||
"name": "New Bugs", | |||
"type": "INT", | |||
}, | |||
} | |||
} | |||
onEndOfList={[Function]} | |||
onGoToParent={[Function]} | |||
onHighlight={[Function]} | |||
onSelect={[Function]} | |||
rootComponent={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "foo", | |||
"name": "foo", | |||
"qualifier": "VW", | |||
} | |||
} | |||
/> | |||
</div> | |||
<ListFooter | |||
count={1} | |||
loadMore={[Function]} | |||
total={1} | |||
/> | |||
</div> | |||
</div> | |||
`; |
@@ -21,7 +21,7 @@ import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent' | |||
const routes = [ | |||
{ | |||
indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } | |||
indexRoute: { component: lazyLoadComponent(() => import('./components/AppCode')) } | |||
} | |||
]; | |||
@@ -1401,6 +1401,10 @@ duplications.dups_found_on_deleted_resource=This file contains duplicated blocks | |||
# GENERIC CODE VIEWER | |||
# | |||
#------------------------------------------------------------------------------ | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.TRK=No code files were found for analysis. | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.APP=No projects in this application. | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.VW=No projects, applications, or portfolios in this portfolio. | |||
code_viewer.no_source_code_displayed_due_to_empty_analysis.SVW=No projects, applications, or portfolios in this portfolio. | |||
code_viewer.no_source_code_displayed_due_to_security=Due to security settings, no source code can be displayed. | |||
code_viewer.no_source_code_displayed_due_to_source_removed=The file was removed, no source code can be displayed. | |||