]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14057 Mark Azure projects previously imported
authorJeremy Davis <jeremy.davis@sonarsource.com>
Wed, 18 Nov 2020 10:03:26 +0000 (11:03 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 25 Nov 2020 20:06:27 +0000 (20:06 +0000)
server/sonar-web/src/main/js/apps/create/project/AzureProjectAccordion.tsx
server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectAccordion-test.tsx
server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectAccordion-test.tsx.snap
server/sonar-web/src/main/js/apps/create/project/style.css
server/sonar-web/src/main/js/types/alm-integration.ts

index 87d2f5a1d8fbb37ad1b489815744441e4cfb702a..6205e32b1bb9eeb8bed53eb726f5f8784a77aaea 100644 (file)
@@ -24,9 +24,12 @@ import { Link } from 'react-router';
 import BoxedGroupAccordion from 'sonar-ui-common/components/controls/BoxedGroupAccordion';
 import ListFooter from 'sonar-ui-common/components/controls/ListFooter';
 import Radio from 'sonar-ui-common/components/controls/Radio';
+import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon';
 import { Alert } from 'sonar-ui-common/components/ui/Alert';
 import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
 import { translate } from 'sonar-ui-common/helpers/l10n';
+import { colors } from '../../../app/theme';
+import { getProjectUrl } from '../../../helpers/urls';
 import { AzureProject, AzureRepository } from '../../../types/alm-integration';
 import { CreateProjectModes } from './types';
 
@@ -57,6 +60,9 @@ export default function AzureProjectAccordion(props: AzureProjectAccordionProps)
   const [page, setPage] = React.useState(1);
   const limitedRepositories = repositories.slice(0, page * PAGE_SIZE);
 
+  const isSelected = (repo: AzureRepository) =>
+    selectedRepository?.projectName === project.key && selectedRepository.name === repo.name;
+
   return (
     <BoxedGroupAccordion
       className={classNames('big-spacer-bottom', {
@@ -90,19 +96,36 @@ export default function AzureProjectAccordion(props: AzureProjectAccordionProps)
             <>
               <div className="display-flex-wrap">
                 {limitedRepositories.map(repo => (
-                  <Radio
-                    checked={selectedRepository?.name === repo.name}
-                    className={classNames(
-                      'display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden',
-                      importing && ['disabled', 'text-muted', 'link-no-underline']
+                  <div
+                    className="display-flex-start spacer-right spacer-bottom create-project-azdo-repo"
+                    key={repo.name}>
+                    {repo.sqProjectKey ? (
+                      <>
+                        <CheckIcon className="spacer-right" fill={colors.green} size={14} />
+                        <div className="overflow-hidden">
+                          <div className="little-spacer-bottom text-ellipsis">
+                            <strong title={repo.sqProjectName}>
+                              <Link to={getProjectUrl(repo.sqProjectKey)}>
+                                {repo.sqProjectName}
+                              </Link>
+                            </strong>
+                          </div>
+                          <em>{translate('onboarding.create_project.repository_imported')}</em>
+                        </div>
+                      </>
+                    ) : (
+                      <Radio
+                        checked={isSelected(repo)}
+                        className="overflow-hidden"
+                        disabled={importing}
+                        onCheck={() => props.onSelectRepository(repo)}
+                        value={repo.name}>
+                        <strong className="text-ellipsis" title={repo.name}>
+                          {repo.name}
+                        </strong>
+                      </Radio>
                     )}
-                    key={repo.name}
-                    onCheck={() => !importing && props.onSelectRepository(repo)}
-                    value={repo.name}>
-                    <strong className="text-ellipsis" title={repo.name}>
-                      {repo.name}
-                    </strong>
-                  </Radio>
+                  </div>
                 ))}
               </div>
               <ListFooter
index 394205a78522b1e752e6849d5510973414e03b27..61588b9fbf61ffd4fb01386626dc0a2bf0860487 100644 (file)
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import BoxedGroupAccordion from 'sonar-ui-common/components/controls/BoxedGroupAccordion';
+import Radio from 'sonar-ui-common/components/controls/Radio';
 import { mockAzureProject, mockAzureRepository } from '../../../../helpers/mocks/alm-integrations';
+import { mockEvent } from '../../../../helpers/testMocks';
 import AzureProjectAccordion, { AzureProjectAccordionProps } from '../AzureProjectAccordion';
 
 it('should render correctly', () => {
   expect(shallowRender({ loading: true })).toMatchSnapshot('loading');
   expect(shallowRender({ startsOpen: false })).toMatchSnapshot('closed');
-  expect(shallowRender({ repositories: [mockAzureRepository()] })).toMatchSnapshot(
-    'with a repository'
-  );
+  expect(
+    shallowRender({
+      repositories: [
+        mockAzureRepository(),
+        mockAzureRepository({ sqProjectKey: 'sq-key', sqProjectName: 'SQ Name' })
+      ]
+    })
+  ).toMatchSnapshot('with repositories');
   expect(shallowRender({ importing: true, repositories: [mockAzureRepository()] })).toMatchSnapshot(
     'importing'
   );
@@ -95,6 +102,19 @@ it('should close when clicked', () => {
   ).toBe(false);
 });
 
+it('should trigger selection when repo is clicked', () => {
+  const onSelectRepository = jest.fn();
+  const repo = mockAzureRepository();
+  const wrapper = shallowRender({ onSelectRepository, repositories: [repo] });
+
+  wrapper
+    .find(Radio)
+    .props()
+    .onCheck(mockEvent());
+
+  expect(onSelectRepository).toBeCalledWith(repo);
+});
+
 function shallowRender(overrides: Partial<AzureProjectAccordionProps> = {}) {
   return shallow(
     <AzureProjectAccordion
index 15116a710babca24975ba9106e31e284ef79d6c2..5189109e856ce5997606fe3f44e271f26d18d71a 100644 (file)
@@ -30,20 +30,25 @@ exports[`should render correctly: importing 1`] = `
     <div
       className="display-flex-wrap"
     >
-      <Radio
-        checked={false}
-        className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden disabled text-muted link-no-underline"
+      <div
+        className="display-flex-start spacer-right spacer-bottom create-project-azdo-repo"
         key="Azure repo 1"
-        onCheck={[Function]}
-        value="Azure repo 1"
       >
-        <strong
-          className="text-ellipsis"
-          title="Azure repo 1"
+        <Radio
+          checked={false}
+          className="overflow-hidden"
+          disabled={true}
+          onCheck={[Function]}
+          value="Azure repo 1"
         >
-          Azure repo 1
-        </strong>
-      </Radio>
+          <strong
+            className="text-ellipsis"
+            title="Azure repo 1"
+          >
+            Azure repo 1
+          </strong>
+        </Radio>
+      </div>
     </div>
     <ListFooter
       count={1}
@@ -80,7 +85,7 @@ exports[`should render correctly: loading 1`] = `
 </BoxedGroupAccordion>
 `;
 
-exports[`should render correctly: with a repository 1`] = `
+exports[`should render correctly: with repositories 1`] = `
 <BoxedGroupAccordion
   className="big-spacer-bottom open"
   onClick={[Function]}
@@ -97,25 +102,70 @@ exports[`should render correctly: with a repository 1`] = `
     <div
       className="display-flex-wrap"
     >
-      <Radio
-        checked={false}
-        className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden"
+      <div
+        className="display-flex-start spacer-right spacer-bottom create-project-azdo-repo"
         key="Azure repo 1"
-        onCheck={[Function]}
-        value="Azure repo 1"
       >
-        <strong
-          className="text-ellipsis"
-          title="Azure repo 1"
+        <Radio
+          checked={false}
+          className="overflow-hidden"
+          disabled={false}
+          onCheck={[Function]}
+          value="Azure repo 1"
         >
-          Azure repo 1
-        </strong>
-      </Radio>
+          <strong
+            className="text-ellipsis"
+            title="Azure repo 1"
+          >
+            Azure repo 1
+          </strong>
+        </Radio>
+      </div>
+      <div
+        className="display-flex-start spacer-right spacer-bottom create-project-azdo-repo"
+        key="Azure repo 1"
+      >
+        <CheckIcon
+          className="spacer-right"
+          fill="#00aa00"
+          size={14}
+        />
+        <div
+          className="overflow-hidden"
+        >
+          <div
+            className="little-spacer-bottom text-ellipsis"
+          >
+            <strong
+              title="SQ Name"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/dashboard",
+                    "query": Object {
+                      "branch": undefined,
+                      "id": "sq-key",
+                    },
+                  }
+                }
+              >
+                SQ Name
+              </Link>
+            </strong>
+          </div>
+          <em>
+            onboarding.create_project.repository_imported
+          </em>
+        </div>
+      </div>
     </div>
     <ListFooter
-      count={1}
+      count={2}
       loadMore={[Function]}
-      total={1}
+      total={2}
     />
   </DeferredSpinner>
 </BoxedGroupAccordion>
index b02012dfe230abaac6392ba204e6d418e4f9f8fc..d2e9420fcbd76db7f715dd1e14a013013f461113 100644 (file)
   justify-content: space-between;
 }
 
+.create-project-azdo-repo {
+  width: 250px;
+  min-height: 40px;
+}
+
 .create-project-import-bbs .open .boxed-group-header {
   border-bottom: 1px solid var(--barBorderColor);
 }
index fca78f50149c2243f42ec26d8dc1718c632443bd..603d3cbd71fe5a1c5acfb531eff1e9879c1aac7e 100644 (file)
@@ -26,6 +26,8 @@ export interface AzureProject {
 export interface AzureRepository {
   name: string;
   projectName: string;
+  sqProjectKey?: string;
+  sqProjectName?: string;
 }
 
 export interface BitbucketProject {