return postJSON('/api/editions/preview', data).catch(throwGlobalError);
}
+export function getFormData(): Promise<{ serverId: string; ncloc: number }> {
+ return getJSON('/api/editions/form_data').catch(throwGlobalError);
+}
+
export function applyLicense(data: { license: string }): Promise<EditionStatus> {
return postJSON('/api/editions/apply_license', data).catch(throwGlobalError);
}
interface State {
license: string;
- loading: boolean;
status?: string;
+ submitting: boolean;
}
export default class LicenseEditionForm extends React.PureComponent<Props, State> {
mounted: boolean;
- state: State = { license: '', loading: false };
+ state: State = { license: '', submitting: false };
componentDidMount() {
this.mounted = true;
event.preventDefault();
const { license, status } = this.state;
if (license && status && ['AUTOMATIC_INSTALL', 'NO_INSTALL'].includes(status)) {
- this.setState({ loading: true });
+ this.setState({ submitting: true });
applyLicense({ license }).then(
editionStatus => {
this.props.updateEditionStatus(editionStatus);
},
() => {
if (this.mounted) {
- this.setState({ loading: false });
+ this.setState({ submitting: false });
}
}
);
render() {
const { edition } = this.props;
- const { loading, status } = this.state;
+ const { submitting, status } = this.state;
const header = translateWithParameters('marketplace.install_x', edition.name);
return (
<Modal
/>
<footer className="modal-foot">
- {loading && <i className="spinner spacer-right" />}
+ {submitting && <i className="spinner spacer-right" />}
{status &&
['NO_INSTALL', 'AUTOMATIC_INSTALL'].includes(status) && (
- <button className="js-confirm" onClick={this.handleConfirmClick} disabled={loading}>
+ <button className="js-confirm" onClick={this.handleConfirmClick} disabled={submitting}>
{status === 'NO_INSTALL' ? translate('save') : translate('marketplace.install')}
</button>
)}
*/
import * as React from 'react';
import * as classNames from 'classnames';
+import { stringify } from 'querystring';
import { debounce } from 'lodash';
-import { Edition, getLicensePreview } from '../../../api/marketplace';
+import { omitNil } from '../../../helpers/request';
+import { Edition, getFormData, getLicensePreview } from '../../../api/marketplace';
import { translate, translateWithParameters } from '../../../helpers/l10n';
export interface Props {
interface State {
license: string;
licenseEdition?: Edition;
- loading: boolean;
previewStatus?: string;
+ formData?: {
+ serverId?: string;
+ ncloc?: number;
+ };
}
export default class LicenseEditionSet extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
- this.state = { license: '', loading: false };
+ this.state = { license: '' };
this.fetchLicensePreview = debounce(this.fetchLicensePreview, 100);
}
componentDidMount() {
this.mounted = true;
+ this.fetchFormData();
}
componentWillUnmount() {
}
);
+ fetchFormData = () => {
+ getFormData().then(
+ formData => {
+ if (this.mounted) {
+ this.setState({ formData });
+ }
+ },
+ () => {}
+ );
+ };
+
+ getLicenseFormUrl = (edition: Edition) => {
+ let url = edition.request_license_link;
+ if (this.state.formData) {
+ const query = stringify(omitNil(this.state.formData));
+ if (query) {
+ url += '?' + query;
+ }
+ }
+ return url;
+ };
+
handleLicenseChange = (event: React.SyntheticEvent<HTMLTextAreaElement>) => {
const license = event.currentTarget.value;
if (license) {
return (
<div className={className}>
{edition && (
- <label className="spacer-bottom" htmlFor="set-license">
+ <label className="display-inline-block spacer-bottom" htmlFor="set-license">
{translateWithParameters('marketplace.enter_license_for_x', edition.name)}
<em className="mandatory">*</em>
</label>
{edition && (
<a
className="display-inline-block spacer-top"
- href={edition.request_license_link}
+ href={this.getLicenseFormUrl(edition)}
target="_blank">
{translate('marketplace.i_need_a_license')}
</a>
exports[`should display correctly 1`] = `
<div>
<label
- className="spacer-bottom"
+ className="display-inline-block spacer-bottom"
htmlFor="set-license"
>
marketplace.enter_license_for_x.Foo
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.
- */
-// @flow
-import React from 'react';
-import classNames from 'classnames';
-
-/*::
-type Props = {
- children?: React.Element<*>,
- className?: string,
- loading?: boolean,
- timeout: number
-};
-*/
-
-/*::
-type State = {
- showSpinner: boolean
-};
-*/
-
-export default class DeferredSpinner extends React.PureComponent {
- /*:: props: Props; */
- /*:: state: State; */
- /*:: timer: number; */
-
- static defaultProps = {
- timeout: 100
- };
-
- constructor(props /*: Props */) {
- super(props);
- this.state = { showSpinner: false };
- }
-
- componentDidMount() {
- if (this.props.loading == null || this.props.loading === true) {
- this.startTimer();
- }
- }
-
- componentWillReceiveProps(nextProps /*: Props */) {
- if (this.props.loading === false && nextProps.loading === true) {
- this.stopTimer();
- this.startTimer();
- }
- if (this.props.loading === true && nextProps.loading === false) {
- this.stopTimer();
- this.setState({ showSpinner: false });
- }
- }
-
- componentWillUnmount() {
- this.stopTimer();
- }
-
- startTimer = () => {
- this.timer = setTimeout(() => this.setState({ showSpinner: true }), this.props.timeout);
- };
-
- stopTimer = () => {
- clearTimeout(this.timer);
- };
-
- render() {
- return this.state.showSpinner ? (
- <i className={classNames('spinner', this.props.className)} />
- ) : (
- this.props.children || null
- );
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 classNames from 'classnames';
+
+interface Props {
+ children?: JSX.Element;
+ className?: string;
+ loading?: boolean;
+ timeout: number;
+}
+
+interface State {
+ showSpinner: boolean;
+}
+
+export default class DeferredSpinner extends React.PureComponent<Props, State> {
+ timer: any;
+
+ static defaultProps = {
+ timeout: 100
+ };
+
+ state: State = { showSpinner: false };
+
+ componentDidMount() {
+ if (this.props.loading == null || this.props.loading === true) {
+ this.startTimer();
+ }
+ }
+
+ componentWillReceiveProps(nextProps: Props) {
+ if (this.props.loading === false && nextProps.loading === true) {
+ this.stopTimer();
+ this.startTimer();
+ }
+ if (this.props.loading === true && nextProps.loading === false) {
+ this.stopTimer();
+ this.setState({ showSpinner: false });
+ }
+ }
+
+ componentWillUnmount() {
+ this.stopTimer();
+ }
+
+ startTimer = () => {
+ this.timer = setTimeout(() => this.setState({ showSpinner: true }), this.props.timeout);
+ };
+
+ stopTimer = () => {
+ clearTimeout(this.timer);
+ };
+
+ render() {
+ if (this.state.showSpinner) {
+ return <i className={classNames('spinner', this.props.className)} />;
+ }
+ return (this.props.children as JSX.Element) || null;
+ }
+}