export default class Measure extends React.PureComponent {
static propTypes = {
+ className: React.PropTypes.string,
measure: React.PropTypes.object,
metric: React.PropTypes.object,
decimals: React.PropTypes.number
}
render() {
- const { measure, metric, decimals } = this.props;
+ const { measure, metric, decimals, className } = this.props;
const finalMetric = metric || measure.metric;
if (finalMetric.type === 'RATING') {
const formattedValue = isDiffMetric(finalMetric)
? formatLeak(measure.leak, finalMetric, { decimals })
: formatMeasure(measure.value, finalMetric.type, { decimals });
-
return (
- <span>
+ <span className={className}>
{formattedValue != null ? formattedValue : '–'}
</span>
);
<div className="layout-page-main">
<div className="layout-page-main-inner">
<PageHeaderContainer onOpenOptionBar={this.openOptionBar} />
- {view === 'overall' &&
+ {view !== 'visualizations' &&
<ProjectsListContainer
isFavorite={this.props.isFavorite}
isFiltered={isFiltered}
organization={this.props.organization}
+ cardType={view}
/>}
- {view === 'overall' &&
+ {view !== 'visualizations' &&
<ProjectsListFooterContainer
query={query}
isFavorite={this.props.isFavorite}
import moment from 'moment';
import { Link } from 'react-router';
import ProjectCardQualityGate from './ProjectCardQualityGate';
-import ProjectCardMeasures from './ProjectCardMeasures';
+import ProjectCardLeakMeasures from './ProjectCardLeakMeasures';
+import ProjectCardOverallMeasures from './ProjectCardOverallMeasures';
import FavoriteContainer from '../../../components/controls/FavoriteContainer';
import Organization from '../../../components/shared/Organization';
import TagsList from '../../../components/tags/TagsList';
import PrivateBadge from '../../../components/common/PrivateBadge';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-export default class ProjectCard extends React.PureComponent {
- props: {
- measures: { [string]: string },
- organization?: {},
- project?: {
- analysisDate?: string,
- key: string,
- name: string,
- tags: Array<string>,
- isFavorite?: boolean,
- organization?: string
- }
- };
+type Props = {
+ measures: { [string]: string },
+ organization?: { key: string },
+ project?: {
+ analysisDate?: string,
+ key: string,
+ name: string,
+ tags: Array<string>,
+ isFavorite?: boolean,
+ organization?: string
+ },
+ type?: string
+};
- render() {
- const { project } = this.props;
+export default function ProjectCard({ measures, organization, project, type }: Props) {
+ if (project == null) {
+ return null;
+ }
- if (project == null) {
- return null;
- }
+ const isProjectAnalyzed = project.analysisDate != null;
+ const isLeakView = type === 'leak';
- const isProjectAnalyzed = project.analysisDate != null;
- // check reliability_rating because only some measures can be loaded
- // if coming from visualizations tab
- const areProjectMeasuresLoaded =
- !isProjectAnalyzed ||
- (this.props.measures != null &&
- this.props.measures['reliability_rating'] != null &&
- this.props.measures['sqale_rating'] != null);
- const displayQualityGate = areProjectMeasuresLoaded && isProjectAnalyzed;
+ let areProjectMeasuresLoaded;
+ // check for particular measures because only some measures can be loaded
+ // if coming from visualizations tab
+ if (isLeakView) {
+ areProjectMeasuresLoaded = measures != null && measures['new_bugs'];
+ } else {
+ areProjectMeasuresLoaded =
+ measures != null &&
+ measures['reliability_rating'] != null &&
+ measures['sqale_rating'] != null;
+ }
- const className = classNames('boxed-group', 'project-card', {
- 'boxed-group-loading': !areProjectMeasuresLoaded
- });
+ const displayQualityGate = areProjectMeasuresLoaded && isProjectAnalyzed;
+ const className = classNames('boxed-group', 'project-card', {
+ 'boxed-group-loading': isProjectAnalyzed && !areProjectMeasuresLoaded
+ });
- return (
- <div data-key={project.key} className={className}>
- {displayQualityGate &&
- <div className="boxed-group-actions">
- <ProjectCardQualityGate status={this.props.measures['alert_status']} />
- </div>}
+ return (
+ <div data-key={project.key} className={className}>
+ {displayQualityGate &&
+ <div className="boxed-group-actions">
+ <ProjectCardQualityGate status={measures['alert_status']} />
+ </div>}
- <div className="boxed-group-header">
- {project.isFavorite != null &&
- <FavoriteContainer className="spacer-right" componentKey={project.key} />}
- <h2 className="project-card-name">
- {this.props.organization == null &&
- project.organization != null &&
- <span className="text-normal">
- <Organization organizationKey={project.organization} />
- </span>}
- <Link to={{ pathname: '/dashboard', query: { id: project.key } }}>
- {project.name}
- </Link>
- </h2>
- {project.visibility === 'private' && <PrivateBadge className="spacer-left" />}
- {project.tags.length > 0 && <TagsList tags={project.tags} customClass="spacer-left" />}
- </div>
+ <div className="boxed-group-header">
+ {project.isFavorite != null &&
+ <FavoriteContainer className="spacer-right" componentKey={project.key} />}
+ <h2 className="project-card-name">
+ {organization == null &&
+ project.organization != null &&
+ <span className="text-normal">
+ <Organization organizationKey={project.organization} />
+ </span>}
+ <Link to={{ pathname: '/dashboard', query: { id: project.key } }}>{project.name}</Link>
+ </h2>
+ {project.visibility === 'private' && <PrivateBadge className="spacer-left" />}
+ {project.tags.length > 0 && <TagsList tags={project.tags} customClass="spacer-left" />}
+ </div>
- {isProjectAnalyzed
- ? <div className="boxed-group-inner">
- {areProjectMeasuresLoaded && <ProjectCardMeasures measures={this.props.measures} />}
+ {isProjectAnalyzed
+ ? <div className="boxed-group-inner">
+ {areProjectMeasuresLoaded && isLeakView
+ ? <ProjectCardLeakMeasures measures={measures} />
+ : <ProjectCardOverallMeasures measures={measures} />}
+ </div>
+ : <div className="boxed-group-inner">
+ <div className="note project-card-not-analyzed">
+ {translate('projects.not_analyzed')}
</div>
- : <div className="boxed-group-inner">
- <div className="note project-card-not-analyzed">
- {translate('projects.not_analyzed')}
- </div>
- </div>}
-
- {isProjectAnalyzed &&
- <div className="project-card-analysis-date note">
- {translateWithParameters(
- 'overview.last_analysis_on_x',
- moment(project.analysisDate).format('LLL')
- )}
</div>}
- </div>
- );
- }
+
+ {isProjectAnalyzed &&
+ <div className="project-card-analysis-date note">
+ {translateWithParameters(
+ 'overview.last_analysis_on_x',
+ moment(project.analysisDate).format('LLL')
+ )}
+ </div>}
+ </div>
+ );
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+//@flow
+import React from 'react';
+import Measure from '../../component-measures/components/Measure';
+import BugIcon from '../../../components/ui/BugIcon';
+import CodeSmellIcon from '../../../components/ui/CodeSmellIcon';
+import Rating from '../../../components/ui/Rating';
+import VulnerabilityIcon from '../../../components/ui/VulnerabilityIcon';
+import { translate } from '../../../helpers/l10n';
+
+type Props = {
+ measures?: { [string]: string }
+};
+
+export default function ProjectCardLeakMeasures({ measures }: Props) {
+ if (measures == null) {
+ return null;
+ }
+
+ return (
+ <div className="project-card-leak-measures">
+ <div className="project-card-measure smaller-card" data-key="new_reliability_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ className="spacer-right"
+ measure={{ leak: measures['new_bugs'] }}
+ metric={{ key: 'new_bugs', type: 'SHORT_INT' }}
+ />
+ <Rating value={measures['new_reliability_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ <BugIcon className="little-spacer-right vertical-bottom" />
+ {translate('metric.new_bugs.name')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="new_security_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ className="spacer-right"
+ measure={{ leak: measures['new_vulnerabilities'] }}
+ metric={{ key: 'new_vulnerabilities', type: 'SHORT_INT' }}
+ />
+ <Rating value={measures['new_security_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ <VulnerabilityIcon className="little-spacer-right vertical-bottom" />
+ {translate('metric.new_vulnerabilities.name')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="new_maintainability_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ className="spacer-right"
+ measure={{ leak: measures['new_code_smells'] }}
+ metric={{ key: 'new_code_smells', type: 'SHORT_INT' }}
+ />
+ <Rating value={measures['new_maintainability_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ <CodeSmellIcon className="little-spacer-right vertical-bottom" />
+ {translate('metric.new_code_smells.name')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="new_coverage">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ measure={{ leak: measures['new_coverage'] }}
+ metric={{ key: 'new_coverage', type: 'PERCENT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric.new_coverage.name')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="new_duplicated_lines_density">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ measure={{ leak: measures['new_duplicated_lines_density'] }}
+ metric={{ key: 'new_duplicated_lines_density', type: 'PERCENT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric.new_duplicated_lines_density.short_name')}
+ </div>
+ </div>
+ </div>
+
+ {measures['new_lines'] != null &&
+ <div className="project-card-measure smaller-card" data-key="new_lines">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Measure
+ measure={{ leak: measures['new_lines'] }}
+ metric={{ key: 'new_lines', type: 'SHORT_INT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric.new_lines.short_name')}
+ </div>
+ </div>
+ </div>}
+ </div>
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 React from 'react';
-import ProjectCardLanguages from './ProjectCardLanguages';
-import Measure from '../../component-measures/components/Measure';
-import Rating from '../../../components/ui/Rating';
-import CoverageRating from '../../../components/ui/CoverageRating';
-import DuplicationsRating from '../../../components/ui/DuplicationsRating';
-import SizeRating from '../../../components/ui/SizeRating';
-import { translate } from '../../../helpers/l10n';
-
-export default class ProjectCardMeasures extends React.PureComponent {
- static propTypes = {
- measures: React.PropTypes.object
- };
-
- render() {
- const { measures } = this.props;
-
- if (measures == null) {
- return null;
- }
-
- return (
- <div className="project-card-measures">
- <div className="project-card-measure" data-key="reliability_rating">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- <Rating value={measures['reliability_rating']} />
- </div>
- <div className="project-card-measure-label">
- {translate('metric_domain.Reliability')}
- </div>
- </div>
- </div>
-
- <div className="project-card-measure" data-key="security_rating">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- <Rating value={measures['security_rating']} />
- </div>
- <div className="project-card-measure-label">
- {translate('metric_domain.Security')}
- </div>
- </div>
- </div>
-
- <div className="project-card-measure" data-key="sqale_rating">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- <Rating value={measures['sqale_rating']} />
- </div>
- <div className="project-card-measure-label">
- {translate('metric_domain.Maintainability')}
- </div>
- </div>
- </div>
-
- <div className="project-card-measure" data-key="coverage">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- {measures['coverage'] != null &&
- <span className="spacer-right">
- <CoverageRating value={measures['coverage']} />
- </span>}
- <Measure
- measure={{ value: measures['coverage'] }}
- metric={{ key: 'coverage', type: 'PERCENT' }}
- />
- </div>
- <div className="project-card-measure-label">
- {translate('metric.coverage.name')}
- </div>
- </div>
- </div>
-
- <div className="project-card-measure" data-key="duplicated_lines_density">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- {measures['duplicated_lines_density'] != null &&
- <span className="spacer-right">
- <DuplicationsRating value={measures['duplicated_lines_density']} />
- </span>}
- <Measure
- measure={{ value: measures['duplicated_lines_density'] }}
- metric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}
- />
- </div>
- <div className="project-card-measure-label">
- {translate('metric.duplicated_lines_density.short_name')}
- </div>
- </div>
- </div>
-
- {measures['ncloc'] != null &&
- <div className="project-card-measure" data-key="ncloc">
- <div className="project-card-measure-inner">
- <div className="project-card-measure-number">
- <span className="spacer-right">
- <SizeRating value={measures['ncloc']} />
- </span>
- <Measure
- measure={{ value: measures['ncloc'] }}
- metric={{ key: 'ncloc', type: 'SHORT_INT' }}
- />
- </div>
- <div className="project-card-measure-label">
- <ProjectCardLanguages distribution={measures['ncloc_language_distribution']} />
- </div>
- </div>
- </div>}
- </div>
- );
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+//@flow
+import React from 'react';
+import ProjectCardLanguages from './ProjectCardLanguages';
+import Measure from '../../component-measures/components/Measure';
+import Rating from '../../../components/ui/Rating';
+import CoverageRating from '../../../components/ui/CoverageRating';
+import DuplicationsRating from '../../../components/ui/DuplicationsRating';
+import SizeRating from '../../../components/ui/SizeRating';
+import { translate } from '../../../helpers/l10n';
+import { formatMeasure } from '../../../helpers/measures';
+
+type Props = {
+ measures?: { [string]: string }
+};
+
+export default function ProjectCardMeasures({ measures }: Props) {
+ if (measures == null) {
+ return null;
+ }
+
+ return (
+ <div className="project-card-measures">
+ <div className="project-card-measure smaller-card" data-key="reliability_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Rating value={measures['reliability_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric_domain.Reliability')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure smaller-card" data-key="security_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Rating value={measures['security_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric_domain.Security')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="sqale_rating">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <Rating value={measures['sqale_rating']} />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric_domain.Maintainability')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="coverage">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ {measures['coverage'] != null &&
+ <span className="spacer-right">
+ <CoverageRating value={measures['coverage']} />
+ </span>}
+ <Measure
+ measure={{ value: measures['coverage'] }}
+ metric={{ key: 'coverage', type: 'PERCENT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric.coverage.name')}
+ </div>
+ </div>
+ </div>
+
+ <div className="project-card-measure" data-key="duplicated_lines_density">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ {measures['duplicated_lines_density'] != null &&
+ <span className="spacer-right">
+ <DuplicationsRating
+ value={formatMeasure(measures['duplicated_lines_density'], 'FLOAT')}
+ />
+ </span>}
+ <Measure
+ measure={{ value: measures['duplicated_lines_density'] }}
+ metric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ {translate('metric.duplicated_lines_density.short_name')}
+ </div>
+ </div>
+ </div>
+
+ {measures['ncloc'] != null &&
+ <div className="project-card-measure" data-key="ncloc">
+ <div className="project-card-measure-inner">
+ <div className="project-card-measure-number">
+ <span className="spacer-right">
+ <SizeRating value={formatMeasure(measures['ncloc'], 'INT')} />
+ </span>
+ <Measure
+ measure={{ value: measures['ncloc'] }}
+ metric={{ key: 'ncloc', type: 'SHORT_INT' }}
+ />
+ </div>
+ <div className="project-card-measure-label">
+ <ProjectCardLanguages distribution={measures['ncloc_language_distribution']} />
+ </div>
+ </div>
+ </div>}
+ </div>
+ );
+}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+//@flow
import React from 'react';
import ProjectCardContainer from './ProjectCardContainer';
import NoFavoriteProjects from './NoFavoriteProjects';
import EmptyInstance from './EmptyInstance';
import EmptySearch from '../../../components/common/EmptySearch';
+type Props = {
+ projects?: Array<string>,
+ isFavorite: boolean,
+ isFiltered: boolean,
+ organization?: { key: string },
+ cardType?: string
+};
+
export default class ProjectsList extends React.PureComponent {
- static propTypes = {
- projects: React.PropTypes.arrayOf(React.PropTypes.string),
- isFavorite: React.PropTypes.bool.isRequired,
- isFiltered: React.PropTypes.bool.isRequired,
- organization: React.PropTypes.object
- };
+ props: Props;
renderNoProjects() {
if (this.props.isFavorite && !this.props.isFiltered) {
key={projectKey}
projectKey={projectKey}
organization={this.props.organization}
+ type={this.props.cardType}
/>
))
: this.renderNoProjects()}
import { receiveFavorites } from '../../../store/favorites/duck';
import { getOrganizations } from '../../../api/organizations';
import { receiveOrganizations } from '../../../store/organizations/duck';
+import { isDiffMetric, getPeriodValue } from '../../../helpers/measures';
const PAGE_SIZE = 50;
const PAGE_SIZE_VISUALIZATIONS = 99;
'ncloc_language_distribution'
];
+const LEAK_METRICS = [
+ 'alert_status',
+ 'new_bugs',
+ 'new_reliability_rating',
+ 'new_vulnerabilities',
+ 'new_security_rating',
+ 'new_code_smells',
+ 'new_maintainability_rating',
+ 'new_coverage',
+ 'new_duplicated_lines_density',
+ 'new_lines'
+];
+
const METRICS_BY_VISUALIZATION = {
risk: ['reliability_rating', 'security_rating', 'coverage', 'ncloc', 'sqale_index'],
// x, y, size, color
Object.keys(byComponentKey).forEach(componentKey => {
const measures = {};
byComponentKey[componentKey].forEach(measure => {
- measures[measure.metric] = measure.value;
+ measures[measure.metric] = isDiffMetric(measure.metric)
+ ? getPeriodValue(measure, 1)
+ : measure.value;
});
toStore[componentKey] = measures;
});
};
const defineMetrics = query => {
- if (query.view === 'visualizations') {
- return METRICS_BY_VISUALIZATION[query.visualization || 'risk'];
- } else {
- return METRICS;
+ switch (query.view) {
+ case 'visualizations':
+ return METRICS_BY_VISUALIZATION[query.visualization || 'risk'];
+ case 'leak':
+ return LEAK_METRICS;
+ default:
+ return METRICS;
}
};
return values.split(',').map(elementGetter);
};
-const getView = rawValue => (rawValue === 'visualizations' ? rawValue : undefined);
+const getView = rawValue => (rawValue === 'overall' ? undefined : rawValue);
const getVisualization = value => {
return VISUALIZATIONS.includes(value) ? value : null;
margin: 0 -15px;
}
+.project-card-leak-measures {
+ padding: 4px 0;
+ margin: 0 -4px 4px;
+ background-color: #fbf3d5;
+ border: 1px solid #eae3c7;
+}
+
.project-card-measures .project-card-measure {
width: 120px;
box-sizing: border-box;
padding: 0 15px;
}
-.project-card-measures .project-card-measure:nth-child(-n+2) {
+.project-card-leak-measures .project-card-measure {
+ width: 140px;
+ box-sizing: border-box;
+ padding: 0 5px;
+}
+
+.project-card-measure.smaller-card {
width: 90px;
}
+@media (max-width: 1130px) {
+ .project-card-leak-measures .project-card-measure {
+ width: 134px;
+ padding: 0 2px;
+ }
+ .project-card-measure.smaller-card {
+ width: 81px;
+ }
+}
+
.project-card-measure {
position: relative;
display: inline-block;
export const saveFavorite = () => save(LOCALSTORAGE_FAVORITE);
-export const VIEWS = ['overall'];
+export const VIEWS = ['overall', 'leak'];
export const VISUALIZATIONS = [
'risk',
// @flow
import React from 'react';
-export default function BugIcon() {
+export default function BugIcon({ className }: { className?: string }) {
/* eslint-disable max-len */
return (
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
+ <svg
+ className={className}
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 16 16"
+ width="16"
+ height="16">
<path
style={{ fill: 'currentColor' }}
d="M11 9h1.3l.5.8.8-.5-.8-1.3H11v-.3l2-2.3V3h-1v2l-1 1.2V5c-.1-.8-.7-1.5-1.4-1.9L11 1.8l-.7-.7-1.8 1.6-1.8-1.6-.7.7 1.5 1.3C6.7 3.5 6.1 4.2 6 5v1.1L5 5V3H4v2.3l2 2.3V8H4.2l-.7 1.2.8.5.4-.7H6v.3l-2 1.9V14h1v-2.4l1-1C6 12 7.1 13 8.4 13h.8c.7 0 1.4-.3 1.8-.9.3-.4.3-.9.2-1.4l.9.9V14h1v-2.8l-2-1.9V9zm-2 2H8V6h1v5z"
// @flow
import React from 'react';
-export default function CodeSmellIcon() {
+export default function CodeSmellIcon({ className }: { className?: string }) {
/* eslint-disable max-len */
return (
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
+ <svg
+ className={className}
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 16 16"
+ width="16"
+ height="16">
<path
style={{ fill: 'currentColor' }}
d="M8 2C4.7 2 2 4.7 2 8s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zm-.5 5.5h.9v.9h-.9v-.9zm-3.8.2c-.1 0-.2-.1-.2-.2 0-.4.1-1.2.6-2S5.3 4.2 5.6 4c.2 0 .3 0 .3.1l1.3 2.3c0 .1 0 .2-.1.2-.1.2-.2.3-.3.5-.1.2-.2.4-.2.5 0 .1-.1.2-.2.2l-2.7-.1zM9.9 12c-.3.2-1.1.5-2 .5-.9 0-1.7-.3-2-.5-.1 0-.1-.2-.1-.3l1.3-2.3c0-.1.1-.1.2-.1.2.1.3.1.5.1s.4 0 .5-.1c.1 0 .2 0 .2.1l1.3 2.3c.2.2.2.3.1.3zm2.5-4.1L9.7 8c-.1 0-.2-.1-.2-.2 0-.2-.1-.4-.2-.5 0-.1-.2-.3-.3-.4-.1 0-.1-.1-.1-.2l1.3-2.3c.1-.1.2-.1.3-.1.3.2 1 .7 1.5 1.5s.6 1.6.6 2c0 0-.1.1-.2.1z"
// @flow
import React from 'react';
-export default function VulnerabilityIcon() {
+export default function VulnerabilityIcon({ className }: { className?: string }) {
/* eslint-disable max-len */
return (
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
+ <svg
+ className={className}
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 16 16"
+ width="16"
+ height="16">
<path
style={{ fill: 'currentColor' }}
d="M10.8 5H6V3.9a2.28 2.28 0 0 1 2-2.5 2.22 2.22 0 0 1 1.8 1.2.48.48 0 0 0 .7.2.48.48 0 0 0 .2-.7A3 3 0 0 0 8 .4a3.34 3.34 0 0 0-3 3.5v1.2a2.16 2.16 0 0 0-2 2.1v4.4a2.22 2.22 0 0 0 2.2 2.2h5.6a2.22 2.22 0 0 0 2.2-2.2V7.2A2.22 2.22 0 0 0 10.8 5zm-2.2 5.5v1.2H7.4v-1.2a1.66 1.66 0 0 1-1.1-1.6A1.75 1.75 0 0 1 8 7.2a1.71 1.71 0 0 1 .6 3.3z"
projects.perspective=Perspective
projects.view_settings=Settings
projects.view.overall=Overall Status
+projects.view.leak=Leak
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.
metric.new_duplicated_lines.description=Duplicated Lines on New Code
metric.new_duplicated_lines_density.description=Duplicated lines on new code balanced by statements
metric.new_duplicated_lines_density.name=Duplicated Lines on New Code (%)
+metric.new_duplicated_lines_density.short_name=New Lines Duplication
metric.new_info_violations.description=New Info issues
metric.new_info_violations.name=New Info Issues
metric.new_it_branch_coverage.description=Integration tests condition coverage of new/changed code
metric.new_minor_violations.name=New Minor Issues
metric.new_lines.name=Lines on New Code
metric.new_lines.description=Non commenting lines on new code
+metric.new_lines.short_name=New Lines
metric.new_overall_branch_coverage.description=Condition coverage of new/changed code by all tests
metric.new_overall_branch_coverage.name=Overall Condition Coverage on New Code
metric.new_overall_conditions_to_cover.description=New conditions to cover by all tests