]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12167 Prevent facet spinner from overlapping with button
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Mon, 24 Jun 2019 08:29:46 +0000 (10:29 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 28 Jun 2019 06:45:53 +0000 (08:45 +0200)
15 files changed:
server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/StandardFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx
server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StandardFacet-test.tsx.snap
server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StatusFacet-test.tsx.snap
server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/TypeFacet-test.tsx.snap
server/sonar-web/src/main/js/components/facet/FacetHeader.tsx
server/sonar-web/src/main/js/components/facet/ListStyleFacet.tsx
server/sonar-web/src/main/js/components/facet/__tests__/FacetHeader-test.tsx
server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetHeader-test.tsx.snap
server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/ListStyleFacet-test.tsx.snap
server/sonar-web/src/main/js/components/search-navigator.css

index ba6b59c2df95903f7a00df7a7334e75c753412f0..13bf358cbc122a76b9219df707179f4eb12866c6 100644 (file)
@@ -32,7 +32,6 @@ import DateRangeInput from '../../../components/controls/DateRangeInput';
 import { isSameDay, parseDate } from '../../../helpers/dates';
 import { translate } from '../../../helpers/l10n';
 import { formatMeasure } from '../../../helpers/measures';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 
 interface Props {
   component: T.Component | undefined;
@@ -279,6 +278,7 @@ class CreationDateFacet extends React.PureComponent<Props & InjectedIntlProps> {
     return (
       <FacetBox property={this.property}>
         <FacetHeader
+          fetching={this.props.fetching}
           name={translate('issues.facet', this.property)}
           onClear={this.handleClear}
           onClick={this.handleHeaderClick}
@@ -286,7 +286,6 @@ class CreationDateFacet extends React.PureComponent<Props & InjectedIntlProps> {
           values={this.getValues()}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && this.renderInner()}
       </FacetBox>
     );
index 958245f1ad695f9726fd3061071e097f0513d9d0..8a667b7d93df46c0516eebe7ef3387d46e1b5fed 100644 (file)
@@ -25,7 +25,6 @@ import FacetHeader from '../../../components/facet/FacetHeader';
 import FacetItem from '../../../components/facet/FacetItem';
 import FacetItemsList from '../../../components/facet/FacetItemsList';
 import { translate } from '../../../helpers/l10n';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import MultipleSelectionHint from '../../../components/facet/MultipleSelectionHint';
 
 interface Props {
@@ -116,6 +115,7 @@ export default class ResolutionFacet extends React.PureComponent<Props> {
       <FacetBox property={this.property}>
         <FacetHeader
           clearLabel="reset_verb"
+          fetching={this.props.fetching}
           name={translate('issues.facet', this.property)}
           onClear={this.handleClear}
           onClick={this.handleHeaderClick}
@@ -123,7 +123,6 @@ export default class ResolutionFacet extends React.PureComponent<Props> {
           values={values}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && (
           <>
             <FacetItemsList>{RESOLUTIONS.map(this.renderItem)}</FacetItemsList>
index 4bd9b25755ab085bfddb56b68ccd1b4a3d3f2c3c..0a8916e945d403a675f2957f2455775fdb91d33d 100644 (file)
@@ -26,7 +26,6 @@ import FacetItem from '../../../components/facet/FacetItem';
 import FacetItemsList from '../../../components/facet/FacetItemsList';
 import SeverityHelper from '../../../components/shared/SeverityHelper';
 import { translate } from '../../../helpers/l10n';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import MultipleSelectionHint from '../../../components/facet/MultipleSelectionHint';
 
 interface Props {
@@ -100,6 +99,7 @@ export default class SeverityFacet extends React.PureComponent<Props> {
     return (
       <FacetBox property={this.property}>
         <FacetHeader
+          fetching={this.props.fetching}
           name={translate('issues.facet', this.property)}
           onClear={this.handleClear}
           onClick={this.handleHeaderClick}
@@ -107,7 +107,6 @@ export default class SeverityFacet extends React.PureComponent<Props> {
           values={values}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && (
           <>
             <FacetItemsList>{SEVERITIES.map(this.renderItem)}</FacetItemsList>
index 51dde5811c3a274d5f37ebe28c6263cab016dc8e..d932ecdc790dca54dffedced2ce27d83e6741c21 100644 (file)
@@ -19,7 +19,6 @@
  */
 import * as React from 'react';
 import { sortBy, without, omit } from 'lodash';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import FacetBox from '../../../components/facet/FacetBox';
 import FacetHeader from '../../../components/facet/FacetHeader';
 import FacetItem from '../../../components/facet/FacetItem';
@@ -300,6 +299,7 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
       <>
         <FacetBox className="is-inner" property="sonarsourceSecurity">
           <FacetHeader
+            fetching={this.props.fetchingSonarSourceSecurity}
             name={translate('issues.facet.sonarsourceSecurity')}
             onClick={this.handleSonarSourceSecurityHeaderClick}
             open={this.props.sonarsourceSecurityOpen}
@@ -307,7 +307,6 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
               renderSonarSourceSecurityCategory(this.state.standards, item)
             )}
           />
-          <DeferredSpinner loading={this.props.fetchingSonarSourceSecurity} />
           {this.props.sonarsourceSecurityOpen && (
             <>
               {this.renderSonarSourceSecurityList()}
@@ -317,6 +316,7 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
         </FacetBox>
         <FacetBox className="is-inner" property="owaspTop10">
           <FacetHeader
+            fetching={this.props.fetchingOwaspTop10}
             name={translate('issues.facet.owaspTop10')}
             onClick={this.handleOwaspTop10HeaderClick}
             open={this.props.owaspTop10Open}
@@ -324,7 +324,6 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
               renderOwaspTop10Category(this.state.standards, item)
             )}
           />
-          <DeferredSpinner loading={this.props.fetchingOwaspTop10} />
           {this.props.owaspTop10Open && (
             <>
               {this.renderOwaspTop10List()}
@@ -334,6 +333,7 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
         </FacetBox>
         <FacetBox className="is-inner" property="sansTop25">
           <FacetHeader
+            fetching={this.props.fetchingSansTop25}
             name={translate('issues.facet.sansTop25')}
             onClick={this.handleSansTop25HeaderClick}
             open={this.props.sansTop25Open}
@@ -341,7 +341,6 @@ export default class StandardFacet extends React.PureComponent<Props, State> {
               renderSansTop25Category(this.state.standards, item)
             )}
           />
-          <DeferredSpinner loading={this.props.fetchingSansTop25} />
           {this.props.sansTop25Open && (
             <>
               {this.renderSansTop25List()}
index ea83e7a20c25fd578d4274bf6703c1c7538a1d70..33ef4e83e7d3745ee971a522383ace7a1cd02868 100644 (file)
@@ -26,7 +26,6 @@ import FacetItem from '../../../components/facet/FacetItem';
 import FacetItemsList from '../../../components/facet/FacetItemsList';
 import StatusHelper from '../../../components/shared/StatusHelper';
 import { translate } from '../../../helpers/l10n';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import MultipleSelectionHint from '../../../components/facet/MultipleSelectionHint';
 
 interface Props {
@@ -100,6 +99,7 @@ export default class StatusFacet extends React.PureComponent<Props> {
     return (
       <FacetBox property={this.property}>
         <FacetHeader
+          fetching={this.props.fetching}
           name={translate('issues.facet', this.property)}
           onClear={this.handleClear}
           onClick={this.handleHeaderClick}
@@ -107,7 +107,6 @@ export default class StatusFacet extends React.PureComponent<Props> {
           values={values}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && (
           <>
             <FacetItemsList title={translate('issues')}>
index 3c4b92588bd841d866742995495b29d6f8bd2e0d..bf3d9f9f428807a392c555c542fe8874d196e3ca 100644 (file)
@@ -21,7 +21,6 @@ import * as React from 'react';
 import { connect } from 'react-redux';
 import { Link } from 'react-router';
 import { orderBy, without } from 'lodash';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import FacetBox from '../../../components/facet/FacetBox';
 import FacetHeader from '../../../components/facet/FacetHeader';
 import FacetItem from '../../../components/facet/FacetItem';
@@ -143,6 +142,7 @@ export class TypeFacet extends React.PureComponent<Props> {
       <FacetBox property={this.property}>
         <FacetHeader
           clearLabel="reset_verb"
+          fetching={this.props.fetching}
           name={translate('issues.facet', this.property)}
           onClear={this.handleClear}
           onClick={this.handleHeaderClick}
@@ -150,7 +150,6 @@ export class TypeFacet extends React.PureComponent<Props> {
           values={values}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && (
           <>
             <FacetItemsList>{ISSUE_TYPES.map(this.renderItem)}</FacetItemsList>
index 363f646c08b5203d666784136f94899689b0ab87..a38caf5b8161216be229d6f3800e1ad8970787ce 100644 (file)
@@ -20,15 +20,12 @@ exports[`should render empty sub-facet 1`] = `
   property="sansTop25"
 >
   <FacetHeader
+    fetching={false}
     name="issues.facet.sansTop25"
     onClick={[Function]}
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <div
     className="search-navigator-facet-empty little-spacer-top"
   >
@@ -64,6 +61,7 @@ exports[`should render sub-facets 1`] = `
     property="sonarsourceSecurity"
   >
     <FacetHeader
+      fetching={false}
       name="issues.facet.sonarsourceSecurity"
       onClick={[Function]}
       open={true}
@@ -73,10 +71,6 @@ exports[`should render sub-facets 1`] = `
         ]
       }
     />
-    <DeferredSpinner
-      loading={false}
-      timeout={100}
-    />
     <FacetItemsList>
       <FacetItem
         active={true}
@@ -101,6 +95,7 @@ exports[`should render sub-facets 1`] = `
     property="owaspTop10"
   >
     <FacetHeader
+      fetching={false}
       name="issues.facet.owaspTop10"
       onClick={[Function]}
       open={true}
@@ -110,10 +105,6 @@ exports[`should render sub-facets 1`] = `
         ]
       }
     />
-    <DeferredSpinner
-      loading={false}
-      timeout={100}
-    />
     <FacetItemsList>
       <FacetItem
         active={false}
@@ -150,6 +141,7 @@ exports[`should render sub-facets 1`] = `
     property="sansTop25"
   >
     <FacetHeader
+      fetching={false}
       name="issues.facet.sansTop25"
       onClick={[Function]}
       open={true}
@@ -159,10 +151,6 @@ exports[`should render sub-facets 1`] = `
         ]
       }
     />
-    <DeferredSpinner
-      loading={false}
-      timeout={100}
-    />
     <FacetItemsList>
       <FacetItem
         active={false}
index 9d01da1c88e1996e066dee2c47b61eb9ed0f76ff..e3e5366f6a15ca1f40a9b94656af54bd18a74e3d 100644 (file)
@@ -5,16 +5,13 @@ exports[`should render correctly 1`] = `
   property="statuses"
 >
   <FacetHeader
+    fetching={false}
     name="issues.facet.statuses"
     onClear={[Function]}
     onClick={[Function]}
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <FacetItemsList
     title="issues"
   >
index 2f78c19d462fae0e093dcf66f835f75e019f402c..47aafc2c20bdf0bd33061efda91bc15c35bd6587 100644 (file)
@@ -99,6 +99,7 @@ exports[`should render open by default 1`] = `
 >
   <FacetHeader
     clearLabel="reset_verb"
+    fetching={false}
     name="issues.facet.types"
     onClear={[Function]}
     onClick={[Function]}
@@ -110,10 +111,6 @@ exports[`should render open by default 1`] = `
       ]
     }
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <FacetItemsList>
     <FacetItem
       active={false}
index 0e3f757beb082a1ddd812aea469ad062fdf76092..600ee76ca42a35eb1a287a14a23c2b0ffc68944b 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import OpenCloseIcon from '../icons-components/OpenCloseIcon';
-import HelpTooltip from '../controls/HelpTooltip';
 import { Button } from '../ui/buttons';
+import DeferredSpinner from '../common/DeferredSpinner';
+import HelpTooltip from '../controls/HelpTooltip';
+import OpenCloseIcon from '../icons-components/OpenCloseIcon';
 import { translate, translateWithParameters } from '../../helpers/l10n';
 
 interface Props {
   children?: React.ReactNode;
   clearLabel?: string;
+  fetching?: boolean;
   helper?: string;
   name: React.ReactNode;
   onClear?: () => void;
@@ -69,7 +71,7 @@ export default class FacetHeader extends React.PureComponent<Props> {
       this.props.values != null && this.props.values.length > 0 && this.props.onClear != null;
 
     return (
-      <div className="search-navigator-facet-header-wrapper">
+      <div className="search-navigator-facet-header-wrapper display-flex-center">
         {this.props.onClick ? (
           <span className="search-navigator-facet-header display-flex-center">
             <a href="#" onClick={this.handleClick}>
@@ -91,6 +93,12 @@ export default class FacetHeader extends React.PureComponent<Props> {
           {this.renderValueIndicator()}
         </span>
 
+        {this.props.fetching && (
+          <span className="little-spacer-right">
+            <DeferredSpinner />
+          </span>
+        )}
+
         {showClearButton && (
           <Button
             className="search-navigator-facet-header-button button-small button-red"
index a10f486cbe9d956b16330d78967a437d9de2afd9..f5c7dd0f9d2741c1a876655484c1938be702ea37 100644 (file)
@@ -27,7 +27,6 @@ import FacetItemsList from './FacetItemsList';
 import ListStyleFacetFooter from './ListStyleFacetFooter';
 import MultipleSelectionHint from './MultipleSelectionHint';
 import { Alert } from '../ui/Alert';
-import DeferredSpinner from '../common/DeferredSpinner';
 import ListFooter from '../controls/ListFooter';
 import SearchBox from '../controls/SearchBox';
 import Tooltip from '../controls/Tooltip';
@@ -394,6 +393,7 @@ export default class ListStyleFacet<S> extends React.Component<Props<S>, State<S
         })}
         property={this.props.property}>
         <FacetHeader
+          fetching={this.props.fetching}
           name={
             <Tooltip overlay={disabled ? this.props.disabledHelper : undefined}>
               <span>{this.props.facetHeader}</span>
@@ -405,7 +405,6 @@ export default class ListStyleFacet<S> extends React.Component<Props<S>, State<S
           values={values}
         />
 
-        <DeferredSpinner loading={this.props.fetching} />
         {this.props.open && !disabled && (
           <>
             {this.renderSearch()}
index bf0b4468b8b314becd0ec813535af9447d5c2ee2..98c980fec5eea6812400de27573713214c45d434 100644 (file)
@@ -46,6 +46,10 @@ it('should render without link', () => {
   expect(shallow(<FacetHeader name="foo" open={false} />)).toMatchSnapshot();
 });
 
+it('should render with a spinner if loading', () => {
+  expect(shallow(<FacetHeader fetching={true} name="foo" open={false} />)).toMatchSnapshot();
+});
+
 it('should call onClick', () => {
   const onClick = jest.fn();
   const wrapper = shallow(<FacetHeader name="foo" onClick={onClick} open={false} />);
index 27ff73ed3fa14ad3a1cc70f4910943dc57c14d86..2e5979cbff64cc473f04d1a4c5d73f54be064219 100644 (file)
@@ -2,7 +2,7 @@
 
 exports[`should clear 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
@@ -39,7 +39,7 @@ exports[`should clear 1`] = `
 
 exports[`should render closed facet with value 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
@@ -70,7 +70,7 @@ exports[`should render closed facet with value 1`] = `
 
 exports[`should render closed facet without value 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
@@ -94,7 +94,7 @@ exports[`should render closed facet without value 1`] = `
 
 exports[`should render open facet with value 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
@@ -125,7 +125,7 @@ exports[`should render open facet with value 1`] = `
 
 exports[`should render open facet without value 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
@@ -147,9 +147,31 @@ exports[`should render open facet without value 1`] = `
 </div>
 `;
 
+exports[`should render with a spinner if loading 1`] = `
+<div
+  className="search-navigator-facet-header-wrapper display-flex-center"
+>
+  <span
+    className="search-navigator-facet-header display-flex-center"
+  >
+    foo
+  </span>
+  <span
+    className="search-navigator-facet-header-value spacer-left spacer-right "
+  />
+  <span
+    className="little-spacer-right"
+  >
+    <DeferredSpinner
+      timeout={100}
+    />
+  </span>
+</div>
+`;
+
 exports[`should render without link 1`] = `
 <div
-  className="search-navigator-facet-header-wrapper"
+  className="search-navigator-facet-header-wrapper display-flex-center"
 >
   <span
     className="search-navigator-facet-header display-flex-center"
index 63928439fe3fc09cc3512e8a9a857fc53753cbab..bf3706e1d5db40f5faf883d7289765e2c27ccfca 100644 (file)
@@ -6,6 +6,7 @@ exports[`should be disabled 1`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip
         overlay="Disabled helper description"
@@ -19,10 +20,6 @@ exports[`should be disabled 1`] = `
     open={false}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
 </FacetBox>
 `;
 
@@ -32,6 +29,7 @@ exports[`should display all selected items 1`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -50,10 +48,6 @@ exports[`should display all selected items 1`] = `
       ]
     }
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -126,6 +120,7 @@ exports[`should render 1`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -138,10 +133,6 @@ exports[`should render 1`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -207,6 +198,7 @@ exports[`should search 1`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -219,10 +211,6 @@ exports[`should search 1`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -278,6 +266,7 @@ exports[`should search 2`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -290,10 +279,6 @@ exports[`should search 2`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -361,6 +346,7 @@ exports[`should search 3`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -373,10 +359,6 @@ exports[`should search 3`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -442,6 +424,7 @@ exports[`should search 4`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -454,10 +437,6 @@ exports[`should search 4`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
@@ -485,6 +464,7 @@ exports[`should search 5`] = `
   property="foo"
 >
   <FacetHeader
+    fetching={false}
     name={
       <Tooltip>
         <span>
@@ -497,10 +477,6 @@ exports[`should search 5`] = `
     open={true}
     values={Array []}
   />
-  <DeferredSpinner
-    loading={false}
-    timeout={100}
-  />
   <SearchBox
     autoFocus={false}
     className="little-spacer-top spacer-bottom"
index 34a7066236b87c3f2823c1d7e455d4469e45a8b4..74fef2124af9a8c35704393df8373790988848ed 100644 (file)
   color: var(--secondFontColor);
 }
 
-.search-navigator-facet-box > .spinner {
-  float: right;
-  margin-top: -24px;
-}
-
 .search-navigator-facet {
   position: relative;
   display: inline-flex;