return getFacet(query, 'projectUuids').then(r => extractProjects(r.facet, r.response));
}
-export function getIssuesCount(query: RequestData): Promise<any> {
- const data = { ...query, ps: 1, facetMode: 'effort' };
- return searchIssues(data).then(r => {
- return { issues: r.paging.total, debt: r.debtTotal };
- });
-}
-
export function searchIssueTags(
data: { organization?: string; ps?: number; q?: string } = { ps: 100 }
): Promise<string[]> {
assigned: boolean;
assignees: string[];
component: Component | undefined;
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={this.getAssigneeName(assignee)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(assignee), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(assignee))}
tooltip={this.props.assignees.length === 1 && !this.isAssigneeActive(assignee)}
value={assignee}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={author}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(author), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(author))}
tooltip={this.props.authors.length === 1 && !this.props.authors.includes(author)}
value={author}
/>
createdAt: string;
createdBefore: Date | undefined;
createdInLast: string;
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
const width = barsWidth * data.length - 1 + 10;
const maxValue = max(data.map(d => d.y));
- const format = this.props.facetMode === 'count' ? 'SHORT_INT' : 'SHORT_WORK_DUR';
- const xValues = data.map(d => (d.y === maxValue ? formatMeasure(maxValue, format) : ''));
+ const xValues = data.map(d => (d.y === maxValue ? formatMeasure(maxValue, 'SHORT_INT') : ''));
return (
<BarChart
interface Props {
directories: string[];
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={this.renderName(directory)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(directory), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(directory))}
tooltip={
this.props.directories.length === 1 && !this.props.directories.includes(directory)
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 { Query } from '../utils';
-import FacetBox from '../../../components/facet/FacetBox';
-import FacetHeader from '../../../components/facet/FacetHeader';
-import FacetItem from '../../../components/facet/FacetItem';
-import FacetItemsList from '../../../components/facet/FacetItemsList';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
- facetMode: string;
- onChange: (changes: Partial<Query>) => void;
-}
-
-export default class FacetMode extends React.PureComponent<Props> {
- property = 'facetMode';
-
- handleItemClick = (itemValue: string) => {
- this.props.onChange({ [this.property]: itemValue });
- };
-
- render() {
- const { facetMode } = this.props;
- const modes = ['count', 'effort'];
-
- return (
- <FacetBox property={this.property}>
- <FacetHeader name={translate('issues.facet.mode')} open={false} />
-
- <FacetItemsList>
- {modes.map(mode => (
- <FacetItem
- active={facetMode === mode}
- halfWidth={true}
- key={mode}
- name={translate('issues.facet.mode', mode)}
- onClick={this.handleItemClick}
- value={mode}
- />
- ))}
- </FacetItemsList>
- </FacetBox>
- );
- }
-}
import { collapsePath } from '../../../helpers/path';
interface Props {
- facetMode: string;
files: string[];
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
loading={this.props.loading}
name={this.renderName(file)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(file), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(file))}
tooltip={this.props.files.length === 1 && !this.props.files.includes(file)}
value={file}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
languages: string[];
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
loading={this.props.loading}
name={this.getLanguageName(language)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(language), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(language))}
tooltip={this.props.languages.length === 1 && !this.props.languages.includes(language)}
value={language}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
modules: string[];
onChange: (changes: Partial<Query>) => void;
loading={this.props.loading}
name={this.renderName(module)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(module), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(module))}
tooltip={this.props.modules.length === 1 && !this.props.modules.includes(module)}
value={module}
/>
interface Props {
component: Component | undefined;
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={this.renderName(project)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(project), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(project))}
tooltip={this.props.projects.length === 1 && !this.props.projects.includes(project)}
value={project}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={this.getFacetItemName(resolution)}
onClick={this.handleItemClick}
- stat={formatFacetStat(stat, this.props.facetMode)}
+ stat={formatFacetStat(stat)}
tooltip={
this.props.resolutions.length === 1 &&
resolution !== '' &&
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
languages: string[];
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
loading={this.props.loading}
name={this.getRuleName(rule)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(rule), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(rule))}
tooltip={this.props.rules.length === 1 && !this.props.rules.includes(rule)}
value={rule}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={<SeverityHelper severity={severity} />}
onClick={this.handleItemClick}
- stat={formatFacetStat(stat, this.props.facetMode)}
+ stat={formatFacetStat(stat)}
tooltip={this.props.severities.length === 1 && !this.props.severities.includes(severity)}
value={severity}
/>
import AuthorFacet from './AuthorFacet';
import CreationDateFacet from './CreationDateFacet';
import DirectoryFacet from './DirectoryFacet';
-import FacetMode from './FacetMode';
import FileFacet from './FileFacet';
import LanguageFacet from './LanguageFacet';
import ModuleFacet from './ModuleFacet';
return (
<div className="search-navigator-facets-list">
- <FacetMode facetMode={query.facetMode} onChange={this.props.onFilterChange} />
<TypeFacet
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
types={query.types}
/>
<SeverityFacet
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
stats={facets.severities}
/>
<ResolutionFacet
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
stats={facets.resolutions}
/>
<StatusFacet
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
createdAt={query.createdAt}
createdBefore={query.createdBefore}
createdInLast={query.createdInLast}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
stats={facets.createdAt}
/>
<LanguageFacet
- facetMode={query.facetMode}
languages={query.languages}
loading={this.props.loading}
onChange={this.props.onFilterChange}
stats={facets.languages}
/>
<RuleFacet
- facetMode={query.facetMode}
languages={query.languages}
loading={this.props.loading}
onChange={this.props.onFilterChange}
/>
<TagFacet
component={component}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
{displayProjectsFacet && (
<ProjectFacet
component={component}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
)}
{displayModulesFacet && (
<ModuleFacet
- facetMode={query.facetMode}
loading={this.props.loading}
modules={query.modules}
onChange={this.props.onFilterChange}
{displayDirectoriesFacet && (
<DirectoryFacet
directories={query.directories}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
)}
{displayFilesFacet && (
<FileFacet
- facetMode={query.facetMode}
files={query.files}
loading={this.props.loading}
onChange={this.props.onFilterChange}
assigned={query.assigned}
assignees={query.assignees}
component={component}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
{displayAuthorFacet && (
<AuthorFacet
authors={query.authors}
- facetMode={query.facetMode}
loading={this.props.loading}
onChange={this.props.onFilterChange}
onToggle={this.props.onFacetToggle}
loading={this.props.loading}
name={renderName(category)}
onClick={onClick}
- stat={formatFacetStat(getStat(category), '')}
+ stat={formatFacetStat(getStat(category))}
tooltip={values.length === 1 && !values.includes(category)}
value={category}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={<StatusHelper resolution={undefined} status={status} />}
onClick={this.handleItemClick}
- stat={formatFacetStat(stat, this.props.facetMode)}
+ stat={formatFacetStat(stat)}
tooltip={this.props.statuses.length === 1 && !this.props.statuses.includes(status)}
value={status}
/>
interface Props {
component: Component | undefined;
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
loading={this.props.loading}
name={this.renderTag(tag)}
onClick={this.handleItemClick}
- stat={formatFacetStat(this.getStat(tag), this.props.facetMode)}
+ stat={formatFacetStat(this.getStat(tag))}
tooltip={this.props.tags.length === 1 && !this.props.tags.includes(tag)}
value={tag}
/>
import { translate } from '../../../helpers/l10n';
interface Props {
- facetMode: string;
loading?: boolean;
onChange: (changes: Partial<Query>) => void;
onToggle: (property: string) => void;
</span>
}
onClick={this.handleItemClick}
- stat={formatFacetStat(stat, this.props.facetMode)}
+ stat={formatFacetStat(stat)}
tooltip={this.props.types.length === 1 && !this.props.types.includes(type)}
value={type}
/>
assigned={true}
assignees={[]}
component={undefined}
- facetMode="count"
onChange={jest.fn()}
onToggle={jest.fn()}
open={true}
exports[`should render facets for developer 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
exports[`should render facets for directory 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
exports[`should render facets for global page 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
exports[`should render facets for module 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
exports[`should render facets for project 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
exports[`should render facets when my issues are selected 1`] = `
Array [
- "FacetMode",
"TypeFacet",
"SeverityFacet",
"ResolutionFacet",
queriesEqual,
cleanQuery,
parseAsBoolean,
- parseAsFacetMode,
parseAsArray,
parseAsString,
serializeString,
createdInLast: string;
cwe: string[];
directories: string[];
- facetMode: string;
files: string[];
issues: string[];
languages: string[];
createdInLast: parseAsString(query.createdInLast),
cwe: parseAsArray(query.cwe, parseAsString),
directories: parseAsArray(query.directories, parseAsString),
- facetMode: parseAsFacetMode(query.facetMode),
files: parseAsArray(query.fileUuids, parseAsString),
issues: parseAsArray(query.issues, parseAsString),
languages: parseAsArray(query.languages, parseAsString),
createdInLast: serializeString(query.createdInLast),
cwe: serializeStringArray(query.cwe),
directories: serializeStringArray(query.directories),
- facetMode: query.facetMode === 'effort' ? serializeString(query.facetMode) : undefined,
fileUuids: serializeStringArray(query.files),
issues: serializeStringArray(query.issues),
languages: serializeStringArray(query.languages),
return result;
}
-export function formatFacetStat(stat: number | undefined, mode: string) {
- return stat && formatMeasure(stat, mode === 'effort' ? 'SHORT_WORK_DUR' : 'SHORT_INT');
+export function formatFacetStat(stat: number | undefined) {
+ return stat && formatMeasure(stat, 'SHORT_INT');
}
export interface ReferencedComponent {
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { Link } from 'react-router';
import enhance, { ComposedProps } from './enhance';
import DateFromNow from '../../../components/intl/DateFromNow';
import { getMetricName } from '../helpers/metrics';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { formatMeasure, isDiffMetric } from '../../../helpers/measures';
-import { getComponentIssuesUrl } from '../../../helpers/urls';
+import { formatMeasure } from '../../../helpers/measures';
import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
-import { getBranchLikeQuery } from '../../../helpers/branches';
+import DrilldownLink from '../../../components/shared/DrilldownLink';
export class CodeSmells extends React.PureComponent<ComposedProps> {
renderHeader() {
return this.props.renderHeader('Maintainability', translate('metric.code_smells.name'));
}
- renderDebt(metric: string, type: string) {
+ renderDebt(metric: string) {
const { branchLike, measures, component } = this.props;
const measure = measures.find(measure => measure.metric.key === metric);
const value = measure ? this.props.getValue(measure) : undefined;
- const params = {
- ...getBranchLikeQuery(branchLike),
- resolved: 'false',
- facetMode: 'effort',
- types: type
- };
-
- if (isDiffMetric(metric)) {
- Object.assign(params, { sinceLeakPeriod: 'true' });
- }
return (
- <Link to={getComponentIssuesUrl(component.key, params)}>
+ <DrilldownLink branchLike={branchLike} component={component.key} metric={metric}>
{formatMeasure(value, 'SHORT_WORK_DUR')}
- </Link>
+ </DrilldownLink>
);
}
<div className="overview-domain-measures">
<div className="overview-domain-measure">
<div className="overview-domain-measure-value">
- <span style={{ marginLeft: 30 }}>
- {this.renderDebt('new_technical_debt', 'CODE_SMELL')}
- </span>
+ <span style={{ marginLeft: 30 }}>{this.renderDebt('new_technical_debt')}</span>
{this.props.renderRating('new_maintainability_rating')}
</div>
<div className="overview-domain-measure-label">{getMetricName('new_effort')}</div>
<div className="overview-domain-measures">
<div className="overview-domain-measure">
<div className="overview-domain-measure-value">
- {this.renderDebt('sqale_index', 'CODE_SMELL')}
+ {this.renderDebt('sqale_index')}
{this.props.renderRating('sqale_rating')}
</div>
<div className="overview-domain-measure-label">
});
});
-describe('parseAsFacetMode', () => {
- it('should facets modes correctly', () => {
- expect(query.parseAsFacetMode('debt')).toBe('effort');
- expect(query.parseAsFacetMode('effort')).toBe('effort');
- expect(query.parseAsFacetMode('count')).toBe('count');
- expect(query.parseAsFacetMode('random')).toBe('count');
- });
-});
-
describe('parseAsString', () => {
it('should parse strings correctly', () => {
expect(query.parseAsString('random')).toBe('random');
return undefined;
}
-export function parseAsFacetMode(facetMode: string): string {
- return facetMode === 'debt' || facetMode === 'effort' ? 'effort' : 'count';
-}
-
export function parseAsString(value: string | undefined): string {
return value || '';
}