+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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';
-
-export interface CreateProjectPageHeaderProps {
- additionalActions?: React.ReactNode;
- title: React.ReactNode;
-}
-
-export default function CreateProjectPageHeader(props: CreateProjectPageHeaderProps) {
- const { additionalActions, title } = props;
-
- return (
- <header className="huge-spacer-bottom bordered-bottom overflow-hidden">
- <h1 className="pull-left huge big-spacer-bottom">{title}</h1>
-
- {additionalActions}
- </header>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { getLeakValue } from '../../../components/measure/utils';
-import CoverageRating from '../../../components/ui/CoverageRating';
-import { translate } from '../../../helpers/l10n';
-import { findMeasure, formatMeasure } from '../../../helpers/measures';
-import { MetricKey } from '../../../types/metrics';
-import { MeasureEnhanced } from '../../../types/types';
-
-export interface SecurityHotspotsReviewedProps {
- measures: MeasureEnhanced[];
- useDiffMetric?: boolean;
-}
-
-export default function SecurityHotspotsReviewed(props: SecurityHotspotsReviewedProps) {
- const { measures, useDiffMetric = false } = props;
- const metric = useDiffMetric
- ? MetricKey.new_security_hotspots_reviewed
- : MetricKey.security_hotspots_reviewed;
- const measure = findMeasure(measures, metric);
-
- let value;
- if (measure) {
- value = useDiffMetric ? getLeakValue(measure) : measure.value;
- }
-
- return (
- <>
- {value === undefined ? (
- <span aria-label={translate('no_data')} className="overview-measures-empty-value" />
- ) : (
- <>
- <CoverageRating value={value} />
- <span className="huge spacer-left">{formatMeasure(value, 'PERCENT')}</span>
- </>
- )}
- <span className="big-spacer-left">
- {translate('overview.measures.security_hotspots_reviewed')}
- </span>
- </>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { groupBy, keyBy, sortBy } from 'lodash';
-import * as React from 'react';
-import { getFacets } from '../../../api/issues';
-import { getMeasures } from '../../../api/measures';
-import { getAllMetrics } from '../../../api/metrics';
-import Link from '../../../components/common/Link';
-import Modal from '../../../components/controls/Modal';
-import { ResetButtonLink } from '../../../components/controls/buttons';
-import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
-import QualifierIcon from '../../../components/icons/QualifierIcon';
-import TagsIcon from '../../../components/icons/TagsIcon';
-import DuplicationsRating from '../../../components/ui/DuplicationsRating';
-import { getBranchLikeQuery } from '../../../helpers/branch-like';
-import { ISSUE_TYPES, SEVERITIES } from '../../../helpers/constants';
-import { getLocalizedMetricName, translate } from '../../../helpers/l10n';
-import {
- enhanceMeasuresWithMetrics,
- formatMeasure,
- getDisplayMetrics,
-} from '../../../helpers/measures';
-import { getBranchLikeUrl } from '../../../helpers/urls';
-import { BranchLike } from '../../../types/branch-like';
-import { ComponentQualifier } from '../../../types/component';
-import { FacetName, IssueSeverity, IssueType as IssueTypeEnum } from '../../../types/issues';
-import { MetricType } from '../../../types/metrics';
-import { FacetValue, IssueType, MeasureEnhanced, SourceViewerFile } from '../../../types/types';
-import Measure from '../../measure/Measure';
-import SeverityHelper from '../../shared/SeverityHelper';
-import CoverageRating from '../../ui/CoverageRating';
-import MeasuresOverlayMeasure from './MeasuresOverlayMeasure';
-
-interface Props {
- branchLike: BranchLike | undefined;
- onClose: () => void;
- sourceViewerFile: SourceViewerFile;
-}
-
-interface Measures {
- [metricKey: string]: MeasureEnhanced;
-}
-
-interface State {
- loading: boolean;
- measures: Measures;
- severitiesFacet?: FacetValue[];
- showAllMeasures: boolean;
- tagsFacet?: FacetValue[];
- typesFacet?: FacetValue<IssueType>[];
-}
-
-export default class MeasuresOverlay extends React.PureComponent<Props, State> {
- mounted = false;
- state: State = { loading: true, measures: {}, showAllMeasures: false };
-
- componentDidMount() {
- this.mounted = true;
- this.fetchData();
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- fetchData = () => {
- Promise.all([this.fetchMeasures(), this.fetchIssues()]).then(
- ([measures, facets]) => {
- if (this.mounted) {
- this.setState({ loading: false, measures, ...facets });
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- },
- );
- };
-
- fetchMeasures = () => {
- return getAllMetrics().then((metrics) => {
- const metricKeys = getDisplayMetrics(metrics).map((metric) => metric.key);
-
- // eslint-disable-next-line promise/no-nesting
- return getMeasures({
- component: this.props.sourceViewerFile.key,
- metricKeys: metricKeys.join(),
- ...getBranchLikeQuery(this.props.branchLike),
- }).then((measures) => {
- const withMetrics = enhanceMeasuresWithMetrics(measures, metrics).filter(
- (measure) => measure.metric,
- );
- return keyBy(withMetrics, (measure) => measure.metric.key);
- });
- });
- };
-
- fetchIssues = () => {
- return getFacets(
- {
- componentKeys: this.props.sourceViewerFile.key,
- resolved: 'false',
- ...getBranchLikeQuery(this.props.branchLike),
- },
- [FacetName.Types, FacetName.Severities, FacetName.Tags],
- ).then(({ facets }) => {
- const severitiesFacet = facets.find((f) => f.property === 'severities');
- const tagsFacet = facets.find((f) => f.property === 'tags');
- const typesFacet = facets.find((f) => f.property === 'types');
- return {
- severitiesFacet: severitiesFacet?.values,
- tagsFacet: tagsFacet?.values,
- typesFacet: typesFacet && (typesFacet.values as FacetValue<IssueType>[]),
- };
- });
- };
-
- handleAllMeasuresClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.currentTarget.blur();
- this.setState({ showAllMeasures: true });
- };
-
- renderMeasure = (measure: MeasureEnhanced | undefined) => {
- return measure ? <MeasuresOverlayMeasure key={measure.metric.key} measure={measure} /> : null;
- };
-
- renderLines = () => {
- const { measures } = this.state;
-
- return (
- <div className="measures-viewer-section">
- <div className="measures-viewer-card">
- <div className="measures">
- {this.renderMeasure(measures.lines)}
- {this.renderMeasure(measures.ncloc)}
- {this.renderMeasure(measures.comment_lines)}
- {this.renderMeasure(measures.comment_lines_density)}
- </div>
-
- <div className="measures">
- {this.renderMeasure(measures.cognitive_complexity)}
- {this.renderMeasure(measures.complexity)}
- {this.renderMeasure(measures.function_complexity)}
- </div>
- </div>
- </div>
- );
- };
-
- renderBigMeasure = (measure: MeasureEnhanced | undefined) => {
- return measure ? (
- <div className="measure measure-big" data-metric={measure.metric.key}>
- <span className="measure-value">
- <Measure
- metricKey={measure.metric.key}
- metricType={measure.metric.type}
- value={measure.value}
- />
- </span>
- <span className="measure-name">{getLocalizedMetricName(measure.metric, true)}</span>
- </div>
- ) : null;
- };
-
- renderIssues = () => {
- const { measures, severitiesFacet, tagsFacet, typesFacet } = this.state;
- return (
- <div className="measures-viewer-section">
- <div className="measures-viewer-card">
- <div className="measures">
- {this.renderBigMeasure(measures.violations)}
- {this.renderBigMeasure(measures.sqale_index)}
- </div>
- {measures.violations && !!measures.violations.value && (
- <>
- {typesFacet && (
- <div className="measures">
- {sortBy(typesFacet, (f) => ISSUE_TYPES.indexOf(f.val as IssueTypeEnum)).map(
- (f) => (
- <div className="measure measure-one-line" key={f.val}>
- <span className="measure-name">
- <IssueTypeIcon className="little-spacer-right" query={f.val} />
- {translate('issue.type', f.val)}
- </span>
- <span className="measure-value">
- {formatMeasure(f.count, MetricType.ShortInteger)}
- </span>
- </div>
- ),
- )}
- </div>
- )}
- {severitiesFacet && (
- <div className="measures">
- {sortBy(severitiesFacet, (f) => SEVERITIES.indexOf(f.val as IssueSeverity)).map(
- (f) => (
- <div className="measure measure-one-line" key={f.val}>
- <span className="measure-name">
- <SeverityHelper severity={f.val} />
- </span>
- <span className="measure-value">
- {formatMeasure(f.count, MetricType.ShortInteger)}
- </span>
- </div>
- ),
- )}
- </div>
- )}
- {tagsFacet && (
- <div className="measures">
- {tagsFacet.map((f) => (
- <div className="measure measure-one-line" key={f.val}>
- <span className="measure-name">
- <TagsIcon className="little-spacer-right" />
- {f.val}
- </span>
- <span className="measure-value">
- {formatMeasure(f.count, MetricType.ShortInteger)}
- </span>
- </div>
- ))}
- </div>
- )}
- </>
- )}
- </div>
- </div>
- );
- };
-
- renderCoverage = () => {
- const { coverage } = this.state.measures;
- if (!coverage) {
- return null;
- }
- return (
- <div className="measures-viewer-section">
- <div className="measures-viewer-card">
- <div className="measures">
- <div className="measures-chart">
- <CoverageRating size="big" value={coverage.value} />
- </div>
- <div className="measure measure-big" data-metric={coverage.metric.key}>
- <span className="measure-value">
- <Measure
- metricKey={coverage.metric.key}
- metricType={coverage.metric.type}
- value={coverage.value}
- />
- </span>
- <span className="measure-name">{getLocalizedMetricName(coverage.metric)}</span>
- </div>
- </div>
-
- <div className="measures">
- {this.renderMeasure(this.state.measures.uncovered_lines)}
- {this.renderMeasure(this.state.measures.lines_to_cover)}
- {this.renderMeasure(this.state.measures.uncovered_conditions)}
- {this.renderMeasure(this.state.measures.conditions_to_cover)}
- </div>
- </div>
- </div>
- );
- };
-
- renderDuplications = () => {
- const { duplicated_lines_density: duplications } = this.state.measures;
- if (!duplications) {
- return null;
- }
- return (
- <div className="measures-viewer-section">
- <div className="measures-viewer-card">
- <div className="measures">
- <div className="measures-chart">
- <DuplicationsRating
- muted={duplications.value === undefined}
- size="big"
- value={Number(duplications.value || 0)}
- />
- </div>
- <div className="measure measure-big" data-metric={duplications.metric.key}>
- <span className="measure-value">
- <Measure
- metricKey={duplications.metric.key}
- metricType={duplications.metric.type}
- value={duplications.value}
- />
- </span>
- <span className="measure-name">
- {getLocalizedMetricName(duplications.metric, true)}
- </span>
- </div>
- </div>
-
- <div className="measures">
- {this.renderMeasure(this.state.measures.duplicated_blocks)}
- {this.renderMeasure(this.state.measures.duplicated_lines)}
- </div>
- </div>
- </div>
- );
- };
-
- renderTests = () => {
- const { measures } = this.state;
- return (
- <div className="measures-viewer">
- <div className="measures-viewer-section measures-viewer-section-limited">
- <div className="measures-viewer-card">
- <div className="measures">
- {this.renderMeasure(measures.tests)}
- {this.renderMeasure(measures.test_success_density)}
- {this.renderMeasure(measures.test_failures)}
- {this.renderMeasure(measures.test_errors)}
- {this.renderMeasure(measures.skipped_tests)}
- {this.renderMeasure(measures.test_execution_time)}
- </div>
- </div>
- </div>
- </div>
- );
- };
-
- renderDomain = (domain: string, measures: MeasureEnhanced[]) => {
- return (
- <div className="measures-viewer-card" key={domain}>
- <div className="measures">
- <div className="measure measure-big">
- <span className="measure-name">{translate('metric_domain', domain)}</span>
- </div>
- {sortBy(
- measures.filter((measure) => measure.value !== undefined),
- (measure) => getLocalizedMetricName(measure.metric),
- ).map((measure) => this.renderMeasure(measure))}
- </div>
- </div>
- );
- };
-
- renderAllMeasures = () => {
- const domains = groupBy(Object.values(this.state.measures), (measure) => measure.metric.domain);
- const domainKeys = Object.keys(domains);
- const odd = domainKeys.filter((_, index) => index % 2 === 1);
- const even = domainKeys.filter((_, index) => index % 2 === 0);
- return (
- <div className="measures-viewer measures-viewer-secondary">
- <div className="measures-viewer-section">
- {odd.map((domain) => this.renderDomain(domain, domains[domain]))}
- </div>
- <div className="measures-viewer-section">
- {even.map((domain) => this.renderDomain(domain, domains[domain]))}
- </div>
- </div>
- );
- };
-
- render() {
- const { branchLike, sourceViewerFile } = this.props;
- const { loading } = this.state;
-
- const header = translate('component_viewer.file_measures');
- return (
- <Modal contentLabel={header} onRequestClose={this.props.onClose} size="large">
- <div className="modal-head">
- <h2>{header}</h2>
- </div>
- <div className="modal-body modal-container">
- <div className="measures-viewer-header big-spacer-bottom">
- <div>
- <QualifierIcon
- className="little-spacer-right"
- qualifier={ComponentQualifier.Project}
- />
- <Link to={getBranchLikeUrl(sourceViewerFile.project, branchLike)}>
- {sourceViewerFile.projectName}
- </Link>
- </div>
-
- <div className="display-flex-center little-spacer-top">
- <QualifierIcon className="little-spacer-right" qualifier={sourceViewerFile.q} />
- {sourceViewerFile.path}
- </div>
- </div>
-
- {loading ? (
- <i className="spinner" />
- ) : (
- <>
- {sourceViewerFile.q === ComponentQualifier.TestFile ? (
- this.renderTests()
- ) : (
- <div className="measures-viewer">
- {this.renderLines()}
- {this.renderIssues()}
- {this.renderCoverage()}
- {this.renderDuplications()}
- </div>
- )}
- </>
- )}
-
- <div className="spacer-top">
- {this.state.showAllMeasures ? (
- this.renderAllMeasures()
- ) : (
- <a className="js-show-all-measures" href="#" onClick={this.handleAllMeasuresClick}>
- {translate('component_viewer.show_all_measures')}
- </a>
- )}
- </div>
- </div>
-
- <footer className="modal-foot">
- <ResetButtonLink onClick={this.props.onClose}>{translate('close')}</ResetButtonLink>
- </footer>
- </Modal>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
-import { getLocalizedMetricName } from '../../../helpers/l10n';
-import { isMetricKey, MetricKey } from '../../../types/metrics';
-import { Metric } from '../../../types/types';
-import Measure from '../../measure/Measure';
-
-export interface MeasureWithMetric {
- metric: Metric;
- value?: string;
-}
-
-interface Props {
- measure: MeasureWithMetric;
-}
-
-export default function MeasuresOverlayMeasure({ measure }: Props) {
- return (
- <div
- className="measure measure-one-line"
- data-metric={measure.metric.key}
- key={measure.metric.key}
- >
- <span className="measure-name">
- {isMetricKey(measure.metric.key) &&
- [MetricKey.bugs, MetricKey.vulnerabilities, MetricKey.code_smells].includes(
- measure.metric.key,
- ) && <IssueTypeIcon className="little-spacer-right" query={measure.metric.key} />}
- {getLocalizedMetricName(measure.metric)}
- </span>
- <span className="measure-value">
- <Measure
- metricKey={measure.metric.key}
- metricType={measure.metric.type}
- small
- value={measure.value}
- />
- </span>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.bar-chart-bar {
- fill: var(--blue);
-}
-
-.bar-chart-tick {
- fill: var(--secondFontColor);
- font-size: var(--smallFontSize);
- text-anchor: middle;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { max } from 'd3-array';
-import { scaleBand, ScaleBand, scaleLinear, ScaleLinear } from 'd3-scale';
-import * as React from 'react';
-import Tooltip from '../controls/Tooltip';
-import './BarChart.css';
-
-interface DataPoint {
- tooltip?: React.ReactNode;
- description: string;
- x: number;
- y: number;
-}
-
-interface Props<T> {
- barsWidth: number;
- data: Array<DataPoint & T>;
- height: number;
- onBarClick?: (point: DataPoint & T) => void;
- padding?: [number, number, number, number];
- width: number;
- xTicks?: string[];
- xValues?: string[];
-}
-
-export default class BarChart<T> extends React.PureComponent<Props<T>> {
- handleClick = (point: DataPoint & T) => {
- if (this.props.onBarClick) {
- this.props.onBarClick(point);
- }
- };
-
- renderXTicks = (xScale: ScaleBand<number>, yScale: ScaleLinear<number, number>) => {
- const { data, xTicks = [] } = this.props;
-
- if (!xTicks.length) {
- return null;
- }
-
- const ticks = xTicks.map((tick, index) => {
- const point = data[index];
- const x = Math.round((xScale(point.x) as number) + xScale.bandwidth() / 2);
- const y = yScale.range()[0];
- const d = data[index];
- const text = (
- <text
- className="bar-chart-tick"
- dy="1.5em"
- // eslint-disable-next-line react/no-array-index-key
- key={index}
- onClick={() => this.handleClick(point)}
- style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }}
- x={x}
- y={y}
- >
- {tick}
- </text>
- );
- return (
- // eslint-disable-next-line react/no-array-index-key
- <Tooltip key={index} overlay={d.tooltip || undefined}>
- {text}
- </Tooltip>
- );
- });
- return <g>{ticks}</g>;
- };
-
- renderXValues = (xScale: ScaleBand<number>, yScale: ScaleLinear<number, number>) => {
- const { data, xValues = [] } = this.props;
-
- if (!xValues.length) {
- return null;
- }
-
- const ticks = xValues.map((value, index) => {
- const point = data[index];
- const x = Math.round((xScale(point.x) as number) + xScale.bandwidth() / 2);
- const y = yScale(point.y);
- const text = (
- <text
- className="bar-chart-tick"
- dy="-1em"
- // eslint-disable-next-line react/no-array-index-key
- key={index}
- onClick={() => this.handleClick(point)}
- style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }}
- x={x}
- y={y}
- >
- {value}
- </text>
- );
- return (
- // eslint-disable-next-line react/no-array-index-key
- <Tooltip key={index} overlay={point.tooltip || undefined}>
- {text}
- </Tooltip>
- );
- });
- return <g>{ticks}</g>;
- };
-
- renderBars = (xScale: ScaleBand<number>, yScale: ScaleLinear<number, number>) => {
- const bars = this.props.data.map((point, index) => {
- const x = Math.round(xScale(point.x) as number);
- const maxY = yScale.range()[0];
- const y = Math.round(yScale(point.y)) - /* minimum bar height */ 1;
- const height = maxY - y;
- const rect = (
- <rect
- className="bar-chart-bar"
- aria-label={point.description}
- height={height}
- // eslint-disable-next-line react/no-array-index-key
- key={index}
- onClick={() => this.handleClick(point)}
- style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }}
- width={this.props.barsWidth}
- x={x}
- y={y}
- />
- );
- return (
- // eslint-disable-next-line react/no-array-index-key
- <Tooltip key={index} overlay={point.tooltip || undefined}>
- {rect}
- </Tooltip>
- );
- });
- return <g>{bars}</g>;
- };
-
- render() {
- const { barsWidth, data, width, height, padding = [10, 10, 10, 10] } = this.props;
-
- const availableWidth = width - padding[1] - padding[3];
- const availableHeight = height - padding[0] - padding[2];
-
- const innerPadding = (availableWidth - barsWidth * data.length) / (data.length - 1);
- const relativeInnerPadding = innerPadding / (innerPadding + barsWidth);
-
- const maxY = max(data, (d) => d.y) as number;
- const xScale = scaleBand<number>()
- .domain(data.map((d) => d.x))
- .range([0, availableWidth])
- .paddingInner(relativeInnerPadding);
- const yScale = scaleLinear().domain([0, maxY]).range([availableHeight, 0]);
-
- return (
- <svg className="bar-chart" height={height} width={width}>
- <g transform={`translate(${padding[3]}, ${padding[0]})`}>
- {this.renderXTicks(xScale, yScale)}
- {this.renderXValues(xScale, yScale)}
- {this.renderBars(xScale, yScale)}
- </g>
- </svg>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { extent, max } from 'd3-array';
-import { ScaleLinear, scaleLinear } from 'd3-scale';
-import { curveBasis, area as d3Area, line as d3Line } from 'd3-shape';
-import * as React from 'react';
-import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer';
-import './LineChart.css';
-
-interface DataPoint {
- x: number;
- y?: number;
-}
-
-interface Props {
- backdropConstraints?: [number, number];
- data: DataPoint[];
- displayBackdrop?: boolean;
- displayPoints?: boolean;
- displayVerticalGrid?: boolean;
- domain?: [number, number];
- height: number;
- padding?: [number, number, number, number];
- width?: number;
- xTicks?: {}[];
- xValues?: {}[];
-}
-
-export default class LineChart extends React.PureComponent<Props> {
- renderBackdrop(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const { displayBackdrop = true } = this.props;
-
- if (!displayBackdrop) {
- return null;
- }
-
- const area = d3Area<DataPoint>()
- .x((d) => xScale(d.x))
- .y0(yScale.range()[0])
- .y1((d) => yScale(d.y || 0))
- .defined((d) => d.y != null)
- .curve(curveBasis);
-
- let { data } = this.props;
-
- if (this.props.backdropConstraints) {
- const c = this.props.backdropConstraints;
- data = data.filter((d) => c[0] <= d.x && d.x <= c[1]);
- }
-
- return <path className="line-chart-backdrop" d={area(data) as string} />;
- }
-
- renderPoints(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const { displayPoints = true } = this.props;
-
- if (!displayPoints) {
- return null;
- }
-
- const points = this.props.data
- .filter((point) => point.y != null)
- .map((point, index) => {
- const x = xScale(point.x);
- const y = yScale(point.y || 0);
-
- // eslint-disable-next-line react/no-array-index-key
- return <circle className="line-chart-point" cx={x} cy={y} key={index} r="3" />;
- });
-
- return <g>{points}</g>;
- }
-
- renderVerticalGrid(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const { displayVerticalGrid = true } = this.props;
-
- if (!displayVerticalGrid) {
- return null;
- }
-
- const lines = this.props.data.map((point, index) => {
- const x = xScale(point.x);
- const y1 = yScale.range()[0];
- const y2 = yScale(point.y || 0);
-
- // eslint-disable-next-line react/no-array-index-key
- return <line className="line-chart-grid" key={index} x1={x} x2={x} y1={y1} y2={y2} />;
- });
-
- return <g>{lines}</g>;
- }
-
- renderXTicks(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const { xTicks = [] } = this.props;
-
- if (!xTicks.length) {
- return null;
- }
-
- const ticks = xTicks.map((tick, index) => {
- const point = this.props.data[index];
- const x = xScale(point.x);
- const y = yScale.range()[0];
-
- return (
- // eslint-disable-next-line react/no-array-index-key
- <text className="line-chart-tick sw-body-sm" dy="1.5em" key={index} x={x} y={y}>
- {tick}
- </text>
- );
- });
-
- return <g>{ticks}</g>;
- }
-
- renderXValues(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const { xValues = [] } = this.props;
-
- if (!xValues.length) {
- return null;
- }
-
- const ticks = xValues.map((value, index) => {
- const point = this.props.data[index];
- const x = xScale(point.x);
- const y = yScale(point.y || 0);
-
- return (
- // eslint-disable-next-line react/no-array-index-key
- <text className="line-chart-tick sw-body-sm" dy="-1em" key={index} x={x} y={y}>
- {value}
- </text>
- );
- });
-
- return <g>{ticks}</g>;
- }
-
- renderLine(xScale: ScaleLinear<number, number>, yScale: ScaleLinear<number, number>) {
- const p = d3Line<DataPoint>()
- .x((d) => xScale(d.x))
- .y((d) => yScale(d.y || 0))
- .defined((d) => d.y != null)
- .curve(curveBasis);
-
- return <path className="line-chart-path" d={p(this.props.data) as string} />;
- }
-
- renderChart = (width: number) => {
- const { height, padding = [10, 10, 10, 10] } = this.props;
-
- if (!width || !height) {
- return <div />;
- }
-
- const availableWidth = width - padding[1] - padding[3];
- const availableHeight = height - padding[0] - padding[2];
-
- const xScale = scaleLinear()
- .domain(extent(this.props.data, (d) => d.x) as [number, number])
- .range([0, availableWidth]);
-
- const yScale = scaleLinear().range([availableHeight, 0]);
-
- if (this.props.domain) {
- yScale.domain(this.props.domain);
- } else {
- const maxY = max(this.props.data, (d) => d.y) as number;
- yScale.domain([0, maxY]);
- }
-
- return (
- <svg className="line-chart" height={height} width={width}>
- <g transform={`translate(${padding[3]}, ${padding[0]})`}>
- {this.renderVerticalGrid(xScale, yScale)}
- {this.renderBackdrop(xScale, yScale)}
- {this.renderLine(xScale, yScale)}
- {this.renderPoints(xScale, yScale)}
- {this.renderXTicks(xScale, yScale)}
- {this.renderXValues(xScale, yScale)}
- </g>
- </svg>
- );
- };
-
- render() {
- return this.props.width !== undefined ? (
- this.renderChart(this.props.width)
- ) : (
- <AutoSizer disableHeight>{(size) => this.renderChart(size.width)}</AutoSizer>
- );
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { Link, LinkProps } from 'design-system';
+import * as React from 'react';
+import { useDocUrl } from '../../helpers/docs';
+
+type Props = Omit<LinkProps, 'to'> & { to: string; innerRef?: React.Ref<HTMLAnchorElement> };
+
+export default function DocumentationLink({ to, innerRef, ...props }: Props) {
+ const toStatic = useDocUrl(to);
+ return <Link ref={innerRef} to={toStatic} target="_blank" {...props} />;
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.location-index {
- position: relative;
- display: inline-block;
- vertical-align: top;
- line-height: 16px;
- padding-left: 6px;
- padding-right: 6px;
- border-radius: 2px;
- background-color: var(--conciseIssueRed);
- color: #fff;
- font-family: var(--baseFontFamily);
- font-size: var(--smallFontSize);
- transition: background-color 0.3s ease;
- user-select: none;
-}
-
-.selected > .location-index,
-.location-index.selected {
- background-color: var(--conciseIssueRedSelected);
-}
-
-.location-index.muted {
- background-color: var(--gray80);
-}
-
-.location-index.is-leading:first-child {
- margin-left: 0;
-}
-
-.location-index[tabindex] {
- cursor: pointer;
-}
-
-.location-index[tabindex]:hover,
-a:hover > .location-index {
- background-color: var(--conciseIssueRedSelected);
-}
-
-.location-index[tabindex]:focus {
- outline: none;
-}
-
-.source-line-code-inner .location-index {
- line-height: 16px;
- margin: 1px;
- margin-left: 4px;
- margin-right: 4px;
-}
-
-.source-line-code-inner .location-index + .location-index {
- margin-left: 0;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import './LocationIndex.css';
-
-interface Props {
- children?: React.ReactNode;
- leading?: boolean;
- onClick?: () => void;
- selected?: boolean;
- [x: string]: any;
-}
-
-export default function LocationIndex(props: Props) {
- const { children, leading, onClick, selected, ...other } = props;
- const clickAttributes = onClick ? { onClick, role: 'button', tabIndex: 0 } : {};
- // put {...others} because Tooltip sets some event handlers
- return (
- <div
- className={classNames('location-index', {
- 'is-leading': leading,
- selected,
- })}
- {...clickAttributes}
- {...other}
- >
- {children}
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.measures-link {
- border: none;
-}
-
-.measures-link > span {
- border-bottom: 1px solid var(--lightBlue);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import MeasuresIcon from '../../components/icons/MeasuresIcon';
-import { translate } from '../../helpers/l10n';
-import { getComponentDrilldownUrl } from '../../helpers/urls';
-import { BranchLike } from '../../types/branch-like';
-import Link from './Link';
-import './MeasuresLink.css';
-
-export interface MeasuresLinkProps {
- branchLike?: BranchLike;
- className?: string;
- component: string;
- label?: string;
- metric: string;
-}
-
-export default function MeasuresLink(props: MeasuresLinkProps) {
- const { branchLike, className, component, label, metric } = props;
- return (
- <Link
- className={classNames('measures-link', className)}
- to={getComponentDrilldownUrl({ branchLike, componentKey: component, metric })}
- >
- <MeasuresIcon className="little-spacer-right" size={14} />
- <span>{label || translate('portfolio.measures_link')}</span>
- </Link>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { colors } from '../../app/theme';
-import { translate } from '../../helpers/l10n';
-import Tooltip from './Tooltip';
-
-interface Props {
- className?: string;
- disabled?: boolean;
- onClick: () => void;
- tooltip?: string;
-}
-
-export default class BackButton extends React.PureComponent<Props> {
- handleClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.currentTarget.blur();
- if (!this.props.disabled) {
- this.props.onClick();
- }
- };
-
- renderIcon = () => {
- const { tooltip = translate('issues.return_to_list') } = this.props;
- return (
- <svg height="24" viewBox="0 0 21 24" width="21" aria-label={tooltip}>
- <path
- d="M3.845 12.9992l5.993 5.993.052.056c.049.061.093.122.129.191.082.159.121.339.111.518-.006.102-.028.203-.064.298-.149.39-.537.652-.954.644-.102-.002-.204-.019-.301-.052-.148-.05-.273-.135-.387-.241l-8.407-8.407 8.407-8.407.056-.052c.061-.048.121-.092.19-.128.116-.06.237-.091.366-.108.076-.004.075-.004.153-.003.155.015.3.052.437.129.088.051.169.115.239.19.246.266.33.656.214.999-.051.149-.135.273-.241.387l-5.983 5.984c5.287-.044 10.577-.206 15.859.013.073.009.091.009.163.027.187.047.359.15.49.292.075.081.136.175.18.276.044.101.072.209.081.319.032.391-.175.775-.521.962-.097.052-.202.089-.311.107-.073.012-.091.01-.165.013H3.845z"
- fill={this.props.disabled ? colors.disableGrayText : colors.secondFontColor}
- />
- </svg>
- );
- };
-
- render() {
- const { tooltip = translate('issues.return_to_list') } = this.props;
- return (
- <Tooltip overlay={tooltip}>
- <a
- className={classNames(
- 'link-no-underline',
- { 'cursor-not-allowed': this.props.disabled },
- this.props.className,
- )}
- href="#"
- onClick={this.handleClick}
- >
- {this.renderIcon()}
- </a>
- </Tooltip>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { colors } from '../../app/theme';
-import { translate } from '../../helpers/l10n';
-import Tooltip from './Tooltip';
-
-interface Props {
- className?: string;
- tooltip?: string;
- onClick: () => void;
-}
-
-export default class ReloadButton extends React.PureComponent<Props> {
- handleClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.currentTarget.blur();
- this.props.onClick();
- };
-
- render() {
- const { tooltip = translate('reload') } = this.props;
- return (
- <Tooltip overlay={tooltip}>
- <a
- className={classNames('link-no-underline', this.props.className)}
- href="#"
- onClick={this.handleClick}
- >
- {
- <svg height="24" viewBox="0 0 18 24" width="18">
- <path
- d="M16.6454 8.1084c-.3-.5-.9-.7-1.4-.4-.5.3-.7.9-.4 1.4.9 1.6 1.1 3.4.6 5.1-.5 1.7-1.7 3.2-3.2 4-3.3 1.8-7.4.6-9.1-2.7-1.8-3.1-.8-6.9 2.1-8.8v3.3h2v-7h-7v2h3.9c-3.7 2.5-5 7.5-2.8 11.4 1.6 3 4.6 4.6 7.7 4.6 1.4 0 2.8-.3 4.2-1.1 2-1.1 3.5-3 4.2-5.2.6-2.2.3-4.6-.8-6.6z"
- fill={colors.secondFontColor}
- />
- </svg>
- }
- </a>
- </Tooltip>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-interface Props extends IconProps {
- animated?: boolean;
- inverseDirection?: boolean;
-}
-
-export default function ArrowIcon({
- animated = false,
- fill = 'currentColor',
- inverseDirection = false,
- ...iconProps
-}: Props) {
- const style: React.CSSProperties = {};
- if (inverseDirection) {
- style.transform = 'scaleX(-1)';
- }
-
- if (animated) {
- style.transition = 'transform 0.2s';
- }
- return (
- <Icon style={style} {...iconProps}>
- <path
- d="M13.99 6.867l.668.005H4.99l3.04-3.046a.79.79 0 00.23-.561.789.789 0 00-.23-.56l-.473-.474A.784.784 0 006.998 2a.784.784 0 00-.558.23L1.23 7.44A.783.783 0 001 8c0 .212.081.41.23.56l5.21 5.21c.149.148.347.23.558.23.212 0 .41-.082.559-.23l.472-.473a.782.782 0 000-1.106L4.956 9.128H14a.819.819 0 00.801-.81v-.67c0-.435-.376-.78-.812-.78z"
- fill={fill}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function BubblesIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon style={{ fillRule: 'nonzero' }} {...iconProps}>
- <path
- d="M4.1 10.2c1 0 1.9.8 1.9 1.9S5.1 14 4.1 14s-1.9-.8-1.9-1.9.8-1.9 1.9-1.9m0-2C2 8.2.2 9.9.2 12.1S1.9 16 4.1 16 8 14.3 8 12.1 6.2 8.2 4.1 8.2zM10.3 2c2 0 3.7 1.7 3.7 3.7s-1.7 3.7-3.7 3.7-3.8-1.6-3.8-3.7S8.2 2 10.3 2m0-2C7.1 0 4.5 2.6 4.5 5.7s2.6 5.7 5.7 5.7S16 8.9 16 5.7 13.4 0 10.3 0z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function ChevronLeftIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M4.404 8.28l4.604 4.602a.382.382 0 0 0 .279.118c.108 0 .2-.04.279-.118l1.03-1.03a.382.382 0 0 0 .117-.278.382.382 0 0 0-.117-.28L7.3 8l3.295-3.294a.382.382 0 0 0 .117-.28.382.382 0 0 0-.117-.279l-1.03-1.03A.382.382 0 0 0 9.286 3a.382.382 0 0 0-.278.118L4.404 7.72A.382.382 0 0 0 4.287 8c0 .108.04.201.117.28z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function ChevronUpIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M8.28 4.404l4.602 4.604a.382.382 0 0 1 .118.279c0 .108-.04.2-.118.279l-1.03 1.03a.382.382 0 0 1-.278.117.382.382 0 0 1-.28-.117L8 7.3l-3.294 3.295a.382.382 0 0 1-.28.117.382.382 0 0 1-.279-.117l-1.03-1.03A.382.382 0 0 1 3 9.286c0-.107.04-.2.118-.278L7.72 4.404A.382.382 0 0 1 8 4.287c.108 0 .201.04.28.117z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function ChevronsIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M6.27 11.07L3.2 8l3.07-3.07L5.33 4l-4 4 4 4 .94-.93zm3.46 0L12.8 8 9.73 4.93l.94-.93 4 4-4 4-.94-.93z"
- fill={fill}
- fillRule="nonzero"
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { colors } from '../../app/theme';
-import Icon, { IconProps } from './Icon';
-
-export default function ClockIcon({ className, ...iconProps }: IconProps) {
- return (
- <Icon className={classNames('icon-clock', className)} {...iconProps}>
- <g fill="#fff" stroke={colors.gray60} transform="matrix(1.4 0 0 1.4 .3 .7)">
- <circle cx="5.5" cy="5.2" r="5" />
- <path d="M5.6 2.9v2.7l2-.5" fillRule="nonzero" />
- </g>
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function CogIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M14.922 9.704L13.6 8.696a4.55 4.551 0 000-1.057l1.323-1.006a.62.62 0 00.156-.805l-1.374-2.314a.658.658 0 00-.795-.28l-1.558.611a5.275 5.275 0 00-.935-.53l-.24-1.611a.631.631 0 00-.635-.537H6.787a.63.63 0 00-.633.532l-.239 1.616a5.62 5.62 0 00-.934.53l-1.563-.611a.645.645 0 00-.789.273L1.253 5.826a.616.616 0 00.157.808L2.73 7.64a4.517 4.519 0 000 1.058L1.41 9.705a.62.62 0 00-.158.805l1.374 2.314a.658.658 0 00.794.28l1.557-.61c.293.206.607.384.937.53l.24 1.61a.63.63 0 00.632.537H9.54a.63.63 0 00.634-.532l.24-1.616a5.62 5.62 0 00.934-.53l1.563.611a.645.645 0 00.789-.273l1.382-2.328a.618.619 0 00-.16-.8zm-6.758 1.382C6.51 11.087 5.17 9.78 5.17 8.17S6.51 5.252 8.164 5.252c1.654 0 2.995 1.307 2.995 2.917-.001 1.61-1.342 2.915-2.995 2.917z"
- fill={fill}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function ExpandSnippetIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <g fill="none" fillRule="evenodd">
- <path
- d="M8 1v4H4"
- stroke={fill}
- strokeWidth="2"
- transform="scale(-.83333 -.84583) rotate(45 7.66 -19.75)"
- />
- <path d="M3 5.78h10v1.7H3z" fill={fill} />
- <path d="M7.17 2.4h1.66v5.07H7.17z" fill={fill} />
- <g>
- <path
- d="M8.16 1.81V6.1H3.9"
- stroke={fill}
- strokeWidth="2"
- transform="scale(.83333 .84583) rotate(45 -4.2 13.2)"
- />
- <path d="M13 10.01H3v-1.7h10z" fill={fill} />
- <path d="M8.83 13.4H7.17V9.15h1.66z" fill={fill} />
- </g>
- </g>
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function FilterIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M13.957 2.333a.536.536 0 0 1-.12.596l-4.2 4.202v6.323a.552.552 0 0 1-.333.503.632.632 0 0 1-.213.043.51.51 0 0 1-.384-.162l-2.181-2.182a.542.542 0 0 1-.162-.383V7.13L2.162 2.929a.536.536 0 0 1-.12-.596A.552.552 0 0 1 2.547 2h10.908c.222 0 .418.137.503.333z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { colors } from '../../app/theme';
-import Icon, { IconProps } from './Icon';
-
-interface Props extends IconProps {
- filled?: boolean;
-}
-
-export default function HomeIcon({ className, fill, filled = false, ...iconProps }: Props) {
- return (
- <Icon
- className={classNames(className, 'icon-outline', { 'is-filled': filled })}
- style={{ color: fill || colors.homepageColor }}
- {...iconProps}
- >
- <g transform="matrix(0.870918,0,0,0.870918,0.978227,0.978227)">
- <path d="M15.9,7.8L8.2,0.1C8.1,0 7.9,0 7.8,0.1L0.1,7.8C0,7.9 0,8.1 0.1,8.2C0.2,8.3 0.2,8.3 0.3,8.3L2.2,8.3L2.2,15.8C2.2,15.9 2.2,15.9 2.3,16C2.3,16 2.4,16.1 2.5,16.1L6.2,16.1C6.3,16.1 6.5,16 6.5,15.8L6.5,10.5L9.7,10.5L9.7,15.8C9.7,15.9 9.8,16.1 10,16.1L13.7,16.1C13.8,16.1 14,16 14,15.8L14,8.2L15.9,8.2C16,8.2 16,8.2 16.1,8.1C16,8 16.1,7.9 15.9,7.8Z" />
- </g>
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function LightBulbIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M10.042 5.083a.3.3 0 0 1-.292.292.3.3 0 0 1-.292-.292c0-.629-.975-.875-1.458-.875a.3.3 0 0 1-.292-.291A.3.3 0 0 1 8 3.625c.848 0 2.042.447 2.042 1.458zm1.458 0c0-1.823-1.85-2.916-3.5-2.916S4.5 3.26 4.5 5.083c0 .584.237 1.194.62 1.641.173.2.373.392.556.602.647.774 1.194 1.686 1.285 2.716h2.078c.091-1.03.638-1.942 1.285-2.716.183-.21.383-.402.556-.602.383-.447.62-1.057.62-1.64zm1.167 0c0 .94-.31 1.75-.94 2.443-.628.693-1.457 1.668-1.53 2.643a.876.876 0 0 1 .428.748.852.852 0 0 1-.228.583.852.852 0 0 1 .228.583c0 .301-.155.575-.41.739a.89.89 0 0 1 .118.428c0 .592-.465.875-.993.875A1.479 1.479 0 0 1 8 15a1.479 1.479 0 0 1-1.34-.875c-.528 0-.993-.283-.993-.875 0-.146.045-.3.118-.428a.876.876 0 0 1-.41-.739c0-.218.082-.428.228-.583a.852.852 0 0 1-.228-.583c0-.301.164-.593.428-.748-.073-.975-.902-1.95-1.53-2.643a3.507 3.507 0 0 1-.94-2.443C3.333 2.604 5.694 1 8 1c2.306 0 4.667 1.604 4.667 4.083z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function ListIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M15.045 11.526v1.007q0 0.204-0.149 0.354t-0.354 0.149h-13.084q-0.204 0-0.354-0.149t-0.149-0.354v-1.006q0-0.204 0.149-0.354t0.354-0.149h13.084q0.204 0 0.354 0.149t0.149 0.354zM15.045 8.506v1.006q0 0.204-0.149 0.354t-0.354 0.149h-13.084q-0.204 0-0.354-0.149t-0.149-0.354v-1.006q0-0.204 0.149-0.354t0.354-0.149h13.084q0.204 0 0.354 0.149t0.149 0.354zM15.045 5.487v1.006q0 0.204-0.149 0.354t-0.354 0.149h-13.084q-0.204 0-0.354-0.149t-0.149-0.354v-1.006q0-0.204 0.149-0.354t0.354-0.149h13.084q0.204 0 0.354 0.149t0.149 0.354zM15.045 2.468v1.006q0 0.204-0.149 0.354t-0.354 0.149h-13.084q-0.204 0-0.354-0.149t-0.149-0.354v-1.006q0-0.204 0.149-0.354t0.354-0.149h13.084q0.204 0 0.354 0.149t0.149 0.354z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { colors } from '../../app/theme';
-import Icon, { IconProps } from './Icon';
-
-export default function LongLivingBranchIcon({ fill, ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <g transform="translate(5, 0)">
- <path
- d="M4.5 8c0-.9-.6-1.7-1.5-1.9V4c.9-.2 1.5-1 1.5-1.9 0-1.1-.9-2-2-2s-2 .9-2 2C.5 3 1.1 3.8 2 4v2.1C1.1 6.3.5 7.1.5 8s.6 1.7 1.5 2v2.1c-.9.2-1.5 1-1.5 1.9 0 1.1.9 2 2 2s2-.9 2-2c0-.9-.6-1.7-1.5-1.9V10c.9-.3 1.5-1 1.5-2zm-3-5.9c0-.6.4-1 1-1s1 .4 1 1-.4 1-1 1-1-.5-1-1zm0 5.9c0-.6.4-1 1-1s1 .4 1 1-.4 1-1 1-1-.4-1-1zm2 6c0 .6-.4 1-1 1s-1-.4-1-1 .4-1 1-1 1 .5 1 1z"
- style={{ fill: fill || colors.blue }}
- />
- </g>
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { colors } from '../../app/theme';
-import Icon, { IconProps } from './Icon';
-
-interface Props extends IconProps {
- hasUnread?: boolean;
-}
-
-export default function NotificationIcon({
- fill = 'currentColor',
- hasUnread,
- ...iconProps
-}: Props) {
- return (
- <Icon {...iconProps}>
- {hasUnread ? (
- <>
- <path
- d="M8 1a.875.875 0 0 0-.875.875v.57c-2.009.418-3.498 2.118-3.498 4.242 0 2.798-.987 3.652-1.516 4.22a.856.856 0 0 0-.236.593.875.875 0 0 0 .877.875h10.496a.875.875 0 0 0 .877-.875.854.854 0 0 0-.236-.594c-.497-.534-1.388-1.342-1.494-3.76a2.814 2.814 0 0 1-.768.108A2.814 2.814 0 0 1 8.814 4.44a2.814 2.814 0 0 1 .665-1.818 4.543 4.543 0 0 0-.604-.178v-.57A.875.875 0 0 0 8 1zM6.25 13.25a1.75 1.75 0 0 0 3.5 0h-3.5z"
- style={{ fill }}
- />
- <circle cx="11.627" cy="4.441" r="2" style={{ fill: colors.blue }} />
- </>
- ) : (
- <path
- d="M8 15a1.75 1.75 0 0 0 1.75-1.75h-3.5c0 .967.784 1.75 1.75 1.75zm5.89-4.094c-.529-.567-1.517-1.421-1.517-4.218 0-2.125-1.49-3.826-3.499-4.243v-.57a.875.875 0 1 0-1.748 0v.57c-2.01.417-3.499 2.118-3.499 4.243 0 2.797-.988 3.65-1.517 4.218a.854.854 0 0 0-.235.594.876.876 0 0 0 .878.875h10.494a.876.876 0 0 0 .878-.875.853.853 0 0 0-.235-.594z"
- style={{ fill }}
- />
- )}
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function PinIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M7.25 7.25v-3.5a.243.243 0 0 0-.07-.18A.243.243 0 0 0 7 3.5a.243.243 0 0 0-.18.07.243.243 0 0 0-.07.18v3.5c0 .073.023.133.07.18.047.047.107.07.18.07a.243.243 0 0 0 .18-.07.243.243 0 0 0 .07-.18zM12.5 10a.482.482 0 0 1-.148.352.482.482 0 0 1-.352.148H8.648l-.398 3.773a.29.29 0 0 1-.082.161.219.219 0 0 1-.16.066H8c-.141 0-.224-.07-.25-.211L7.156 10.5H4a.482.482 0 0 1-.352-.148A.482.482 0 0 1 3.5 10c0-.641.204-1.217.613-1.73.409-.513.871-.77 1.387-.77v-4a.96.96 0 0 1-.703-.297A.96.96 0 0 1 4.5 2.5a.96.96 0 0 1 .297-.703A.96.96 0 0 1 5.5 1.5h5a.96.96 0 0 1 .703.297.96.96 0 0 1 .297.703.96.96 0 0 1-.297.703.96.96 0 0 1-.703.297v4c.516 0 .978.257 1.387.77.409.513.613 1.089.613 1.73z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function PlusIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path d="M1,7L7,7L7,1L9,1L9,7L15,7L15,9L9,9L9,15L7,15L7,9L1,9L1,7Z" style={{ fill }} />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function RocketIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M13.754 2.002C11.41 1.96 8.74 3.184 7.049 5.084A6.345 6.345 0 002.7 6.935a.25.25 0 00.14.426l1.927.276-.238.266a.25.25 0 00.01.344l3.213 3.213a.25.25 0 00.344.01l.266-.239.276 1.928c.014.093.088.162.177.192a.23.23 0 00.072.011.282.282 0 00.193-.08 6.331 6.331 0 001.836-4.332c1.901-1.694 3.136-4.365 3.081-6.704a.251.251 0 00-.244-.244zM11.45 6.318a1.246 1.246 0 01-.884.365c-.32 0-.64-.122-.884-.365a1.252 1.252 0 010-1.768 1.251 1.251 0 011.768 0 1.251 1.251 0 010 1.768zm-8.088 4.135c-.535.535-1.27 2.952-1.351 3.225a.25.25 0 00.311.311c.274-.082 2.69-.816 3.226-1.351a1.547 1.547 0 000-2.185 1.548 1.548 0 00-2.186 0z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function RuleScopeIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M8 3.071c2.724 0 4.929 2.204 4.929 4.929s-2.204 4.929-4.929 4.929c-2.724 0-4.929-2.204-4.929-4.929s2.204-4.929 4.929-4.929zM8 1.357c-3.669 0-6.643 2.974-6.643 6.643s2.974 6.643 6.643 6.643 6.643-2.974 6.643-6.643-2.974-6.643-6.643-6.643zM8 6.286c0.945 0 1.714 0.769 1.714 1.714s-0.769 1.714-1.714 1.714-1.714-0.769-1.714-1.714 0.769-1.714 1.714-1.714zM8 4.571c-1.893 0-3.429 1.535-3.429 3.429s1.535 3.429 3.429 3.429 3.429-1.535 3.429-3.429-1.535-3.429-3.429-3.429z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { colors } from '../../app/theme';
-import Icon, { IconProps } from './Icon';
-
-export default function ShortLivingBranchIcon({ fill, ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <g transform="translate(3, 0)">
- <path
- d="M9.5 6.5c0-1.1-.9-2-2-2s-2 .9-2 2c0 .8.5 1.5 1.2 1.8-.3.6-.7 1.1-1.2 1.4-.9.5-1.9.5-2.5.4V4c.9-.2 1.5-1 1.5-1.9 0-1.1-.9-2-2-2s-2 .9-2 2C.5 3 1.1 3.8 2 4v8c-.9.2-1.5 1-1.5 1.9 0 1.1.9 2 2 2s2-.9 2-2c0-.9-.6-1.7-1.5-1.9v-1c.2 0 .5.1.7.1.7 0 1.5-.1 2.2-.6.8-.5 1.4-1.2 1.7-2.1 1.1 0 1.9-.9 1.9-1.9zm-8-4.4c0-.6.4-1 1-1s1 .4 1 1-.4 1-1 1-1-.5-1-1zm2 11.9c0 .6-.4 1-1 1s-1-.4-1-1 .4-1 1-1 1 .4 1 1zm4-6.5c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1z"
- style={{ fill: fill || colors.blue }}
- />
- </g>
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function SortAscIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M6.571 12.857q0 0.107-0.089 0.214l-2.848 2.848q-0.089 0.080-0.205 0.080-0.107 0-0.205-0.080l-2.857-2.857q-0.134-0.143-0.063-0.313 0.071-0.179 0.268-0.179h1.714v-12.286q0-0.125 0.080-0.205t0.205-0.080h1.714q0.125 0 0.205 0.080t0.080 0.205v12.286h1.714q0.125 0 0.205 0.080t0.080 0.205zM16 14v1.714q0 0.125-0.080 0.205t-0.205 0.080h-7.429q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h7.429q0.125 0 0.205 0.080t0.080 0.205zM14.286 9.429v1.714q0 0.125-0.080 0.205t-0.205 0.080h-5.714q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h5.714q0.125 0 0.205 0.080t0.080 0.205zM12.571 4.857v1.714q0 0.125-0.080 0.205t-0.205 0.080h-4q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h4q0.125 0 0.205 0.080t0.080 0.205zM10.857 0.286v1.714q0 0.125-0.080 0.205t-0.205 0.080h-2.286q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h2.286q0.125 0 0.205 0.080t0.080 0.205z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function SortDescIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M10.857 14v1.714q0 0.125-0.080 0.205t-0.205 0.080h-2.286q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h2.286q0.125 0 0.205 0.080t0.080 0.205zM6.571 12.857q0 0.107-0.089 0.214l-2.848 2.848q-0.089 0.080-0.205 0.080-0.107 0-0.205-0.080l-2.857-2.857q-0.134-0.143-0.063-0.313 0.071-0.179 0.268-0.179h1.714v-12.286q0-0.125 0.080-0.205t0.205-0.080h1.714q0.125 0 0.205 0.080t0.080 0.205v12.286h1.714q0.125 0 0.205 0.080t0.080 0.205zM12.571 9.429v1.714q0 0.125-0.080 0.205t-0.205 0.080h-4q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h4q0.125 0 0.205 0.080t0.080 0.205zM14.286 4.857v1.714q0 0.125-0.080 0.205t-0.205 0.080h-5.714q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h5.714q0.125 0 0.205 0.080t0.080 0.205zM16 0.286v1.714q0 0.125-0.080 0.205t-0.205 0.080h-7.429q-0.125 0-0.205-0.080t-0.080-0.205v-1.714q0-0.125 0.080-0.205t0.205-0.080h7.429q0.125 0 0.205 0.080t0.080 0.205z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { colors } from '../../app/theme';
-import { Dict } from '../../types/types';
-import Icon, { IconProps } from './Icon';
-
-interface Props extends IconProps {
- status: string;
-}
-
-const statusIcons: Dict<(props: IconProps) => React.ReactElement> = {
- ok: OkTestStatusIcon,
- failure: FailureTestStatusIcon,
- error: ErrorTestStatusIcon,
- skipped: SkippedTestStatusIcon,
-};
-
-export default function TestStatusIcon({ status, ...iconProps }: Props) {
- const DesiredStatusIcon = statusIcons[status.toLowerCase()];
- return DesiredStatusIcon ? <DesiredStatusIcon {...iconProps} /> : null;
-}
-
-function OkTestStatusIcon(iconProps: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M12.03 6.734a.49.49 0 0 0-.14-.36l-.71-.702a.48.48 0 0 0-.352-.15.474.474 0 0 0-.35.15l-3.19 3.18-1.765-1.766a.479.479 0 0 0-.35-.15.479.479 0 0 0-.353.15l-.71.703a.482.482 0 0 0-.14.358c0 .14.046.258.14.352l2.828 2.828c.098.1.216.15.35.15.142 0 .26-.05.36-.15l4.243-4.242a.475.475 0 0 0 .14-.352l-.001.001zM14 8c0 1.09-.268 2.092-.805 3.012a5.96 5.96 0 0 1-2.183 2.183A5.863 5.863 0 0 1 8 14a5.863 5.863 0 0 1-3.012-.805 5.96 5.96 0 0 1-2.183-2.183A5.863 5.863 0 0 1 2 8c0-1.09.268-2.092.805-3.012a5.96 5.96 0 0 1 2.183-2.183A5.863 5.863 0 0 1 8 2c1.09 0 2.092.268 3.012.805a5.96 5.96 0 0 1 2.183 2.183C13.732 5.908 14 6.91 14 8z"
- style={{ fill: colors.green }}
- />
- </Icon>
- );
-}
-
-function FailureTestStatusIcon(iconProps: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M8 14c-3.311 0-6-2.689-6-6s2.689-6 6-6 6 2.689 6 6-2.689 6-6 6zM7 9h2V4H7v5zm0 3h2v-2H7v2z"
- style={{ fill: colors.orange, fillRule: 'nonzero' }}
- />
- </Icon>
- );
-}
-
-function ErrorTestStatusIcon(iconProps: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M10.977 9.766a.497.497 0 0 0-.149-.352L9.414 8l1.414-1.414a.497.497 0 0 0 0-.711l-.703-.703a.497.497 0 0 0-.71 0L8 6.586 6.586 5.172a.497.497 0 0 0-.711 0l-.703.703a.497.497 0 0 0 0 .71L6.586 8 5.172 9.414a.497.497 0 0 0 0 .711l.703.703a.497.497 0 0 0 .71 0L8 9.414l1.414 1.414a.497.497 0 0 0 .711 0l.703-.703a.515.515 0 0 0 .149-.36zM14 8c0 3.313-2.688 6-6 6-3.313 0-6-2.688-6-6 0-3.313 2.688-6 6-6 3.313 0 6 2.688 6 6z"
- style={{ fill: colors.red, fillRule: 'nonzero' }}
- />
- </Icon>
- );
-}
-
-function SkippedTestStatusIcon(iconProps: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M11.5 8.5v-1c0-.273-.227-.5-.5-.5H5c-.273 0-.5.227-.5.5v1c0 .273.227.5.5.5h6c.273 0 .5-.227.5-.5zM14 8c0 3.313-2.688 6-6 6-3.313 0-6-2.688-6-6 0-3.313 2.688-6 6-6 3.313 0 6 2.688 6 6z"
- style={{ fill: colors.gray71, fillRule: 'nonzero' }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function TreeIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M15.045 2.467c0-0.277-0.225-0.503-0.503-0.503h-13.084c-0.277 0-0.503 0.225-0.503 0.503v1.007c0 0.277 0.225 0.503 0.503 0.503h13.084c0.277 0 0.503-0.225 0.503-0.503v-1.007zM15.045 5.487c0-0.277-0.194-0.503-0.432-0.503h-11.216c-0.238 0-0.432 0.225-0.432 0.503v1.007c0 0.277 0.193 0.503 0.432 0.503h11.216c0.238 0 0.432-0.225 0.432-0.503v-1.007zM15.045 8.506c0-0.277-0.161-0.503-0.359-0.503h-9.346c-0.198 0-0.359 0.225-0.359 0.503v1.007c0 0.277 0.161 0.503 0.359 0.503h9.346c0.198 0 0.359-0.225 0.359-0.503v-1.007zM15.045 11.527c0-0.277-0.129-0.503-0.287-0.503h-7.477c-0.159 0-0.288 0.225-0.288 0.503v1.007c0 0.277 0.129 0.503 0.288 0.503h7.477c0.159 0 0.287-0.225 0.287-0.503v-1.007z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function TreemapIcon({ fill = 'currentColor', size = 14, ...iconProps }: IconProps) {
- return (
- <Icon size={size} {...iconProps}>
- <path
- d="M0 0h8v16h-8zM9.143 0h6.857v9.143h-6.857zM9.143 10.286h6.857v5.714h-6.857z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Icon, { IconProps } from './Icon';
-
-export default function VisibleIcon({ fill = 'currentColor', ...iconProps }: IconProps) {
- return (
- <Icon {...iconProps}>
- <path
- d="M13.524 8.403q-1.093-1.697-2.74-2.539 0.439 0.748 0.439 1.618 0 1.331-0.946 2.276t-2.276 0.946-2.276-0.946-0.946-2.276q0-0.87 0.439-1.618-1.647 0.842-2.74 2.539 0.957 1.474 2.399 2.348t3.125 0.874 3.125-0.874 2.399-2.348zM8.345 5.641q0-0.144-0.101-0.245t-0.245-0.101q-0.899 0-1.543 0.644t-0.644 1.543q0 0.144 0.101 0.245t0.245 0.101 0.245-0.101 0.101-0.245q0-0.619 0.439-1.057t1.057-0.439q0.144 0 0.245-0.101t0.101-0.245zM14.444 8.403q0 0.245-0.144 0.496-1.007 1.654-2.708 2.65t-3.593 0.996-3.593-1-2.708-2.647q-0.144-0.252-0.144-0.496t0.144-0.496q1.007-1.647 2.708-2.647t3.593-1 3.593 1 2.708 2.647q0.144 0.252 0.144 0.496z"
- style={{ fill }}
- />
- </Icon>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { injectIntl, WrappedComponentProps } from 'react-intl';
-import { ButtonLink } from '../../../components/controls/buttons';
-import Toggler from '../../../components/controls/Toggler';
-import DropdownIcon from '../../../components/icons/DropdownIcon';
-import { translateWithParameters } from '../../../helpers/l10n';
-import { Issue } from '../../../types/types';
-import { formatterOption } from '../../intl/DateFormatter';
-import DateFromNow from '../../intl/DateFromNow';
-import ChangelogPopup from '../popups/ChangelogPopup';
-
-export interface IssueChangelogProps extends WrappedComponentProps {
- isOpen: boolean;
- issue: Pick<Issue, 'author' | 'creationDate' | 'key'>;
- creationDate: string;
- togglePopup: (popup: string, show?: boolean) => void;
-}
-
-function IssueChangelog(props: IssueChangelogProps) {
- const {
- isOpen,
- issue,
- creationDate,
- intl: { formatDate },
- } = props;
- return (
- <div className="dropdown">
- <Toggler
- onRequestClose={() => {
- props.togglePopup('changelog', false);
- }}
- open={isOpen}
- overlay={<ChangelogPopup issue={issue} />}
- >
- <ButtonLink
- aria-expanded={isOpen}
- aria-label={translateWithParameters(
- 'issue.changelog.found_on_x_show_more',
- formatDate(creationDate, formatterOption),
- )}
- className="issue-action issue-action-with-options js-issue-show-changelog"
- onClick={() => {
- props.togglePopup('changelog');
- }}
- >
- <span className="issue-meta-label">
- <DateFromNow date={creationDate} />
- </span>
- <DropdownIcon className="little-spacer-left" />
- </ButtonLink>
- </Toggler>
- </div>
- );
-}
-
-export default injectIntl(IssueChangelog);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 Toggler from '../../../components/controls/Toggler';
-import { DeleteButton, EditButton } from '../../../components/controls/buttons';
-import { PopupPlacement } from '../../../components/ui/popups';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { sanitizeUserInput } from '../../../helpers/sanitize';
-import { IssueComment } from '../../../types/types';
-import DateFromNow from '../../intl/DateFromNow';
-import LegacyAvatar from '../../ui/LegacyAvatar';
-import CommentDeletePopup from '../popups/CommentDeletePopup';
-import CommentPopup from '../popups/CommentPopup';
-
-interface Props {
- comment: IssueComment;
- onDelete: (comment: string) => void;
- onEdit: (comment: string, text: string) => void;
-}
-
-interface State {
- openPopup: string;
-}
-
-export default class IssueCommentLine extends React.PureComponent<Props, State> {
- state: State = {
- openPopup: '',
- };
-
- handleEdit = (text: string) => {
- this.props.onEdit(this.props.comment.key, text);
- this.toggleEditPopup(false);
- };
-
- handleDelete = () => {
- this.props.onDelete(this.props.comment.key);
- this.toggleDeletePopup(false);
- };
-
- togglePopup = (popupName: string, force?: boolean) => {
- this.setState((prevState) => {
- if (prevState.openPopup !== popupName && force !== false) {
- return { openPopup: popupName };
- } else if (prevState.openPopup === popupName && force !== true) {
- return { openPopup: '' };
- }
- return prevState;
- });
- };
-
- toggleDeletePopup = (force?: boolean) => {
- this.togglePopup('delete', force);
- };
-
- toggleEditPopup = (force?: boolean) => {
- this.togglePopup('edit', force);
- };
-
- closePopups = () => {
- this.setState({ openPopup: '' });
- };
-
- render() {
- const { comment } = this.props;
- const author = comment.authorName || comment.author;
- const displayName =
- comment.authorActive === false && author
- ? translateWithParameters('user.x_deleted', author)
- : author;
- return (
- <li className="issue-comment">
- <div className="issue-comment-author" title={displayName}>
- <LegacyAvatar
- className="little-spacer-right"
- hash={comment.authorAvatar}
- name={author}
- size={16}
- />
- {displayName}
- </div>
- <div
- className="issue-comment-text markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(comment.htmlText) }}
- />
- <div className="issue-comment-age">
- <span className="sw-sr-only">{translate('issue.comment.posted_on')}</span>
- <DateFromNow date={comment.createdAt} />
- </div>
- <div className="issue-comment-actions">
- {comment.updatable && (
- <div className="dropdown">
- <Toggler
- closeOnClickOutside={false}
- onRequestClose={this.closePopups}
- open={this.state.openPopup === 'edit'}
- overlay={
- <CommentPopup
- comment={comment}
- onComment={this.handleEdit}
- placeholder=""
- placement={PopupPlacement.BottomRight}
- toggleComment={this.toggleEditPopup}
- />
- }
- >
- <EditButton
- aria-label={translate('issue.comment.edit')}
- className="js-issue-comment-edit button-small"
- onClick={this.toggleEditPopup}
- />
- </Toggler>
- </div>
- )}
- {comment.updatable && (
- <div className="dropdown">
- <Toggler
- onRequestClose={this.closePopups}
- open={this.state.openPopup === 'delete'}
- overlay={<CommentDeletePopup onDelete={this.handleDelete} />}
- >
- <DeleteButton
- aria-label={translate('issue.comment.delete')}
- className="js-issue-comment-delete button-small"
- onClick={this.toggleDeletePopup}
- />
- </Toggler>
- </div>
- )}
- </div>
- </li>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { getIssueChangelog } from '../../../api/issues';
-import { DropdownOverlay } from '../../../components/controls/Dropdown';
-import { PopupPlacement } from '../../../components/ui/popups';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { Issue, IssueChangelog } from '../../../types/types';
-import DateTimeFormatter from '../../intl/DateTimeFormatter';
-import LegacyAvatar from '../../ui/LegacyAvatar';
-import IssueChangelogDiff from '../components/IssueChangelogDiff';
-
-interface Props {
- issue: Pick<Issue, 'author' | 'creationDate' | 'key'>;
-}
-
-interface State {
- changelog: IssueChangelog[];
-}
-
-export default class ChangelogPopup extends React.PureComponent<Props, State> {
- mounted = false;
- state: State = { changelog: [] };
-
- componentDidMount() {
- this.mounted = true;
- this.loadChangelog();
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- loadChangelog() {
- getIssueChangelog(this.props.issue.key).then(
- ({ changelog }) => {
- if (this.mounted) {
- this.setState({ changelog });
- }
- },
- () => {},
- );
- }
-
- render() {
- const { issue } = this.props;
- const { author } = issue;
- return (
- <DropdownOverlay placement={PopupPlacement.BottomRight}>
- <div className="menu is-container issue-changelog">
- <table className="spaced">
- <tbody>
- <tr>
- <td className="thin text-left text-top nowrap">
- <DateTimeFormatter date={issue.creationDate} />
- </td>
- <td className="text-left text-top">
- {author ? `${translate('created_by')} ${author}` : translate('created')}
- </td>
- </tr>
-
- {this.state.changelog.map((item, idx) => {
- const userName = item.userName || item.user || item.externalUser;
-
- return (
- <tr key={idx}>
- <td className="thin text-left text-top nowrap">
- <DateTimeFormatter date={item.creationDate} />
- </td>
- <td className="text-left text-top">
- <div>
- {userName && (
- <>
- <LegacyAvatar
- className="little-spacer-right"
- hash={item.avatar}
- name={userName}
- size={16}
- />
- {item.isUserActive || item.externalUser
- ? userName
- : translateWithParameters('user.x_deleted', userName)}
- </>
- )}
- {item.webhookSource &&
- translateWithParameters(
- 'issue.changelog.webhook_source',
- item.webhookSource,
- )}
- </div>
- {item.diffs.map((diff) => (
- <IssueChangelogDiff diff={diff} key={diff.key} />
- ))}
- </td>
- </tr>
- );
- })}
- </tbody>
- </table>
- </div>
- </DropdownOverlay>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { Button } from '../../../components/controls/buttons';
-import { DropdownOverlay } from '../../../components/controls/Dropdown';
-import { PopupPlacement } from '../../../components/ui/popups';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
- onDelete: () => void;
-}
-
-export default function CommentDeletePopup({ onDelete }: Props) {
- return (
- <DropdownOverlay placement={PopupPlacement.BottomRight}>
- <div className="menu is-container">
- <div className="spacer-bottom">{translate('issue.comment.delete_confirm_message')}</div>
- <Button className="button-red" onClick={onDelete}>
- {translate('delete')}
- </Button>
- </div>
- </DropdownOverlay>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { sanitizeUserInput } from '../../../helpers/sanitize';
-import { IssueComment } from '../../../types/types';
-import { DeleteButton, EditButton } from '../../controls/buttons';
-import DateTimeFormatter from '../../intl/DateTimeFormatter';
-import LegacyAvatar from '../../ui/LegacyAvatar';
-import CommentForm from './CommentForm';
-
-interface CommentTileProps {
- comment: IssueComment;
- handleDelete: (commentKey: string) => void;
- onEdit: (comment: string, text: string) => void;
-}
-
-interface CommentTileState {
- showEditArea: boolean;
-}
-
-export default class CommentTile extends React.PureComponent<CommentTileProps, CommentTileState> {
- state = {
- showEditArea: false,
- };
-
- handleEditClick = () => {
- const { showEditArea } = this.state;
- this.setState({ showEditArea: !showEditArea });
- };
-
- handleSaveClick = (editedComment: string) => {
- const { comment } = this.props;
- this.props.onEdit(comment.key, editedComment);
- this.setState({ showEditArea: false });
- };
-
- handleCancelClick = () => {
- this.setState({ showEditArea: false });
- };
-
- render() {
- const { comment } = this.props;
- const { showEditArea } = this.state;
- const author = comment.authorName ?? comment.author;
- const displayName =
- comment.authorActive === false && author
- ? translateWithParameters('user.x_deleted', author)
- : author;
- return (
- <div className="issue-comment-tile spacer-bottom padded">
- <div className="display-flex-center">
- <div className="issue-comment-author display-flex-center" title={displayName}>
- <LegacyAvatar
- className="little-spacer-right"
- hash={comment.authorAvatar}
- name={author}
- size={24}
- />
- {displayName}
- </div>
- <span className="little-spacer-left little-spacer-right">-</span>
- <DateTimeFormatter date={comment.createdAt} />
- </div>
- <div className="spacer-top display-flex-space-between">
- {!showEditArea && (
- <div
- className="flex-1 markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(comment.htmlText) }}
- />
- )}
- {showEditArea && (
- <div className="flex-1">
- <CommentForm
- onCancel={this.handleCancelClick}
- onSaveComment={this.handleSaveClick}
- showFormatHelp={false}
- comment={comment.markdown}
- />
- </div>
- )}
- {comment.updatable && (
- <div>
- <EditButton
- aria-label={translate('issue.comment.edit')}
- className="js-issue-comment-edit button-small"
- onClick={this.handleEditClick}
- />
- <DeleteButton
- aria-label={translate('issue.comment.delete')}
- className="js-issue-comment-delete button-small"
- onClick={() => {
- this.props.handleDelete(comment.key);
- }}
- />
- </div>
- )}
- </div>
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.locations-navigator-file {
- position: relative;
-}
-
-.locations-navigator-file + .locations-navigator-file {
- margin-top: calc(1.5 * var(--gridSize));
-}
-
-.locations-navigator-file:not(:last-child)::before {
- position: absolute;
- display: block;
- width: 0;
- top: 13px;
- bottom: calc(-2 * var(--gridSize));
- left: 4px;
- border-left: 1px dotted var(--conciseIssueRed);
- content: '';
-}
-
-.location-file-locations {
- padding-left: calc(2 * var(--gridSize));
-}
-
-.location-file {
- height: calc(2 * var(--gridSize));
- padding-bottom: calc(0.5 * var(--gridSize));
- font-size: var(--smallFontSize);
- font-weight: bold;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.location-file-circle,
-.location-file-circle-multiple,
-.location-file-circle-multiple::before,
-.location-file-circle-multiple::after {
- position: relative;
- top: 1px;
- display: inline-block;
- width: calc(1px + var(--gridSize));
- height: calc(1px + var(--gridSize));
- border: 1px solid var(--conciseIssueRed);
- border-radius: 100%;
- box-sizing: border-box;
- background-color: var(--issueBgColor);
-}
-
-.location-file-circle-multiple {
- top: -2px;
-}
-
-.location-file-circle-multiple::before {
- position: absolute;
- z-index: calc(5 + var(--normalZIndex));
- top: 2px;
- left: -1px;
- content: '';
-}
-
-.location-file-circle-multiple::after {
- position: absolute;
- z-index: calc(5 + var(--aboveNormalZIndex));
- top: 5px;
- left: -1px;
- content: '';
-}
-
-.location-file-more {
- border-color: rgba(209, 133, 130, 0.2);
- color: rgb(209, 133, 130) !important;
- font-style: italic;
- font-weight: normal;
-}
-
-.location-file-more:hover,
-.location-file-more:focus {
- border-color: rgba(209, 133, 130, 0.6);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { translateWithParameters } from '../../helpers/l10n';
-import { collapsePath } from '../../helpers/path';
-import { MessageFormatting } from '../../types/issues';
-import { FlowLocation } from '../../types/types';
-import './CrossFileLocationNavigator.css';
-import SingleFileLocationNavigator from './SingleFileLocationNavigator';
-
-interface Props {
- locations: FlowLocation[];
- onLocationSelect: (index: number) => void;
- selectedLocationIndex: number | undefined;
-}
-
-interface State {
- collapsed: boolean;
-}
-
-interface LocationGroup {
- component: string | undefined;
- componentName: string | undefined;
- firstLocationIndex: number;
- locations: FlowLocation[];
-}
-
-const MAX_PATH_LENGTH = 15;
-
-export default class CrossFileLocationNavigator extends React.PureComponent<Props, State> {
- state: State = { collapsed: true };
-
- componentDidUpdate() {
- const { locations, selectedLocationIndex } = this.props;
- if (
- selectedLocationIndex &&
- selectedLocationIndex > 0 &&
- locations !== undefined &&
- selectedLocationIndex < locations.length - 1 &&
- this.state.collapsed
- ) {
- this.setState({ collapsed: false });
- }
- }
-
- handleMoreLocationsClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.currentTarget.blur();
- this.setState({ collapsed: false });
- };
-
- groupByFile = (locations: FlowLocation[]) => {
- const groups: LocationGroup[] = [];
-
- let currentLocations: FlowLocation[] = [];
- let currentComponent: string | undefined;
- let currentComponentName: string | undefined;
- let currentFirstLocationIndex = 0;
-
- for (let index = 0; index < locations.length; index++) {
- const location = locations[index];
- if (location.component === currentComponent) {
- currentLocations.push(location);
- } else {
- if (currentLocations.length > 0) {
- groups.push({
- component: currentComponent,
- componentName: currentComponentName,
- firstLocationIndex: currentFirstLocationIndex,
- locations: currentLocations,
- });
- }
- currentLocations = [location];
- currentComponent = location.component;
- currentComponentName = location.componentName;
- currentFirstLocationIndex = index;
- }
- }
-
- if (currentLocations.length > 0) {
- groups.push({
- component: currentComponent,
- componentName: currentComponentName,
- firstLocationIndex: currentFirstLocationIndex,
- locations: currentLocations,
- });
- }
-
- return groups;
- };
-
- renderLocation = (
- index: number,
- message: string | undefined,
- messageFormattings: MessageFormatting[] | undefined,
- ) => {
- return (
- <SingleFileLocationNavigator
- index={index}
- key={index}
- message={message}
- messageFormattings={messageFormattings}
- onClick={this.props.onLocationSelect}
- selected={index === this.props.selectedLocationIndex}
- />
- );
- };
-
- renderGroup = (
- group: LocationGroup,
- groupIndex: number,
- { onlyFirst = false, onlyLast = false } = {},
- ) => {
- const { firstLocationIndex } = group;
- const lastLocationIndex = group.locations.length - 1;
- return (
- <div className="locations-navigator-file" key={groupIndex}>
- <div className="location-file">
- <i className="location-file-circle little-spacer-right" />
- {collapsePath(group.componentName || '', MAX_PATH_LENGTH)}
- </div>
- {group.locations.length > 0 && (
- <div className="location-file-locations">
- {onlyFirst &&
- this.renderLocation(
- firstLocationIndex,
- group.locations[0].msg,
- group.locations[0].msgFormattings,
- )}
-
- {onlyLast &&
- this.renderLocation(
- firstLocationIndex + lastLocationIndex,
- group.locations[lastLocationIndex].msg,
- group.locations[lastLocationIndex].msgFormattings,
- )}
-
- {!onlyFirst &&
- !onlyLast &&
- group.locations.map((location, index) =>
- this.renderLocation(
- firstLocationIndex + index,
- location.msg,
- location.msgFormattings,
- ),
- )}
- </div>
- )}
- </div>
- );
- };
-
- render() {
- const { locations } = this.props;
- const groups = this.groupByFile(locations);
- // below: fold the location list when there are >3 locations
- const MIN_LOCATION_LENGTH = 3;
-
- if (locations.length > MIN_LOCATION_LENGTH && groups.length > 1 && this.state.collapsed) {
- // the top and bottom locations are always displayed
- const nbLocationsAlwaysDisplayed = 2;
-
- const firstGroup = groups[0];
- const lastGroup = groups[groups.length - 1];
-
- return (
- <div className="spacer-top">
- {this.renderGroup(firstGroup, 0, { onlyFirst: true })}
- <div className="locations-navigator-file">
- <div className="location-file">
- <i className="location-file-circle-multiple little-spacer-right" />
- <a className="location-file-more" href="#" onClick={this.handleMoreLocationsClick}>
- {translateWithParameters(
- 'issues.x_more_locations',
- locations.length - nbLocationsAlwaysDisplayed,
- )}
- </a>
- </div>
- </div>
- {this.renderGroup(lastGroup, groups.length - 1, { onlyLast: true })}
- </div>
- );
- }
- return (
- <div className="spacer-top">
- {groups.map((group, groupIndex) => this.renderGroup(group, groupIndex))}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { uniq } from 'lodash';
-import * as React from 'react';
-import { FlowLocation } from '../../types/types';
-import CrossFileLocationNavigator from './CrossFileLocationNavigator';
-import SingleFileLocationNavigator from './SingleFileLocationNavigator';
-
-interface Props {
- componentKey: string;
- locations: FlowLocation[];
- onLocationSelect: (index: number) => void;
- selectedLocationIndex?: number;
- showCrossFile?: boolean;
-}
-
-export default class LocationsList extends React.PureComponent<Props> {
- render() {
- const { locations, componentKey, selectedLocationIndex, showCrossFile = true } = this.props;
-
- const locationComponents = [componentKey, ...locations.map((location) => location.component)];
- const isCrossFile = uniq(locationComponents).length > 1;
-
- if (!locations || locations.length === 0) {
- return null;
- }
-
- if (isCrossFile && showCrossFile) {
- return (
- <CrossFileLocationNavigator
- locations={locations}
- onLocationSelect={this.props.onLocationSelect}
- selectedLocationIndex={selectedLocationIndex}
- />
- );
- }
- return (
- <ul className="spacer-top">
- {locations.map((location, index) => (
- // eslint-disable-next-line react/no-array-index-key
- <li className="display-flex-column" key={index}>
- <SingleFileLocationNavigator
- index={index}
- message={location.msg}
- messageFormattings={location.msgFormattings}
- onClick={this.props.onLocationSelect}
- selected={index === selectedLocationIndex}
- />
- </li>
- ))}
- </ul>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { AlmKeys } from '../../../types/alm-settings';
-import AllSet from './AllSet';
-import Step from './Step';
-
-export interface AllSetStepProps {
- alm: AlmKeys;
- open: boolean;
- stepNumber: number;
- willRefreshAutomatically?: boolean;
-}
-
-export default function AllSetStep(props: AllSetStepProps) {
- const { alm, open, stepNumber, willRefreshAutomatically } = props;
- return (
- <Step
- finished={false}
- open={open}
- renderForm={() => (
- <div className="boxed-group-inner">
- <AllSet alm={alm} willRefreshAutomatically={willRefreshAutomatically} />
- </div>
- )}
- stepNumber={stepNumber}
- stepTitle={translate('onboarding.tutorial.ci_outro.all_set.title')}
- />
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { rawSizes } from '../../../app/theme';
-import { Button } from '../../../components/controls/buttons';
-import ChevronRightIcon from '../../../components/icons/ChevronRightIcon';
-import { translate } from '../../../helpers/l10n';
-
-export interface FinishButtonProps {
- onClick: () => void;
-}
-
-export default function FinishButton(props: FinishButtonProps) {
- return (
- <Button className="big-spacer-top big-spacer-bottom" onClick={props.onClick}>
- {translate('tutorials.finish')}
- <ChevronRightIcon size={rawSizes.baseFontSizeRaw} />
- </Button>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-
-type EllipsisPredicate = (
- node: HTMLElement,
- props: Omit<AutoEllipsisProps, 'customShouldEllipsis'>,
-) => boolean;
-
-interface AutoEllipsisProps {
- customShouldEllipsis?: EllipsisPredicate;
- maxHeight?: number;
- maxWidth?: number;
- useParent?: boolean;
-}
-
-interface Props extends AutoEllipsisProps {
- children: React.ReactElement;
-}
-
-/*
- * This component allows to automatically add the .text-ellipsis class on it's children if this one
- * might overflow the max width/height passed as props.
- * If one of maxHeight or maxWidth is not specified, they will be ignored in the conditions to add the ellipsis class.
- * If useParent is true, then the parent size will be used instead of the undefined maxHeight/maxWidth
- */
-export default function AutoEllipsis(props: Props) {
- const { children, ...autoEllipsisProps } = props;
- const [autoEllispis, ref] = useAutoEllipsis(autoEllipsisProps);
-
- return React.cloneElement(children, {
- className: classNames(children.props.className, { 'text-ellipsis': autoEllispis }),
- ref,
- });
-}
-
-export function useAutoEllipsis(props: AutoEllipsisProps): [boolean, (node: HTMLElement) => void] {
- const [autoEllipsis, setAutoEllipsis] = React.useState(false);
-
- // useCallback instead of useRef to be able to compute if the flag is needed as soon as the ref is attached
- // useRef doesn't accept a callback to notify us that the current ref value was attached,
- // see https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node for more info on this.
- const ref = React.useCallback(
- (node: HTMLElement) => {
- if (!autoEllipsis && node) {
- const shouldEllipsis = props.customShouldEllipsis ?? defaultShouldEllipsis;
- setAutoEllipsis(shouldEllipsis(node, props));
- }
- },
- // We don't want to apply this effect when ellipsis state change, only this effect can change it
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [props.customShouldEllipsis, props.maxHeight, props.maxWidth, props.useParent],
- );
-
- return [autoEllipsis, ref];
-}
-
-export const defaultShouldEllipsis: EllipsisPredicate = (
- node,
- { useParent = true, maxWidth, maxHeight },
-) => {
- if (node.parentElement && useParent) {
- maxWidth = maxWidth ?? node.parentElement.clientWidth;
- maxHeight = maxHeight ?? node.parentElement.clientHeight;
- }
- return (
- (maxWidth !== undefined && node.clientWidth > maxWidth) ||
- (maxHeight !== undefined && node.clientHeight > maxHeight)
- );
-};
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.news-box {
- border: 1px solid var(--alertBorderInfo);
- border-radius: 2px;
- background-color: var(--veryLightBlue);
- padding: var(--gridSize);
-}
-
-.news-box-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { translate } from '../../helpers/l10n';
-import { ClearButton } from '../controls/buttons';
-import './NewsBox.css';
-
-export interface Props {
- children: React.ReactNode;
- className?: string;
- onClose: () => void;
- title: string;
-}
-
-export default function NewsBox({ children, className, onClose, title }: Props) {
- return (
- <div className={classNames('news-box', className)} role="alert">
- <div className="news-box-header">
- <div className="display-flex-center">
- <span className="badge badge-info spacer-right">{translate('new')}</span>
- <strong>{title}</strong>
- </div>
- <ClearButton
- className="button-tiny"
- iconProps={{ size: 12, thin: true }}
- onClick={onClose}
- />
- </div>
- <div className="big-spacer-top note">{children}</div>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.placeholder-bar {
- display: inline-block;
- vertical-align: middle;
- height: 8px;
- background-color: currentColor;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 './PlaceholderBar.css';
-
-interface Props {
- color?: string;
- width: number;
- height?: number;
-}
-
-export default function PlaceholderBar({ color, width, height }: Props) {
- return <span className="placeholder-bar" style={{ color, width, height }} />;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.size-rating {
- display: inline-block;
- vertical-align: top;
- width: var(--controlHeight);
- height: var(--controlHeight);
- line-height: var(--controlHeight);
- border-radius: var(--controlHeight);
- background-color: var(--sizeRatingBackground);
- color: #fff;
- font-size: var(--smallFontSize);
- font-weight: bold;
- text-align: center;
-}
-
-.size-rating-muted {
- background-color: var(--gray71);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import { inRange } from 'lodash';
-import * as React from 'react';
-import './SizeRating.css';
-
-export interface Props {
- muted?: boolean;
- value: number | null | undefined;
-}
-
-export default function SizeRating({ muted = false, value }: Props) {
- if (value == null) {
- return <div className="size-rating size-rating-muted"> </div>;
- }
-
- let letter;
- if (inRange(value, 0, 1000)) {
- letter = 'XS';
- } else if (inRange(value, 1000, 10000)) {
- letter = 'S';
- } else if (inRange(value, 10000, 100000)) {
- letter = 'M';
- } else if (inRange(value, 100000, 500000)) {
- letter = 'L';
- } else if (value >= 500000) {
- letter = 'XL';
- }
-
- const className = classNames('size-rating', {
- 'size-rating-muted': muted,
- });
-
- return (
- <div aria-hidden="true" className={className}>
- {letter}
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-.update-center-meta-data {
- margin: 16px 0;
- padding: 16px 16px 8px 16px;
- background: #f9f9fb;
- border: 1px solid #e6e6e6;
- border-radius: 3px;
-}
-
-.update-center-meta-data a svg {
- margin-right: 8px;
-}
-
-.update-center-meta-data-header {
- border-bottom: 1px solid #cfd3d7;
- padding-bottom: 16px;
-}
-
-.update-center-meta-data-header,
-.update-center-meta-data-version-release-info,
-.update-center-meta-data-version-links {
- display: flex;
-}
-
-.update-center-meta-data-header > * + *,
-.update-center-meta-data-version-release-info > * + * {
- margin-left: 16px;
-}
-
-.update-center-meta-data-header > * + * {
- padding-left: 16px;
- border-left: 1px solid #cfd3d7;
-}
-
-.update-center-meta-data-versions {
- margin-top: 16px;
-}
-
-.update-center-meta-data-versions-show-more {
- font-size: 14px;
- float: right;
- color: #51575a;
- border-color: #7b8184;
- border-width: 0 0 1px 0;
- padding-left: 0;
- padding-right: 0;
- background: transparent;
- cursor: pointer;
-}
-
-.update-center-meta-data-versions-show-more:hover {
- color: #2d3032;
- border-color: #2d3032;
-}
-
-.update-center-meta-data-version {
- margin-bottom: 16px;
-}
-
-.update-center-meta-data-version + .update-center-meta-data-version {
- padding-top: 8px;
- border-top: 1px dashed #cfd3d7;
-}
-
-.update-center-meta-data-version-version {
- font-weight: bold;
- font-size: 18px;
-}
-
-.update-center-meta-data-version-release-info {
- margin-top: 8px;
- font-style: italic;
-}
-
-.update-center-meta-data-version-release-description {
- margin-top: 8px;
-}
-
-.update-center-meta-data-version-download > a,
-.update-center-meta-data-version-release-notes > a {
- display: inline-block;
- margin: 8px 16px 0 0;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { isSuccessStatus } from '../../../helpers/request';
-import './MetaData.css';
-import MetaDataVersions from './MetaDataVersions';
-import { MetaDataInformation } from './update-center-metadata';
-
-interface Props {
- updateCenterKey?: string;
-}
-
-interface State {
- data?: MetaDataInformation;
-}
-
-export default class MetaData extends React.Component<Props, State> {
- mounted = false;
- state: State = {};
-
- componentDidMount() {
- this.mounted = true;
- this.fetchData();
- }
-
- componentDidUpdate(prevProps: Props) {
- if (prevProps.updateCenterKey !== this.props.updateCenterKey) {
- this.fetchData();
- }
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- fetchData() {
- const { updateCenterKey } = this.props;
-
- if (updateCenterKey) {
- window
- .fetch(`https://update.sonarsource.org/${updateCenterKey}.json`)
- .then((response: Response) => {
- if (isSuccessStatus(response.status)) {
- return response.json();
- }
- return Promise.reject(response);
- })
- .then((data) => {
- if (this.mounted) {
- this.setState({ data });
- }
- })
- .catch(() => {
- if (this.mounted) {
- this.setState({ data: undefined });
- }
- });
- } else {
- this.setState({ data: undefined });
- }
- }
-
- render() {
- const { data } = this.state;
-
- if (!data) {
- return null;
- }
-
- const { isSonarSourceCommercial, issueTrackerURL, license, organization, versions } = data;
-
- let vendor;
- if (organization) {
- vendor = organization.name;
- if (organization.url) {
- vendor = (
- <a href={organization.url} rel="noopener noreferrer" target="_blank">
- {vendor}
- </a>
- );
- }
- }
-
- return (
- <div className="update-center-meta-data">
- <div className="update-center-meta-data-header">
- {vendor && <span className="update-center-meta-data-vendor">By {vendor}</span>}
- {license && <span className="update-center-meta-data-license">{license}</span>}
- {issueTrackerURL && (
- <span className="update-center-meta-data-issue-tracker">
- <a href={issueTrackerURL} rel="noopener noreferrer" target="_blank">
- Issue Tracker
- </a>
- </span>
- )}
- {isSonarSourceCommercial && (
- <span className="update-center-meta-data-supported">Supported by SonarSource</span>
- )}
- </div>
- {versions && versions.length > 0 && <MetaDataVersions versions={versions} />}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { AdvancedDownloadUrl, MetaDataVersionInformation } from './update-center-metadata';
-
-export interface MetaDataVersionProps {
- versionInformation: MetaDataVersionInformation;
-}
-
-export default function MetaDataVersion(props: MetaDataVersionProps) {
- const {
- versionInformation: {
- archived,
- changeLogUrl,
- compatibility,
- date,
- description,
- downloadURL,
- version,
- },
- } = props;
-
- const fallbackLabel = 'Download';
-
- const advancedDownloadUrls = isAdvancedDownloadUrlArray(downloadURL)
- ? downloadURL.map((url) => ({ ...url, label: url.label || fallbackLabel }))
- : [{ label: fallbackLabel, url: downloadURL }];
-
- return (
- <div
- className={classNames('update-center-meta-data-version', {
- 'update-center-meta-data-version-archived': archived,
- })}
- >
- <div className="update-center-meta-data-version-version">{version}</div>
-
- <div className="update-center-meta-data-version-release-info">
- {date && <time className="update-center-meta-data-version-release-date">{date}</time>}
-
- {compatibility && (
- <span className="update-center-meta-data-version-compatibility">{compatibility}</span>
- )}
- </div>
-
- {description && (
- <div className="update-center-meta-data-version-release-description">{description}</div>
- )}
-
- {(advancedDownloadUrls.length > 0 || changeLogUrl) && (
- <div className="update-center-meta-data-version-release-links">
- {advancedDownloadUrls.length > 0 &&
- advancedDownloadUrls.map(
- (advancedDownloadUrl, i) =>
- advancedDownloadUrl.url && (
- // eslint-disable-next-line react/no-array-index-key
- <span className="update-center-meta-data-version-download" key={i}>
- <a href={advancedDownloadUrl.url} rel="noopener noreferrer" target="_blank">
- {advancedDownloadUrl.label}
- </a>
- </span>
- ),
- )}
-
- {changeLogUrl && (
- <span className="update-center-meta-data-version-release-notes">
- <a href={changeLogUrl} rel="noopener noreferrer" target="_blank">
- Release notes
- </a>
- </span>
- )}
- </div>
- )}
- </div>
- );
-}
-
-function isAdvancedDownloadUrlArray(
- downloadUrl: string | AdvancedDownloadUrl[] | undefined,
-): downloadUrl is AdvancedDownloadUrl[] {
- return !!downloadUrl && typeof downloadUrl !== 'string';
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 MetaDataVersion from './MetaDataVersion';
-import { MetaDataVersionInformation } from './update-center-metadata';
-
-interface Props {
- versions: MetaDataVersionInformation[];
-}
-
-interface State {
- collapsed: boolean;
-}
-
-export default class MetaDataVersions extends React.Component<Props, State> {
- state: State = {
- collapsed: true,
- };
-
- componentDidUpdate(prevProps: Props) {
- if (prevProps.versions !== this.props.versions) {
- this.setState({ collapsed: true });
- }
- }
-
- handleClick = (event: React.SyntheticEvent<HTMLButtonElement>) => {
- event.preventDefault();
- event.currentTarget.blur();
- this.setState(({ collapsed }) => ({ collapsed: !collapsed }));
- };
-
- render() {
- const { versions } = this.props;
- const { collapsed } = this.state;
-
- const archivedVersions = versions.filter((version) => version.archived);
- const currentVersions = versions.filter((version) => !version.archived);
-
- return (
- <div className="update-center-meta-data-versions">
- {archivedVersions.length > 0 && (
- <button
- className="update-center-meta-data-versions-show-more"
- onClick={this.handleClick}
- type="button"
- >
- {collapsed ? 'Show more versions' : 'Show fewer versions'}
- </button>
- )}
-
- {currentVersions.map((versionInformation) => (
- <MetaDataVersion
- key={versionInformation.version}
- versionInformation={versionInformation}
- />
- ))}
-
- {!collapsed &&
- archivedVersions.map((archivedVersionInformation) => (
- <MetaDataVersion
- key={archivedVersionInformation.version}
- versionInformation={archivedVersionInformation}
- />
- ))}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { MetaDataInformation, MetaDataVersionInformation } from '../update-center-metadata';
-
-export function mockMetaDataVersionInformation(
- overrides?: Partial<MetaDataVersionInformation>,
-): MetaDataVersionInformation {
- return {
- version: '5.13',
- date: '2019-05-31',
- compatibility: '6.7',
- archived: false,
- downloadURL: 'https://example.com/sonar-java-plugin-5.13.0.18197.jar',
- changeLogUrl: 'https://example.com/sonar-java-plugin/release',
- ...overrides,
- };
-}
-
-export function mockMetaDataInformation(
- overrides?: Partial<MetaDataInformation>,
-): MetaDataInformation {
- return {
- name: 'SonarJava',
- key: 'java',
- isSonarSourceCommercial: true,
- organization: {
- name: 'SonarSource',
- url: 'http://www.sonarsource.com/',
- },
- category: 'Languages',
- license: 'SonarSource',
- issueTrackerURL: 'https://jira.sonarsource.com/browse/SONARJAVA',
- sourcesURL: 'https://github.com/SonarSource/sonar-java',
- versions: [
- mockMetaDataVersionInformation({ version: '2.0' }),
- mockMetaDataVersionInformation({ version: '1.0', archived: true }),
- ],
- ...overrides,
- };
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-export interface MetaDataInformation {
- category?: string;
- isSonarSourceCommercial?: boolean;
- issueTrackerURL?: string;
- key?: string;
- license?: string;
- name: string;
- organization?: {
- name: string;
- url?: string;
- };
- sourcesURL?: string;
- versions?: MetaDataVersionInformation[];
-}
-
-export interface MetaDataVersionInformation {
- archived?: boolean;
- changeLogUrl?: string;
- compatibility?: string;
- date?: string;
- description?: string;
- downloadURL?: string | AdvancedDownloadUrl[];
- version: string;
-}
-
-export interface AdvancedDownloadUrl {
- label?: string;
- url: string;
-}
import { UpdateUseCase } from '../utils';
const ui = {
- toggleButton: byRole('button', { name: 'learn_more' }),
+ learnMoreButton: byRole('button', { name: 'learn_more' }),
header: byRole('heading', { name: 'system.system_upgrade' }),
downloadLink: byRole('link', { name: /system.see_sonarqube_downloads/ }),
renderSystemUpgradeButton();
- await user.click(ui.toggleButton.get());
+ await user.click(ui.learnMoreButton.get());
expect(ui.header.get()).toBeInTheDocument();
expect(ui.ltsVersionHeader.get()).toBeInTheDocument();
'9.9',
);
- await user.click(ui.toggleButton.get());
+ await user.click(ui.learnMoreButton.get());
expect(ui.header.get()).toBeInTheDocument();
expect(ui.newPatchWarning.get()).toBeInTheDocument();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.
- */
-type ActionCreator = (...args: any[]) => { type: string };
-
-export type ActionType<F extends ActionCreator, T> = Omit<ReturnType<F>, 'type'> & { type: T };