]> source.dussan.org Git - sonarqube.git/commitdiff
apply more feedback on onboarding tutorial (#2179)
authorStas Vilchik <stas.vilchik@sonarsource.com>
Mon, 19 Jun 2017 12:48:01 +0000 (05:48 -0700)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Tue, 20 Jun 2017 11:10:53 +0000 (04:10 -0700)
17 files changed:
server/sonar-web/src/main/js/app/components/help/LinksHelp.js
server/sonar-web/src/main/js/app/components/help/LinksHelpSonarCloud.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js
server/sonar-web/src/main/js/apps/overview/components/App.js
server/sonar-web/src/main/js/apps/overview/components/EmptyOverview.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/AnalysisStep.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Msvc.js
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap
server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Msvc-test.js.snap
sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index e76ef2c6bb69e7ce058ff6cfbe5d4c5b90ced606..b84c28222d554531050ab39f042a8e9d15daaa5e 100644 (file)
@@ -29,22 +29,35 @@ export default function LinksHelp({ onClose }: Props) {
     <div>
       <h2 className="spacer-top spacer-bottom">{translate('help.section.links')}</h2>
 
-      <a href="http://www.sonarqube.org">{translate('footer.community')}</a>{' - '}
-      <a href="https://redirect.sonarsource.com/doc/home.html">
-        {translate('footer.documentation')}
-      </a>
-      {' - '}
-      <a href="https://redirect.sonarsource.com/doc/community.html">
-        {translate('footer.support')}
-      </a>
-      {' - '}
-      <a href="https://redirect.sonarsource.com/doc/plugin-library.html">
-        {translate('footer.plugins')}
-      </a>
-      {' - '}
-      <Link to="/web_api" onClick={onClose}>{translate('footer.web_api')}</Link>
-      {' - '}
-      <Link to="/about" onClick={onClose}>{translate('footer.about')}</Link>
+      <p className="spacer-bottom">
+        <a href="http://www.sonarqube.org">{translate('footer.community')}</a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://redirect.sonarsource.com/doc/home.html">
+          {translate('footer.documentation')}
+        </a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://redirect.sonarsource.com/doc/community.html">
+          {translate('footer.support')}
+        </a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://redirect.sonarsource.com/doc/plugin-library.html">
+          {translate('footer.plugins')}
+        </a>
+      </p>
+
+      <p className="spacer-bottom">
+        <Link to="/web_api" onClick={onClose}>{translate('footer.web_api')}</Link>
+      </p>
+
+      <p>
+        <Link to="/about" onClick={onClose}>{translate('footer.about')}</Link>
+      </p>
     </div>
   );
 }
index 6efdac91b50a9e8e663a610d876bcc68db9ea850..9fdf2751253f603d07d3ed22d16269c2b9660a82 100644 (file)
@@ -29,17 +29,29 @@ export default function LinksHelpSonarCloud({ onClose }: Props) {
     <div>
       <h2 className="spacer-top spacer-bottom">{translate('help.section.links')}</h2>
 
-      <a href="https://about.sonarcloud.io/news/">{translate('footer.news')}</a>
-      {' - '}
-      <a href="https://about.sonarcloud.io/terms.pdf">{translate('footer.terms')}</a>
-      {' - '}
-      <a href="https://twitter.com/sonarqube">{translate('footer.twitter')}</a>
-      {' - '}
-      <a href="https://about.sonarcloud.io/get-started/">{translate('footer.get_started')}</a>
-      {' - '}
-      <a href="https://about.sonarcloud.io/contact/">{translate('footer.help')}</a>
-      {' - '}
-      <Link to="/about" onClick={onClose}>{translate('footer.about')}</Link>
+      <p className="spacer-bottom">
+        <a href="https://about.sonarcloud.io/news/">{translate('footer.news')}</a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://about.sonarcloud.io/terms.pdf">{translate('footer.terms')}</a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://twitter.com/sonarqube">{translate('footer.twitter')}</a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://about.sonarcloud.io/get-started/">{translate('footer.get_started')}</a>
+      </p>
+
+      <p className="spacer-bottom">
+        <a href="https://about.sonarcloud.io/contact/">{translate('footer.help')}</a>
+      </p>
+
+      <p>
+        <Link to="/about" onClick={onClose}>{translate('footer.about')}</Link>
+      </p>
     </div>
   );
 }
index cb2d2eca4284e9a58cd5eb4d8ec7e6fe16a52bbc..5f6de29a8f78273726fec9e0b538e664ea671f87 100644 (file)
@@ -87,9 +87,7 @@ class GlobalNav extends React.PureComponent {
 
   openOnboardingTutorial = () => this.setState({ helpOpen: false, onboardingTutorialOpen: true });
 
-  finishOnboardingTutorial = () => this.setState({ onboardingTutorialOpen: false });
-
-  skipOnboardingTutorial = () => {
+  closeOnboardingTutorial = () => {
     this.setState({ onboardingTutorialOpen: false, onboardingTutorialTooltip: true });
     this.interval = setInterval(() => {
       this.setState({ onboardingTutorialTooltip: false });
@@ -131,10 +129,7 @@ class GlobalNav extends React.PureComponent {
           />}
 
         {this.state.onboardingTutorialOpen &&
-          <OnboardingModal
-            onFinish={this.finishOnboardingTutorial}
-            onSkip={this.skipOnboardingTutorial}
-          />}
+          <OnboardingModal onFinish={this.closeOnboardingTutorial} />}
       </nav>
     );
   }
index 8a4adde9571a04b26e9bccee0ec4cfa9def957f9..5e314f44351ab0d49e5995626e93cc78fc33b167 100644 (file)
@@ -60,7 +60,7 @@ class App extends React.PureComponent {
     }
 
     if (!component.analysisDate) {
-      return <EmptyOverview {...this.props} />;
+      return <EmptyOverview component={component} />;
     }
 
     return <OverviewApp {...this.props} leakPeriodIndex="1" />;
index 8bba1c5c7a58e2478ff13626421360635e64c1c7..ba9689b3b5e58bf5d8e451581e910dbd98252ef7 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+// @flow
 import React from 'react';
+import { Link } from 'react-router';
 import { translate } from '../../../helpers/l10n';
 
-const EmptyOverview = ({ component }) => {
+type Props = {
+  component: { key: string }
+};
+
+export default function EmptyOverview({ component }: Props) {
+  const rawMessage = translate('provisioning.no_analysis.delete');
+  const head = rawMessage.substr(0, rawMessage.indexOf('{0}'));
+  const tail = rawMessage.substr(rawMessage.indexOf('{0}') + 3);
+
   return (
     <div className="page page-limited">
       <div className="alert alert-warning">
         {translate('provisioning.no_analysis')}
       </div>
+
+      <div className="big-spacer-top">
+        {head}
+        <Link
+          className="text-danger"
+          to={{ pathname: '/project/deletion', query: { id: component.key } }}>
+          {translate('provisioning.no_analysis.delete_it')}
+        </Link>
+        {tail}
+      </div>
+
       <div className="big-spacer-top">
         <h4>{translate('key')}</h4>
         <code>{component.key}</code>
       </div>
     </div>
   );
-};
-
-export default EmptyOverview;
+}
index 78733e66992c40886cde5c4aa0f2f1ce13ef8784..497f104b304c7b83f0459d2fc29eebc301278e59 100644 (file)
@@ -69,6 +69,7 @@ export default class AnalysisStep extends React.PureComponent {
             <LanguageStep
               onDone={this.handleLanguageSelect}
               onReset={this.handleLanguageReset}
+              organization={this.props.organization}
               sonarCloud={this.props.sonarCloud}
             />
           </div>
index 2f79f7add07a3ab000c76996db67bd89a080a23d..45df83f7dcd1e206a2c03ec625d980937712a86b 100644 (file)
@@ -33,7 +33,6 @@ import './styles.css';
 type Props = {|
   currentUser: { login: string, isLoggedIn: boolean },
   onFinish: () => void,
-  onSkip: () => void,
   organizationsEnabled: boolean,
   sonarCloud: boolean
 |};
@@ -76,16 +75,12 @@ export default class Onboarding extends React.PureComponent {
     this.mounted = false;
   }
 
-  finishOnboarding = (skipped: boolean = false) => {
+  finishOnboarding = () => {
     this.setState({ skipping: true });
     skipOnboarding().then(
       () => {
         if (this.mounted) {
-          if (skipped) {
-            this.props.onSkip();
-          } else {
-            this.props.onFinish();
-          }
+          this.props.onFinish();
 
           if (this.state.projectKey) {
             this.context.router.push(getProjectUrl(this.state.projectKey));
@@ -119,7 +114,7 @@ export default class Onboarding extends React.PureComponent {
 
   handleSkipClick = (event: Event) => {
     event.preventDefault();
-    this.finishOnboarding(true);
+    this.finishOnboarding();
   };
 
   handleFinish = (projectKey?: string) => this.setState({ finished: true, projectKey });
index 3ec32829d17dac40ebe4e9ee20d984c63eeb7747..7ae513347557bb6390a2da6d9f05e56d0772b677 100644 (file)
@@ -23,8 +23,7 @@ import Modal from 'react-modal';
 import { translate } from '../../../helpers/l10n';
 
 type Props = {|
-  onFinish: () => void,
-  onSkip: () => void
+  onFinish: () => void
 |};
 
 type State = {
@@ -63,8 +62,7 @@ export default class OnboardingModal extends React.PureComponent {
         contentLabel={translate('tutorials.onboarding')}
         className="modal modal-large"
         overlayClassName="modal-overlay">
-        {OnboardingContainer != null &&
-          <OnboardingContainer onFinish={this.props.onFinish} onSkip={this.props.onSkip} />}
+        {OnboardingContainer != null && <OnboardingContainer onFinish={this.props.onFinish} />}
       </Modal>
     );
   }
index f336d73a79b34c36187d7e621235a8d85cdd8701..ae21ca80fc9e0147385d4855eb350a11814d331b 100644 (file)
@@ -34,7 +34,6 @@ it('guides for on-premise', () => {
     <Onboarding
       currentUser={currentUser}
       onFinish={jest.fn()}
-      onSkip={jest.fn()}
       organizationsEnabled={false}
       sonarCloud={false}
     />
@@ -52,7 +51,6 @@ it('guides for sonarcloud', () => {
     <Onboarding
       currentUser={currentUser}
       onFinish={jest.fn()}
-      onSkip={jest.fn()}
       organizationsEnabled={true}
       sonarCloud={true}
     />
@@ -70,19 +68,18 @@ it('guides for sonarcloud', () => {
   expect(wrapper).toMatchSnapshot();
 });
 
-it('skips', () => {
-  const onSkip = jest.fn();
+it('finishes', () => {
+  const onFinish = jest.fn();
   const wrapper = mount(
     <Onboarding
       currentUser={currentUser}
-      onFinish={jest.fn()}
-      onSkip={onSkip}
+      onFinish={onFinish}
       organizationsEnabled={false}
       sonarCloud={false}
     />
   );
   click(wrapper.find('.js-skip'));
   return doAsync(() => {
-    expect(onSkip).toBeCalled();
+    expect(onFinish).toBeCalled();
   });
 });
index 3f89a2bb24181c791a8141843220a7cad671cf0c..f7a710b94724a2c380f61f257ca28a80ea222874 100644 (file)
@@ -29,7 +29,7 @@ type Props = {|
 |};
 
 export default function JavaGradle(props: Props) {
-  const config = 'plugins {\n  id "org.sonarqube" version "2.2"\n}';
+  const config = 'plugins {\n  id "org.sonarqube" version "2.5"\n}';
 
   const command = [
     './gradlew sonarqube',
@@ -54,6 +54,12 @@ export default function JavaGradle(props: Props) {
         className="big-spacer-top markdown"
         dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.docs') }}
       />
+      <p
+        className="big-spacer-top markdown"
+        dangerouslySetInnerHTML={{
+          __html: translate('onboarding.analysis.browse_url_after_analysis')
+        }}
+      />
     </div>
   );
 }
index 6317b1bac2e4d05a54431e9d0017d864d6abc96c..1166463012ab2d38946559c4e0423d11c18de29d 100644 (file)
@@ -45,6 +45,12 @@ export default function JavaMaven(props: Props) {
         className="big-spacer-top markdown"
         dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.maven.docs') }}
       />
+      <p
+        className="big-spacer-top markdown"
+        dangerouslySetInnerHTML={{
+          __html: translate('onboarding.analysis.browse_url_after_analysis')
+        }}
+      />
     </div>
   );
 }
index 00fba90474af50fc493be988df9c6c65ddc5574b..fe18afad6e36ce88dda9e7bfbaff2011441444bb 100644 (file)
@@ -41,7 +41,7 @@ export default function Msvc(props: Props) {
     `/d:"sonar.login=${props.token}"`
   ];
 
-  const command2 = 'build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild';
+  const command2 = ['build-wrapper-win-x86-64.exe', '--out-dir bw-output MsBuild.exe /t:Rebuild'];
 
   const command3 = ['SonarQube.Scanner.MSBuild.exe end', `/d:"sonar.login=${props.token}"`];
 
index df6bf9db47fa9c0b0573df2879e60ee2648a72c7..559864e0d90d1cedeb92929231adad5c88635eb9 100644 (file)
@@ -17,7 +17,7 @@ exports[`renders correctly 1`] = `
   />
   <Command
     command="plugins {
-    id \\"org.sonarqube\\" version \\"2.2\\"
+    id \\"org.sonarqube\\" version \\"2.5\\"
   }"
   />
   <p
@@ -43,6 +43,14 @@ exports[`renders correctly 1`] = `
       }
     }
   />
+  <p
+    className="big-spacer-top markdown"
+    dangerouslySetInnerHTML={
+      Object {
+        "__html": "onboarding.analysis.browse_url_after_analysis",
+      }
+    }
+  />
 </div>
 `;
 
@@ -63,7 +71,7 @@ exports[`renders correctly 2`] = `
   />
   <Command
     command="plugins {
-    id \\"org.sonarqube\\" version \\"2.2\\"
+    id \\"org.sonarqube\\" version \\"2.5\\"
   }"
   />
   <p
@@ -89,5 +97,13 @@ exports[`renders correctly 2`] = `
       }
     }
   />
+  <p
+    className="big-spacer-top markdown"
+    dangerouslySetInnerHTML={
+      Object {
+        "__html": "onboarding.analysis.browse_url_after_analysis",
+      }
+    }
+  />
 </div>
 `;
index 3cd4796988b128bbdd3b7b0e32c407c1bad0b381..60d6f6c8dfb80c58519dc67868650759b43b068e 100644 (file)
@@ -30,6 +30,14 @@ exports[`renders correctly 1`] = `
       }
     }
   />
+  <p
+    className="big-spacer-top markdown"
+    dangerouslySetInnerHTML={
+      Object {
+        "__html": "onboarding.analysis.browse_url_after_analysis",
+      }
+    }
+  />
 </div>
 `;
 
@@ -63,5 +71,13 @@ exports[`renders correctly 2`] = `
       }
     }
   />
+  <p
+    className="big-spacer-top markdown"
+    dangerouslySetInnerHTML={
+      Object {
+        "__html": "onboarding.analysis.browse_url_after_analysis",
+      }
+    }
+  />
 </div>
 `;
index c2f54b404961dc79d8b170d0fddad9286a2754d1..564d75fb708c77c7b54549a5fd9577e4f9023357 100644 (file)
@@ -33,7 +33,12 @@ exports[`renders correctly 1`] = `
     }
   />
   <Command
-    command="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
+    command={
+      Array [
+        "build-wrapper-win-x86-64.exe",
+        "--out-dir bw-output MsBuild.exe /t:Rebuild",
+      ]
+    }
   />
   <Command
     command={
@@ -87,7 +92,12 @@ exports[`renders correctly 2`] = `
     }
   />
   <Command
-    command="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
+    command={
+      Array [
+        "build-wrapper-win-x86-64.exe",
+        "--out-dir bw-output MsBuild.exe /t:Rebuild",
+      ]
+    }
   />
   <Command
     command={
index 9a184cc3f54a04a6b8e5e7d8cda5689f3f8521d9..27dc00819175c4c6bed0d14d3e7cb7aced7f8a6f 100644 (file)
@@ -125,7 +125,7 @@ public class CorePropertyDefinitions {
       PropertyDefinition.builder(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS)
         .name("Show an onboarding tutorial to new users")
         .type(BOOLEAN)
-        .description("Show an onboarding tutorial to news, that explains how to analyze a first project, after logging in for the fist time.")
+        .description("Show an onboarding tutorial to new users, that explains how to analyze a first project, after logging in for the fist time.")
         .category(CoreProperties.CATEGORY_GENERAL)
         .defaultValue(String.valueOf(false))
         .build(),
index 6eb28fde7ae47d8db1a83919f32635fdaa10bf59..f2f47860d44e636d8363f304b53c29ba6a3c90e8 100644 (file)
@@ -1952,6 +1952,8 @@ provisioning.no_results=There is currently no provisioned project.
 provisioning.missing.key=Key is missing
 provisioning.missing.name=Name is missing
 provisioning.no_analysis=No analysis has been performed since creation. The only available section is the configuration.
+provisioning.no_analysis.delete=Either you should retry to analyze the project, or simply {0}.
+provisioning.no_analysis.delete_it=delete it
 
 
 #------------------------------------------------------------------------------
@@ -2961,7 +2963,7 @@ onboarding.header.sonarcloud=Welcome to SonarCloud!
 onboarding.header.description=Let's analyze a new project.
 
 onboarding.token.header=Generate a token
-onboarding.token.text=We'll use it as a replacement of the user login. This will increase the security of your installation by not letting your analysis user's password going through your network.
+onboarding.token.text=The token is used to identify you when an analysis is performed. If it has been compromised, you can revoke it at any point of time in your user account.
 onboarding.token.generate=Generate
 onboarding.token.placeholder=Enter a name for your token
 
@@ -2976,6 +2978,7 @@ onboarding.organization.key_requirement=2 to 32 characters. All chars must be lo
 onboarding.project_key_requirement=Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit. 400 characters max.
 
 onboarding.analysis.header=Run analysis on your project
+onboarding.analysis.browse_url_after_analysis=Once the analysis is completed, you will be able to browse your project at the URL displayed at the end of the logs.
 
 onboarding.language=What is your project's main language?
 onboarding.language.java=Java