aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/app/components/StartupModal.tsx
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2018-05-25 17:32:53 +0200
committerSonarTech <sonartech@sonarsource.com>2018-06-12 20:20:58 +0200
commitcbf8cf43e9b606681e63454dbfd83d2472c837c6 (patch)
treea51b9758159d204f4bccdfa6e9e022c26d5a8cba /server/sonar-web/src/main/js/app/components/StartupModal.tsx
parent9c920745177dc467e7efd00715454c7eeb5cd2ca (diff)
downloadsonarqube-cbf8cf43e9b606681e63454dbfd83d2472c837c6.tar.gz
sonarqube-cbf8cf43e9b606681e63454dbfd83d2472c837c6.zip
SONAR-10695 Prompt admin to enter a license on new instance
Diffstat (limited to 'server/sonar-web/src/main/js/app/components/StartupModal.tsx')
-rw-r--r--server/sonar-web/src/main/js/app/components/StartupModal.tsx148
1 files changed, 148 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx
new file mode 100644
index 00000000000..f71ddd87bad
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx
@@ -0,0 +1,148 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as React from 'react';
+import * as PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import OnboardingModal from '../../apps/tutorials/onboarding/OnboardingModal';
+import LicensePromptModal from '../../apps/marketplace/components/LicensePromptModal';
+import { showLicense } from '../../api/marketplace';
+import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates';
+import { hasMessage } from '../../helpers/l10n';
+import { save, get } from '../../helpers/storage';
+import { getCurrentUser, getAppState } from '../../store/rootReducer';
+import { skipOnboarding } from '../../store/users/actions';
+import { CurrentUser, isLoggedIn } from '../types';
+
+interface StateProps {
+ canAdmin: boolean;
+ currentEdition: string;
+ currentUser: CurrentUser;
+}
+
+interface DispatchProps {
+ skipOnboarding: () => void;
+}
+
+interface OwnProps {
+ children?: React.ReactNode;
+}
+
+type Props = StateProps & DispatchProps & OwnProps;
+
+enum ModalKey {
+ license,
+ onboarding
+}
+
+interface State {
+ modal?: ModalKey;
+}
+
+const LICENSE_PROMPT = 'sonarqube.license.prompt';
+
+export class StartupModal extends React.PureComponent<Props, State> {
+ static childContextTypes = {
+ closeOnboardingTutorial: PropTypes.func,
+ openOnboardingTutorial: PropTypes.func
+ };
+
+ state: State = {};
+
+ getChildContext() {
+ return {
+ closeOnboardingTutorial: this.closeOnboarding,
+ openOnboardingTutorial: this.openOnboarding
+ };
+ }
+
+ componentDidMount() {
+ this.tryAutoOpenLicense().catch(this.tryAutoOpenOnboarding);
+ }
+
+ closeOnboarding = () => {
+ this.setState(state => ({
+ modal: state.modal === ModalKey.onboarding ? undefined : state.modal
+ }));
+ this.props.skipOnboarding();
+ };
+
+ closeLicense = () => {
+ this.setState(state => ({
+ modal: state.modal === ModalKey.license ? undefined : state.modal
+ }));
+ };
+
+ openOnboarding = () => {
+ this.setState({ modal: ModalKey.onboarding });
+ };
+
+ tryAutoOpenLicense = () => {
+ const { canAdmin, currentEdition, currentUser } = this.props;
+ const hasLicenseManager = hasMessage('license.prompt.title');
+ if (
+ currentEdition !== 'community' &&
+ isLoggedIn(currentUser) &&
+ canAdmin &&
+ hasLicenseManager
+ ) {
+ const lastPrompt = get(LICENSE_PROMPT, currentUser.login);
+ if (!lastPrompt || differenceInDays(new Date(), parseDate(lastPrompt)) >= 1) {
+ return showLicense().then(license => {
+ if (!license || license.edition !== currentEdition) {
+ save(LICENSE_PROMPT, toShortNotSoISOString(new Date()), currentUser.login);
+ this.setState({ modal: ModalKey.license });
+ return Promise.resolve();
+ }
+ return Promise.reject('License exists');
+ });
+ }
+ }
+ return Promise.reject('No license prompt');
+ };
+
+ tryAutoOpenOnboarding = () => {
+ if (this.props.currentUser.showOnboardingTutorial) {
+ this.openOnboarding();
+ }
+ };
+
+ render() {
+ const { modal } = this.state;
+ return (
+ <>
+ {this.props.children}
+ {modal === ModalKey.license && <LicensePromptModal onClose={this.closeLicense} />}
+ {modal === ModalKey.onboarding && <OnboardingModal onFinish={this.closeOnboarding} />}
+ </>
+ );
+ }
+}
+
+const mapStateToProps = (state: any): StateProps => ({
+ canAdmin: getAppState(state).canAdmin,
+ currentEdition: getAppState(state).edition,
+ currentUser: getCurrentUser(state)
+});
+
+const mapDispatchToProps: DispatchProps = { skipOnboarding };
+
+export default connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(
+ StartupModal
+);