]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15801 Highlight inaccessible projects in App definition
authorJeremy Davis <jeremy.davis@sonarsource.com>
Thu, 30 Dec 2021 11:00:06 +0000 (12:00 +0100)
committersonartech <sonartech@sonarsource.com>
Mon, 3 Jan 2022 20:02:55 +0000 (20:02 +0000)
server/sonar-web/src/main/js/app/styles/init/misc.css
server/sonar-web/src/main/js/apps/application-console/ApplicationProjects.tsx
server/sonar-web/src/main/js/apps/application-console/__tests__/ApplicationProjects-test.tsx
server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ApplicationProjects-test.tsx.snap
server/sonar-web/src/main/js/types/application.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index c9fd156cc2b6a3678ace3c35ce01276a44173d13..d04aecfc52a1de9c7a43dc6d61b008566fa7d867 100644 (file)
@@ -157,6 +157,10 @@ th.hide-overflow {
   padding: var(--gridSize) !important;
 }
 
+.little-padded {
+  padding: calc(var(--gridSize) / 2) !important;
+}
+
 .big-padded {
   padding: calc(2 * var(--gridSize)) !important;
 }
@@ -601,8 +605,8 @@ th.huge-spacer-right {
 }
 
 .bg-warning {
-  background-color: var(--orange);
-  color: #fff;
+  background-color: var(--alertBackgroundWarning);
+  color: var(--alertTextWarning);
 }
 
 .bg-info {
index d1cf0d1a682d140db0369332dc8aa023c87b5c25..c7ca29443b0c010bb7ee7e181159be515f65c838 100644 (file)
@@ -17,6 +17,7 @@
  * 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 { find, without } from 'lodash';
 import * as React from 'react';
 import {
@@ -28,7 +29,10 @@ import SelectList, {
   SelectListFilter,
   SelectListSearchParams
 } from '../../components/controls/SelectList';
+import Tooltip from '../../components/controls/Tooltip';
 import QualifierIcon from '../../components/icons/QualifierIcon';
+import WarningIcon from '../../components/icons/WarningIcon';
+import { translate } from '../../helpers/l10n';
 import { Application, ApplicationProject } from '../../types/application';
 
 interface Props {
@@ -185,8 +189,17 @@ export default class ApplicationProjects extends React.PureComponent<Props, Stat
     }
 
     return (
-      <div className="views-project-item display-flex-center">
-        <QualifierIcon className="spacer-right" qualifier="TRK" />
+      <div
+        className={classNames('views-project-item display-flex-center little-padded', {
+          'bg-warning': !project.accessible
+        })}>
+        {!project.accessible ? (
+          <Tooltip overlay={translate('application_console.project_inaccessible')}>
+            <WarningIcon className="spacer-right" />
+          </Tooltip>
+        ) : (
+          <QualifierIcon className="spacer-right" qualifier="TRK" />
+        )}
         <div>
           <div title={project.name}>{project.name}</div>
           <div className="note">{project.key}</div>
index ded53e11350f122fb35483cab00b7479549f2e0a..3ea49a97ba945373ebec6500e72af765df17439d 100644 (file)
@@ -33,9 +33,16 @@ jest.mock('../../../api/application', () => ({
   getApplicationProjects: jest.fn().mockResolvedValue({
     paging: { pageIndex: 1, pageSize: 3, total: 55 },
     projects: [
-      { key: 'test1', name: 'test1', selected: false },
-      { key: 'test2', name: 'test2', selected: false, disabled: true, includedIn: 'foo' },
-      { key: 'test3', name: 'test3', selected: true }
+      { key: 'test1', name: 'test1', accessible: true, selected: false },
+      {
+        key: 'test2',
+        name: 'test2',
+        accessible: false,
+        selected: false,
+        disabled: true,
+        includedIn: 'foo'
+      },
+      { key: 'test3', name: 'test3', accessible: true, selected: true }
     ]
   }),
   addProjectToApplication: jest.fn().mockResolvedValue({}),
@@ -53,8 +60,9 @@ it('should render correctly in application mode', async () => {
   await waitAndUpdate(wrapper);
 
   expect(wrapper).toMatchSnapshot();
-  expect(wrapper.instance().renderElement('test1')).toMatchSnapshot();
-  expect(wrapper.instance().renderElement('test2')).toMatchSnapshot();
+  expect(wrapper.instance().renderElement('test1')).toMatchSnapshot('render project: basic');
+  expect(wrapper.instance().renderElement('test2')).toMatchSnapshot('render project: inaccessible');
+  expect(wrapper.instance().renderElement('cheeseburger')).toMatchInlineSnapshot(`""`);
 
   expect(getApplicationProjects).toHaveBeenCalledWith(
     expect.objectContaining({
index caedd4c5d95325f729c1af7afcbc0150843d89c9..cfd64c1000d59190a415eb6858a46c9a435f7432 100644 (file)
@@ -25,9 +25,9 @@ exports[`should render correctly in application mode 1`] = `
 />
 `;
 
-exports[`should render correctly in application mode 2`] = `
+exports[`should render correctly in application mode: render project: basic 1`] = `
 <div
-  className="views-project-item display-flex-center"
+  className="views-project-item display-flex-center little-padded"
 >
   <QualifierIcon
     className="spacer-right"
@@ -48,14 +48,17 @@ exports[`should render correctly in application mode 2`] = `
 </div>
 `;
 
-exports[`should render correctly in application mode 3`] = `
+exports[`should render correctly in application mode: render project: inaccessible 1`] = `
 <div
-  className="views-project-item display-flex-center"
+  className="views-project-item display-flex-center little-padded bg-warning"
 >
-  <QualifierIcon
-    className="spacer-right"
-    qualifier="TRK"
-  />
+  <Tooltip
+    overlay="application_console.project_inaccessible"
+  >
+    <WarningIcon
+      className="spacer-right"
+    />
+  </Tooltip>
   <div>
     <div
       title="test2"
index f919f75f5e9d2f632c2409e0120de93c41d9aefa..0269a3c9047b88aeb42be0d4f62c33262025d575 100644 (file)
@@ -42,4 +42,5 @@ export interface ApplicationProject {
   key: string;
   name: string;
   selected?: boolean;
+  accessible?: boolean;
 }
index 24e273ea316279c2a1b6629ecf6ff8ec07301fe5..37eb30ae7aa0b1ec521d8c1e2abcd4d69072dbc4 100644 (file)
@@ -557,6 +557,7 @@ visibility.private.description.long=Only members of the organization will be abl
 #------------------------------------------------------------------------------
 
 application_console.edit=Edit Application
+application_console.project_inaccessible=You do not have access to this project
 application_console.branches=Application Branches
 application_console.branches.cannot_access_all_child_projects=You must have access to all projects in this Application in order to administer branches.
 application_console.branches.cancel=Cancel