]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10800 Use 'Close' instead of 'Skip' to dismiss onboarding tutorial
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Tue, 5 Jun 2018 13:28:48 +0000 (15:28 +0200)
committerSonarTech <sonartech@sonarsource.com>
Tue, 12 Jun 2018 18:21:03 +0000 (20:21 +0200)
server/sonar-web/src/main/js/app/components/StartupModal.tsx
server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx
server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap

index b2429cccd1955797ef4e52701a493f4da3b93980..600d8ad5cb858f94ff64460dbe693e1dcfc7a949 100644 (file)
@@ -53,6 +53,7 @@ enum ModalKey {
 }
 
 interface State {
+  automatic: boolean;
   modal?: ModalKey;
 }
 
@@ -60,17 +61,13 @@ const LICENSE_PROMPT = 'sonarqube.license.prompt';
 
 export class StartupModal extends React.PureComponent<Props, State> {
   static childContextTypes = {
-    closeOnboardingTutorial: PropTypes.func,
     openOnboardingTutorial: PropTypes.func
   };
 
-  state: State = {};
+  state: State = { automatic: false };
 
   getChildContext() {
-    return {
-      closeOnboardingTutorial: this.closeOnboarding,
-      openOnboardingTutorial: this.openOnboarding
-    };
+    return { openOnboardingTutorial: this.openOnboarding };
   }
 
   componentDidMount() {
@@ -81,7 +78,7 @@ export class StartupModal extends React.PureComponent<Props, State> {
     this.setState(state => {
       if (state.modal === ModalKey.onboarding) {
         this.props.skipOnboarding();
-        return { modal: undefined };
+        return { automatic: false, modal: undefined };
       }
       return undefined;
     });
@@ -90,7 +87,7 @@ export class StartupModal extends React.PureComponent<Props, State> {
   closeLicense = () => {
     this.setState(state => {
       if (state.modal === ModalKey.license) {
-        return { modal: undefined };
+        return { automatic: false, modal: undefined };
       }
       return undefined;
     });
@@ -112,7 +109,7 @@ export class StartupModal extends React.PureComponent<Props, State> {
         return showLicense().then(license => {
           if (!license || !license.isValidEdition) {
             save(LICENSE_PROMPT, toShortNotSoISOString(new Date()), currentUser.login);
-            this.setState({ modal: ModalKey.license });
+            this.setState({ automatic: true, modal: ModalKey.license });
             return Promise.resolve();
           }
           return Promise.reject('License exists');
@@ -124,17 +121,20 @@ export class StartupModal extends React.PureComponent<Props, State> {
 
   tryAutoOpenOnboarding = () => {
     if (this.props.currentUser.showOnboardingTutorial) {
+      this.setState({ automatic: true });
       this.openOnboarding();
     }
   };
 
   render() {
-    const { modal } = this.state;
+    const { automatic, modal } = this.state;
     return (
       <>
         {this.props.children}
         {modal === ModalKey.license && <LicensePromptModal onClose={this.closeLicense} />}
-        {modal === ModalKey.onboarding && <OnboardingModal onFinish={this.closeOnboarding} />}
+        {modal === ModalKey.onboarding && (
+          <OnboardingModal automatic={automatic} onFinish={this.closeOnboarding} />
+        )}
       </>
     );
   }
index cc04c85868c56ddca259a3d73d92b654a3d31e92..afcf049e3971c7da8107498fd01bbcfa41b40ff1 100644 (file)
@@ -25,16 +25,18 @@ import TokenStep from './TokenStep';
 import OrganizationStep from './OrganizationStep';
 import AnalysisStep from './AnalysisStep';
 import ProjectWatcher from './ProjectWatcher';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
 import InstanceMessage from '../../../components/common/InstanceMessage';
 import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
 import { skipOnboarding } from '../../../api/users';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { getProjectUrl } from '../../../helpers/urls';
-import './styles.css';
 import { isSonarCloud } from '../../../helpers/system';
+import './styles.css';
 
 /*::
 type Props = {|
+  automatic?:boolean,
   className?: string,
   currentUser: { login: string, isLoggedIn: boolean },
   onFinish: () => void,
@@ -145,7 +147,7 @@ export default class Onboarding extends React.PureComponent {
       return null;
     }
 
-    const { organizationsEnabled } = this.props;
+    const { automatic, organizationsEnabled } = this.props;
     const { step, token } = this.state;
     let stepNumber = 1;
 
@@ -161,13 +163,12 @@ export default class Onboarding extends React.PureComponent {
               <InstanceMessage message={translate('onboarding.header')} />
             </h1>
             <div className="page-actions">
-              {this.state.skipping ? (
-                <i className="spinner" />
-              ) : (
+              <DeferredSpinner loading={this.state.skipping}>
                 <a className="js-skip text-muted" href="#" onClick={this.handleSkipClick}>
-                  {translate('tutorials.skip')}
+                  {automatic ? translate('tutorials.skip') : translate('close')}
                 </a>
-              )}
+              </DeferredSpinner>
+
               <p className="note">
                 {translate(
                   isSonarCloud()
index e1013a3f750c4d3fbd897411e4ba1acc807ae974..188e5cc7927a62ccba1a0a365e625f6c33e32e62 100644 (file)
@@ -23,15 +23,16 @@ import { translate } from '../../../helpers/l10n';
 import { lazyLoad } from '../../../components/lazyLoad';
 
 interface Props {
+  automatic?: boolean;
   onFinish: () => void;
 }
 
 const OnboardingContainer = lazyLoad(() => import('./OnboardingContainer'));
 
-export default function OnboardingModal({ onFinish }: Props) {
+export default function OnboardingModal(props: Props) {
   return (
     <Modal contentLabel={translate('tutorials.onboarding')} large={true}>
-      <OnboardingContainer onFinish={onFinish} />
+      <OnboardingContainer {...props} />
     </Modal>
   );
 }
index 313284fb6a0e6e7cdec1cfa376e409bee145573a..1635dc70bd540b885ab291ef6b4e2443831d10e7 100644 (file)
@@ -23,13 +23,18 @@ exports[`guides for on-premise 1`] = `
       <div
         className="page-actions"
       >
-        <a
-          className="js-skip text-muted"
-          href="#"
-          onClick={[Function]}
+        <DeferredSpinner
+          loading={false}
+          timeout={100}
         >
-          tutorials.skip
-        </a>
+          <a
+            className="js-skip text-muted"
+            href="#"
+            onClick={[Function]}
+          >
+            close
+          </a>
+        </DeferredSpinner>
         <p
           className="note"
         >
@@ -88,13 +93,18 @@ exports[`guides for on-premise 2`] = `
       <div
         className="page-actions"
       >
-        <a
-          className="js-skip text-muted"
-          href="#"
-          onClick={[Function]}
+        <DeferredSpinner
+          loading={false}
+          timeout={100}
         >
-          tutorials.skip
-        </a>
+          <a
+            className="js-skip text-muted"
+            href="#"
+            onClick={[Function]}
+          >
+            close
+          </a>
+        </DeferredSpinner>
         <p
           className="note"
         >
@@ -152,13 +162,18 @@ exports[`guides for sonarcloud 1`] = `
       <div
         className="page-actions"
       >
-        <a
-          className="js-skip text-muted"
-          href="#"
-          onClick={[Function]}
+        <DeferredSpinner
+          loading={false}
+          timeout={100}
         >
-          tutorials.skip
-        </a>
+          <a
+            className="js-skip text-muted"
+            href="#"
+            onClick={[Function]}
+          >
+            close
+          </a>
+        </DeferredSpinner>
         <p
           className="note"
         >
@@ -228,13 +243,18 @@ exports[`guides for sonarcloud 2`] = `
       <div
         className="page-actions"
       >
-        <a
-          className="js-skip text-muted"
-          href="#"
-          onClick={[Function]}
+        <DeferredSpinner
+          loading={false}
+          timeout={100}
         >
-          tutorials.skip
-        </a>
+          <a
+            className="js-skip text-muted"
+            href="#"
+            onClick={[Function]}
+          >
+            close
+          </a>
+        </DeferredSpinner>
         <p
           className="note"
         >
@@ -305,13 +325,18 @@ exports[`guides for sonarcloud 3`] = `
       <div
         className="page-actions"
       >
-        <a
-          className="js-skip text-muted"
-          href="#"
-          onClick={[Function]}
+        <DeferredSpinner
+          loading={false}
+          timeout={100}
         >
-          tutorials.skip
-        </a>
+          <a
+            className="js-skip text-muted"
+            href="#"
+            onClick={[Function]}
+          >
+            close
+          </a>
+        </DeferredSpinner>
         <p
           className="note"
         >