aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/projects/__tests__/utils-test.ts6
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx38
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/PageHeader.tsx34
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx27
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx40
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/PageHeader-test.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx27
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx23
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap122
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageHeader-test.tsx.snap115
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap113
-rw-r--r--server/sonar-web/src/main/js/apps/projects/query.ts17
-rw-r--r--server/sonar-web/src/main/js/apps/projects/styles.css68
-rw-r--r--server/sonar-web/src/main/js/apps/projects/utils.ts45
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.tsx40
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx194
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Security.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx185
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx89
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Coverage-test.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Duplications-test.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Maintainability-test.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Reliability-test.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Risk-test.tsx56
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Security-test.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/SimpleBubbleChart-test.tsx59
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Visualizations-test.tsx32
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Coverage-test.tsx.snap33
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Duplications-test.tsx.snap27
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Maintainability-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Reliability-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap179
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Security-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap171
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Visualizations-test.tsx.snap40
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties12
40 files changed, 73 insertions, 2122 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/projects/__tests__/utils-test.ts
index 53b73377297..9661ddc8a29 100644
--- a/server/sonar-web/src/main/js/apps/projects/__tests__/utils-test.ts
+++ b/server/sonar-web/src/main/js/apps/projects/__tests__/utils-test.ts
@@ -85,13 +85,13 @@ describe('formatDuration', () => {
describe('fetchProjects', () => {
it('correctly converts the passed arguments to the desired query format', async () => {
- await utils.fetchProjects({ view: 'visualizations' }, true);
+ await utils.fetchProjects({}, true);
expect(searchProjects).toBeCalledWith({
f: 'analysisDate,leakPeriodDate',
facets: utils.FACETS.join(),
filter: 'isFavorite',
p: undefined,
- ps: 99
+ ps: 50
});
await utils.fetchProjects({ view: 'leak' }, false, 3);
@@ -119,7 +119,7 @@ describe('fetchProjects', () => {
],
paging: { total: 2 }
});
- await utils.fetchProjects({ view: 'visualizations' }, true).then(r => {
+ await utils.fetchProjects({}, true).then(r => {
expect(r).toEqual({
facets: {
new_coverage: { NO_DATA: 0 },
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
index 812d23ac385..be94169551e 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
@@ -34,11 +34,10 @@ import { get, save } from '../../../helpers/storage';
import { isLoggedIn } from '../../../helpers/users';
import { ComponentQualifier } from '../../../types/component';
import { CurrentUser, RawQuery } from '../../../types/types';
-import { hasFilterParams, hasVisualizationParams, parseUrlQuery, Query } from '../query';
+import { hasFilterParams, hasViewParams, parseUrlQuery, Query } from '../query';
import '../styles.css';
import { Facets, Project } from '../types';
import { fetchProjects, parseSorting, SORTING_SWITCH } from '../utils';
-import Visualizations from '../visualizations/Visualizations';
import PageHeader from './PageHeader';
import PageSidebar from './PageSidebar';
import ProjectsList from './ProjectsList';
@@ -62,7 +61,6 @@ interface State {
export const LS_PROJECTS_SORT = 'sonarqube.projects.sort';
export const LS_PROJECTS_VIEW = 'sonarqube.projects.view';
-export const LS_PROJECTS_VISUALIZATION = 'sonarqube.projects.visualization';
export class AllProjects extends React.PureComponent<Props, State> {
mounted = false;
@@ -131,7 +129,6 @@ export class AllProjects extends React.PureComponent<Props, State> {
const options: {
sort?: string;
view?: string;
- visualization?: string;
} = {};
if (get(LS_PROJECTS_SORT)) {
options.sort = get(LS_PROJECTS_SORT) || undefined;
@@ -139,16 +136,11 @@ export class AllProjects extends React.PureComponent<Props, State> {
if (get(LS_PROJECTS_VIEW)) {
options.view = get(LS_PROJECTS_VIEW) || undefined;
}
- if (get(LS_PROJECTS_VISUALIZATION)) {
- options.visualization = get(LS_PROJECTS_VISUALIZATION) || undefined;
- }
return options;
};
getView = () => this.state.query.view || 'overall';
- getVisualization = () => this.state.query.visualization || 'risk';
-
handleClearAll = () => {
this.props.router.push({ pathname: this.props.location.pathname });
};
@@ -165,14 +157,12 @@ export class AllProjects extends React.PureComponent<Props, State> {
});
};
- handlePerspectiveChange = ({ view, visualization }: { view: string; visualization?: string }) => {
+ handlePerspectiveChange = ({ view }: { view: string }) => {
const query: {
view: string | undefined;
- visualization: string | undefined;
sort?: string | undefined;
} = {
- view: view === 'overall' ? undefined : view,
- visualization
+ view: view === 'overall' ? undefined : view
};
if (this.state.query.view === 'leak' || view === 'leak') {
@@ -189,16 +179,14 @@ export class AllProjects extends React.PureComponent<Props, State> {
save(LS_PROJECTS_SORT, query.sort);
save(LS_PROJECTS_VIEW, query.view);
- save(LS_PROJECTS_VISUALIZATION, visualization);
};
handleQueryChange(initialMount: boolean) {
const query = parseUrlQuery(this.props.location.query);
const savedOptions = this.getStorageOptions();
- const savedOptionsSet = savedOptions.sort || savedOptions.view || savedOptions.visualization;
+ const savedOptionsSet = savedOptions.sort || savedOptions.view;
- // if there is no visualization parameters (sort, view, visualization), but there are saved preferences in the localStorage
- if (initialMount && !hasVisualizationParams(query) && savedOptionsSet) {
+ if (initialMount && !hasViewParams(query) && savedOptionsSet) {
this.props.router.replace({ pathname: this.props.location.pathname, query: savedOptions });
} else {
this.fetchProjects(query);
@@ -244,7 +232,6 @@ export class AllProjects extends React.PureComponent<Props, State> {
onQueryChange={this.updateLocationQuery}
query={this.state.query}
view={this.getView()}
- visualization={this.getVisualization()}
/>
</div>
</div>
@@ -263,12 +250,10 @@ export class AllProjects extends React.PureComponent<Props, State> {
onPerspectiveChange={this.handlePerspectiveChange}
onQueryChange={this.updateLocationQuery}
onSortChange={this.handleSortChange}
- projects={this.state.projects}
query={this.state.query}
selectedSort={this.getSort()}
total={this.state.total}
view={this.getView()}
- visualization={this.getVisualization()}
/>
</div>
</div>
@@ -280,18 +265,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
return <DeferredSpinner />;
}
- return this.getView() === 'visualizations' ? (
- <div className="layout-page-main-inner">
- {this.state.projects && (
- <Visualizations
- projects={this.state.projects}
- sort={this.state.query.sort}
- total={this.state.total}
- visualization={this.getVisualization()}
- />
- )}
- </div>
- ) : (
+ return (
<div className="layout-page-main-inner">
{this.state.projects && (
<ProjectsList
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.tsx
index 04b1e10c34e..594cea686cb 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.tsx
@@ -20,12 +20,10 @@
import classNames from 'classnames';
import * as React from 'react';
import HomePageSelect from '../../../components/controls/HomePageSelect';
-import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';
import { isLoggedIn } from '../../../helpers/users';
import { CurrentUser, RawQuery } from '../../../types/types';
import SearchFilterContainer from '../filters/SearchFilterContainer';
-import { Project } from '../types';
import ApplicationCreation from './ApplicationCreation';
import PerspectiveSelect from './PerspectiveSelect';
import ProjectCreationMenu from './ProjectCreationMenu';
@@ -34,24 +32,19 @@ import ProjectsSortingSelect from './ProjectsSortingSelect';
interface Props {
currentUser: CurrentUser;
loading: boolean;
- onPerspectiveChange: (x: { view: string; visualization?: string }) => void;
+ onPerspectiveChange: (x: { view: string }) => void;
onQueryChange: (change: RawQuery) => void;
onSortChange: (sort: string, desc: boolean) => void;
- projects?: Project[];
query: RawQuery;
selectedSort: string;
total?: number;
view: string;
- visualization?: string;
}
export default function PageHeader(props: Props) {
- const { loading, total, projects, currentUser, view } = props;
- const limitReached = projects != null && total != null && projects.length < total;
+ const { loading, total, currentUser, view } = props;
const defaultOption = isLoggedIn(currentUser) ? 'name' : 'analysis_date';
- const sortingDisabled = view === 'visualizations' && !limitReached;
-
return (
<div className="page-header">
<div className="display-flex-space-between spacer-top">
@@ -81,21 +74,18 @@ export default function PageHeader(props: Props) {
<PerspectiveSelect
className="projects-topbar-item js-projects-perspective-select"
onChange={props.onPerspectiveChange}
- view={props.view}
- visualization={props.visualization}
+ view={view}
/>
- <Tooltip overlay={sortingDisabled ? translate('projects.sort.disabled') : undefined}>
- <div className={classNames('projects-topbar-item', { disabled: sortingDisabled })}>
- <ProjectsSortingSelect
- className="js-projects-sorting-select"
- defaultOption={defaultOption}
- onChange={props.onSortChange}
- selectedSort={props.selectedSort}
- view={props.view}
- />
- </div>
- </Tooltip>
+ <div className={classNames('projects-topbar-item')}>
+ <ProjectsSortingSelect
+ className="js-projects-sorting-select"
+ defaultOption={defaultOption}
+ onChange={props.onSortChange}
+ selectedSort={props.selectedSort}
+ view={view}
+ />
+ </div>
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
index 417b9e7af82..0c487635681 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
@@ -50,11 +50,10 @@ export interface PageSidebarProps {
onQueryChange: (change: RawQuery) => void;
query: RawQuery;
view: string;
- visualization: string;
}
export default function PageSidebar(props: PageSidebarProps) {
- const { applicationsEnabled, facets, onQueryChange, query, view, visualization } = props;
+ const { applicationsEnabled, facets, onQueryChange, query, view } = props;
const isFiltered = hasFilterParams(query);
const isLeakView = view === 'leak';
const maxFacetValue = getMaxFacetValue(facets);
@@ -63,10 +62,6 @@ export default function PageSidebar(props: PageSidebarProps) {
let linkQuery: RawQuery | undefined = undefined;
if (view !== 'overall') {
linkQuery = { view };
-
- if (view === 'visualizations') {
- linkQuery.visualization = visualization;
- }
}
return (
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx b/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx
index 8a9e0a71fee..a9a39b06aa4 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx
@@ -21,31 +21,24 @@ import { omit } from 'lodash';
import * as React from 'react';
import { components, OptionProps } from 'react-select';
import Select from '../../../components/controls/Select';
-import BubblesIcon from '../../../components/icons/BubblesIcon';
import ListIcon from '../../../components/icons/ListIcon';
import { translate } from '../../../helpers/l10n';
-import { VIEWS, VISUALIZATIONS } from '../utils';
+import { VIEWS } from '../utils';
interface Props {
className?: string;
- onChange: (x: { view: string; visualization?: string }) => void;
+ onChange: (x: { view: string }) => void;
view: string;
- visualization?: string;
}
export interface PerspectiveOption {
- type: string;
value: string;
label: string;
}
export default class PerspectiveSelect extends React.PureComponent<Props> {
handleChange = (option: PerspectiveOption) => {
- if (option && option.type === 'view') {
- this.props.onChange({ view: option.value });
- } else if (option && option.type === 'visualization') {
- this.props.onChange({ view: 'visualizations', visualization: option.value });
- }
+ this.props.onChange({ view: option.value });
};
perspectiveOptionRender = (props: OptionProps<PerspectiveOption, false>) => {
@@ -54,26 +47,18 @@ export default class PerspectiveSelect extends React.PureComponent<Props> {
<components.Option
{...omit(props, ['children', 'className'])}
className={`it__projects-perspective-option-${data.value} ${className}`}>
- {data.type === 'view' && <ListIcon className="little-spacer-right" />}
- {data.type === 'visualization' && <BubblesIcon className="little-spacer-right" />}
+ <ListIcon className="little-spacer-right" />
{props.children}
</components.Option>
);
};
render() {
- const { view, visualization } = this.props;
- const perspective = view === 'visualizations' ? visualization : view;
+ const { view } = this.props;
const options: PerspectiveOption[] = [
...VIEWS.map(opt => ({
- type: 'view',
value: opt.value,
label: translate('projects.view', opt.label)
- })),
- ...VISUALIZATIONS.map(opt => ({
- type: 'visualization',
- value: opt,
- label: translate('projects.visualization', opt)
}))
];
return (
@@ -89,7 +74,7 @@ export default class PerspectiveSelect extends React.PureComponent<Props> {
}}
options={options}
isSearchable={false}
- value={options.find(option => option.value === perspective)}
+ value={options.find(option => option.value === view)}
/>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
index 721837c89a5..819e956a14a 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
@@ -22,12 +22,7 @@ import * as React from 'react';
import { get, save } from '../../../../helpers/storage';
import { ComponentQualifier } from '../../../../types/component';
import { Dict } from '../../../../types/types';
-import {
- AllProjects,
- LS_PROJECTS_SORT,
- LS_PROJECTS_VIEW,
- LS_PROJECTS_VISUALIZATION
-} from '../AllProjects';
+import { AllProjects, LS_PROJECTS_SORT, LS_PROJECTS_VIEW } from '../AllProjects';
jest.mock(
'../ProjectsList',
@@ -78,8 +73,6 @@ beforeEach(() => {
it('renders', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot();
- wrapper.setState({ query: { view: 'visualizations' } });
- expect(wrapper).toMatchSnapshot();
});
it('fetches projects', () => {
@@ -103,8 +96,7 @@ it('fetches projects', () => {
size: undefined,
sort: undefined,
tags: undefined,
- view: undefined,
- visualization: undefined
+ view: undefined
},
false
);
@@ -113,8 +105,7 @@ it('fetches projects', () => {
it('redirects to the saved search', () => {
const localeStorageMock: Dict<string> = {
[LS_PROJECTS_VIEW]: 'leak',
- [LS_PROJECTS_SORT]: 'coverage',
- [LS_PROJECTS_VISUALIZATION]: 'security'
+ [LS_PROJECTS_SORT]: 'coverage'
};
(get as jest.Mock).mockImplementation((key: string) => localeStorageMock[key]);
@@ -125,8 +116,7 @@ it('redirects to the saved search', () => {
pathname: '/projects',
query: {
view: localeStorageMock[LS_PROJECTS_VIEW],
- sort: localeStorageMock[LS_PROJECTS_SORT],
- visualization: localeStorageMock[LS_PROJECTS_VISUALIZATION]
+ sort: localeStorageMock[LS_PROJECTS_SORT]
}
});
});
@@ -145,11 +135,10 @@ it('changes perspective to leak', () => {
wrapper.find('PageHeader').prop<Function>('onPerspectiveChange')({ view: 'leak' });
expect(push).lastCalledWith({
pathname: '/projects',
- query: { view: 'leak', visualization: undefined }
+ query: { view: 'leak' }
});
expect(save).toHaveBeenCalledWith(LS_PROJECTS_SORT, undefined);
expect(save).toHaveBeenCalledWith(LS_PROJECTS_VIEW, 'leak');
- expect(save).toHaveBeenCalledWith(LS_PROJECTS_VISUALIZATION, undefined);
});
it('updates sorting when changing perspective from leak', () => {
@@ -161,27 +150,10 @@ it('updates sorting when changing perspective from leak', () => {
});
expect(push).lastCalledWith({
pathname: '/projects',
- query: { sort: 'coverage', view: undefined, visualization: undefined }
+ query: { sort: 'coverage', view: undefined }
});
expect(save).toHaveBeenCalledWith(LS_PROJECTS_SORT, 'coverage');
expect(save).toHaveBeenCalledWith(LS_PROJECTS_VIEW, undefined);
- expect(save).toHaveBeenCalledWith(LS_PROJECTS_VISUALIZATION, undefined);
-});
-
-it('changes perspective to risk visualization', () => {
- const push = jest.fn();
- const wrapper = shallowRender({}, push);
- wrapper.find('PageHeader').prop<Function>('onPerspectiveChange')({
- view: 'visualizations',
- visualization: 'risk'
- });
- expect(push).lastCalledWith({
- pathname: '/projects',
- query: { view: 'visualizations', visualization: 'risk' }
- });
- expect(save).toHaveBeenCalledWith(LS_PROJECTS_SORT, undefined);
- expect(save).toHaveBeenCalledWith(LS_PROJECTS_VIEW, 'visualizations');
- expect(save).toHaveBeenCalledWith(LS_PROJECTS_VISUALIZATION, 'risk');
});
it('handles favorite projects', () => {
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageHeader-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageHeader-test.tsx
index b563f6d487b..c50803a8740 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageHeader-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageHeader-test.tsx
@@ -37,23 +37,11 @@ it('should not render projects total', () => {
).toBe(false);
});
-it('should render disabled sorting options for visualizations', () => {
- expect(
- shallowRender({
- open: true,
- total: undefined,
- view: 'visualizations',
- visualization: 'coverage'
- })
- ).toMatchSnapshot();
-});
-
it('should render switch the default sorting option for anonymous users', () => {
expect(
shallowRender({
currentUser: { isLoggedIn: true },
- open: true,
- visualization: 'risk'
+ open: true
}).find('ProjectsSortingSelect')
).toMatchSnapshot();
@@ -61,8 +49,7 @@ it('should render switch the default sorting option for anonymous users', () =>
shallowRender({
currentUser: { isLoggedIn: false },
open: true,
- view: 'leak',
- visualization: 'risk'
+ view: 'leak'
}).find('ProjectsSortingSelect')
).toMatchSnapshot();
});
@@ -75,7 +62,6 @@ function shallowRender(props?: {}) {
onPerspectiveChange={jest.fn()}
onQueryChange={jest.fn()}
onSortChange={jest.fn()}
- projects={[]}
query={{ search: 'test' }}
selectedSort="size"
total={12}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
index 4a6feb9d70f..2940711cbbc 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
@@ -24,8 +24,7 @@ import PageSidebar, { PageSidebarProps } from '../PageSidebar';
it('should render correctly', () => {
const sidebar = shallowRender({
query: { size: '3' },
- view: 'overall',
- visualization: 'risk'
+ view: 'overall'
});
expect(sidebar).toMatchSnapshot();
@@ -35,8 +34,7 @@ it('should render correctly with no applications', () => {
const sidebar = shallowRender({
applicationsEnabled: false,
query: { size: '3' },
- view: 'overall',
- visualization: 'risk'
+ view: 'overall'
});
expect(sidebar).toMatchSnapshot();
@@ -45,8 +43,7 @@ it('should render correctly with no applications', () => {
it('should render `leak` view correctly', () => {
const sidebar = shallowRender({
query: { view: 'leak' },
- view: 'leak',
- visualization: 'risk'
+ view: 'leak'
});
expect(sidebar).toMatchSnapshot();
});
@@ -55,33 +52,19 @@ it('should render `leak` view correctly with no applications', () => {
const sidebar = shallowRender({
applicationsEnabled: false,
query: { view: 'leak' },
- view: 'leak',
- visualization: 'risk'
+ view: 'leak'
});
expect(sidebar).toMatchSnapshot();
});
-it('reset function should work correctly with view and visualizations', () => {
- const sidebar = shallowRender({
- query: { view: 'visualizations', visualization: 'bugs' },
- view: 'visualizations',
- visualization: 'bugs'
- });
-
- expect(sidebar.find('ClearAll').exists()).toBe(false);
- sidebar.setProps({ query: { size: '3' } });
- expect(sidebar.find('ClearAll').exists()).toBe(true);
-});
-
function shallowRender(overrides: Partial<PageSidebarProps> = {}) {
return shallow(
<PageSidebar
applicationsEnabled={true}
onClearAll={jest.fn()}
onQueryChange={jest.fn()}
- query={{ view: 'visualizations', visualization: 'bugs' }}
+ query={{ view: 'overall' }}
view="overall"
- visualization="bugs"
{...overrides}
/>
);
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx
index 53b6abc36aa..37f00bee449 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx
@@ -19,7 +19,6 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import BubblesIcon from '../../../../components/icons/BubblesIcon';
import ListIcon from '../../../../components/icons/ListIcon';
import { mockReactSelectOptionProps } from '../../../../helpers/mocks/react-select';
import PerspectiveSelect from '../PerspectiveSelect';
@@ -28,37 +27,25 @@ it('should render correctly', () => {
expect(shallow(<PerspectiveSelect onChange={jest.fn()} view="overall" />)).toMatchSnapshot();
});
-it('should render with coverage selected', () => {
- expect(shallowRender({ view: 'visualizations', visualization: 'coverage' })).toMatchSnapshot();
-});
-
it('should render option correctly', () => {
const wrapper = shallowRender();
const OptionRender = wrapper.instance().perspectiveOptionRender;
- let option = shallow(
- <OptionRender {...mockReactSelectOptionProps({ type: 'view', value: 'test', label: 'test' })} />
+ const option = shallow(
+ <OptionRender {...mockReactSelectOptionProps({ value: 'test', label: 'test' })} />
);
-
expect(option.find(ListIcon).type).toBeDefined();
- option = shallow(
- <OptionRender
- {...mockReactSelectOptionProps({ type: 'visualization', value: 'test', label: '' })}
- />
- );
- expect(option.find(BubblesIcon).type).toBeDefined();
});
it('should handle perspective change correctly', () => {
const onChange = jest.fn();
const instance = shallowRender({ onChange }).instance();
- instance.handleChange({ label: 'overall', value: 'overall', type: 'view' });
- instance.handleChange({ label: 'leak', value: 'leak', type: 'view' });
- instance.handleChange({ label: 'coverage', value: 'coverage', type: 'visualization' });
+ instance.handleChange({ label: 'overall', value: 'overall' });
+ instance.handleChange({ label: 'leak', value: 'leak' });
expect(onChange.mock.calls).toMatchSnapshot();
});
function shallowRender(overrides: Partial<PerspectiveSelect['props']> = {}) {
return shallow<PerspectiveSelect>(
- <PerspectiveSelect onChange={jest.fn()} view="visualizations" {...overrides} />
+ <PerspectiveSelect onChange={jest.fn()} view="overall" {...overrides} />
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
index 566c969e57a..229c1295c61 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
@@ -84,18 +84,6 @@ exports[`renders 1`] = `
onPerspectiveChange={[Function]}
onQueryChange={[Function]}
onSortChange={[Function]}
- projects={
- Array [
- Object {
- "key": "foo",
- "measures": Object {},
- "name": "Foo",
- "qualifier": "TRK",
- "tags": Array [],
- "visibility": "public",
- },
- ]
- }
query={
Object {
"coverage": undefined,
@@ -119,13 +107,11 @@ exports[`renders 1`] = `
"sort": undefined,
"tags": undefined,
"view": undefined,
- "visualization": undefined,
}
}
selectedSort="name"
total={0}
view="overall"
- visualization="risk"
/>
</div>
</div>
@@ -178,7 +164,6 @@ exports[`renders 1`] = `
"sort": undefined,
"tags": undefined,
"view": undefined,
- "visualization": undefined,
}
}
/>
@@ -194,110 +179,3 @@ exports[`renders 1`] = `
</div>
</div>
`;
-
-exports[`renders 2`] = `
-<div
- className="layout-page projects-page"
- id="projects-page"
->
- <Suggestions
- suggestions="projects"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- prioritizeSeoTags={false}
- title="projects.page"
- />
- <h1
- className="a11y-hidden"
- >
- projects.page
- </h1>
- <ScreenPositionHelper
- className="layout-page-side-outer"
- >
- <Component />
- </ScreenPositionHelper>
- <div
- className="layout-page-main"
- >
- <A11ySkipTarget
- anchor="projects_main"
- />
- <div
- role="main"
- >
- <h2
- className="a11y-hidden"
- >
- list_of_projects
- </h2>
- <div
- className="layout-page-header-panel layout-page-main-header"
- >
- <div
- className="layout-page-header-panel-inner layout-page-main-header-inner"
- >
- <div
- className="layout-page-main-inner"
- >
- <PageHeader
- currentUser={
- Object {
- "isLoggedIn": true,
- }
- }
- loading={false}
- onPerspectiveChange={[Function]}
- onQueryChange={[Function]}
- onSortChange={[Function]}
- projects={
- Array [
- Object {
- "key": "foo",
- "measures": Object {},
- "name": "Foo",
- "qualifier": "TRK",
- "tags": Array [],
- "visibility": "public",
- },
- ]
- }
- query={
- Object {
- "view": "visualizations",
- }
- }
- selectedSort="name"
- total={0}
- view="visualizations"
- visualization="risk"
- />
- </div>
- </div>
- </div>
- <div
- className="layout-page-main-inner"
- >
- <Visualizations
- projects={
- Array [
- Object {
- "key": "foo",
- "measures": Object {},
- "name": "Foo",
- "qualifier": "TRK",
- "tags": Array [],
- "visibility": "public",
- },
- ]
- }
- total={0}
- visualization="risk"
- />
- </div>
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
index 31ec1cb22bf..6f89a384375 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
@@ -60,19 +60,17 @@ exports[`should render correctly 1`] = `
onChange={[MockFunction]}
view="overall"
/>
- <Tooltip>
- <div
- className="projects-topbar-item"
- >
- <ProjectsSortingSelect
- className="js-projects-sorting-select"
- defaultOption="analysis_date"
- onChange={[MockFunction]}
- selectedSort="size"
- view="overall"
- />
- </div>
- </Tooltip>
+ <div
+ className="projects-topbar-item"
+ >
+ <ProjectsSortingSelect
+ className="js-projects-sorting-select"
+ defaultOption="analysis_date"
+ onChange={[MockFunction]}
+ selectedSort="size"
+ view="overall"
+ />
+ </div>
</div>
</div>
</div>
@@ -138,88 +136,17 @@ exports[`should render correctly while loading 1`] = `
onChange={[MockFunction]}
view="overall"
/>
- <Tooltip>
- <div
- className="projects-topbar-item"
- >
- <ProjectsSortingSelect
- className="js-projects-sorting-select"
- defaultOption="analysis_date"
- onChange={[MockFunction]}
- selectedSort="size"
- view="overall"
- />
- </div>
- </Tooltip>
- </div>
- </div>
-</div>
-`;
-
-exports[`should render disabled sorting options for visualizations 1`] = `
-<div
- className="page-header"
->
- <div
- className="display-flex-space-between spacer-top"
- >
- <SearchFilterContainer
- onQueryChange={[MockFunction]}
- query={
- Object {
- "search": "test",
- }
- }
- />
- <div
- className="display-flex-center"
- >
- <Connect(withCurrentUser(ProjectCreationMenu))
- className="little-spacer-right"
- />
- <Connect(withAppState(Connect(withCurrentUser(withRouter(ApplicationCreation)))))
- className="little-spacer-right"
- />
- <Connect(HomePageSelect)
- className="spacer-left little-spacer-right"
- currentPage={
- Object {
- "type": "PROJECTS",
- }
- }
- />
- </div>
- </div>
- <div
- className="big-spacer-top display-flex-space-between"
- >
- <div
- className="display-flex-center"
- />
- <div
- className="display-flex-center"
- >
- <PerspectiveSelect
- className="projects-topbar-item js-projects-perspective-select"
- onChange={[MockFunction]}
- view="visualizations"
- visualization="coverage"
- />
- <Tooltip
- overlay="projects.sort.disabled"
+ <div
+ className="projects-topbar-item"
>
- <div
- className="projects-topbar-item disabled"
- >
- <ProjectsSortingSelect
- className="js-projects-sorting-select"
- defaultOption="analysis_date"
- onChange={[MockFunction]}
- selectedSort="size"
- view="visualizations"
- />
- </div>
- </Tooltip>
+ <ProjectsSortingSelect
+ className="js-projects-sorting-select"
+ defaultOption="analysis_date"
+ onChange={[MockFunction]}
+ selectedSort="size"
+ view="overall"
+ />
+ </div>
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap
index 24bf353513a..2bc12d3f297 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap
@@ -12,12 +12,6 @@ Array [
"view": "leak",
},
],
- Array [
- Object {
- "view": "visualizations",
- "visualization": "coverage",
- },
- ],
]
`;
@@ -44,127 +38,20 @@ exports[`should render correctly 1`] = `
Array [
Object {
"label": "projects.view.overall",
- "type": "view",
"value": "overall",
},
Object {
"label": "projects.view.new_code",
- "type": "view",
"value": "leak",
},
- Object {
- "label": "projects.visualization.risk",
- "type": "visualization",
- "value": "risk",
- },
- Object {
- "label": "projects.visualization.reliability",
- "type": "visualization",
- "value": "reliability",
- },
- Object {
- "label": "projects.visualization.security",
- "type": "visualization",
- "value": "security",
- },
- Object {
- "label": "projects.visualization.maintainability",
- "type": "visualization",
- "value": "maintainability",
- },
- Object {
- "label": "projects.visualization.coverage",
- "type": "visualization",
- "value": "coverage",
- },
- Object {
- "label": "projects.visualization.duplications",
- "type": "visualization",
- "value": "duplications",
- },
]
}
value={
Object {
"label": "projects.view.overall",
- "type": "view",
"value": "overall",
}
}
/>
</div>
`;
-
-exports[`should render with coverage selected 1`] = `
-<div>
- <label
- id="aria-projects-perspective"
- >
- projects.perspective
- :
- </label>
- <Select
- aria-labelledby="aria-projects-perspective"
- className="little-spacer-left input-medium it__projects-perspective-select"
- components={
- Object {
- "Option": [Function],
- }
- }
- isClearable={false}
- isSearchable={false}
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "projects.view.overall",
- "type": "view",
- "value": "overall",
- },
- Object {
- "label": "projects.view.new_code",
- "type": "view",
- "value": "leak",
- },
- Object {
- "label": "projects.visualization.risk",
- "type": "visualization",
- "value": "risk",
- },
- Object {
- "label": "projects.visualization.reliability",
- "type": "visualization",
- "value": "reliability",
- },
- Object {
- "label": "projects.visualization.security",
- "type": "visualization",
- "value": "security",
- },
- Object {
- "label": "projects.visualization.maintainability",
- "type": "visualization",
- "value": "maintainability",
- },
- Object {
- "label": "projects.visualization.coverage",
- "type": "visualization",
- "value": "coverage",
- },
- Object {
- "label": "projects.visualization.duplications",
- "type": "visualization",
- "value": "duplications",
- },
- ]
- }
- value={
- Object {
- "label": "projects.visualization.coverage",
- "type": "visualization",
- "value": "coverage",
- }
- }
- />
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/query.ts b/server/sonar-web/src/main/js/apps/projects/query.ts
index 5a457130958..888c45841fb 100644
--- a/server/sonar-web/src/main/js/apps/projects/query.ts
+++ b/server/sonar-web/src/main/js/apps/projects/query.ts
@@ -19,7 +19,6 @@
*/
import { ComponentQualifier } from '../../types/component';
import { Dict, RawQuery } from '../../types/types';
-import { VISUALIZATIONS } from './utils';
type Level = 'ERROR' | 'WARN' | 'OK';
@@ -45,7 +44,6 @@ export interface Query {
search?: string;
sort?: string;
view?: string;
- visualization?: string;
[x: string]: string | number | string[] | undefined;
}
@@ -71,8 +69,7 @@ export function parseUrlQuery(urlQuery: RawQuery): Query {
qualifier: getAsQualifier(urlQuery['qualifier']),
search: getAsString(urlQuery['search']),
sort: getAsString(urlQuery['sort']),
- view: getView(urlQuery['view']),
- visualization: getVisualization(urlQuery['visualization'])
+ view: getView(urlQuery['view'])
};
}
@@ -121,17 +118,17 @@ export function convertToFilter(query: Query, isFavorite: boolean): string {
return conditions.join(' and ');
}
-const visualizationParams = ['sort', 'view', 'visualization'];
+const viewParems = ['sort', 'view'];
export function hasFilterParams(query: Query) {
return Object.keys(query)
- .filter(key => !visualizationParams.includes(key))
+ .filter(key => !viewParems.includes(key))
.some(key => query[key] !== undefined);
}
-export function hasVisualizationParams(query: Query) {
+export function hasViewParams(query: Query) {
return Object.keys(query)
- .filter(key => visualizationParams.includes(key))
+ .filter(key => viewParems.includes(key))
.some(key => query[key] !== undefined);
}
@@ -172,10 +169,6 @@ function getView(value: any): string | undefined {
return typeof value !== 'string' || value === 'overall' ? undefined : value;
}
-function getVisualization(value: string): string | undefined {
- return VISUALIZATIONS.includes(value) ? value : undefined;
-}
-
function convertIssuesRating(metric: string, rating: number): string {
if (rating > 1 && rating < 5) {
return `${metric} >= ${rating}`;
diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css
index 605f5f16453..e6881bc56a7 100644
--- a/server/sonar-web/src/main/js/apps/projects/styles.css
+++ b/server/sonar-web/src/main/js/apps/projects/styles.css
@@ -36,15 +36,6 @@
padding-left: 32px;
}
-.projects-topbar-item.disabled {
- cursor: not-allowed;
- opacity: 0.4;
-}
-
-.projects-topbar-item.disabled * {
- pointer-events: none !important;
-}
-
.projects-topbar-item-search {
position: relative;
flex: 1;
@@ -99,65 +90,6 @@
background-color: var(--blue);
}
-.projects-visualization {
- position: relative;
- height: 600px;
-}
-
-.projects-visualization .measure-details-bubble-chart-axis.y {
- width: 300px;
- left: 15px;
- margin-top: 150px;
- transform-origin: 0 0;
- text-align: center;
-}
-
-.projects-visualizations-footer {
- margin-top: 8px;
- padding: 15px 60px;
- border-top: 1px solid var(--barBorderColor);
- font-size: var(--smallFontSize);
- line-height: 1.4;
- text-align: center;
-}
-
-.projects-visualizations-footer .note {
- font-style: italic;
-}
-
-.measure-details-bubble-chart-title {
- position: absolute;
- left: 20px;
-}
-
-.measure-details-bubble-chart-axis {
- position: absolute;
- color: var(--secondFontColor);
- font-size: var(--smallFontSize);
-}
-
-.measure-details-bubble-chart-axis.x {
- left: 50%;
- bottom: 16px;
- width: 500px;
- margin-left: -250px;
- text-align: center;
-}
-
-.measure-details-bubble-chart-axis.y {
- top: 50%;
- left: -20px;
- transform: rotate(-90deg);
-}
-
-.measure-details-bubble-chart-axis.size {
- display: flex;
- align-items: center;
- justify-content: space-around;
- top: 16px;
- width: 100%;
-}
-
.projects-empty-list {
padding: calc(4 * var(--gridSize)) 0;
text-align: center;
diff --git a/server/sonar-web/src/main/js/apps/projects/utils.ts b/server/sonar-web/src/main/js/apps/projects/utils.ts
index 91547de10ef..58916044832 100644
--- a/server/sonar-web/src/main/js/apps/projects/utils.ts
+++ b/server/sonar-web/src/main/js/apps/projects/utils.ts
@@ -84,17 +84,7 @@ export const VIEWS = [
{ value: 'leak', label: 'new_code' }
];
-export const VISUALIZATIONS = [
- 'risk',
- 'reliability',
- 'security',
- 'maintainability',
- 'coverage',
- 'duplications'
-];
-
const PAGE_SIZE = 50;
-const PAGE_SIZE_VISUALIZATIONS = 99;
const METRICS = [
MetricKey.alert_status,
@@ -129,37 +119,6 @@ const LEAK_METRICS = [
MetricKey.projects
];
-const METRICS_BY_VISUALIZATION: Dict<string[]> = {
- risk: [
- MetricKey.reliability_rating,
- MetricKey.security_rating,
- MetricKey.coverage,
- MetricKey.ncloc,
- MetricKey.sqale_index
- ],
- // x, y, size, color
- reliability: [
- MetricKey.ncloc,
- MetricKey.reliability_remediation_effort,
- MetricKey.bugs,
- MetricKey.reliability_rating
- ],
- security: [
- MetricKey.ncloc,
- MetricKey.security_remediation_effort,
- MetricKey.vulnerabilities,
- MetricKey.security_rating
- ],
- maintainability: [
- MetricKey.ncloc,
- MetricKey.sqale_index,
- MetricKey.code_smells,
- MetricKey.sqale_rating
- ],
- coverage: [MetricKey.complexity, MetricKey.coverage, MetricKey.uncovered_lines],
- duplications: [MetricKey.ncloc, MetricKey.duplicated_lines_density, MetricKey.duplicated_blocks]
-};
-
export const FACETS = [
'reliability_rating',
'security_rating',
@@ -200,7 +159,7 @@ export function parseSorting(sort: string): { sortValue: string; sortDesc: boole
}
export function fetchProjects(query: Query, isFavorite: boolean, pageIndex = 1) {
- const ps = query.view === 'visualizations' ? PAGE_SIZE_VISUALIZATIONS : PAGE_SIZE;
+ const ps = PAGE_SIZE;
const data = convertToQueryData(query, isFavorite, {
p: pageIndex > 1 ? pageIndex : undefined,
ps,
@@ -233,8 +192,6 @@ export function fetchProjects(query: Query, isFavorite: boolean, pageIndex = 1)
function defineMetrics(query: Query): string[] {
switch (query.view) {
- case 'visualizations':
- return METRICS_BY_VISUALIZATION[query.visualization || 'risk'];
case 'leak':
return LEAK_METRICS;
default:
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.tsx
deleted file mode 100644
index b5b7629d8f0..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Project } from '../types';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-export default function Coverage(props: Props) {
- return (
- <SimpleBubbleChart
- {...props}
- sizeMetric={{ key: 'uncovered_lines', type: 'SHORT_INT' }}
- title={translate('projects.visualization', 'coverage')}
- xMetric={{ key: 'complexity', type: 'SHORT_INT' }}
- yDomain={[100, 0]}
- yMetric={{ key: 'coverage', type: 'PERCENT' }}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.tsx
deleted file mode 100644
index 32cd26b0498..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Project } from '../types';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-export default function Duplications(props: Props) {
- return (
- <SimpleBubbleChart
- {...props}
- sizeMetric={{ key: 'duplicated_blocks', type: 'SHORT_INT' }}
- title={translate('projects.visualization', 'duplications')}
- xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
- yMetric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.tsx
deleted file mode 100644
index d49d3de2e1b..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Project } from '../types';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-export default function Maintainability(props: Props) {
- return (
- <SimpleBubbleChart
- {...props}
- colorMetric="sqale_rating"
- sizeMetric={{ key: 'code_smells', type: 'SHORT_INT' }}
- title={translate('projects.visualization', 'maintainability')}
- xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
- yMetric={{ key: 'sqale_index', type: 'SHORT_WORK_DUR' }}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.tsx
deleted file mode 100644
index f214cc62472..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Project } from '../types';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-export default function Reliability(props: Props) {
- return (
- <SimpleBubbleChart
- {...props}
- colorMetric="reliability_rating"
- sizeMetric={{ key: 'bugs', type: 'SHORT_INT' }}
- title={translate('projects.visualization', 'reliability')}
- xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
- yMetric={{ key: 'reliability_remediation_effort', type: 'SHORT_WORK_DUR' }}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx
deleted file mode 100644
index efc148b2cad..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import BubbleChart from '../../../components/charts/BubbleChart';
-import ColorRatingsLegend from '../../../components/charts/ColorRatingsLegend';
-import HelpTooltip from '../../../components/controls/HelpTooltip';
-import QualifierIcon from '../../../components/icons/QualifierIcon';
-import { RATING_COLORS } from '../../../helpers/constants';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { formatMeasure } from '../../../helpers/measures';
-import { isDefined } from '../../../helpers/types';
-import { getProjectUrl } from '../../../helpers/urls';
-import { ComponentQualifier } from '../../../types/component';
-import { Project } from '../types';
-
-const X_METRIC = 'sqale_index';
-const X_METRIC_TYPE = 'SHORT_WORK_DUR';
-const Y_METRIC = 'coverage';
-const Y_METRIC_TYPE = 'PERCENT';
-const SIZE_METRIC = 'ncloc';
-const SIZE_METRIC_TYPE = 'SHORT_INT';
-const COLOR_METRIC_1 = 'reliability_rating';
-const COLOR_METRIC_2 = 'security_rating';
-const COLOR_METRIC_TYPE = 'RATING';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-interface State {
- ratingFilters: { [rating: number]: boolean };
-}
-
-export default class Risk extends React.PureComponent<Props, State> {
- state: State = {
- ratingFilters: {}
- };
-
- getMetricTooltip(metric: { key: string; type: string }, value?: number) {
- const name = translate('metric', metric.key, 'name');
- const formattedValue = value != null ? formatMeasure(value, metric.type) : '–';
- return (
- <div>
- {name}
- {': '}
- {formattedValue}
- </div>
- );
- }
-
- getTooltip(
- project: Project,
- x?: number,
- y?: number,
- size?: number,
- color1?: number,
- color2?: number
- ) {
- return (
- <div className="text-left">
- <div className="little-spacer-bottom display-flex-center display-flex-space-between">
- <strong>{project.name}</strong>
-
- {project.qualifier === ComponentQualifier.Application && (
- <div className="big-spacer-left nowrap">
- <QualifierIcon
- className="little-spacer-right"
- fill="currentColor"
- qualifier={ComponentQualifier.Application}
- />
- {translate('qualifier.APP')}
- </div>
- )}
- </div>
- {this.getMetricTooltip({ key: COLOR_METRIC_1, type: COLOR_METRIC_TYPE }, color1)}
- {this.getMetricTooltip({ key: COLOR_METRIC_2, type: COLOR_METRIC_TYPE }, color2)}
- {this.getMetricTooltip({ key: Y_METRIC, type: Y_METRIC_TYPE }, y)}
- {this.getMetricTooltip({ key: X_METRIC, type: X_METRIC_TYPE }, x)}
- {this.getMetricTooltip({ key: SIZE_METRIC, type: SIZE_METRIC_TYPE }, size)}
- </div>
- );
- }
-
- handleRatingFilterClick = (selection: number) => {
- this.setState(({ ratingFilters }) => {
- return { ratingFilters: { ...ratingFilters, [selection]: !ratingFilters[selection] } };
- });
- };
-
- render() {
- const { ratingFilters } = this.state;
-
- const items = this.props.projects
- .map(project => {
- const x =
- project.measures[X_METRIC] != null ? Number(project.measures[X_METRIC]) : undefined;
- const y =
- project.measures[Y_METRIC] != null ? Number(project.measures[Y_METRIC]) : undefined;
- const size =
- project.measures[SIZE_METRIC] != null ? Number(project.measures[SIZE_METRIC]) : undefined;
- const color1 =
- project.measures[COLOR_METRIC_1] != null
- ? Number(project.measures[COLOR_METRIC_1])
- : undefined;
- const color2 =
- project.measures[COLOR_METRIC_2] != null
- ? Number(project.measures[COLOR_METRIC_2])
- : undefined;
-
- const colorRating =
- color1 !== undefined && color2 !== undefined ? Math.max(color1, color2) : undefined;
-
- // Filter out items that match ratingFilters
- if (colorRating !== undefined && ratingFilters[colorRating]) {
- return undefined;
- }
-
- return {
- x: x || 0,
- y: y || 0,
- size: size || 0,
- color: colorRating !== undefined ? RATING_COLORS[colorRating - 1] : undefined,
- key: project.key,
- tooltip: this.getTooltip(project, x, y, size, color1, color2),
- link: getProjectUrl(project.key)
- };
- })
- .filter(isDefined);
-
- const formatXTick = (tick: number) => formatMeasure(tick, X_METRIC_TYPE);
- const formatYTick = (tick: number) => formatMeasure(tick, Y_METRIC_TYPE);
-
- return (
- <div>
- <BubbleChart
- formatXTick={formatXTick}
- formatYTick={formatYTick}
- height={600}
- items={items}
- padding={[80, 20, 60, 100]}
- yDomain={[100, 0]}
- />
-
- <div className="measure-details-bubble-chart-axis x">
- {translate('metric', X_METRIC, 'name')}
- </div>
- <div className="measure-details-bubble-chart-axis y">
- {translate('metric', Y_METRIC, 'name')}
- </div>
- <div className="measure-details-bubble-chart-axis size">
- <span className="measure-details-bubble-chart-title">
- <span className="text-middle">{translate('projects.visualization.risk')}</span>
- <HelpTooltip className="spacer-left" overlay={this.props.helpText} />
- </span>
- <div>
- <span className="spacer-right">
- {translateWithParameters(
- 'component_measures.legend.color_x',
- translate('projects.worse_of_reliablity_and_security')
- )}
- </span>
- {translateWithParameters(
- 'component_measures.legend.size_x',
- translate('metric', SIZE_METRIC, 'name')
- )}
- <ColorRatingsLegend
- className="big-spacer-top"
- filters={ratingFilters}
- onRatingClick={this.handleRatingFilterClick}
- />
- </div>
- </div>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Security.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Security.tsx
deleted file mode 100644
index 1abfc615c77..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Security.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate } from '../../../helpers/l10n';
-import { Project } from '../types';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-interface Props {
- helpText: string;
- projects: Project[];
-}
-
-export default function Security(props: Props) {
- return (
- <SimpleBubbleChart
- {...props}
- colorMetric="security_rating"
- sizeMetric={{ key: 'vulnerabilities', type: 'SHORT_INT' }}
- title={translate('projects.visualization', 'security')}
- xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
- yMetric={{ key: 'security_remediation_effort', type: 'SHORT_WORK_DUR' }}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx
deleted file mode 100644
index e8376adf59e..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import BubbleChart from '../../../components/charts/BubbleChart';
-import ColorRatingsLegend from '../../../components/charts/ColorRatingsLegend';
-import HelpTooltip from '../../../components/controls/HelpTooltip';
-import QualifierIcon from '../../../components/icons/QualifierIcon';
-import { RATING_COLORS } from '../../../helpers/constants';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { formatMeasure } from '../../../helpers/measures';
-import { isDefined } from '../../../helpers/types';
-import { getProjectUrl } from '../../../helpers/urls';
-import { ComponentQualifier } from '../../../types/component';
-import { Project } from '../types';
-
-interface Metric {
- key: string;
- type: string;
-}
-
-interface Props {
- colorMetric?: string;
- helpText: string;
- projects: Project[];
- sizeMetric: Metric;
- title?: string;
- xMetric: Metric;
- yDomain?: [number, number];
- yMetric: Metric;
-}
-
-interface State {
- ratingFilters: { [rating: number]: boolean };
-}
-
-export default class SimpleBubbleChart extends React.PureComponent<Props, State> {
- state: State = {
- ratingFilters: {}
- };
-
- getMetricTooltip(metric: Metric, value?: number) {
- const name = translate('metric', metric.key, 'name');
- const formattedValue = value != null ? formatMeasure(value, metric.type) : '–';
- return (
- <div>
- {name}
- {': '}
- {formattedValue}
- </div>
- );
- }
-
- getTooltip(project: Project, x?: number, y?: number, size?: number, color?: number) {
- return (
- <div className="text-left">
- <div className="little-spacer-bottom display-flex-center display-flex-space-between">
- <strong>{project.name}</strong>
-
- {project.qualifier === ComponentQualifier.Application && (
- <div className="big-spacer-left nowrap">
- <QualifierIcon
- className="little-spacer-right"
- fill="currentColor"
- qualifier={ComponentQualifier.Application}
- />
- {translate('qualifier.APP')}
- </div>
- )}
- </div>
- {this.getMetricTooltip(this.props.xMetric, x)}
- {this.getMetricTooltip(this.props.yMetric, y)}
- {this.getMetricTooltip(this.props.sizeMetric, size)}
- {/* if `color` is defined then `this.props.colorMetric` is defined too */}
- {color && this.getMetricTooltip({ key: this.props.colorMetric!, type: 'RATING' }, color)}
- </div>
- );
- }
-
- handleRatingFilterClick = (selection: number) => {
- this.setState(({ ratingFilters }) => {
- return { ratingFilters: { ...ratingFilters, [selection]: !ratingFilters[selection] } };
- });
- };
-
- render() {
- const { xMetric, yMetric, sizeMetric, colorMetric } = this.props;
- const { ratingFilters } = this.state;
-
- const items = this.props.projects
- .filter(project => colorMetric == null || project.measures[colorMetric] !== null)
- .map(project => {
- const x =
- project.measures[xMetric.key] != null ? Number(project.measures[xMetric.key]) : undefined;
- const y =
- project.measures[yMetric.key] != null ? Number(project.measures[yMetric.key]) : undefined;
- const size =
- project.measures[sizeMetric.key] != null
- ? Number(project.measures[sizeMetric.key])
- : undefined;
- const color = colorMetric ? Number(project.measures[colorMetric]) : undefined;
-
- // Filter out items that match ratingFilters
- if (color && ratingFilters[color]) {
- return undefined;
- }
-
- return {
- x: x || 0,
- y: y || 0,
- size: size || 0,
- color: color ? RATING_COLORS[color - 1] : undefined,
- key: project.key,
- tooltip: this.getTooltip(project, x, y, size, color),
- link: getProjectUrl(project.key)
- };
- })
- .filter(isDefined);
-
- const formatXTick = (tick: number) => formatMeasure(tick, xMetric.type);
- const formatYTick = (tick: number) => formatMeasure(tick, yMetric.type);
-
- return (
- <div>
- <BubbleChart
- formatXTick={formatXTick}
- formatYTick={formatYTick}
- height={600}
- items={items}
- padding={[colorMetric ? 80 : 40, 20, 60, 100]}
- yDomain={this.props.yDomain}
- />
- <div className="measure-details-bubble-chart-axis x">
- {translate('metric', xMetric.key, 'name')}
- </div>
- <div className="measure-details-bubble-chart-axis y">
- {translate('metric', yMetric.key, 'name')}
- </div>
- <div className="measure-details-bubble-chart-axis size">
- <span className="measure-details-bubble-chart-title">
- <span className="text-middle">{this.props.title}</span>
- <HelpTooltip className="spacer-left" overlay={this.props.helpText} />
- </span>
- <div>
- {colorMetric != null && (
- <span className="spacer-right">
- {translateWithParameters(
- 'component_measures.legend.color_x',
- translate('metric', colorMetric, 'name')
- )}
- </span>
- )}
- {translateWithParameters(
- 'component_measures.legend.size_x',
- translate('metric', sizeMetric.key, 'name')
- )}
- {colorMetric != null && (
- <ColorRatingsLegend
- className="big-spacer-top"
- filters={ratingFilters}
- onRatingClick={this.handleRatingFilterClick}
- />
- )}
- </div>
- </div>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx
deleted file mode 100644
index f25ce4fb271..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { Dict } from '../../../types/types';
-import { Project } from '../types';
-import { localizeSorting } from '../utils';
-import Coverage from './Coverage';
-import Duplications from './Duplications';
-import Maintainability from './Maintainability';
-import Reliability from './Reliability';
-import Risk from './Risk';
-import Security from './Security';
-
-interface Props {
- projects: Project[];
- sort?: string;
- total?: number;
- visualization: string;
-}
-
-export default class Visualizations extends React.PureComponent<Props> {
- renderVisualization(projects: Project[]) {
- const visualizationToComponent: Dict<any> = {
- risk: Risk,
- reliability: Reliability,
- security: Security,
- maintainability: Maintainability,
- coverage: Coverage,
- duplications: Duplications
- };
- const Component = visualizationToComponent[this.props.visualization];
-
- return Component ? (
- <Component
- helpText={translate('projects.visualization', this.props.visualization, 'description')}
- projects={projects}
- />
- ) : null;
- }
-
- renderFooter() {
- const { projects, total, sort } = this.props;
-
- const limitReached = projects != null && total != null && projects.length < total;
-
- return limitReached ? (
- <footer className="projects-visualizations-footer">
- <p className="note spacer-top">
- {translateWithParameters(
- 'projects.limited_set_of_projects',
- projects!.length,
- localizeSorting(sort)
- )}
- </p>
- </footer>
- ) : null;
- }
-
- render() {
- const { projects } = this.props;
-
- return (
- <div className="boxed-group projects-visualizations">
- <main className="projects-visualization">
- {projects != null && this.renderVisualization(projects)}
- </main>
- {this.renderFooter()}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Coverage-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Coverage-test.tsx
deleted file mode 100644
index 9fa76d3f3d9..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Coverage-test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Coverage from '../Coverage';
-
-it('renders', () => {
- expect(shallow(<Coverage helpText="foobar" projects={[]} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Duplications-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Duplications-test.tsx
deleted file mode 100644
index 6fe9cca6eaf..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Duplications-test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Duplications from '../Duplications';
-
-it('renders', () => {
- expect(shallow(<Duplications helpText="foobar" projects={[]} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Maintainability-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Maintainability-test.tsx
deleted file mode 100644
index 940d8974c84..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Maintainability-test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Maintainability from '../Maintainability';
-
-it('renders', () => {
- expect(shallow(<Maintainability helpText="foobar" projects={[]} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Reliability-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Reliability-test.tsx
deleted file mode 100644
index 56be0e385d3..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Reliability-test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Reliability from '../Reliability';
-
-it('renders', () => {
- expect(shallow(<Reliability helpText="foobar" projects={[]} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Risk-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Risk-test.tsx
deleted file mode 100644
index d56b65fa874..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Risk-test.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { mockProject } from '../../../../helpers/mocks/projects';
-import Risk from '../Risk';
-
-it('renders', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should handle filtering', () => {
- const wrapper = shallowRender();
-
- wrapper.instance().handleRatingFilterClick(2);
-
- expect(wrapper.state().ratingFilters).toEqual({ 2: true });
-});
-
-function shallowRender(overrides: Partial<Risk['props']> = {}) {
- const project1 = mockProject({
- key: 'foo',
- measures: {
- complexity: '17.2',
- coverage: '53.5',
- ncloc: '1734',
- sqale_index: '1',
- reliability_rating: '3',
- security_rating: '2'
- },
- name: 'Foo'
- });
- const project2 = mockProject({
- key: 'bar',
- name: 'Bar',
- measures: {}
- });
- return shallow<Risk>(<Risk helpText="foobar" projects={[project1, project2]} {...overrides} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Security-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Security-test.tsx
deleted file mode 100644
index fb3cb5d35e7..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Security-test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Security from '../Security';
-
-it('renders', () => {
- expect(shallow(<Security helpText="foobar" projects={[]} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/SimpleBubbleChart-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/SimpleBubbleChart-test.tsx
deleted file mode 100644
index 399d308bcf0..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/SimpleBubbleChart-test.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { mockProject } from '../../../../helpers/mocks/projects';
-import { ComponentQualifier } from '../../../../types/component';
-import SimpleBubbleChart from '../SimpleBubbleChart';
-
-it('renders', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should handle filtering', () => {
- const wrapper = shallowRender();
-
- wrapper.instance().handleRatingFilterClick(2);
-
- expect(wrapper.state().ratingFilters).toEqual({ 2: true });
-});
-
-function shallowRender(overrides: Partial<SimpleBubbleChart['props']> = {}) {
- const project1 = mockProject({
- measures: { complexity: '17.2', coverage: '53.5', ncloc: '1734', security_rating: '2' }
- });
- const app = mockProject({
- key: 'app',
- measures: { complexity: '23.1', coverage: '87.3', ncloc: '32478', security_rating: '1' },
- name: 'App',
- qualifier: ComponentQualifier.Application
- });
- return shallow<SimpleBubbleChart>(
- <SimpleBubbleChart
- colorMetric="security_rating"
- helpText="foobar"
- projects={[app, project1]}
- sizeMetric={{ key: 'ncloc', type: 'INT' }}
- xMetric={{ key: 'complexity', type: 'INT' }}
- yMetric={{ key: 'coverage', type: 'PERCENT' }}
- {...overrides}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Visualizations-test.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Visualizations-test.tsx
deleted file mode 100644
index 37815b9f1ad..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Visualizations-test.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 Visualizations from '../Visualizations';
-
-it('renders', () => {
- expect(shallow(<Visualizations projects={[]} visualization="coverage" />)).toMatchSnapshot();
-});
-
-it('renders when limit is reached', () => {
- expect(
- shallow(<Visualizations projects={[]} total={1000} visualization="coverage" />)
- ).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Coverage-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Coverage-test.tsx.snap
deleted file mode 100644
index 469481fc92f..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Coverage-test.tsx.snap
+++ /dev/null
@@ -1,33 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<SimpleBubbleChart
- helpText="foobar"
- projects={Array []}
- sizeMetric={
- Object {
- "key": "uncovered_lines",
- "type": "SHORT_INT",
- }
- }
- title="projects.visualization.coverage"
- xMetric={
- Object {
- "key": "complexity",
- "type": "SHORT_INT",
- }
- }
- yDomain={
- Array [
- 100,
- 0,
- ]
- }
- yMetric={
- Object {
- "key": "coverage",
- "type": "PERCENT",
- }
- }
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Duplications-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Duplications-test.tsx.snap
deleted file mode 100644
index 67fba43c178..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Duplications-test.tsx.snap
+++ /dev/null
@@ -1,27 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<SimpleBubbleChart
- helpText="foobar"
- projects={Array []}
- sizeMetric={
- Object {
- "key": "duplicated_blocks",
- "type": "SHORT_INT",
- }
- }
- title="projects.visualization.duplications"
- xMetric={
- Object {
- "key": "ncloc",
- "type": "SHORT_INT",
- }
- }
- yMetric={
- Object {
- "key": "duplicated_lines_density",
- "type": "PERCENT",
- }
- }
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Maintainability-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Maintainability-test.tsx.snap
deleted file mode 100644
index e69496b58a5..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Maintainability-test.tsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<SimpleBubbleChart
- colorMetric="sqale_rating"
- helpText="foobar"
- projects={Array []}
- sizeMetric={
- Object {
- "key": "code_smells",
- "type": "SHORT_INT",
- }
- }
- title="projects.visualization.maintainability"
- xMetric={
- Object {
- "key": "ncloc",
- "type": "SHORT_INT",
- }
- }
- yMetric={
- Object {
- "key": "sqale_index",
- "type": "SHORT_WORK_DUR",
- }
- }
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Reliability-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Reliability-test.tsx.snap
deleted file mode 100644
index e018ca736b8..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Reliability-test.tsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<SimpleBubbleChart
- colorMetric="reliability_rating"
- helpText="foobar"
- projects={Array []}
- sizeMetric={
- Object {
- "key": "bugs",
- "type": "SHORT_INT",
- }
- }
- title="projects.visualization.reliability"
- xMetric={
- Object {
- "key": "ncloc",
- "type": "SHORT_INT",
- }
- }
- yMetric={
- Object {
- "key": "reliability_remediation_effort",
- "type": "SHORT_WORK_DUR",
- }
- }
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap
deleted file mode 100644
index e62a6b6a11e..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap
+++ /dev/null
@@ -1,179 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div>
- <BubbleChart
- displayXGrid={true}
- displayXTicks={true}
- displayYGrid={true}
- displayYTicks={true}
- formatXTick={[Function]}
- formatYTick={[Function]}
- height={600}
- items={
- Array [
- Object {
- "color": "#eabe06",
- "key": "foo",
- "link": Object {
- "pathname": "/dashboard",
- "query": Object {
- "branch": undefined,
- "id": "foo",
- },
- },
- "size": 1734,
- "tooltip": <div
- className="text-left"
- >
- <div
- className="little-spacer-bottom display-flex-center display-flex-space-between"
- >
- <strong>
- Foo
- </strong>
- </div>
- <div>
- metric.reliability_rating.name
- :
- C
- </div>
- <div>
- metric.security_rating.name
- :
- B
- </div>
- <div>
- metric.coverage.name
- :
- 53.5%
- </div>
- <div>
- metric.sqale_index.name
- :
- work_duration.x_minutes.1
- </div>
- <div>
- metric.ncloc.name
- :
- 1.7short_number_suffix.k
- </div>
- </div>,
- "x": 1,
- "y": 53.5,
- },
- Object {
- "color": undefined,
- "key": "bar",
- "link": Object {
- "pathname": "/dashboard",
- "query": Object {
- "branch": undefined,
- "id": "bar",
- },
- },
- "size": 0,
- "tooltip": <div
- className="text-left"
- >
- <div
- className="little-spacer-bottom display-flex-center display-flex-space-between"
- >
- <strong>
- Bar
- </strong>
- </div>
- <div>
- metric.reliability_rating.name
- :
- –
- </div>
- <div>
- metric.security_rating.name
- :
- –
- </div>
- <div>
- metric.coverage.name
- :
- –
- </div>
- <div>
- metric.sqale_index.name
- :
- –
- </div>
- <div>
- metric.ncloc.name
- :
- –
- </div>
- </div>,
- "x": 0,
- "y": 0,
- },
- ]
- }
- padding={
- Array [
- 80,
- 20,
- 60,
- 100,
- ]
- }
- sizeRange={
- Array [
- 5,
- 45,
- ]
- }
- yDomain={
- Array [
- 100,
- 0,
- ]
- }
- />
- <div
- className="measure-details-bubble-chart-axis x"
- >
- metric.sqale_index.name
- </div>
- <div
- className="measure-details-bubble-chart-axis y"
- >
- metric.coverage.name
- </div>
- <div
- className="measure-details-bubble-chart-axis size"
- >
- <span
- className="measure-details-bubble-chart-title"
- >
- <span
- className="text-middle"
- >
- projects.visualization.risk
- </span>
- <HelpTooltip
- className="spacer-left"
- overlay="foobar"
- />
- </span>
- <div>
- <span
- className="spacer-right"
- >
- component_measures.legend.color_x.projects.worse_of_reliablity_and_security
- </span>
- component_measures.legend.size_x.metric.ncloc.name
- <ColorRatingsLegend
- className="big-spacer-top"
- filters={Object {}}
- onRatingClick={[Function]}
- />
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Security-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Security-test.tsx.snap
deleted file mode 100644
index 17e548978ec..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Security-test.tsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<SimpleBubbleChart
- colorMetric="security_rating"
- helpText="foobar"
- projects={Array []}
- sizeMetric={
- Object {
- "key": "vulnerabilities",
- "type": "SHORT_INT",
- }
- }
- title="projects.visualization.security"
- xMetric={
- Object {
- "key": "ncloc",
- "type": "SHORT_INT",
- }
- }
- yMetric={
- Object {
- "key": "security_remediation_effort",
- "type": "SHORT_WORK_DUR",
- }
- }
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap
deleted file mode 100644
index bc2daa21d57..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap
+++ /dev/null
@@ -1,171 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div>
- <BubbleChart
- displayXGrid={true}
- displayXTicks={true}
- displayYGrid={true}
- displayYTicks={true}
- formatXTick={[Function]}
- formatYTick={[Function]}
- height={600}
- items={
- Array [
- Object {
- "color": "#00aa00",
- "key": "app",
- "link": Object {
- "pathname": "/dashboard",
- "query": Object {
- "branch": undefined,
- "id": "app",
- },
- },
- "size": 32478,
- "tooltip": <div
- className="text-left"
- >
- <div
- className="little-spacer-bottom display-flex-center display-flex-space-between"
- >
- <strong>
- App
- </strong>
- <div
- className="big-spacer-left nowrap"
- >
- <QualifierIcon
- className="little-spacer-right"
- fill="currentColor"
- qualifier="APP"
- />
- qualifier.APP
- </div>
- </div>
- <div>
- metric.complexity.name
- :
- 23
- </div>
- <div>
- metric.coverage.name
- :
- 87.3%
- </div>
- <div>
- metric.ncloc.name
- :
- 32,478
- </div>
- <div>
- metric.security_rating.name
- :
- A
- </div>
- </div>,
- "x": 23.1,
- "y": 87.3,
- },
- Object {
- "color": "#b0d513",
- "key": "foo",
- "link": Object {
- "pathname": "/dashboard",
- "query": Object {
- "branch": undefined,
- "id": "foo",
- },
- },
- "size": 1734,
- "tooltip": <div
- className="text-left"
- >
- <div
- className="little-spacer-bottom display-flex-center display-flex-space-between"
- >
- <strong>
- Foo
- </strong>
- </div>
- <div>
- metric.complexity.name
- :
- 17
- </div>
- <div>
- metric.coverage.name
- :
- 53.5%
- </div>
- <div>
- metric.ncloc.name
- :
- 1,734
- </div>
- <div>
- metric.security_rating.name
- :
- B
- </div>
- </div>,
- "x": 17.2,
- "y": 53.5,
- },
- ]
- }
- padding={
- Array [
- 80,
- 20,
- 60,
- 100,
- ]
- }
- sizeRange={
- Array [
- 5,
- 45,
- ]
- }
- />
- <div
- className="measure-details-bubble-chart-axis x"
- >
- metric.complexity.name
- </div>
- <div
- className="measure-details-bubble-chart-axis y"
- >
- metric.coverage.name
- </div>
- <div
- className="measure-details-bubble-chart-axis size"
- >
- <span
- className="measure-details-bubble-chart-title"
- >
- <span
- className="text-middle"
- />
- <HelpTooltip
- className="spacer-left"
- overlay="foobar"
- />
- </span>
- <div>
- <span
- className="spacer-right"
- >
- component_measures.legend.color_x.metric.security_rating.name
- </span>
- component_measures.legend.size_x.metric.ncloc.name
- <ColorRatingsLegend
- className="big-spacer-top"
- filters={Object {}}
- onRatingClick={[Function]}
- />
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Visualizations-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Visualizations-test.tsx.snap
deleted file mode 100644
index a74c4bec92d..00000000000
--- a/server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Visualizations-test.tsx.snap
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div
- className="boxed-group projects-visualizations"
->
- <main
- className="projects-visualization"
- >
- <Coverage
- helpText="projects.visualization.coverage.description"
- projects={Array []}
- />
- </main>
-</div>
-`;
-
-exports[`renders when limit is reached 1`] = `
-<div
- className="boxed-group projects-visualizations"
->
- <main
- className="projects-visualization"
- >
- <Coverage
- helpText="projects.visualization.coverage.description"
- projects={Array []}
- />
- </main>
- <footer
- className="projects-visualizations-footer"
- >
- <p
- className="note spacer-top"
- >
- projects.limited_set_of_projects.0.projects.sort.name
- </p>
- </footer>
-</div>
-`;
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index ddb16c6434a..f72d1fd1dbe 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1030,18 +1030,6 @@ projects.view.overall=Overall Status
projects.view.overall_code=Overall Code
projects.view.new_code=New Code
projects.worse_of_reliablity_and_security=Worse of Reliability and Security
-projects.visualization.risk=Risk
-projects.visualization.risk.description=Get quick insights into the operational risks in your projects. Any color but green indicates immediate risks: Bugs or Vulnerabilities that should be examined. A position at the top or right of the graph means that the longer-term health of the project may be at risk. Green bubbles at the bottom-left are best.
-projects.visualization.reliability=Reliability
-projects.visualization.reliability.description=See bugs' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst bugs in the project. Bubble size indicates bug volume in the project, and each bubble's vertical position reflects the estimated time to address the bugs in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.security=Security
-projects.visualization.security.description=See vulnerabilities' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst vulnerabilities in the project. Bubble size indicates vulnerability volume in the project, and each bubble's vertical position reflects the estimated time to address the vulnerabilities in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.maintainability=Maintainability
-projects.visualization.maintainability.description=See code smells' long-term risks to your projects. The closer a bubble's color is to red, the higher the ratio of technical debt to project size. Bubble size indicates code smell volume in the project, and each bubble's vertical position reflects the estimated time to address the code smells in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.coverage=Coverage
-projects.visualization.coverage.description=See missing test coverage's long-term risks to your projects. Bubble size indicates the volume of uncovered lines in the project, and each bubble's vertical position reflects the volume of missing coverage. Small bubbles on the bottom edge are best.
-projects.visualization.duplications=Duplications
-projects.visualization.duplications.description=See duplications' long-term risks to your projects. Bubble size indicates the volume of duplicated blocks in the project, and each bubble's vertical position reflects the volume of lines in those blocks. Small bubbles on the bottom edge are best.
projects.limited_set_of_projects=Displayed project set limited to the top {0} projects based on current sort: {1}.
projects.facets.quality_gate=Quality Gate
projects.facets.quality_gate.warning_help=Warning status is deprecated. This filter will disappear when no Warning Quality Gate remains.