]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12594 Udpate issue type icons
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Tue, 15 Oct 2019 09:33:25 +0000 (11:33 +0200)
committerSonarTech <sonartech@sonarsource.com>
Mon, 21 Oct 2019 18:21:11 +0000 (20:21 +0200)
16 files changed:
server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/SimilarRulesFilter.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/SimilarRulesFilter-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/SimilarRulesFilter-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/Line.css
server/sonar-web/src/main/js/components/common/SelectListItem.tsx
server/sonar-web/src/main/js/components/issue/components/IssueType.tsx
server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.tsx.snap
server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.tsx
server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.tsx
server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.tsx
server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.tsx.snap
server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.tsx.snap
server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SimilarIssuesPopup-test.tsx.snap

index 4bed1a8943b771c7f43bcd1426c7089f4023a427..dfa86f63668d9ecd7516d6ea547022f344914a74 100644 (file)
@@ -228,15 +228,23 @@ export default class RuleListItem extends React.PureComponent<Props> {
                       {translate('rules.status', rule.status)}
                     </span>
                   )}
-                  <span className="spacer-left note">{rule.langName}</span>
+                  <span className="display-inline-flex-center spacer-left note">
+                    {rule.langName}
+                  </span>
                   <Tooltip overlay={translate('coding_rules.type.tooltip', rule.type)}>
                     <span className="display-inline-flex-center spacer-left note">
-                      <IssueTypeIcon className="little-spacer-right" query={rule.type} />
-                      {translate('issue.type', rule.type)}
+                      <IssueTypeIcon query={rule.type} />
+                      <span className="little-spacer-left text-middle">
+                        {translate('issue.type', rule.type)}
+                      </span>
                     </span>
                   </Tooltip>
                   {allTags.length > 0 && (
-                    <TagsList allowUpdate={false} className="note spacer-left" tags={allTags} />
+                    <TagsList
+                      allowUpdate={false}
+                      className="display-inline-flex-center note spacer-left"
+                      tags={allTags}
+                    />
                   )}
                   <SimilarRulesFilter onFilterChange={this.props.onFilterChange} rule={rule} />
                 </div>
index 83e73cdd6322ca92d0e4292e4fbedc0d5a653d7b..8215db4f3072be1171012f540021623f710ff9df 100644 (file)
@@ -21,6 +21,7 @@ import * as React from 'react';
 import Dropdown from 'sonar-ui-common/components/controls/Dropdown';
 import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon';
 import FilterIcon from 'sonar-ui-common/components/icons/FilterIcon';
+import IssueTypeIcon from 'sonar-ui-common/components/icons/IssueTypeIcon';
 import TagsIcon from 'sonar-ui-common/components/icons/TagsIcon';
 import { translate } from 'sonar-ui-common/helpers/l10n';
 import SeverityHelper from '../../../components/shared/SeverityHelper';
@@ -76,38 +77,49 @@ export default class SimilarRulesFilter extends React.PureComponent<Props> {
             <ul className="menu">
               <li className="menu-header">{translate('coding_rules.filter_similar_rules')}</li>
               <li>
-                <a data-field="language" href="#" onClick={this.handleLanguageClick}>
+                <a
+                  data-test="coding-rules__similar-language"
+                  href="#"
+                  onClick={this.handleLanguageClick}>
                   {rule.langName}
                 </a>
               </li>
 
               <li>
-                <a data-field="type" href="#" onClick={this.handleTypeClick}>
-                  {translate('issue.type', rule.type)}
+                <a
+                  className="display-flex-center"
+                  data-test="coding-rules__similar-type"
+                  href="#"
+                  onClick={this.handleTypeClick}>
+                  <IssueTypeIcon query={rule.type} />
+                  <span className="little-spacer-left">{translate('issue.type', rule.type)}</span>
                 </a>
               </li>
 
               {severity && (
                 <li>
-                  <a data-field="severity" href="#" onClick={this.handleSeverityClick}>
-                    <SeverityHelper severity={rule.severity} />
+                  <a
+                    data-test="coding-rules__similar-severity"
+                    href="#"
+                    onClick={this.handleSeverityClick}>
+                    <SeverityHelper className="display-flex-center" severity={rule.severity} />
                   </a>
                 </li>
               )}
 
-              {allTags.length > 0 && (
-                <>
-                  <li className="divider" />
-                  {allTags.map(tag => (
-                    <li key={tag}>
-                      <a data-field="tag" data-tag={tag} href="#" onClick={this.handleTagClick}>
-                        <TagsIcon className="icon-half-transparent little-spacer-right text-middle" />
-                        <span className="text-middle">{tag}</span>
-                      </a>
-                    </li>
-                  ))}
-                </>
-              )}
+              {allTags.length > 0 && <li className="divider" />}
+              {allTags.map(tag => (
+                <li key={tag}>
+                  <a
+                    data-tag={tag}
+                    data-test="coding-rules__similar-tag"
+                    href="#"
+                    onClick={this.handleTagClick}>
+                    <TagsIcon className="icon-half-transparent little-spacer-right text-middle" />
+                    <span className="text-middle">{tag}</span>
+                  </a>
+                </li>
+              ))}
             </ul>
           </>
         }>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/SimilarRulesFilter-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/SimilarRulesFilter-test.tsx
new file mode 100644 (file)
index 0000000..27c9b77
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { mount, shallow } from 'enzyme';
+import * as React from 'react';
+import { click } from 'sonar-ui-common/helpers/testUtils';
+import { mockRule } from '../../../../helpers/testMocks';
+import SimilarRulesFilter from '../SimilarRulesFilter';
+
+it('should render correctly', () => {
+  expect(
+    shallow(<SimilarRulesFilter onFilterChange={jest.fn()} rule={mockRule()} />)
+  ).toMatchSnapshot();
+});
+
+it('should filter by similar language', () => {
+  const onFilterChange = jest.fn();
+  const wrapper = mountRenderAction('language', { onFilterChange });
+  click(wrapper);
+  expect(onFilterChange).toBeCalledWith({ languages: ['js'] });
+});
+
+it('should filter by similar type', () => {
+  const onFilterChange = jest.fn();
+  const wrapper = mountRenderAction('type', { onFilterChange });
+  click(wrapper);
+  expect(onFilterChange).toBeCalledWith({ types: ['CODE_SMELL'] });
+});
+
+it('should filter by similar severity', () => {
+  const onFilterChange = jest.fn();
+  const wrapper = mountRenderAction('severity', { onFilterChange });
+  click(wrapper);
+  expect(onFilterChange).toBeCalledWith({ severities: ['MAJOR'] });
+});
+
+it('should filter by similar tag', () => {
+  const onFilterChange = jest.fn();
+  const wrapper = mountRenderAction('tag', { onFilterChange });
+  click(wrapper);
+  expect(onFilterChange).toBeCalledWith({ tags: ['x'] });
+});
+
+function mountRenderAction(actionName: string, props: Partial<SimilarRulesFilter['props']> = {}) {
+  const wrapper = mount(
+    <SimilarRulesFilter onFilterChange={jest.fn()} rule={mockRule()} {...props} />
+  );
+  return mount(wrapper.find('Dropdown').prop<React.ReactElement>('overlay'))
+    .find(`a[data-test="coding-rules__similar-${actionName}"]`)
+    .first();
+}
index 279ddfd36e6145e978e2bf45aa8837a1530bd36a..a48a11f7ef0df65a6846908ff42c5b887b573bf9 100644 (file)
@@ -127,7 +127,7 @@ exports[`should render 1`] = `
             className="display-flex-center coding-rule-meta"
           >
             <span
-              className="spacer-left note"
+              className="display-inline-flex-center spacer-left note"
             >
               JavaScript
             </span>
@@ -138,15 +138,18 @@ exports[`should render 1`] = `
                 className="display-inline-flex-center spacer-left note"
               >
                 <IssueTypeIcon
-                  className="little-spacer-right"
                   query="CODE_SMELL"
                 />
-                issue.type.CODE_SMELL
+                <span
+                  className="little-spacer-left text-middle"
+                >
+                  issue.type.CODE_SMELL
+                </span>
               </span>
             </Tooltip>
             <TagsList
               allowUpdate={false}
-              className="note spacer-left"
+              className="display-inline-flex-center note spacer-left"
               tags={
                 Array [
                   "x",
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/SimilarRulesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/SimilarRulesFilter-test.tsx.snap
new file mode 100644 (file)
index 0000000..7f08048
--- /dev/null
@@ -0,0 +1,125 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Dropdown
+  className="display-inline-block"
+  overlay={
+    <React.Fragment>
+      <ul
+        className="menu"
+      >
+        <li
+          className="menu-header"
+        >
+          coding_rules.filter_similar_rules
+        </li>
+        <li>
+          <a
+            data-test="coding-rules__similar-language"
+            href="#"
+            onClick={[Function]}
+          >
+            JavaScript
+          </a>
+        </li>
+        <li>
+          <a
+            className="display-flex-center"
+            data-test="coding-rules__similar-type"
+            href="#"
+            onClick={[Function]}
+          >
+            <IssueTypeIcon
+              query="CODE_SMELL"
+            />
+            <span
+              className="little-spacer-left"
+            >
+              issue.type.CODE_SMELL
+            </span>
+          </a>
+        </li>
+        <li>
+          <a
+            data-test="coding-rules__similar-severity"
+            href="#"
+            onClick={[Function]}
+          >
+            <SeverityHelper
+              className="display-flex-center"
+              severity="MAJOR"
+            />
+          </a>
+        </li>
+        <li
+          className="divider"
+        />
+        <li>
+          <a
+            data-tag="x"
+            data-test="coding-rules__similar-tag"
+            href="#"
+            onClick={[Function]}
+          >
+            <TagsIcon
+              className="icon-half-transparent little-spacer-right text-middle"
+            />
+            <span
+              className="text-middle"
+            >
+              x
+            </span>
+          </a>
+        </li>
+        <li>
+          <a
+            data-tag="a"
+            data-test="coding-rules__similar-tag"
+            href="#"
+            onClick={[Function]}
+          >
+            <TagsIcon
+              className="icon-half-transparent little-spacer-right text-middle"
+            />
+            <span
+              className="text-middle"
+            >
+              a
+            </span>
+          </a>
+        </li>
+        <li>
+          <a
+            data-tag="b"
+            data-test="coding-rules__similar-tag"
+            href="#"
+            onClick={[Function]}
+          >
+            <TagsIcon
+              className="icon-half-transparent little-spacer-right text-middle"
+            />
+            <span
+              className="text-middle"
+            >
+              b
+            </span>
+          </a>
+        </li>
+      </ul>
+    </React.Fragment>
+  }
+>
+  <a
+    className="js-rule-filter link-no-underline spacer-left dropdown-toggle"
+    href="#"
+    title="coding_rules.filter_similar_rules"
+  >
+    <FilterIcon
+      className="icon-half-transparent"
+    />
+    <DropdownIcon
+      className="icon-half-transparent"
+    />
+  </a>
+</Dropdown>
+`;
index 7e16ba09c35501c083026a82b006fcf5410873c5..b8385c54db256083f21b92f91a46ebe0bbb8d776 100644 (file)
@@ -344,10 +344,10 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
     const options = types.map(type => ({ label: translate('issue.type', type), value: type }));
 
     const optionRenderer = (option: { label: string; value: string }) => (
-      <span>
-        <IssueTypeIcon className="little-spacer-right" query={option.value} />
-        {option.label}
-      </span>
+      <>
+        <IssueTypeIcon query={option.value} />
+        <span className="little-spacer-left">{option.label}</span>
+      </>
     );
 
     const input = (
index 8052467813b427c33eb3386934ee7443f43b9819..4858d14b49b42bc497173995ccb851eef6e21a3f 100644 (file)
   cursor: pointer;
 }
 
-.source-meta + .source-meta {
-  border-left: 1px solid var(--barBackgroundColor);
-}
-
 .source-line-number {
   min-width: 18px;
   padding: 0 10px;
   white-space: nowrap;
 }
 
-.source-line-with-issues {
-  padding-right: 4px;
+.source-line-with-issues svg {
+  padding-right: 2px;
+  vertical-align: middle;
 }
 
 .source-line-issues-counter {
index 17236942c19ad2b6010f351ae4718aa5ad4712cb..e70ef01ba388f3852e5d8383aa91117032893cfd 100644 (file)
@@ -23,6 +23,7 @@ import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
 
 interface Props {
   active?: string;
+  className?: string;
   item: string;
   onHover?: (item: string) => void;
   onSelect?: (item: string) => void;
@@ -48,7 +49,10 @@ export default class SelectListItem extends React.PureComponent<Props> {
     return (
       <li>
         <a
-          className={classNames({ active: this.props.active === this.props.item })}
+          className={classNames(
+            { active: this.props.active === this.props.item },
+            this.props.className
+          )}
           href="#"
           onClick={this.handleSelect}
           onFocus={this.handleHover}
index 9f277bee515c5151e70850b02708b0a08a680dce..56461143ecbb4df29f051dde455dde954204a4bc 100644 (file)
@@ -24,6 +24,7 @@ import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon';
 import IssueTypeIcon from 'sonar-ui-common/components/icons/IssueTypeIcon';
 import { translate } from 'sonar-ui-common/helpers/l10n';
 import { IssueResponse, setIssueType } from '../../../api/issues';
+import { colors } from '../../../app/theme';
 import SetTypePopup from '../popups/SetTypePopup';
 
 interface Props {
@@ -64,7 +65,11 @@ export default class IssueType extends React.PureComponent<Props> {
             <ButtonLink
               className="issue-action issue-action-with-options js-issue-set-type"
               onClick={this.toggleSetType}>
-              <IssueTypeIcon className="little-spacer-right" query={issue.type} />
+              <IssueTypeIcon
+                className="little-spacer-right"
+                fill={colors.baseFontColor}
+                query={issue.type}
+              />
               {translate('issue.type', issue.type)}
               <DropdownIcon className="little-spacer-left" />
             </ButtonLink>
index 6af3b059348ccb533e1a4f664827d1e9b00d4f17..ecd72edd3106283addc0c769218cfac7ba0f1d49 100644 (file)
@@ -33,6 +33,7 @@ exports[`should open the popup when the button is clicked 2`] = `
     >
       <IssueTypeIcon
         className="little-spacer-right"
+        fill="#444"
         query="BUG"
       />
       issue.type.BUG
@@ -68,6 +69,7 @@ exports[`should render with the action 1`] = `
     >
       <IssueTypeIcon
         className="little-spacer-right"
+        fill="#444"
         query="BUG"
       />
       issue.type.BUG
index 10ffa22cb49338e0b3f6e1bcfb596677e03ace64..2e8f1a489d412a8397e5ac947bb6bd43386a2f2f 100644 (file)
@@ -36,7 +36,7 @@ export default function SetSeverityPopup({ issue, onSelect }: Props) {
     <DropdownOverlay>
       <SelectList currentItem={issue.severity} items={SEVERITY} onSelect={onSelect}>
         {SEVERITY.map(severity => (
-          <SelectListItem item={severity} key={severity}>
+          <SelectListItem className="display-flex-center" item={severity} key={severity}>
             <SeverityIcon className="little-spacer-right" severity={severity} />
             {translate('severity', severity)}
           </SelectListItem>
index 070f01b0271561339718b0ac57b3bf5ebfa6c226..7f13d002a7b9f5a4052513c2ac5bf8bbafac4808 100644 (file)
@@ -36,7 +36,7 @@ export default function SetTypePopup({ issue, onSelect }: Props) {
     <DropdownOverlay>
       <SelectList currentItem={issue.type} items={TYPES} onSelect={onSelect}>
         {TYPES.map(type => (
-          <SelectListItem item={type} key={type}>
+          <SelectListItem className="display-flex-center" item={type} key={type}>
             <IssueTypeIcon className="little-spacer-right" query={type} />
             {translate('issue.type', type)}
           </SelectListItem>
index b2d34c5a29e03d3bfced278ce1671002cdcefc19..0309b6797645410966a3ea4bca83494c11d4e221 100644 (file)
@@ -69,17 +69,21 @@ export default class SimilarIssuesPopup extends React.PureComponent<Props> {
           currentItem={items[0]}
           items={items}
           onSelect={this.handleSelect}>
-          <SelectListItem item="type">
+          <SelectListItem className="display-flex-center" item="type">
             <IssueTypeIcon className="little-spacer-right" query={issue.type} />
             {translate('issue.type', issue.type)}
           </SelectListItem>
 
           <SelectListItem item="severity">
-            <SeverityHelper severity={issue.severity} />
+            <SeverityHelper className="display-flex-center" severity={issue.severity} />
           </SelectListItem>
 
           <SelectListItem item="status">
-            <StatusHelper resolution={undefined} status={issue.status} />
+            <StatusHelper
+              className="display-flex-center"
+              resolution={undefined}
+              status={issue.status}
+            />
           </SelectListItem>
 
           <SelectListItem item="resolution">
index f8818f53cab27e0b63dc6898d3c18cebf18742ff..405a967b10db8efca0e1ffc946b8e634f6571a4c 100644 (file)
@@ -16,6 +16,7 @@ exports[`should render tags popup correctly 1`] = `
     onSelect={[MockFunction]}
   >
     <SelectListItem
+      className="display-flex-center"
       item="BLOCKER"
       key="BLOCKER"
     >
@@ -26,6 +27,7 @@ exports[`should render tags popup correctly 1`] = `
       severity.BLOCKER
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="CRITICAL"
       key="CRITICAL"
     >
@@ -36,6 +38,7 @@ exports[`should render tags popup correctly 1`] = `
       severity.CRITICAL
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="MAJOR"
       key="MAJOR"
     >
@@ -46,6 +49,7 @@ exports[`should render tags popup correctly 1`] = `
       severity.MAJOR
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="MINOR"
       key="MINOR"
     >
@@ -56,6 +60,7 @@ exports[`should render tags popup correctly 1`] = `
       severity.MINOR
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="INFO"
       key="INFO"
     >
index 5055d807449201612fbc25d085b82f7323f059ba..1073a5fd23c3d488f1aea98ecf0553496a6ab0f4 100644 (file)
@@ -14,6 +14,7 @@ exports[`should render tags popup correctly 1`] = `
     onSelect={[MockFunction]}
   >
     <SelectListItem
+      className="display-flex-center"
       item="BUG"
       key="BUG"
     >
@@ -24,6 +25,7 @@ exports[`should render tags popup correctly 1`] = `
       issue.type.BUG
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="VULNERABILITY"
       key="VULNERABILITY"
     >
@@ -34,6 +36,7 @@ exports[`should render tags popup correctly 1`] = `
       issue.type.VULNERABILITY
     </SelectListItem>
     <SelectListItem
+      className="display-flex-center"
       item="CODE_SMELL"
       key="CODE_SMELL"
     >
index 5907065424707451e587ca64d59e4fd7551c3d49..595727bceb6d0abdda207267ee98b8eb9ed9daf1 100644 (file)
@@ -31,6 +31,7 @@ exports[`should render correctly 1`] = `
     onSelect={[Function]}
   >
     <SelectListItem
+      className="display-flex-center"
       item="type"
     >
       <IssueTypeIcon
@@ -43,6 +44,7 @@ exports[`should render correctly 1`] = `
       item="severity"
     >
       <SeverityHelper
+        className="display-flex-center"
         severity="MAJOR"
       />
     </SelectListItem>
@@ -50,6 +52,7 @@ exports[`should render correctly 1`] = `
       item="status"
     >
       <StatusHelper
+        className="display-flex-center"
         status="OPEN"
       />
     </SelectListItem>