From c12f3d56cb99478c36242fd122258ebf0d26f740 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 10 Aug 2016 18:16:54 +0200 Subject: SONAR-7919 Rewrite "Update Key" project page (#1140) --- .../main/js/apps/project-admin/key/BulkUpdate.js | 127 +++++++++++++++++++ .../js/apps/project-admin/key/BulkUpdateForm.js | 75 ++++++++++++ .../js/apps/project-admin/key/BulkUpdateResults.js | 111 +++++++++++++++++ .../js/apps/project-admin/key/FineGrainedUpdate.js | 53 ++++++++ .../src/main/js/apps/project-admin/key/Header.js | 36 ++++++ .../src/main/js/apps/project-admin/key/Key.js | 134 +++++++++++++++++++++ .../main/js/apps/project-admin/key/UpdateForm.js | 76 ++++++++++++ .../js/apps/project-admin/key/UpdateKeyForm.js | 92 ++++++++++++++ .../key/views/UpdateKeyConfirmation.hbs | 30 +++++ .../key/views/UpdateKeyConfirmation.js | 48 ++++++++ 10 files changed, 782 insertions(+) create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/Header.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/Key.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs create mode 100644 server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js (limited to 'server/sonar-web/src/main/js/apps/project-admin/key') diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js new file mode 100644 index 00000000000..1624faddc3f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js @@ -0,0 +1,127 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import BulkUpdateForm from './BulkUpdateForm'; +import BulkUpdateResults from './BulkUpdateResults'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { bulkChangeKey } from '../../../api/components'; +import { getComponentUrl } from '../../../helpers/urls'; + +export default class BulkUpdate extends React.Component { + static propTypes = { + component: React.PropTypes.object.isRequired + }; + + state = { + updating: false, + updated: false, + newComponentKey: null + }; + + handleSubmit (replace, by) { + this.loadResults(replace, by); + } + + handleConfirm () { + this.setState({ updating: true }); + + const { component } = this.props; + const { replace, by } = this.state; + bulkChangeKey(component.key, replace, by).then(r => { + const result = r.keys.find(result => result.key === component.key); + const newComponentKey = result != null ? result.newKey : component.key; + this.setState({ + updating: false, + updated: true, + newComponentKey + }); + }); + } + + loadResults (replace, by) { + const { component } = this.props; + bulkChangeKey(component.key, replace, by, true).then(r => { + this.setState({ results: r.keys, replace, by }); + }); + } + + renderUpdating () { + return ( +
+ +
+ ); + } + + renderUpdated () { + return ( +
+
+ {translate('update_key.key_updated')} + {' '} + + {translate('check_project')} + +
+
+ ); + } + + render () { + const { component } = this.props; + const { updating, updated } = this.state; + const { results, replace, by } = this.state; + + if (updating) { + return this.renderUpdating(); + } + + if (updated) { + return this.renderUpdated(); + } + + return ( +
+
+
+ {translate('update_key.bulk_change_description')} +
+
+ {translateWithParameters( + 'update_key.current_key_for_project_x_is_x', + component.name, + component.key + )} +
+
+ + + + {results != null && ( + + )} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js new file mode 100644 index 00000000000..db31d98063d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import { translate } from '../../../helpers/l10n'; + +export default class BulkUpdateForm extends React.Component { + static propTypes = { + onSubmit: React.PropTypes.func.isRequired + }; + + handleSubmit (e) { + e.preventDefault(); + this.refs.submit.blur(); + + const replace = this.refs.replace.value; + const by = this.refs.by.value; + + this.props.onSubmit(replace, by); + } + + render () { + return ( +
+
+ + +
+ +
+ + + +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js new file mode 100644 index 00000000000..56f5531875b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js @@ -0,0 +1,111 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import some from 'lodash/some'; +import { translateWithParameters, translate } from '../../../helpers/l10n'; + +export default class BulkUpdateResults extends React.Component { + static propTypes = { + results: React.PropTypes.array.isRequired, + onConfirm: React.PropTypes.func.isRequired + }; + + handleConfirm (e) { + e.preventDefault(); + e.target.blur(); + this.props.onConfirm(); + } + + render () { + const { results, replace, by } = this.props; + const isEmpty = results.length === 0; + const hasDuplications = some(results, r => r.duplicate); + const canUpdate = !isEmpty && !hasDuplications; + + return ( +
+ {isEmpty && ( +
+ {translateWithParameters( + 'update_key.no_key_to_update', + replace + )} +
+ )} + + {hasDuplications && ( +
+ {translateWithParameters( + 'update_key.cant_update_because_duplicate_keys', + replace, + by + )} +
+ )} + + {canUpdate && ( +
+ {translate('update_key.keys_will_be_updated_as_follows')} +
+ )} + + {!isEmpty && ( + + + + + + + + + {results.map(result => ( + + + + + ))} + +
{translate('update_key.old_key')}{translate('update_key.new_key')}
+ {result.key} + + {result.duplicate && ( + + {translate('update_key.duplicate_key')} + + )} + {result.newKey} +
+ )} + +
+ {canUpdate && ( + + )} +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js b/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js new file mode 100644 index 00000000000..6f7deacf0ed --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import UpdateKeyForm from './UpdateKeyForm'; +import QualifierIcon from '../../../components/shared/qualifier-icon'; +import { translate } from '../../../helpers/l10n'; + +export default class FineGrainedUpdate extends React.Component { + render () { + const { component, modules } = this.props; + const components = [component, ...modules]; + + return ( +
+ + + {components.map(component => ( + + + + + ))} + +
+ + {' '} + {component.name} + + +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Header.js b/server/sonar-web/src/main/js/apps/project-admin/key/Header.js new file mode 100644 index 00000000000..c730528a8a2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/Header.js @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import { translate } from '../../../helpers/l10n'; + +export default class Header extends React.Component { + render () { + return ( +
+

+ {translate('update_key.page')} +

+
+ {translate('update_key.page.description')} +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js new file mode 100644 index 00000000000..47b61bc3e6e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js @@ -0,0 +1,134 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import shallowCompare from 'react-addons-shallow-compare'; +import { connect } from 'react-redux'; +import Header from './Header'; +import UpdateForm from './UpdateForm'; +import BulkUpdate from './BulkUpdate'; +import FineGrainedUpdate from './FineGrainedUpdate'; +import { getProjectModules } from '../store/rootReducer'; +import { fetchProjectModules, changeKey } from '../store/actions'; +import { translate } from '../../../helpers/l10n'; + +class Key extends React.Component { + static propTypes = { + component: React.PropTypes.object.isRequired, + fetchProjectModules: React.PropTypes.func.isRequired, + changeKey: React.PropTypes.func.isRequired + }; + + state = { + tab: 'bulk' + }; + + componentDidMount () { + this.props.fetchProjectModules(this.props.component.key); + } + + shouldComponentUpdate (nextProps, nextState) { + return shallowCompare(this, nextProps, nextState); + } + + handleChangeKey (key, newKey) { + return this.props.changeKey(key, newKey).then(() => { + if (key === this.props.component.key) { + window.location = window.baseUrl + + '/project/key?id=' + encodeURIComponent(newKey); + } + }); + } + + handleChangeTab (tab, e) { + e.preventDefault(); + e.target.blur(); + this.setState({ tab }); + } + + render () { + const { component, modules } = this.props; + + const noModules = modules != null && modules.length === 0; + const hasModules = modules != null && modules.length > 0; + + const { tab } = this.state; + + return ( +
+
+ + {modules == null && ( + + )} + + {noModules && ( + + )} + + {hasModules && ( +
+ + + {tab === 'bulk' && ( + + )} + + {tab === 'fine' && ( + + )} +
+ )} +
+ ); + } +} + +const mapStateToProps = (state, ownProps) => ({ + modules: getProjectModules(state, ownProps.component.key) +}); + +export default connect( + mapStateToProps, + { fetchProjectModules, changeKey } +)(Key); diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js new file mode 100644 index 00000000000..701d2070957 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js @@ -0,0 +1,76 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import UpdateKeyConfirmation from './views/UpdateKeyConfirmation'; +import { translate } from '../../../helpers/l10n'; + +export default class UpdateForm extends React.Component { + static propTypes = { + component: React.PropTypes.object.isRequired, + onKeyChange: React.PropTypes.func.isRequired + }; + + state = { newKey: null }; + + handleSubmit (e) { + e.preventDefault(); + + const newKey = this.refs.newKey.value; + + new UpdateKeyConfirmation({ + newKey, + component: this.props.component, + onChange: this.props.onKeyChange + }).render(); + } + + handleChange (e) { + const newKey = e.target.value; + this.setState({ newKey }); + } + + render () { + const value = this.state.newKey != null ? + this.state.newKey : + this.props.component.key; + + const hasChanged = value !== this.props.component.key; + + return ( +
+ + +
+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js new file mode 100644 index 00000000000..f23d1f7069e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js @@ -0,0 +1,92 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 React from 'react'; +import UpdateKeyConfirmation from './views/UpdateKeyConfirmation'; +import { translate } from '../../../helpers/l10n'; + +export default class UpdateKeyForm extends React.Component { + static propTypes = { + component: React.PropTypes.object.isRequired + }; + + state = {}; + + componentWillMount () { + this.handleInputChange = this.handleInputChange.bind(this); + this.handleUpdateClick = this.handleUpdateClick.bind(this); + this.handleResetClick = this.handleResetClick.bind(this); + } + + handleInputChange (e) { + const key = e.target.value; + this.setState({ key }); + } + + handleUpdateClick (e) { + e.preventDefault(); + e.target.blur(); + + const newKey = this.refs.newKey.value; + + new UpdateKeyConfirmation({ + newKey, + component: this.props.component, + onChange: this.props.onKeyChange + }).render(); + } + + handleResetClick (e) { + e.preventDefault(); + e.target.blur(); + this.setState({ key: null }); + } + + render () { + const { component } = this.props; + + const value = this.state.key != null ? + this.state.key : + component.key; + + const hasChanged = this.state.key != null && + this.state.key !== component.key; + + return ( +
+ + +
+ + + +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs new file mode 100644 index 00000000000..bec83b7693e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs @@ -0,0 +1,30 @@ +
+ + + +
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js new file mode 100644 index 00000000000..9b1c4abd26e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js @@ -0,0 +1,48 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 ModalForm from '../../../../components/common/modal-form'; +import Template from './UpdateKeyConfirmation.hbs'; +import { parseError } from '../../../code/utils'; + +export default ModalForm.extend({ + template: Template, + + onFormSubmit () { + ModalForm.prototype.onFormSubmit.apply(this, arguments); + this.disableForm(); + this.showSpinner(); + + this.options.onChange(this.options.component.key, this.options.newKey) + .then(() => this.destroy()) + .catch(e => { + parseError(e).then(msg => this.showSingleError(msg)); + this.hideSpinner(); + this.enableForm(); + }); + }, + + serializeData () { + return { + component: this.options.component, + newKey: this.options.newKey + }; + } +}); + -- cgit v1.2.3