import { BranchParameters } from '../app/types';
import throwGlobalError from '../app/utils/throwGlobalError';
+interface DefinitionField {
+ description: string;
+ key: string;
+ name: string;
+ options: string[];
+}
+
+export interface Definition {
+ category: string;
+ description: string;
+ fields: DefinitionField[];
+ key: string;
+ name: string;
+ options: string[];
+ subCategory: string;
+ type: string;
+}
+
export function getDefinitions(component?: string): Promise<any> {
return getJSON('/api/settings/list_definitions', { component }).then(r => r.definitions);
}
import { connect } from 'react-redux';
import classNames from 'classnames';
import Input from './inputs/Input';
-import DefinitionDefaults from './DefinitionDefaults';
-import DefinitionChanges from './DefinitionChanges';
+import DefinitionActions from './DefinitionActions';
import {
getPropertyName,
getPropertyDescription,
};
state = {
- success: false,
- hasError: false
+ success: false
};
componentDidMount() {
.resetValue(definition.key, componentKey)
.then(() => {
this.props.cancelChange(definition.key, componentKey);
- this.safeSetState({ success: true, hasError: false });
+ this.safeSetState({ success: true });
this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000);
})
.catch(() => {
handleCheck = () => {
const componentKey = this.props.component ? this.props.component.key : null;
- const hasError = !this.props.checkValue(this.props.setting.definition.key, componentKey);
- this.safeSetState({ hasError });
+ this.props.checkValue(this.props.setting.definition.key, componentKey);
};
handleSave = () => {
render() {
const { setting, changedValue, loading } = this.props;
- const { hasError } = this.state;
const { definition } = setting;
const propertyName = getPropertyName(definition);
+ const hasError = this.props.validationMessage != null;
const hasValueChanged = changedValue != null;
)}
{!loading &&
- this.props.validationMessage != null && (
+ hasError && (
<span className="text-danger">
<AlertErrorIcon className="spacer-right" />
<span>
)}
{!loading &&
- this.props.validationMessage == null &&
+ !hasError &&
this.state.success && (
<span className="text-success">
<AlertSuccessIcon className="spacer-right" />
value={effectiveValue}
/>
- {(!hasValueChanged || hasError) && (
- <DefinitionDefaults
- isDefault={isDefault}
- onReset={this.handleReset}
- setting={setting}
- />
- )}
-
- {hasValueChanged && (
- <DefinitionChanges
- enableSave={!hasError}
- onCancel={this.handleCancel}
- onSave={this.handleSave}
- />
- )}
+ <DefinitionActions
+ changedValue={changedValue}
+ hasError={hasError}
+ isDefault={isDefault}
+ onCancel={this.handleCancel}
+ onReset={this.handleReset}
+ onSave={this.handleSave}
+ setting={setting}
+ />
</div>
</div>
);
--- /dev/null
+/*
+ * 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 Modal from '../../../components/controls/Modal';
+import { isEmptyValue, getDefaultValue, getSettingValue } from '../utils';
+import { translate } from '../../../helpers/l10n';
+import { Button } from '../../../components/ui/buttons';
+import { SettingValue, Definition } from '../../../api/settings';
+
+type Props = {
+ changedValue: string;
+ hasError: boolean;
+ isDefault: boolean;
+ onCancel: () => void;
+ onReset: () => void;
+ onSave: () => void;
+ setting: SettingValue & { definition: Definition };
+ valueChanged: boolean;
+};
+
+type State = { reseting: boolean };
+
+export default class DefinitionActions extends React.PureComponent<Props, State> {
+ state: State = { reseting: false };
+
+ handleClose = () => {
+ this.setState({ reseting: false });
+ };
+
+ handleReset = () => {
+ this.setState({ reseting: true });
+ };
+
+ handleSubmit = () => {
+ this.props.onReset();
+ this.handleClose();
+ };
+
+ renderModal() {
+ const header = translate('settings.reset_confirm.title');
+ return (
+ <Modal contentLabel={header} onRequestClose={this.handleClose}>
+ <header className="modal-head">
+ <h2>{header}</h2>
+ </header>
+ <form onSubmit={this.handleSubmit}>
+ <div className="modal-body">
+ <p>{translate('settings.reset_confirm.description')}</p>
+ </div>
+ <footer className="modal-foot">
+ <button className="button-red">{translate('reset_verb')}</button>
+ <button className="button-link" onClick={this.handleClose} type="reset">
+ {translate('cancel')}
+ </button>
+ </footer>
+ </form>
+ </Modal>
+ );
+ }
+
+ render() {
+ const { setting, isDefault, changedValue } = this.props;
+ const hasValueChanged = changedValue != null;
+ const canBeReset = !isDefault && isEmptyValue(setting.definition, changedValue);
+ const isExplicitlySet =
+ !isDefault && !isEmptyValue(setting.definition, getSettingValue(setting));
+
+ return (
+ <>
+ {isDefault && (
+ <div className="spacer-top note" style={{ lineHeight: '24px' }}>
+ {translate('settings._default')}
+ </div>
+ )}
+ <div className="settings-definition-changes nowrap">
+ {hasValueChanged && (
+ <Button
+ className="spacer-right button-success"
+ disabled={this.props.hasError}
+ onClick={this.props.onSave}>
+ {translate('save')}
+ </Button>
+ )}
+
+ {canBeReset && (
+ <Button className="spacer-right" onClick={this.handleReset}>
+ {translate('reset_verb')}
+ </Button>
+ )}
+
+ {hasValueChanged && (
+ <Button className="spacer-right button-link" onClick={this.props.onCancel}>
+ {translate('cancel')}
+ </Button>
+ )}
+
+ {isExplicitlySet && (
+ <span className="note">
+ {translate('default')}
+ {': '}
+ {getDefaultValue(setting)}
+ </span>
+ )}
+
+ {this.state.reseting && this.renderModal()}
+ </div>
+ </>
+ );
+ }
+}
+++ /dev/null
-/*
- * 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.
- */
-// @flow
-import React from 'react';
-import PropTypes from 'prop-types';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {
- enableSave: boolean
-};
-*/
-
-export default class DefinitionChanges extends React.PureComponent {
- static propTypes = {
- onSave: PropTypes.func.isRequired,
- onCancel: PropTypes.func.isRequired
- };
-
- handleSaveClick(e /*: Object */) {
- e.preventDefault();
- e.target.blur();
- this.props.onSave();
- }
-
- handleCancelChange(e /*: Object */) {
- e.preventDefault();
- e.target.blur();
- this.props.onCancel();
- }
-
- render() {
- return (
- <div className="settings-definition-changes">
- {this.props.enableSave && (
- <button className="js-save-changes button-success" onClick={e => this.handleSaveClick(e)}>
- {translate('save')}
- </button>
- )}
- <button
- className="js-cancel-changes big-spacer-left button-link"
- onClick={e => this.handleCancelChange(e)}>
- {translate('cancel')}
- </button>
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-// @flow
-import React from 'react';
-import { getSettingValue, isEmptyValue, getDefaultValue } from '../utils';
-import Modal from '../../../components/controls/Modal';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {
- isDefault: boolean,
- onReset: () => void,
- setting: Object
-};
-*/
-/*::
-type State = { reseting: boolean };
-*/
-
-export default class DefinitionDefaults extends React.PureComponent {
- /*:: props: Props; */
- state /*: State*/ = { reseting: false };
-
- handleClose = () => {
- this.setState({ reseting: false });
- };
-
- handleReset = (e /*: Event & {target: HTMLElement} */) => {
- e.preventDefault();
- e.target.blur();
- this.setState({ reseting: true });
- };
-
- handleSubmit = (event /*: Event */) => {
- event.preventDefault();
- this.props.onReset();
- this.handleClose();
- };
-
- renderModal() {
- const header = translate('settings.reset_confirm.title');
- return (
- <Modal contentLabel={header} onRequestClose={this.handleClose}>
- <header className="modal-head">
- <h2>{header}</h2>
- </header>
- <form onSubmit={this.handleSubmit}>
- <div className="modal-body">
- <p>{translate('settings.reset_confirm.description')}</p>
- </div>
- <footer className="modal-foot">
- <button className="button-red">{translate('reset_verb')}</button>
- <button className="button-link" onClick={this.handleClose} type="reset">
- {translate('cancel')}
- </button>
- </footer>
- </form>
- </Modal>
- );
- }
-
- render() {
- const { setting, isDefault } = this.props;
- const { definition } = setting;
-
- const isExplicitlySet = !isDefault && !isEmptyValue(definition, getSettingValue(setting));
-
- return (
- <div>
- {isDefault && (
- <div className="spacer-top note" style={{ lineHeight: '24px' }}>
- {translate('settings._default')}
- </div>
- )}
-
- {isExplicitlySet && (
- <div className="spacer-top nowrap">
- <button onClick={this.handleReset}>{translate('reset_verb')}</button>
- <span className="spacer-left note">
- {translate('default')}
- {': '}
- {getDefaultValue(setting)}
- </span>
- </div>
- )}
- {this.state.reseting && this.renderModal()}
- </div>
- );
- }
-}
* @returns {string}
*/
export function getDefaultValue(setting) {
- const parentValue = getParentValue(setting);
+ let parentValue = getParentValue(setting);
if (parentValue == null) {
- return setting.definition.defaultValue
- ? setting.definition.defaultValue
- : translate('settings.default.no_value');
+ if (setting.definition.defaultValue) {
+ return setting.definition.defaultValue;
+ }
+ parentValue = getSettingValue(setting);
+ if (parentValue == null) {
+ return translate('settings.default.no_value');
+ }
}
if (setting.definition.multiValues) {