aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorMathieu Suen <mathieu.suen@sonarsource.com>2021-09-30 16:57:18 +0200
committersonartech <sonartech@sonarsource.com>2021-10-01 20:03:19 +0000
commitfe58d75d14ca6bc0005c6110a32d648ffdd361d1 (patch)
tree6d213f7019bb9310b9998b653941570e07de2206 /server/sonar-web/src
parentabb09faf00e8ea3b03642705ca2d42440336bf28 (diff)
downloadsonarqube-fe58d75d14ca6bc0005c6110a32d648ffdd361d1.tar.gz
sonarqube-fe58d75d14ca6bc0005c6110a32d648ffdd361d1.zip
SONAR-15458 Add SonarLint promotion for failed Quality Gate
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap165
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap8
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/SonarLintPromotion.tsx79
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/__tests__/SonarLintPromition-test.tsx63
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/SonarLintPromition-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/PullRequestOverview-test.tsx.snap25
-rw-r--r--server/sonar-web/src/main/js/apps/overview/styles.css9
-rw-r--r--server/sonar-web/src/main/js/components/icons/SonarLintIcon.tsx42
-rw-r--r--server/sonar-web/src/main/js/types/types.d.ts1
12 files changed, 425 insertions, 5 deletions
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx
index 161e1c686eb..2954827ba40 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx
@@ -18,12 +18,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import classNames from 'classnames';
+import { flatMap } from 'lodash';
import * as React from 'react';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { Alert } from '../../../components/ui/Alert';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { QualityGateStatus } from '../../../types/quality-gates';
+import SonarLintPromotion from '../components/SonarLintPromotion';
import QualityGatePanelSection from './QualityGatePanelSection';
export interface QualityGatePanelProps {
@@ -116,6 +118,9 @@ export function QualityGatePanel(props: QualityGatePanelProps) {
</>
)}
</div>
+ <SonarLintPromotion
+ qgConditions={flatMap(qgStatuses, qgStatus => qgStatus.failedConditions)}
+ />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx
index 5a557597687..3470d679423 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx
@@ -23,7 +23,7 @@ import { isDiffMetric } from '../../../helpers/measures';
import { BranchLike } from '../../../types/branch-like';
import { ComponentQualifier } from '../../../types/component';
import { QualityGateStatus } from '../../../types/quality-gates';
-import { QualityGateConditions } from '../components/QualityGateConditions';
+import QualityGateConditions from '../components/QualityGateConditions';
export interface QualityGatePanelSectionProps {
branchLike?: BranchLike;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap
index 580ccebe664..4c5d74724c9 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap
@@ -182,6 +182,81 @@ exports[`should render correctly for applications 1`] = `
/>
</div>
</div>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={
+ Array [
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "coverage",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "foo",
+ "op": "GT",
+ },
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "coverage",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "foo",
+ "op": "GT",
+ },
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "new_code_smells",
+ "key": "new_code_smells",
+ "name": "New_code_smells",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "new_code_smells",
+ "op": "GT",
+ },
+ ]
+ }
+ />
</div>
`;
@@ -320,6 +395,35 @@ exports[`should render correctly for applications 2`] = `
/>
</div>
</div>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={
+ Array [
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "coverage",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "foo",
+ "op": "GT",
+ },
+ ]
+ }
+ />
</div>
`;
@@ -424,6 +528,35 @@ exports[`should render correctly for projects 1`] = `
/>
</div>
</div>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={
+ Array [
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "coverage",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "foo",
+ "op": "GT",
+ },
+ ]
+ }
+ />
</div>
`;
@@ -466,6 +599,9 @@ exports[`should render correctly for projects 2`] = `
</span>
</div>
</div>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={Array []}
+ />
</div>
`;
@@ -585,5 +721,34 @@ exports[`should render correctly for projects 3`] = `
/>
</div>
</div>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={
+ Array [
+ Object {
+ "actual": "10",
+ "error": "0",
+ "level": "ERROR",
+ "measure": Object {
+ "bestValue": true,
+ "leak": "1",
+ "metric": Object {
+ "id": "coverage",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "period": Object {
+ "bestValue": true,
+ "index": 1,
+ "value": "1.0",
+ },
+ "value": "1.0",
+ },
+ "metric": "foo",
+ "op": "GT",
+ },
+ ]
+ }
+ />
</div>
`;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap
index 99121173ca4..84bd6cb3285 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap
@@ -9,7 +9,7 @@ exports[`should render correctly 1`] = `
>
quality_gates.conditions.new_code
</h4>
- <QualityGateConditions
+ <Memo(QualityGateConditions)
component={
Object {
"failedConditions": Array [
@@ -99,7 +99,7 @@ exports[`should render correctly 1`] = `
>
quality_gates.conditions.overall_code
</h4>
- <QualityGateConditions
+ <Memo(QualityGateConditions)
component={
Object {
"failedConditions": Array [
@@ -201,7 +201,7 @@ exports[`should render correctly 2`] = `
>
quality_gates.conditions.new_code
</h4>
- <QualityGateConditions
+ <Memo(QualityGateConditions)
component={
Object {
"failedConditions": Array [
@@ -291,7 +291,7 @@ exports[`should render correctly 2`] = `
>
quality_gates.conditions.overall_code
</h4>
- <QualityGateConditions
+ <Memo(QualityGateConditions)
component={
Object {
"failedConditions": Array [
diff --git a/server/sonar-web/src/main/js/apps/overview/components/SonarLintPromotion.tsx b/server/sonar-web/src/main/js/apps/overview/components/SonarLintPromotion.tsx
new file mode 100644
index 00000000000..32a6ce2a627
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/overview/components/SonarLintPromotion.tsx
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
+import SonarLintIcon from '../../../components/icons/SonarLintIcon';
+import { translate } from '../../../helpers/l10n';
+import { MetricKey } from '../../../types/metrics';
+import { QualityGateStatusCondition } from '../../../types/quality-gates';
+
+export interface SonarLintPromotionProps {
+ currentUser: T.CurrentUser;
+ qgConditions?: QualityGateStatusCondition[];
+}
+
+const CONDITIONS_TO_SHOW = [
+ MetricKey.new_blocker_violations,
+ MetricKey.new_critical_violations,
+ MetricKey.new_info_violations,
+ MetricKey.new_violations,
+ MetricKey.new_major_violations,
+ MetricKey.new_minor_violations,
+ MetricKey.new_code_smells,
+ MetricKey.new_bugs,
+ MetricKey.new_vulnerabilities,
+ MetricKey.new_security_rating,
+ MetricKey.new_maintainability_rating,
+ MetricKey.new_reliability_rating
+];
+
+export function SonarLintPromotion({ currentUser, qgConditions }: SonarLintPromotionProps) {
+ const showMessage = qgConditions?.some(
+ qgCondition =>
+ CONDITIONS_TO_SHOW.includes(qgCondition.metric as MetricKey) && qgCondition.level === 'ERROR'
+ );
+ if (!showMessage || currentUser.usingSonarLintConnectedMode) {
+ return null;
+ }
+ return (
+ <div className="it__overview__sonarlint-promotion big-spacer-top overview-quality-gate-sonar-lint-info">
+ <FormattedMessage
+ id="overview.fix_failed_conditions_with_sonarlint"
+ defaultMessage={translate('overview.fix_failed_conditions_with_sonarlint')}
+ values={{
+ link: (
+ <>
+ <a
+ href="https://www.sonarqube.org/sonarlint/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank">
+ SonarLint
+ </a>
+ <SonarLintIcon size={16} />
+ </>
+ )
+ }}
+ />
+ </div>
+ );
+}
+
+export default withCurrentUser(SonarLintPromotion);
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/SonarLintPromition-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/SonarLintPromition-test.tsx
new file mode 100644
index 00000000000..261794c900a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/SonarLintPromition-test.tsx
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockQualityGateStatusCondition } from '../../../../helpers/mocks/quality-gates';
+import { mockCurrentUser } from '../../../../helpers/testMocks';
+import { MetricKey } from '../../../../types/metrics';
+import { SonarLintPromotion, SonarLintPromotionProps } from '../SonarLintPromotion';
+
+it('should render correctly', () => {
+ expect(shallowRender().type()).toBeNull();
+ expect(
+ shallowRender({ currentUser: mockCurrentUser({ usingSonarLintConnectedMode: true }) }).type()
+ ).toBeNull();
+ expect(
+ shallowRender({
+ qgConditions: [mockQualityGateStatusCondition({ metric: MetricKey.new_bugs, level: 'ERROR' })]
+ })
+ ).toMatchSnapshot('has failed condition');
+});
+
+it.each(
+ [
+ MetricKey.new_blocker_violations,
+ MetricKey.new_critical_violations,
+ MetricKey.new_info_violations,
+ MetricKey.new_violations,
+ MetricKey.new_major_violations,
+ MetricKey.new_minor_violations,
+ MetricKey.new_code_smells,
+ MetricKey.new_bugs,
+ MetricKey.new_vulnerabilities,
+ MetricKey.new_security_rating,
+ MetricKey.new_maintainability_rating,
+ MetricKey.new_reliability_rating
+ ].map(Array.of)
+)('should show message for %s', metric => {
+ const wrapper = shallowRender({
+ qgConditions: [mockQualityGateStatusCondition({ metric: metric as string })]
+ });
+ expect(wrapper.type()).not.toBeNull();
+});
+
+function shallowRender(props: Partial<SonarLintPromotionProps> = {}) {
+ return shallow(<SonarLintPromotion currentUser={mockCurrentUser()} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/SonarLintPromition-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/SonarLintPromition-test.tsx.snap
new file mode 100644
index 00000000000..e0d43e8cda1
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/SonarLintPromition-test.tsx.snap
@@ -0,0 +1,28 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: has failed condition 1`] = `
+<div
+ className="it__overview__sonarlint-promotion big-spacer-top overview-quality-gate-sonar-lint-info"
+>
+ <FormattedMessage
+ defaultMessage="overview.fix_failed_conditions_with_sonarlint"
+ id="overview.fix_failed_conditions_with_sonarlint"
+ values={
+ Object {
+ "link": <React.Fragment>
+ <a
+ href="https://www.sonarqube.org/sonarlint/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ SonarLint
+ </a>
+ <SonarLintIcon
+ size={16}
+ />
+ </React.Fragment>,
+ }
+ }
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx
index 8c542df49e1..d6a0cdcb7ef 100644
--- a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx
@@ -37,6 +37,7 @@ import IssueLabel from '../components/IssueLabel';
import IssueRating from '../components/IssueRating';
import MeasurementLabel from '../components/MeasurementLabel';
import QualityGateConditions from '../components/QualityGateConditions';
+import SonarLintPromotion from '../components/SonarLintPromotion';
import '../styles.css';
import { MeasurementType, PR_METRICS } from '../utils';
import AfterMergeEstimate from './AfterMergeEstimate';
@@ -197,6 +198,8 @@ export class PullRequestOverview extends React.PureComponent<Props, State> {
/>
</h2>
<LargeQualityGateBadge component={component} level={status} />
+
+ <SonarLintPromotion qgConditions={conditions} />
</div>
{failedConditions.length > 0 && (
diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/PullRequestOverview-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/PullRequestOverview-test.tsx.snap
index 8af79d11f7e..c3348c42010 100644
--- a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/PullRequestOverview-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/PullRequestOverview-test.tsx.snap
@@ -53,6 +53,28 @@ exports[`should render correctly for a failed QG 1`] = `
}
level="ERROR"
/>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={
+ Array [
+ Object {
+ "actual": "10",
+ "error": "1.0",
+ "level": "OK",
+ "metric": "new_bugs",
+ "op": "GT",
+ "period": 1,
+ },
+ Object {
+ "actual": "10",
+ "error": "1.0",
+ "level": "ERROR",
+ "metric": "new_code_smells",
+ "op": "GT",
+ "period": 1,
+ },
+ ]
+ }
+ />
</div>
<div
className="pr-overview-failed-conditions big-spacer-right"
@@ -1402,6 +1424,9 @@ exports[`should render correctly for a passed QG 1`] = `
}
level="OK"
/>
+ <Connect(withCurrentUser(SonarLintPromotion))
+ qgConditions={Array []}
+ />
</div>
<div
className="flex-1"
diff --git a/server/sonar-web/src/main/js/apps/overview/styles.css b/server/sonar-web/src/main/js/apps/overview/styles.css
index a91b526a3c1..48cc58fa9f1 100644
--- a/server/sonar-web/src/main/js/apps/overview/styles.css
+++ b/server/sonar-web/src/main/js/apps/overview/styles.css
@@ -30,6 +30,11 @@
border: 1px solid var(--barBorderColor);
}
+.overview-quality-gate-sonar-lint-info {
+ padding: 8px 16px;
+ border: 1px solid var(--barBorderColor);
+}
+
.overview-panel-title {
text-transform: uppercase;
font-weight: 600;
@@ -249,6 +254,10 @@
color: var(--transparentWhite);
}
+.pr-overview .overview-quality-gate-sonar-lint-info {
+ width: 207px;
+}
+
.pr-pverview .overview-measures-row {
min-height: 85px;
}
diff --git a/server/sonar-web/src/main/js/components/icons/SonarLintIcon.tsx b/server/sonar-web/src/main/js/components/icons/SonarLintIcon.tsx
new file mode 100644
index 00000000000..c4a1dcb7579
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/icons/SonarLintIcon.tsx
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import Icon, { IconProps } from './Icon';
+
+export default function SonarLintIcon(props: IconProps) {
+ return (
+ <Icon {...props} viewBox="0 0 512 512">
+ <defs>
+ <path id="a" d="M0 0h512v512H0z" />
+ </defs>
+ <clipPath id="b">
+ <use xlinkHref="#a" style={{ overflow: 'visible' }} />
+ </clipPath>
+ <path
+ d="M255.7 450.7c-107.8 0-195.5-87.6-195.5-195.3 0-107.7 87.7-195.3 195.5-195.3s195.5 87.6 195.5 195.3c0 107.7-87.7 195.3-195.5 195.3m0-355.2c-88.2 0-160 71.7-160 159.8 0 88.1 71.8 159.8 160 159.8s160-71.7 160-159.8c0-88.1-71.8-159.8-160-159.8"
+ style={{ clipPath: 'url(#b)', fill: '#cb2029' }}
+ />
+ <path
+ d="M392.6 244.9c-5.1-10.2-11.5-23-24.1-23-12.5 0-18.9 12.7-24.1 23-4.8 9.5-7.5 14.5-13.5 14.5s-8.7-5-13.5-14.5c-5.1-10.2-11.5-23-24.1-23s-18.9 12.7-24.1 23c-4.8 9.5-7.5 14.5-13.5 14.5s-8.7-5-13.5-14.5c-5.1-10.2-11.5-23-24.1-23s-18.9 12.7-24.1 23c-4.8 9.5-7.5 14.5-13.5 14.5s-8.7-5-13.5-14.5c-5.1-10.2-11.5-23-24.1-23-12.5 0-18.9 12.1-24 22.3 0 0-3.9 8.7-5.6 12.8-1.7 4.1-8.3 19.7-2.3 27.2 3.4 4.2 8.3-1.8 11.1-6.2 2.1-3.4 7.1-13.2 7.1-13.2 5.1-9.1 7.8-14 13.7-14 6 0 8.7 5 13.5 14.5 5.1 10.2 11.5 23 24.1 23 12.5 0 18.9-12.7 24.1-23 4.8-9.5 7.5-14.5 13.5-14.5s8.7 5 13.5 14.5c5.1 10.2 11.5 23 24.1 23 12.5 0 18.9-12.7 24.1-23 4.8-9.5 7.5-14.5 13.5-14.5s8.7 5 13.5 14.5c5.1 10.2 11.5 23 24.1 23s18.9-12.7 24.1-23c4.8-9.5 7.5-14.5 13.5-14.5s8.7 5 13.5 14.5c0 0 2.2 4.3 5.4 9.9 1.4 2.3 6.6 11.1 11.2 10.8 4.1-.3 5.6-13.3 1-24.7-3.1-7.6-7-16.4-7-16.4z"
+ style={{ fill: '#cb2029' }}
+ />
+ </Icon>
+ );
+}
diff --git a/server/sonar-web/src/main/js/types/types.d.ts b/server/sonar-web/src/main/js/types/types.d.ts
index 9391ec3b94b..8173bca1ff1 100644
--- a/server/sonar-web/src/main/js/types/types.d.ts
+++ b/server/sonar-web/src/main/js/types/types.d.ts
@@ -218,6 +218,7 @@ declare namespace T {
export interface CurrentUser {
isLoggedIn: boolean;
permissions?: { global: string[] };
+ usingSonarLintConnectedMode?: boolean;
}
export interface CurrentUserSetting {