]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16537 Change issue file header style
authorMathieu Suen <mathieu.suen@sonarsource.com>
Tue, 26 Jul 2022 12:02:08 +0000 (14:02 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 29 Jul 2022 20:03:14 +0000 (20:03 +0000)
16 files changed:
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/ComponentSourceSnippetGroupViewer.tsx
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewer.tsx
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.css [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/SnippetViewer.css
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/IssueSourceViewerHeader-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/ComponentSourceSnippetGroupViewer-test.tsx.snap
server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/IssueSourceViewerHeader-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/styles.css
server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.tsx
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.css [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap [deleted file]
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 00a82856a42d70e2e4233aaafe87d82e2bba9487..08a9d12d6aa11c06835b0e7d54a24df06ab02e93 100644 (file)
@@ -23,7 +23,6 @@ import Issue from '../../../components/issue/Issue';
 import SecondaryIssue from '../../../components/issue/SecondaryIssue';
 import getCoverageStatus from '../../../components/SourceViewer/helpers/getCoverageStatus';
 import { locationsByLine } from '../../../components/SourceViewer/helpers/indexing';
-import SourceViewerHeaderSlim from '../../../components/SourceViewer/SourceViewerHeaderSlim';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
 import { BranchLike } from '../../../types/branch-like';
 import { isFile } from '../../../types/component';
@@ -40,6 +39,7 @@ import {
   SourceLine,
   SourceViewerFile
 } from '../../../types/types';
+import IssueSourceViewerHeader from './IssueSourceViewerHeader';
 import SnippetViewer from './SnippetViewer';
 import {
   createSnippets,
@@ -422,7 +422,7 @@ export default class ComponentSourceSnippetGroupViewer extends React.PureCompone
 
     return (
       <div className="component-source-container" ref={this.rootNodeRef}>
-        <SourceViewerHeaderSlim
+        <IssueSourceViewerHeader
           branchLike={branchLike}
           expandable={!fullyShown && isFile(snippetGroup.component.q)}
           loading={loading}
index b3b93d314f3467f38f6e87fef5df626cf2b2acbb..0457ce290df39b1383e6a82f8b09819d7ca61785 100644 (file)
@@ -268,29 +268,35 @@ export default class CrossComponentSourceViewer extends React.PureComponent<Prop
         })}
 
         {locationsByComponent.length === 0 && (
-          <ComponentSourceSnippetGroupViewer
-            branchLike={this.props.branchLike}
-            duplications={duplications}
-            duplicationsByLine={duplicationsByLine}
-            highlightedLocationMessage={this.props.highlightedLocationMessage}
-            issue={issue}
-            issuePopup={this.state.issuePopup}
-            issuesByLine={issuesByComponent[issue.component] || {}}
-            isLastOccurenceOfPrimaryComponent={true}
-            lastSnippetGroup={true}
-            loadDuplications={this.fetchDuplications}
-            locations={[]}
-            onIssueChange={this.props.onIssueChange}
-            onIssueSelect={this.props.onIssueSelect}
-            onIssuePopupToggle={this.handleIssuePopupToggle}
-            onLocationSelect={this.props.onLocationSelect}
-            renderDuplicationPopup={this.renderDuplicationPopup}
-            scroll={this.props.scroll}
-            snippetGroup={{
-              locations: [getPrimaryLocation(issue)],
-              ...components[issue.component]
-            }}
-          />
+          <SourceViewerContext.Provider
+            value={{
+              branchLike: this.props.branchLike,
+              file: components[issue.component].component
+            }}>
+            <ComponentSourceSnippetGroupViewer
+              branchLike={this.props.branchLike}
+              duplications={duplications}
+              duplicationsByLine={duplicationsByLine}
+              highlightedLocationMessage={this.props.highlightedLocationMessage}
+              issue={issue}
+              issuePopup={this.state.issuePopup}
+              issuesByLine={issuesByComponent[issue.component] || {}}
+              isLastOccurenceOfPrimaryComponent={true}
+              lastSnippetGroup={true}
+              loadDuplications={this.fetchDuplications}
+              locations={[]}
+              onIssueChange={this.props.onIssueChange}
+              onIssueSelect={this.props.onIssueSelect}
+              onIssuePopupToggle={this.handleIssuePopupToggle}
+              onLocationSelect={this.props.onLocationSelect}
+              renderDuplicationPopup={this.renderDuplicationPopup}
+              scroll={this.props.scroll}
+              snippetGroup={{
+                locations: [getPrimaryLocation(issue)],
+                ...components[issue.component]
+              }}
+            />
+          </SourceViewerContext.Provider>
         )}
       </div>
     );
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.css b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.css
new file mode 100644 (file)
index 0000000..4f70cdd
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+.source-viewer-header-slim {
+  padding: 4px 10px;
+  border: 1px solid var(--gray80);
+  background-color: var(--barBackgroundColor);
+  align-items: center;
+  min-height: 25px;
+}
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/IssueSourceViewerHeader.tsx
new file mode 100644 (file)
index 0000000..69b4465
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import classNames from 'classnames';
+import * as React from 'react';
+import { Link } from 'react-router-dom';
+import { ButtonIcon } from '../../../components/controls/buttons';
+import { ClipboardIconButton } from '../../../components/controls/clipboard';
+import ExpandSnippetIcon from '../../../components/icons/ExpandSnippetIcon';
+import QualifierIcon from '../../../components/icons/QualifierIcon';
+import DeferredSpinner from '../../../components/ui/DeferredSpinner';
+import { getBranchLikeQuery } from '../../../helpers/branch-like';
+import { translate } from '../../../helpers/l10n';
+import { collapsedDirFromPath, fileFromPath } from '../../../helpers/path';
+import { getBranchLikeUrl, getComponentIssuesUrl, getPathUrlAsString } from '../../../helpers/urls';
+import { BranchLike } from '../../../types/branch-like';
+import { ComponentQualifier } from '../../../types/component';
+import { SourceViewerFile } from '../../../types/types';
+import './IssueSourceViewerHeader.css';
+
+export interface Props {
+  branchLike: BranchLike | undefined;
+  expandable?: boolean;
+  displayProjectName?: boolean;
+  linkToProject?: boolean;
+  loading?: boolean;
+  onExpand?: () => void;
+  sourceViewerFile: SourceViewerFile;
+}
+
+export default function IssueSourceViewerHeader(props: Props) {
+  const {
+    branchLike,
+    expandable,
+    displayProjectName = true,
+    linkToProject = true,
+    loading,
+    onExpand,
+    sourceViewerFile
+  } = props;
+  const { measures, path, project, projectName, q } = sourceViewerFile;
+
+  const projectNameLabel = (
+    <>
+      <QualifierIcon qualifier={ComponentQualifier.Project} /> <span>{projectName}</span>
+    </>
+  );
+
+  const isProjectRoot = q === ComponentQualifier.Project;
+
+  return (
+    <div className="source-viewer-header-slim display-flex-row display-flex-space-between">
+      <div className="display-flex-center flex-1">
+        {displayProjectName && (
+          <div className="spacer-right">
+            {linkToProject ? (
+              <a
+                className="link-with-icon"
+                href={getPathUrlAsString(getBranchLikeUrl(project, branchLike))}>
+                {projectNameLabel}
+              </a>
+            ) : (
+              projectNameLabel
+            )}
+          </div>
+        )}
+
+        {!isProjectRoot && (
+          <>
+            <div className="spacer-right">
+              <QualifierIcon qualifier={q} /> <span>{collapsedDirFromPath(path)}</span>
+              <span className="component-name-file">{fileFromPath(path)}</span>
+            </div>
+
+            <div className="spacer-right">
+              <ClipboardIconButton className="button-link link-no-underline" copyValue={path} />
+            </div>
+          </>
+        )}
+      </div>
+
+      {!isProjectRoot && measures.issues !== undefined && (
+        <div
+          className={classNames('flex-0 big-spacer-left', {
+            'little-spacer-right': !expandable || loading
+          })}>
+          <Link
+            to={getComponentIssuesUrl(project, {
+              ...getBranchLikeQuery(branchLike),
+              files: path,
+              resolved: 'false'
+            })}>
+            {translate('source_viewer.view_all_issues')}
+          </Link>
+        </div>
+      )}
+
+      {expandable && (
+        <DeferredSpinner className="little-spacer-right" loading={loading}>
+          <div className="flex-0 big-spacer-left">
+            <ButtonIcon className="js-actions" onClick={onExpand}>
+              <ExpandSnippetIcon />
+            </ButtonIcon>
+          </div>
+        </DeferredSpinner>
+      )}
+    </div>
+  );
+}
index 3f49652df25caf7e67b59ecb66a16635b94d4eb2..b3b151ce897a04c43aaaca50d84dc0f44a1e9ccf 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 .snippet {
-  margin: var(--gridSize);
+  margin: var(--gridSize) 0;
   border: 1px solid var(--gray80);
   overflow-x: auto;
   overflow-y: hidden;
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/IssueSourceViewerHeader-test.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/IssueSourceViewerHeader-test.tsx
new file mode 100644 (file)
index 0000000..0665511
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
+import { mockSourceViewerFile } from '../../../../helpers/mocks/sources';
+import { ComponentQualifier } from '../../../../types/component';
+import IssueSourceViewerHeader, { Props } from '../IssueSourceViewerHeader';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ linkToProject: false })).toMatchSnapshot('no link to project');
+  expect(shallowRender({ displayProjectName: false })).toMatchSnapshot('no project name');
+  expect(
+    shallowRender({
+      sourceViewerFile: mockSourceViewerFile('foo/bar.ts', 'my-project', {
+        q: ComponentQualifier.Project
+      })
+    })
+  ).toMatchSnapshot('project root');
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+  return shallow(
+    <IssueSourceViewerHeader
+      branchLike={mockMainBranch()}
+      expandable={true}
+      onExpand={jest.fn()}
+      sourceViewerFile={mockSourceViewerFile('foo/bar.ts', 'my-project')}
+      {...props}
+    />
+  );
+}
index 58f647c8012cbb4f41de010df79ddbe815ede7b2..9825cb22d5cc3ea2ded7ef8d10ef81e07d352b2c 100644 (file)
@@ -4,7 +4,7 @@ exports[`should render correctly 1`] = `
 <div
   className="component-source-container"
 >
-  <SourceViewerHeaderSlim
+  <IssueSourceViewerHeader
     branchLike={
       Object {
         "analysisDate": "2018-01-01",
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/IssueSourceViewerHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/IssueSourceViewerHeader-test.tsx.snap
new file mode 100644 (file)
index 0000000..0b6e42a
--- /dev/null
@@ -0,0 +1,261 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+  className="source-viewer-header-slim display-flex-row display-flex-space-between"
+>
+  <div
+    className="display-flex-center flex-1"
+  >
+    <div
+      className="spacer-right"
+    >
+      <a
+        className="link-with-icon"
+        href="/dashboard?id=my-project"
+      >
+        <QualifierIcon
+          qualifier="TRK"
+        />
+         
+        <span>
+          MyProject
+        </span>
+      </a>
+    </div>
+    <div
+      className="spacer-right"
+    >
+      <QualifierIcon
+        qualifier="FIL"
+      />
+       
+      <span>
+        foo/
+      </span>
+      <span
+        className="component-name-file"
+      >
+        bar.ts
+      </span>
+    </div>
+    <div
+      className="spacer-right"
+    >
+      <ClipboardIconButton
+        className="button-link link-no-underline"
+        copyValue="foo/bar.ts"
+      />
+    </div>
+  </div>
+  <div
+    className="flex-0 big-spacer-left"
+  >
+    <Link
+      to={
+        Object {
+          "hash": "",
+          "pathname": "/project/issues",
+          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
+        }
+      }
+    >
+      source_viewer.view_all_issues
+    </Link>
+  </div>
+  <DeferredSpinner
+    className="little-spacer-right"
+  >
+    <div
+      className="flex-0 big-spacer-left"
+    >
+      <ButtonIcon
+        className="js-actions"
+        onClick={[MockFunction]}
+      >
+        <ExpandSnippetIcon />
+      </ButtonIcon>
+    </div>
+  </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly: no link to project 1`] = `
+<div
+  className="source-viewer-header-slim display-flex-row display-flex-space-between"
+>
+  <div
+    className="display-flex-center flex-1"
+  >
+    <div
+      className="spacer-right"
+    >
+      <QualifierIcon
+        qualifier="TRK"
+      />
+       
+      <span>
+        MyProject
+      </span>
+    </div>
+    <div
+      className="spacer-right"
+    >
+      <QualifierIcon
+        qualifier="FIL"
+      />
+       
+      <span>
+        foo/
+      </span>
+      <span
+        className="component-name-file"
+      >
+        bar.ts
+      </span>
+    </div>
+    <div
+      className="spacer-right"
+    >
+      <ClipboardIconButton
+        className="button-link link-no-underline"
+        copyValue="foo/bar.ts"
+      />
+    </div>
+  </div>
+  <div
+    className="flex-0 big-spacer-left"
+  >
+    <Link
+      to={
+        Object {
+          "hash": "",
+          "pathname": "/project/issues",
+          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
+        }
+      }
+    >
+      source_viewer.view_all_issues
+    </Link>
+  </div>
+  <DeferredSpinner
+    className="little-spacer-right"
+  >
+    <div
+      className="flex-0 big-spacer-left"
+    >
+      <ButtonIcon
+        className="js-actions"
+        onClick={[MockFunction]}
+      >
+        <ExpandSnippetIcon />
+      </ButtonIcon>
+    </div>
+  </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly: no project name 1`] = `
+<div
+  className="source-viewer-header-slim display-flex-row display-flex-space-between"
+>
+  <div
+    className="display-flex-center flex-1"
+  >
+    <div
+      className="spacer-right"
+    >
+      <QualifierIcon
+        qualifier="FIL"
+      />
+       
+      <span>
+        foo/
+      </span>
+      <span
+        className="component-name-file"
+      >
+        bar.ts
+      </span>
+    </div>
+    <div
+      className="spacer-right"
+    >
+      <ClipboardIconButton
+        className="button-link link-no-underline"
+        copyValue="foo/bar.ts"
+      />
+    </div>
+  </div>
+  <div
+    className="flex-0 big-spacer-left"
+  >
+    <Link
+      to={
+        Object {
+          "hash": "",
+          "pathname": "/project/issues",
+          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
+        }
+      }
+    >
+      source_viewer.view_all_issues
+    </Link>
+  </div>
+  <DeferredSpinner
+    className="little-spacer-right"
+  >
+    <div
+      className="flex-0 big-spacer-left"
+    >
+      <ButtonIcon
+        className="js-actions"
+        onClick={[MockFunction]}
+      >
+        <ExpandSnippetIcon />
+      </ButtonIcon>
+    </div>
+  </DeferredSpinner>
+</div>
+`;
+
+exports[`should render correctly: project root 1`] = `
+<div
+  className="source-viewer-header-slim display-flex-row display-flex-space-between"
+>
+  <div
+    className="display-flex-center flex-1"
+  >
+    <div
+      className="spacer-right"
+    >
+      <a
+        className="link-with-icon"
+        href="/dashboard?id=my-project"
+      >
+        <QualifierIcon
+          qualifier="TRK"
+        />
+         
+        <span>
+          MyProject
+        </span>
+      </a>
+    </div>
+  </div>
+  <DeferredSpinner
+    className="little-spacer-right"
+  >
+    <div
+      className="flex-0 big-spacer-left"
+    >
+      <ButtonIcon
+        className="js-actions"
+        onClick={[MockFunction]}
+      >
+        <ExpandSnippetIcon />
+      </ButtonIcon>
+    </div>
+  </DeferredSpinner>
+</div>
+`;
index 0e5328c913b74354ca15509b1122c4684263ac02..44e4a054e81d2ba377936e99368e773aed97144c 100644 (file)
   color: white;
 }
 
-.component-source-container {
-  border: 1px solid var(--gray80);
-}
-
 .component-source-container + .component-source-container {
   margin-top: var(--gridSize);
 }
index 3c43b8ce50b1e9ed402242e4500a7080178d37e7..7f24e85d95db56bbb39b07e36f417e7225959446 100644 (file)
@@ -60,7 +60,6 @@ import defaultLoadIssues from './helpers/loadIssues';
 import SourceViewerCode from './SourceViewerCode';
 import { SourceViewerContext } from './SourceViewerContext';
 import SourceViewerHeader from './SourceViewerHeader';
-import SourceViewerHeaderSlim from './SourceViewerHeaderSlim';
 import './styles.css';
 
 export interface Props {
@@ -92,7 +91,6 @@ export interface Props {
   selectedIssue?: string;
   showMeasures?: boolean;
   metricKey?: string;
-  slimHeader?: boolean;
 }
 
 interface State {
@@ -605,10 +603,8 @@ export default class SourceViewer extends React.PureComponent<Props, State> {
     );
   }
 
-  renderHeader(branchLike: BranchLike | undefined, sourceViewerFile: SourceViewerFile) {
-    return this.props.slimHeader ? (
-      <SourceViewerHeaderSlim branchLike={branchLike} sourceViewerFile={sourceViewerFile} />
-    ) : (
+  renderHeader(sourceViewerFile: SourceViewerFile) {
+    return (
       <WorkspaceContext.Consumer>
         {({ openComponent }) => (
           <SourceViewerHeader
@@ -653,7 +649,7 @@ export default class SourceViewer extends React.PureComponent<Props, State> {
     return (
       <SourceViewerContext.Provider value={{ branchLike: this.props.branchLike, file: component }}>
         <div className="source-viewer" ref={node => (this.node = node)}>
-          {this.renderHeader(this.props.branchLike, component)}
+          {this.renderHeader(component)}
           {sourceRemoved && (
             <Alert className="spacer-top" variant="warning">
               {translate('code_viewer.no_source_code_displayed_due_to_source_removed')}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.css b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.css
deleted file mode 100644 (file)
index 813f73a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-.source-viewer-header-slim {
-  padding: 4px 10px 4px;
-  border-bottom: 1px solid var(--gray80);
-  background-color: var(--barBackgroundColor);
-  align-items: center;
-  min-height: 25px;
-}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx
deleted file mode 100644 (file)
index b6a6ac4..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import classNames from 'classnames';
-import * as React from 'react';
-import { Link } from 'react-router-dom';
-import { ButtonIcon } from '../../components/controls/buttons';
-import { ClipboardIconButton } from '../../components/controls/clipboard';
-import ExpandSnippetIcon from '../../components/icons/ExpandSnippetIcon';
-import QualifierIcon from '../../components/icons/QualifierIcon';
-import DeferredSpinner from '../../components/ui/DeferredSpinner';
-import { getBranchLikeQuery } from '../../helpers/branch-like';
-import { translate } from '../../helpers/l10n';
-import { collapsedDirFromPath, fileFromPath } from '../../helpers/path';
-import { getBranchLikeUrl, getComponentIssuesUrl, getPathUrlAsString } from '../../helpers/urls';
-import { BranchLike } from '../../types/branch-like';
-import { ComponentQualifier } from '../../types/component';
-import { SourceViewerFile } from '../../types/types';
-import './SourceViewerHeaderSlim.css';
-
-export interface Props {
-  branchLike: BranchLike | undefined;
-  expandable?: boolean;
-  displayProjectName?: boolean;
-  linkToProject?: boolean;
-  loading?: boolean;
-  onExpand?: () => void;
-  sourceViewerFile: SourceViewerFile;
-}
-
-export default function SourceViewerHeaderSlim(props: Props) {
-  const {
-    branchLike,
-    expandable,
-    displayProjectName = true,
-    linkToProject = true,
-    loading,
-    onExpand,
-    sourceViewerFile
-  } = props;
-  const { measures, path, project, projectName, q } = sourceViewerFile;
-
-  const projectNameLabel = (
-    <>
-      <QualifierIcon qualifier={ComponentQualifier.Project} /> <span>{projectName}</span>
-    </>
-  );
-
-  const isProjectRoot = q === ComponentQualifier.Project;
-
-  return (
-    <div className="source-viewer-header-slim display-flex-row display-flex-space-between">
-      <div className="display-flex-center flex-1">
-        {displayProjectName && (
-          <div className="spacer-right">
-            {linkToProject ? (
-              <a
-                className="link-with-icon"
-                href={getPathUrlAsString(getBranchLikeUrl(project, branchLike))}>
-                {projectNameLabel}
-              </a>
-            ) : (
-              projectNameLabel
-            )}
-          </div>
-        )}
-
-        {!isProjectRoot && (
-          <>
-            <div className="spacer-right">
-              <QualifierIcon qualifier={q} /> <span>{collapsedDirFromPath(path)}</span>
-              <span className="component-name-file">{fileFromPath(path)}</span>
-            </div>
-
-            <div className="spacer-right">
-              <ClipboardIconButton className="button-link link-no-underline" copyValue={path} />
-            </div>
-          </>
-        )}
-      </div>
-
-      {!isProjectRoot && measures.issues !== undefined && (
-        <div
-          className={classNames('flex-0 big-spacer-left', {
-            'little-spacer-right': !expandable || loading
-          })}>
-          <Link
-            to={getComponentIssuesUrl(project, {
-              ...getBranchLikeQuery(branchLike),
-              files: path,
-              resolved: 'false'
-            })}>
-            {translate('source_viewer.view_all_issues')}
-          </Link>
-        </div>
-      )}
-
-      {expandable && (
-        <DeferredSpinner className="little-spacer-right" loading={loading}>
-          <div className="flex-0 big-spacer-left">
-            <ButtonIcon className="js-actions" onClick={onExpand}>
-              <ExpandSnippetIcon />
-            </ButtonIcon>
-          </div>
-        </DeferredSpinner>
-      )}
-    </div>
-  );
-}
index e8a35ab3ad911e69d4f5fd336cec0b8aa7c635ef..0039a2b5d3d0a561f52bd2d8b55c53388ae41c68 100644 (file)
@@ -397,7 +397,6 @@ function getSourceViewerUi(override?: Partial<SourceViewer['props']>) {
       onLoaded={jest.fn()}
       onLocationSelect={jest.fn()}
       scroll={jest.fn()}
-      slimHeader={true}
       {...override}
     />
   );
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx
deleted file mode 100644 (file)
index e9b49af..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockMainBranch } from '../../../helpers/mocks/branch-like';
-import { mockSourceViewerFile } from '../../../helpers/mocks/sources';
-import { ComponentQualifier } from '../../../types/component';
-import SourceViewerHeaderSlim, { Props } from '../SourceViewerHeaderSlim';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ linkToProject: false })).toMatchSnapshot('no link to project');
-  expect(shallowRender({ displayProjectName: false })).toMatchSnapshot('no project name');
-  expect(
-    shallowRender({
-      sourceViewerFile: mockSourceViewerFile('foo/bar.ts', 'my-project', {
-        q: ComponentQualifier.Project
-      })
-    })
-  ).toMatchSnapshot('project root');
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(
-    <SourceViewerHeaderSlim
-      branchLike={mockMainBranch()}
-      expandable={true}
-      onExpand={jest.fn()}
-      sourceViewerFile={mockSourceViewerFile('foo/bar.ts', 'my-project')}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap
deleted file mode 100644 (file)
index 0b6e42a..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  className="source-viewer-header-slim display-flex-row display-flex-space-between"
->
-  <div
-    className="display-flex-center flex-1"
-  >
-    <div
-      className="spacer-right"
-    >
-      <a
-        className="link-with-icon"
-        href="/dashboard?id=my-project"
-      >
-        <QualifierIcon
-          qualifier="TRK"
-        />
-         
-        <span>
-          MyProject
-        </span>
-      </a>
-    </div>
-    <div
-      className="spacer-right"
-    >
-      <QualifierIcon
-        qualifier="FIL"
-      />
-       
-      <span>
-        foo/
-      </span>
-      <span
-        className="component-name-file"
-      >
-        bar.ts
-      </span>
-    </div>
-    <div
-      className="spacer-right"
-    >
-      <ClipboardIconButton
-        className="button-link link-no-underline"
-        copyValue="foo/bar.ts"
-      />
-    </div>
-  </div>
-  <div
-    className="flex-0 big-spacer-left"
-  >
-    <Link
-      to={
-        Object {
-          "hash": "",
-          "pathname": "/project/issues",
-          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
-        }
-      }
-    >
-      source_viewer.view_all_issues
-    </Link>
-  </div>
-  <DeferredSpinner
-    className="little-spacer-right"
-  >
-    <div
-      className="flex-0 big-spacer-left"
-    >
-      <ButtonIcon
-        className="js-actions"
-        onClick={[MockFunction]}
-      >
-        <ExpandSnippetIcon />
-      </ButtonIcon>
-    </div>
-  </DeferredSpinner>
-</div>
-`;
-
-exports[`should render correctly: no link to project 1`] = `
-<div
-  className="source-viewer-header-slim display-flex-row display-flex-space-between"
->
-  <div
-    className="display-flex-center flex-1"
-  >
-    <div
-      className="spacer-right"
-    >
-      <QualifierIcon
-        qualifier="TRK"
-      />
-       
-      <span>
-        MyProject
-      </span>
-    </div>
-    <div
-      className="spacer-right"
-    >
-      <QualifierIcon
-        qualifier="FIL"
-      />
-       
-      <span>
-        foo/
-      </span>
-      <span
-        className="component-name-file"
-      >
-        bar.ts
-      </span>
-    </div>
-    <div
-      className="spacer-right"
-    >
-      <ClipboardIconButton
-        className="button-link link-no-underline"
-        copyValue="foo/bar.ts"
-      />
-    </div>
-  </div>
-  <div
-    className="flex-0 big-spacer-left"
-  >
-    <Link
-      to={
-        Object {
-          "hash": "",
-          "pathname": "/project/issues",
-          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
-        }
-      }
-    >
-      source_viewer.view_all_issues
-    </Link>
-  </div>
-  <DeferredSpinner
-    className="little-spacer-right"
-  >
-    <div
-      className="flex-0 big-spacer-left"
-    >
-      <ButtonIcon
-        className="js-actions"
-        onClick={[MockFunction]}
-      >
-        <ExpandSnippetIcon />
-      </ButtonIcon>
-    </div>
-  </DeferredSpinner>
-</div>
-`;
-
-exports[`should render correctly: no project name 1`] = `
-<div
-  className="source-viewer-header-slim display-flex-row display-flex-space-between"
->
-  <div
-    className="display-flex-center flex-1"
-  >
-    <div
-      className="spacer-right"
-    >
-      <QualifierIcon
-        qualifier="FIL"
-      />
-       
-      <span>
-        foo/
-      </span>
-      <span
-        className="component-name-file"
-      >
-        bar.ts
-      </span>
-    </div>
-    <div
-      className="spacer-right"
-    >
-      <ClipboardIconButton
-        className="button-link link-no-underline"
-        copyValue="foo/bar.ts"
-      />
-    </div>
-  </div>
-  <div
-    className="flex-0 big-spacer-left"
-  >
-    <Link
-      to={
-        Object {
-          "hash": "",
-          "pathname": "/project/issues",
-          "search": "?files=foo%2Fbar.ts&resolved=false&id=my-project",
-        }
-      }
-    >
-      source_viewer.view_all_issues
-    </Link>
-  </div>
-  <DeferredSpinner
-    className="little-spacer-right"
-  >
-    <div
-      className="flex-0 big-spacer-left"
-    >
-      <ButtonIcon
-        className="js-actions"
-        onClick={[MockFunction]}
-      >
-        <ExpandSnippetIcon />
-      </ButtonIcon>
-    </div>
-  </DeferredSpinner>
-</div>
-`;
-
-exports[`should render correctly: project root 1`] = `
-<div
-  className="source-viewer-header-slim display-flex-row display-flex-space-between"
->
-  <div
-    className="display-flex-center flex-1"
-  >
-    <div
-      className="spacer-right"
-    >
-      <a
-        className="link-with-icon"
-        href="/dashboard?id=my-project"
-      >
-        <QualifierIcon
-          qualifier="TRK"
-        />
-         
-        <span>
-          MyProject
-        </span>
-      </a>
-    </div>
-  </div>
-  <DeferredSpinner
-    className="little-spacer-right"
-  >
-    <div
-      className="flex-0 big-spacer-left"
-    >
-      <ButtonIcon
-        className="js-actions"
-        onClick={[MockFunction]}
-      >
-        <ExpandSnippetIcon />
-      </ButtonIcon>
-    </div>
-  </DeferredSpinner>
-</div>
-`;
index 34094e1bfa85e0af94fc1700c39acbee42dd970a..0b0167d6bd3a68ffb581240706de769bf4835f69 100644 (file)
@@ -826,6 +826,7 @@ issue.comment.posted_on=Comment posted on
 issue.comment.edit=Edit comment
 issue.comment.delete=Delete comment
 issue.comment.delete_confirm_message=Do you want to delete this comment?
+issue.get_permalink=Get Permalink
 issue.manual_vulnerability=Manual
 issue.manual_vulnerability.description=This Vulnerability was created from a Security Hotspot and has its own issue workflow.
 issue.rule_details=Rule Details