]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9936 Add loading spinner when doing the license preview
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 25 Oct 2017 08:31:38 +0000 (10:31 +0200)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 25 Oct 2017 12:28:47 +0000 (14:28 +0200)
server/sonar-web/src/main/js/app/components/AdminContainer.tsx
server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx
server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap
server/sonar-web/src/main/js/components/common/DeferredSpinner.tsx
server/sonar-web/src/main/js/store/marketplace/actions.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index bf12d09e0a12b74ac46aea80c91885429d524e8b..4060464e1d931169e3b368e522f8e810c5e766d5 100644 (file)
@@ -67,10 +67,10 @@ class AdminContainer extends React.PureComponent<Props> {
   }
 
   fetchNavigationSettings = () =>
-    getSettingsNavigation().then(r => this.props.setAdminPages(r.extensions), () => { });
+    getSettingsNavigation().then(r => this.props.setAdminPages(r.extensions), () => {});
 
   fetchEditionStatus = () =>
-    getEditionStatus().then(editionStatus => this.props.setEditionStatus(editionStatus), () => { });
+    getEditionStatus().then(editionStatus => this.props.setEditionStatus(editionStatus), () => {});
 
   render() {
     const { adminPages, organizationsEnabled } = this.props.appState;
index 58b58f371a7e2afdcb161e4bfe3ed5f5275f611b..3ec3bb3485b182fd67ac07c39f13b9f67a229802 100644 (file)
@@ -21,6 +21,7 @@ import * as React from 'react';
 import * as classNames from 'classnames';
 import { stringify } from 'querystring';
 import { debounce } from 'lodash';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import { omitNil } from '../../../helpers/request';
 import { Edition, getFormData, getLicensePreview } from '../../../api/marketplace';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
@@ -35,6 +36,7 @@ export interface Props {
 interface State {
   license: string;
   licenseEdition?: Edition;
+  loading: boolean;
   previewStatus?: string;
   formData?: {
     serverId?: string;
@@ -47,7 +49,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
 
   constructor(props: Props) {
     super(props);
-    this.state = { license: '' };
+    this.state = { license: '', loading: false };
     this.fetchLicensePreview = debounce(this.fetchLicensePreview, 100);
   }
 
@@ -60,7 +62,8 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
     this.mounted = false;
   }
 
-  fetchLicensePreview = (license: string) =>
+  fetchLicensePreview = (license: string) => {
+    this.setState({ loading: true });
     getLicensePreview({ license }).then(
       ({ previewStatus, nextEditionKey }) => {
         if (this.mounted) {
@@ -77,6 +80,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
         }
       }
     );
+  };
 
   fetchFormData = () => {
     getFormData().then(
@@ -85,7 +89,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
           this.setState({ formData });
         }
       },
-      () => {}
+      () => { }
     );
   };
 
@@ -111,13 +115,33 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
   };
 
   updateLicense = (license: string, licenseEdition?: Edition, previewStatus?: string) => {
-    this.setState({ license, licenseEdition, previewStatus });
+    this.setState({ license, licenseEdition, loading: false, previewStatus });
     this.props.updateLicense(license, previewStatus);
   };
 
+  renderAlert() {
+    const { licenseEdition, previewStatus } = this.state;
+    if (!previewStatus) {
+      return undefined;
+    }
+    return (
+      <p
+        className={classNames('alert spacer-top', {
+          'alert-warning': previewStatus === 'AUTOMATIC_INSTALL',
+          'alert-success': previewStatus === 'NO_INSTALL',
+          'alert-danger': previewStatus === 'MANUAL_INSTALL'
+        })}>
+        {translateWithParameters(
+          'marketplace.license_preview_status.' + previewStatus,
+          licenseEdition ? licenseEdition.name : translate('marketplace.commercial_edition')
+        )}
+      </p>
+    );
+  }
+
   render() {
     const { className, edition } = this.props;
-    const { license, licenseEdition, previewStatus } = this.state;
+    const { license, loading } = this.state;
 
     return (
       <div className={className}>
@@ -137,19 +161,19 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
           style={{ resize: 'none' }}
           value={license}
         />
-        {previewStatus && (
-          <p
-            className={classNames('alert spacer-top', {
-              'alert-warning': previewStatus === 'AUTOMATIC_INSTALL',
-              'alert-success': previewStatus === 'NO_INSTALL',
-              'alert-danger': previewStatus === 'MANUAL_INSTALL'
-            })}>
-            {translateWithParameters(
-              'marketplace.license_preview_status.' + previewStatus,
-              licenseEdition ? licenseEdition.name : translate('marketplace.commercial_edition')
-            )}
-          </p>
-        )}
+
+        <DeferredSpinner
+          className="spacer-top"
+          loading={loading}
+          customSpinner={
+            <p className="spacer-top">
+              <i className="spinner spacer-right text-bottom" />
+              {translate('marketplace.checking_license')}
+            </p>
+          }>
+          {this.renderAlert()}
+        </DeferredSpinner>
+
         {edition && (
           <a
             className="display-inline-block spacer-top"
index 4534dd328d2dd296f1a3f0a9ff92f55dcacc1433..b990a23a26c4d1fac8e651c21bf9ccb58e429438 100644 (file)
@@ -51,6 +51,21 @@ exports[`should display correctly 1`] = `
     }
     value=""
   />
+  <DeferredSpinner
+    className="spacer-top"
+    customSpinner={
+      <p
+        className="spacer-top"
+      >
+        <i
+          className="spinner spacer-right text-bottom"
+        />
+        marketplace.checking_license
+      </p>
+    }
+    loading={false}
+    timeout={100}
+  />
   <a
     className="display-inline-block spacer-top"
     href="license_url"
index a840e2ea6f530e5dabd8f214483145aa92bcc30b..5c434d380d849cbd5d0b2da3131c6810dd0eff64 100644 (file)
@@ -24,7 +24,8 @@ interface Props {
   children?: JSX.Element;
   className?: string;
   loading?: boolean;
-  timeout: number;
+  customSpinner?: JSX.Element;
+  timeout?: number;
 }
 
 interface State {
@@ -71,7 +72,9 @@ export default class DeferredSpinner extends React.PureComponent<Props, State> {
 
   render() {
     if (this.state.showSpinner) {
-      return <i className={classNames('spinner', this.props.className)} />;
+      return (
+        this.props.customSpinner || <i className={classNames('spinner', this.props.className)} />
+      );
     }
     return (this.props.children as JSX.Element) || null;
   }
index e174708803f419800d3a48009b07a8fd8d596fea..297859381793380a45b25ac14f31a2e660d137f0 100644 (file)
@@ -56,7 +56,7 @@ export const setEditionStatus = (status: EditionStatus) => (dispatch: Dispatch<A
   }
   if (status.installationStatus === 'AUTOMATIC_IN_PROGRESS') {
     editionTimer = window.setTimeout(() => {
-      getEditionStatus().then(status => setEditionStatus(status)(dispatch), () => { });
+      getEditionStatus().then(status => setEditionStatus(status)(dispatch), () => {});
       editionTimer = undefined;
     }, 2000);
   }
index 3b7da354e469c1f7792cb1a3e0d739eb02fac33b..5533b2f3cc65cba3782b8531a146370677c53f78 100644 (file)
@@ -2073,6 +2073,7 @@ marketplace.installing=Installing...
 marketplace.uninstall_x=Uninstall {0}
 marketplace.uninstall_x_confirmation=Are you sure you want to uninstall {0}?
 marketplace.pending=Pending...
+marketplace.checking_license=Checking your license...
 marketplace._installed=installed
 marketplace.available_under_commercial_license=Available under our commercial editions
 marketplace.learn_more=Learn more