diff options
author | Pascal Mugnier <pascal.mugnier@sonarsource.com> | 2018-03-23 11:14:46 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-03-29 20:20:46 +0200 |
commit | 8b1c450599a1ee106660d3825941ea890a051c04 (patch) | |
tree | 3ac1562d2307e7e28ef0545bc4b0caf69fcce8bb /server/sonar-web/src/main/js/apps/settings | |
parent | a1f4e05f8490aaff499d8777c72d0f9a3b1c40e5 (diff) | |
download | sonarqube-8b1c450599a1ee106660d3825941ea890a051c04.tar.gz sonarqube-8b1c450599a1ee106660d3825941ea890a051c04.zip |
SONAR-8217 Prevent saving empty values in settings
Diffstat (limited to 'server/sonar-web/src/main/js/apps/settings')
4 files changed, 48 insertions, 9 deletions
diff --git a/server/sonar-web/src/main/js/apps/settings/components/Definition.js b/server/sonar-web/src/main/js/apps/settings/components/Definition.js index 43f52fd1a22..8ca93ac74ae 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/Definition.js +++ b/server/sonar-web/src/main/js/apps/settings/components/Definition.js @@ -34,7 +34,7 @@ import { import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon'; import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon'; import { translateWithParameters, translate } from '../../../helpers/l10n'; -import { resetValue, saveValue } from '../store/actions'; +import { resetValue, saveValue, checkValue } from '../store/actions'; import { passValidation } from '../store/settingsPage/validationMessages/actions'; import { cancelChange, changeValue } from '../store/settingsPage/changedValues/actions'; import { TYPE_PASSWORD } from '../constants'; @@ -63,7 +63,8 @@ class Definition extends React.PureComponent { }; state = { - success: false + success: false, + hasError: false }; componentDidMount() { @@ -85,6 +86,8 @@ class Definition extends React.PureComponent { this.props.changeValue(this.props.setting.definition.key, value); if (this.props.setting.definition.type === TYPE_PASSWORD) { this.handleSave(); + } else { + this.handleCheck(); } }; @@ -94,7 +97,8 @@ class Definition extends React.PureComponent { return this.props .resetValue(definition.key, componentKey) .then(() => { - this.safeSetState({ success: true }); + this.props.changeValue(definition.key, definition.defaultValue); + this.safeSetState({ success: true, hasError: false }); this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000); }) .catch(() => { @@ -108,6 +112,16 @@ class Definition extends React.PureComponent { this.props.passValidation(this.props.setting.definition.key); }; + handleCheck = () => { + this.safeSetState({ success: false }); + const componentKey = this.props.component ? this.props.component.key : null; + if (this.props.checkValue(this.props.setting.definition.key, componentKey)) { + this.safeSetState({ hasError: false }); + } else { + this.safeSetState({ hasError: true }); + } + }; + handleSave = () => { if (this.props.changedValue != null) { this.safeSetState({ success: false }); @@ -126,6 +140,7 @@ class Definition extends React.PureComponent { render() { const { setting, changedValue, loading } = this.props; + const { hasError } = this.state; const { definition } = setting; const propertyName = getPropertyName(definition); @@ -195,7 +210,7 @@ class Definition extends React.PureComponent { value={effectiveValue} /> - {!hasValueChanged && ( + {(!hasValueChanged || hasError) && ( <DefinitionDefaults isDefault={isDefault} onReset={this.handleReset} @@ -203,9 +218,10 @@ class Definition extends React.PureComponent { /> )} - {hasValueChanged && ( - <DefinitionChanges onCancel={this.handleCancel} onSave={this.handleSave} /> - )} + {hasValueChanged && + !hasError && ( + <DefinitionChanges onCancel={this.handleCancel} onSave={this.handleSave} /> + )} </div> </div> ); @@ -223,5 +239,6 @@ export default connect(mapStateToProps, { saveValue, resetValue, passValidation, - cancelChange + cancelChange, + checkValue })(Definition); diff --git a/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js b/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js index df70be22428..4c19a0a8992 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js +++ b/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js @@ -67,7 +67,7 @@ export default class DefinitionDefaults extends React.PureComponent { </div> <footer className="modal-foot"> <button className="button-red">{translate('reset_verb')}</button> - <button type="reset" className="button-link" onClick={this.handleClose}> + <button className="button-link" onClick={this.handleClose} type="reset"> {translate('cancel')} </button> </footer> diff --git a/server/sonar-web/src/main/js/apps/settings/store/actions.js b/server/sonar-web/src/main/js/apps/settings/store/actions.js index dcbf19f63dd..d4d1dddd806 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/actions.js +++ b/server/sonar-web/src/main/js/apps/settings/store/actions.js @@ -59,6 +59,24 @@ export const fetchValues = (keys, component) => dispatch => () => {} ); +export const checkValue = (key, componentKey) => (dispatch, getState) => { + const state = getState(); + const definition = getSettingsAppDefinition(state, key); + const value = getSettingsAppChangedValue(state, key); + + if (isEmptyValue(definition, value)) { + if (definition.defaultValue === undefined) { + dispatch(failValidation(key, translate('settings.state.value_cant_be_empty_no_default'))); + } else { + dispatch(failValidation(key, translate('settings.state.value_cant_be_empty'))); + } + return false; + } + + dispatch(passValidation(key)); + return true; +}; + export const saveValue = (key, componentKey) => (dispatch, getState) => { dispatch(startLoading(key)); diff --git a/server/sonar-web/src/main/js/apps/settings/utils.js b/server/sonar-web/src/main/js/apps/settings/utils.js index f48db75aa2b..ffd8107f659 100644 --- a/server/sonar-web/src/main/js/apps/settings/utils.js +++ b/server/sonar-web/src/main/js/apps/settings/utils.js @@ -117,6 +117,10 @@ function getParentValue(setting) { export function getDefaultValue(setting) { const parentValue = getParentValue(setting); + if (parentValue === undefined) { + return setting.value; + } + if (parentValue == null) { return translate('settings.default.no_value'); } |