aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-11-16 16:41:05 +0100
committersonartech <sonartech@sonarsource.com>2019-01-16 09:43:00 +0100
commita0acec09a79485117ab9c8e3c67a8446224d5de9 (patch)
tree8af9218cdbf66fbd11058ea99595eb14ce2e9c30 /server/sonar-web/src/main
parent9e553274fbe228c06b92527ace1446d08ee244c3 (diff)
downloadsonarqube-a0acec09a79485117ab9c8e3c67a8446224d5de9.tar.gz
sonarqube-a0acec09a79485117ab9c8e3c67a8446224d5de9.zip
SONAR-11477 Drop UI for updating module keys (#958)
Diffstat (limited to 'server/sonar-web/src/main')
-rw-r--r--server/sonar-web/src/main/js/api/components.ts23
-rw-r--r--server/sonar-web/src/main/js/app/utils/startReactApp.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js148
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js71
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js94
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js46
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/Key.js156
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx65
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx75
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/utils.js24
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/store/actions.js51
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/store/components.js45
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js49
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js40
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/Key.tsx55
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx (renamed from server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx)33
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/__tests__/Key-test.tsx42
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/__tests__/UpdateForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/project-admin/key/Header.js)27
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/Key-test.tsx.snap37
-rw-r--r--server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/UpdateForm-test.tsx.snap112
-rw-r--r--server/sonar-web/src/main/js/components/SelectList/SelectListListContainer.tsx2
-rw-r--r--server/sonar-web/src/main/js/store/rootReducer.ts7
22 files changed, 295 insertions, 909 deletions
diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts
index efbeedbaa52..60317a41e39 100644
--- a/server/sonar-web/src/main/js/api/components.ts
+++ b/server/sonar-web/src/main/js/api/components.ts
@@ -222,27 +222,8 @@ export function searchComponents(data?: {
return getJSON('/api/components/search', data);
}
-/**
- * Change component's key
- */
-export function changeKey(from: string, to: string): Promise<void> {
- const url = '/api/projects/update_key';
- const data = { from, to };
- return post(url, data);
-}
-
-/**
- * Bulk change component's key
- */
-export function bulkChangeKey(
- project: string,
- from: string,
- to: string,
- dryRun: boolean = false
-): Promise<any> {
- const url = '/api/projects/bulk_update_key';
- const data = { project, from, to, dryRun };
- return postJSON(url, data);
+export function changeKey(data: { from: string; to: string }) {
+ return post('/api/projects/update_key', data).catch(throwGlobalError);
}
export interface SuggestionsResponse {
diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
index 781120376f3..dca733a3587 100644
--- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
+++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
@@ -268,7 +268,7 @@ export default function startReactApp(
/>
<Route
path="project/key"
- component={lazyLoad(() => import('../../apps/project-admin/key/Key'))}
+ component={lazyLoad(() => import('../../apps/projectKey/Key'))}
/>
</Route>
</Route>
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
deleted file mode 100644
index 59ceb9da3b1..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 React from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import BulkUpdateForm from './BulkUpdateForm';
-import BulkUpdateResults from './BulkUpdateResults';
-import { reloadUpdateKeyPage } from './utils';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { bulkChangeKey } from '../../../api/components';
-import { parseError } from '../../../helpers/request';
-import {
- addGlobalErrorMessage,
- addGlobalSuccessMessage,
- closeAllGlobalMessages
-} from '../../../store/globalMessages';
-import RecentHistory from '../../../app/components/RecentHistory';
-
-class BulkUpdate extends React.PureComponent {
- static propTypes = {
- component: PropTypes.object.isRequired,
- addGlobalErrorMessage: PropTypes.func.isRequired,
- addGlobalSuccessMessage: PropTypes.func.isRequired,
- closeAllGlobalMessages: PropTypes.func.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;
-
- if (newComponentKey !== component.key) {
- RecentHistory.remove(component.key);
- }
-
- this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload'));
- this.setState({ updating: false });
- reloadUpdateKeyPage(newComponentKey);
- })
- .catch(e => {
- this.setState({ updating: false });
- parseError(e).then(message => this.props.addGlobalErrorMessage(message));
- });
- }
-
- loadResults(replace, by) {
- const { component } = this.props;
- bulkChangeKey(component.key, replace, by, true)
- .then(r => {
- this.setState({ results: r.keys, replace, by });
- this.props.closeAllGlobalMessages();
- })
- .catch(e => {
- this.setState({ results: null });
- parseError(e).then(message => this.props.addGlobalErrorMessage(message));
- });
- }
-
- renderUpdating() {
- return (
- <div id="project-key-bulk-update">
- <i className="spinner" />
- </div>
- );
- }
-
- 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 (
- <div id="project-key-bulk-update">
- <header className="big-spacer-bottom">
- <div className="spacer-bottom">{translate('update_key.bulk_change_description')}</div>
- <div>
- {translateWithParameters(
- 'update_key.current_key_for_project_x_is_x',
- component.name,
- component.key
- )}
- </div>
- </header>
-
- <BulkUpdateForm onSubmit={this.handleSubmit.bind(this)} />
-
- {results != null && (
- <BulkUpdateResults
- by={by}
- onConfirm={this.handleConfirm.bind(this)}
- replace={replace}
- results={results}
- />
- )}
- </div>
- );
- }
-}
-
-export default connect(
- null,
- {
- addGlobalErrorMessage,
- addGlobalSuccessMessage,
- closeAllGlobalMessages
- }
-)(BulkUpdate);
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
deleted file mode 100644
index 07814359462..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 React from 'react';
-import PropTypes from 'prop-types';
-import { translate } from '../../../helpers/l10n';
-import { SubmitButton } from '../../../components/ui/buttons';
-
-export default class BulkUpdateForm extends React.PureComponent {
- static propTypes = {
- onSubmit: PropTypes.func.isRequired
- };
-
- handleSubmit = e => {
- e.preventDefault();
-
- const replace = this.refs.replace.value;
- const by = this.refs.by.value;
-
- this.props.onSubmit(replace, by);
- };
-
- render() {
- return (
- <form onSubmit={this.handleSubmit}>
- <div className="modal-field">
- <label htmlFor="bulk-update-replace">{translate('update_key.replace')}</label>
- <input
- id="bulk-update-replace"
- name="replace"
- placeholder={translate('update_key.replace_example')}
- ref="replace"
- required={true}
- type="text"
- />
- </div>
-
- <div className="modal-field">
- <label htmlFor="bulk-update-by">{translate('update_key.by')}</label>
- <input
- id="bulk-update-by"
- name="by"
- placeholder={translate('update_key.by_example')}
- ref="by"
- required={true}
- type="text"
- />
- <SubmitButton className="big-spacer-left" id="bulk-update-see-results">
- {translate('update_key.see_results')}
- </SubmitButton>
- </div>
- </form>
- );
- }
-}
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
deleted file mode 100644
index a51599ae9d6..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 React from 'react';
-import PropTypes from 'prop-types';
-import { some } from 'lodash';
-import { translateWithParameters, translate } from '../../../helpers/l10n';
-import { Button } from '../../../components/ui/buttons';
-
-export default class BulkUpdateResults extends React.PureComponent {
- static propTypes = {
- results: PropTypes.array.isRequired,
- onConfirm: PropTypes.func.isRequired
- };
-
- render() {
- const { results, replace, by } = this.props;
- const isEmpty = results.length === 0;
- const hasDuplications = some(results, r => r.duplicate);
- const canUpdate = !isEmpty && !hasDuplications;
-
- return (
- <div className="big-spacer-top" id="bulk-update-simulation">
- {isEmpty && (
- <div className="spacer-bottom" id="bulk-update-nothing">
- {translateWithParameters('update_key.no_key_to_update', replace)}
- </div>
- )}
-
- {hasDuplications && (
- <div className="spacer-bottom" id="bulk-update-duplicate">
- {translateWithParameters('update_key.cant_update_because_duplicate_keys', replace, by)}
- </div>
- )}
-
- {canUpdate && (
- <div className="spacer-bottom">
- {translate('update_key.keys_will_be_updated_as_follows')}
- </div>
- )}
-
- {!isEmpty && (
- <table className="data zebra zebra-hover" id="bulk-update-results">
- <thead>
- <tr>
- <th>{translate('update_key.old_key')}</th>
- <th>{translate('update_key.new_key')}</th>
- </tr>
- </thead>
- <tbody>
- {results.map(result => (
- <tr data-key={result.key} key={result.key}>
- <td className="js-old-key">{result.key}</td>
- <td className="js-new-key">
- {result.duplicate && (
- <span className="spacer-right badge badge-danger">
- {translate('update_key.duplicate_key')}
- </span>
- )}
- {result.newKey}
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- )}
-
- <div className="big-spacer-top">
- {canUpdate && (
- <Button id="bulk-update-confirm" onClick={this.props.onConfirm}>
- {translate('update_verb')}
- </Button>
- )}
- </div>
- </div>
- );
- }
-}
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
deleted file mode 100644
index 43e17ebfded..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 React from 'react';
-import UpdateKeyForm from './UpdateKeyForm';
-import QualifierIcon from '../../../components/icons-components/QualifierIcon';
-
-export default function FineGrainedUpdate(props) {
- const { component, modules } = props;
- const components = [component, ...modules];
-
- return (
- <div id="project-key-fine-grained-update">
- <table className="data zebra">
- <tbody>
- {components.map(component => (
- <tr key={component.key}>
- <td className="width-40">
- <QualifierIcon qualifier={component.qualifier} /> {component.name}
- </td>
- <td>
- <UpdateKeyForm component={component} onKeyChange={props.onKeyChange} />
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- );
-}
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
deleted file mode 100644
index ee2791f3ded..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 React from 'react';
-import PropTypes from 'prop-types';
-import Helmet from 'react-helmet';
-import { connect } from 'react-redux';
-import Header from './Header';
-import UpdateForm from './UpdateForm';
-import BulkUpdate from './BulkUpdate';
-import FineGrainedUpdate from './FineGrainedUpdate';
-import { reloadUpdateKeyPage } from './utils';
-import { changeKey, fetchProjectModules } from '../store/actions';
-import { translate } from '../../../helpers/l10n';
-import {
- addGlobalErrorMessage,
- addGlobalSuccessMessage,
- closeAllGlobalMessages
-} from '../../../store/globalMessages';
-import RecentHistory from '../../../app/components/RecentHistory';
-import { getProjectAdminProjectModules } from '../../../store/rootReducer';
-
-class Key extends React.PureComponent {
- static propTypes = {
- component: PropTypes.object,
- fetchProjectModules: PropTypes.func.isRequired,
- changeKey: PropTypes.func.isRequired,
- addGlobalErrorMessage: PropTypes.func.isRequired,
- addGlobalSuccessMessage: PropTypes.func.isRequired,
- closeAllGlobalMessages: PropTypes.func.isRequired
- };
-
- state = {
- tab: 'bulk'
- };
-
- componentDidMount() {
- this.props.fetchProjectModules(this.props.component.key);
- }
-
- handleChangeKey = (key, newKey) => {
- return this.props.changeKey(key, newKey).then(() => {
- if (key === this.props.component.key) {
- this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload'));
- RecentHistory.remove(key);
- reloadUpdateKeyPage(newKey);
- } else {
- this.props.addGlobalSuccessMessage(translate('update_key.key_updated'));
- }
- });
- };
-
- handleChangeTab = event => {
- event.preventDefault();
- event.currentTarget.blur();
- const { tab } = event.currentTarget.dataset;
- this.setState({ tab });
- this.props.closeAllGlobalMessages();
- };
-
- 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 (
- <div className="page page-limited" id="project-key">
- <Helmet title={translate('update_key.page')} />
- <Header />
-
- {modules == null && <i className="spinner" />}
-
- {noModules && (
- <div>
- <UpdateForm component={component} onKeyChange={this.handleChangeKey} />
- </div>
- )}
-
- {hasModules && (
- <div className="boxed-group boxed-group-inner">
- <div className="big-spacer-bottom">
- <ul className="tabs">
- <li>
- <a
- className={tab === 'bulk' ? 'selected' : ''}
- data-tab="bulk"
- href="#"
- id="update-key-tab-bulk"
- onClick={this.handleChangeTab}>
- {translate('update_key.bulk_update')}
- </a>
- </li>
- <li>
- <a
- className={tab === 'fine' ? 'selected' : ''}
- data-tab="fine"
- href="#"
- id="update-key-tab-fine"
- onClick={this.handleChangeTab}>
- {translate('update_key.fine_grained_key_update')}
- </a>
- </li>
- </ul>
- </div>
-
- {tab === 'bulk' && <BulkUpdate component={component} />}
-
- {tab === 'fine' && (
- <FineGrainedUpdate
- component={component}
- modules={modules}
- onError={this.props.addGlobalErrorMessage}
- onKeyChange={this.handleChangeKey}
- onSuccess={this.props.closeAllGlobalMessages}
- />
- )}
- </div>
- )}
- </div>
- );
- }
-}
-
-const mapStateToProps = (state, ownProps) => ({
- modules: getProjectAdminProjectModules(state, ownProps.location.query.id)
-});
-
-export default connect(
- mapStateToProps,
- {
- fetchProjectModules,
- changeKey,
- addGlobalErrorMessage,
- addGlobalSuccessMessage,
- closeAllGlobalMessages
- }
-)(Key);
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx
deleted file mode 100644
index 8796aac4386..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 ConfirmButton, { ChildrenProps } from '../../../components/controls/ConfirmButton';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-
-interface Props {
- children: (props: ChildrenProps) => React.ReactNode;
- component: { key: string; name: string };
- newKey: string | undefined;
- onConfirm: (oldKey: string, newKey: string) => Promise<void>;
-}
-
-export default class UpdateKeyConfirm extends React.PureComponent<Props> {
- handleConfirm = () => {
- return this.props.newKey
- ? this.props.onConfirm(this.props.component.key, this.props.newKey)
- : Promise.reject(undefined);
- };
-
- render() {
- const { children, component, newKey } = this.props;
-
- return (
- <ConfirmButton
- confirmButtonText={translate('update_verb')}
- modalBody={
- <>
- {translateWithParameters('update_key.are_you_sure_to_change_key', component.name)}
- <div className="spacer-top">
- {translate('update_key.old_key')}
- {': '}
- <strong>{component.key}</strong>
- </div>
- <div className="spacer-top">
- {translate('update_key.new_key')}
- {': '}
- <strong>{newKey}</strong>
- </div>
- </>
- }
- modalHeader={translate('update_key.page')}
- onConfirm={this.handleConfirm}>
- {children}
- </ConfirmButton>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx
deleted file mode 100644
index 6d8a023ec03..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 UpdateKeyConfirm from './UpdateKeyConfirm';
-import { Button } from '../../../components/ui/buttons';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
- component: { key: string; name: string };
- onKeyChange: (oldKey: string, newKey: string) => Promise<void>;
-}
-
-interface State {
- newKey?: string;
-}
-
-export default class UpdateKeyForm extends React.PureComponent<Props, State> {
- state: State = {};
-
- handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- const newKey = event.currentTarget.value;
- this.setState({ newKey });
- };
-
- handleResetClick = () => {
- this.setState({ newKey: undefined });
- };
-
- render() {
- const { component } = this.props;
- const { newKey } = this.state;
- const value = newKey !== undefined ? newKey : component.key;
- const hasChanged = newKey !== undefined && newKey !== component.key;
-
- return (
- <div className="js-fine-grained-update" data-key={component.key}>
- <input
- className="input-super-large big-spacer-right"
- onChange={this.handleInputChange}
- type="text"
- value={value}
- />
-
- <UpdateKeyConfirm component={component} newKey={newKey} onConfirm={this.props.onKeyChange}>
- {({ onClick }) => (
- <Button disabled={!hasChanged} onClick={onClick}>
- {translate('update_verb')}
- </Button>
- )}
- </UpdateKeyConfirm>
-
- <Button className="spacer-left" disabled={!hasChanged} onClick={this.handleResetClick}>
- {translate('reset_verb')}
- </Button>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/utils.js b/server/sonar-web/src/main/js/apps/project-admin/key/utils.js
deleted file mode 100644
index 0a30626afa5..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/utils.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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.
- */
-export const reloadUpdateKeyPage = componentKey => {
- setTimeout(() => {
- window.location = window.baseUrl + '/project/key?id=' + encodeURIComponent(componentKey);
- }, 3000);
-};
diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js b/server/sonar-web/src/main/js/apps/project-admin/store/actions.js
deleted file mode 100644
index cdb042caee9..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { getTree, changeKey as changeKeyApi } from '../../../api/components';
-import throwGlobalError from '../../../app/utils/throwGlobalError';
-
-export const RECEIVE_PROJECT_MODULES = 'projectAdmin/RECEIVE_PROJECT_MODULES';
-const receiveProjectModules = (projectKey, modules) => ({
- type: RECEIVE_PROJECT_MODULES,
- projectKey,
- modules
-});
-
-export const fetchProjectModules = projectKey => dispatch => {
- getTree({ component: projectKey, qualifiers: 'BRC', s: 'name', ps: 500 }).then(
- r => {
- dispatch(receiveProjectModules(projectKey, r.components));
- },
- () => {}
- );
-};
-
-export const CHANGE_KEY = 'projectAdmin/CHANGE_KEY';
-const changeKeyAction = (key, newKey) => ({
- type: CHANGE_KEY,
- key,
- newKey
-});
-
-export const changeKey = (key, newKey) => dispatch => {
- return changeKeyApi(key, newKey).then(
- () => dispatch(changeKeyAction(key, newKey)),
- throwGlobalError
- );
-};
diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/components.js b/server/sonar-web/src/main/js/apps/project-admin/store/components.js
deleted file mode 100644
index d8e238365db..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/store/components.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { keyBy, omit } from 'lodash';
-import { RECEIVE_PROJECT_MODULES, CHANGE_KEY } from './actions';
-
-const components = (state = {}, action = {}) => {
- if (action.type === RECEIVE_PROJECT_MODULES) {
- const newComponentsByKey = keyBy(action.modules, 'key');
- return { ...state, ...newComponentsByKey };
- }
-
- if (action.type === CHANGE_KEY) {
- const oldComponent = state[action.key];
- if (oldComponent != null) {
- const newComponent = { ...oldComponent, key: action.newKey };
- return {
- ...omit(state, action.key),
- [action.newKey]: newComponent
- };
- }
- }
-
- return state;
-};
-
-export default components;
-
-export const getComponentByKey = (state, key) => state[key];
diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js
deleted file mode 100644
index 9b5014be2d1..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { RECEIVE_PROJECT_MODULES, CHANGE_KEY } from './actions';
-
-const modulesByProject = (state = {}, action = {}) => {
- if (action.type === RECEIVE_PROJECT_MODULES) {
- const moduleKeys = action.modules.map(module => module.key);
- return { ...state, [action.projectKey]: moduleKeys };
- }
-
- if (action.type === CHANGE_KEY) {
- const newState = {};
- Object.keys(state).forEach(projectKey => {
- const moduleKeys = state[projectKey];
- const changedKeyIndex = moduleKeys.indexOf(action.key);
- if (changedKeyIndex !== -1) {
- const newModuleKeys = [...moduleKeys];
- newModuleKeys.splice(changedKeyIndex, 1, action.newKey);
- newState[projectKey] = newModuleKeys;
- } else {
- newState[projectKey] = moduleKeys;
- }
- });
- return newState;
- }
-
- return state;
-};
-
-export default modulesByProject;
-
-export const getProjectModules = (state, projectKey) => state[projectKey];
diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js b/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js
deleted file mode 100644
index 6bff2faed22..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { combineReducers } from 'redux';
-import components, { getComponentByKey as nextGetComponentByKey } from './components';
-import modulesByProject, { getProjectModules as nextGetProjectModules } from './modulesByProject';
-
-const rootReducer = combineReducers({
- components,
- modulesByProject
-});
-
-export default rootReducer;
-
-export const getComponentByKey = (state, componentKey) =>
- nextGetComponentByKey(state.components, componentKey);
-
-export const getProjectModules = (state, projectKey) => {
- const moduleKeys = nextGetProjectModules(state.modulesByProject, projectKey);
- if (moduleKeys == null) {
- return null;
- }
- return moduleKeys.map(moduleKey => getComponentByKey(state, moduleKey));
-};
diff --git a/server/sonar-web/src/main/js/apps/projectKey/Key.tsx b/server/sonar-web/src/main/js/apps/projectKey/Key.tsx
new file mode 100644
index 00000000000..38454a5bc00
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectKey/Key.tsx
@@ -0,0 +1,55 @@
+/*
+ * 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 Helmet from 'react-helmet';
+import { withRouter, WithRouterProps } from 'react-router';
+import UpdateForm from './UpdateForm';
+import { changeKey } from '../../api/components';
+import RecentHistory from '../../app/components/RecentHistory';
+import { translate } from '../../helpers/l10n';
+
+interface Props {
+ component: Pick<T.Component, 'key' | 'name'>;
+}
+
+export class Key extends React.PureComponent<Props & WithRouterProps> {
+ handleChangeKey = (newKey: string) => {
+ return changeKey({ from: this.props.component.key, to: newKey }).then(() => {
+ RecentHistory.remove(this.props.component.key);
+ this.props.router.replace({ pathname: '/project/key', query: { id: newKey } });
+ });
+ };
+
+ render() {
+ const { component } = this.props;
+ return (
+ <div className="page page-limited" id="project-key">
+ <Helmet title={translate('update_key.page')} />
+ <header className="page-header">
+ <h1 className="page-title">{translate('update_key.page')}</h1>
+ <div className="page-description">{translate('update_key.page.description')}</div>
+ </header>
+ <UpdateForm component={component} onKeyChange={this.handleChangeKey} />
+ </div>
+ );
+ }
+}
+
+export default withRouter(Key);
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx
index 1ece13fef36..39dbe961d25 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx
+++ b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx
@@ -18,13 +18,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import UpdateKeyConfirm from './UpdateKeyConfirm';
-import { Button, SubmitButton } from '../../../components/ui/buttons';
-import { translate } from '../../../helpers/l10n';
+import { Button, SubmitButton } from '../../components/ui/buttons';
+import { translate, translateWithParameters } from '../../helpers/l10n';
+import ConfirmButton from '../../components/controls/ConfirmButton';
interface Props {
- component: { key: string; name: string };
- onKeyChange: (oldKey: string, newKey: string) => Promise<void>;
+ component: Pick<T.Component, 'key' | 'name'>;
+ onKeyChange: (newKey: string) => Promise<void>;
}
interface State {
@@ -50,7 +50,26 @@ export default class UpdateForm extends React.PureComponent<Props, State> {
const hasChanged = value !== component.key;
return (
- <UpdateKeyConfirm component={component} newKey={newKey} onConfirm={this.props.onKeyChange}>
+ <ConfirmButton
+ confirmButtonText={translate('update_verb')}
+ confirmData={newKey}
+ modalBody={
+ <>
+ {translateWithParameters('update_key.are_you_sure_to_change_key', component.name)}
+ <div className="spacer-top">
+ {translate('update_key.old_key')}
+ {': '}
+ <strong>{component.key}</strong>
+ </div>
+ <div className="spacer-top">
+ {translate('update_key.new_key')}
+ {': '}
+ <strong>{newKey}</strong>
+ </div>
+ </>
+ }
+ modalHeader={translate('update_key.page')}
+ onConfirm={this.props.onKeyChange}>
{({ onFormSubmit }) => (
<form onSubmit={onFormSubmit}>
<input
@@ -79,7 +98,7 @@ export default class UpdateForm extends React.PureComponent<Props, State> {
</div>
</form>
)}
- </UpdateKeyConfirm>
+ </ConfirmButton>
);
}
}
diff --git a/server/sonar-web/src/main/js/apps/projectKey/__tests__/Key-test.tsx b/server/sonar-web/src/main/js/apps/projectKey/__tests__/Key-test.tsx
new file mode 100644
index 00000000000..57c8aa569b4
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectKey/__tests__/Key-test.tsx
@@ -0,0 +1,42 @@
+/*
+ * 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 { shallow } from 'enzyme';
+import { WithRouterProps } from 'react-router';
+import { Key } from '../Key';
+import { changeKey } from '../../../api/components';
+
+jest.mock('../../../api/components', () => ({
+ changeKey: jest.fn().mockResolvedValue(undefined)
+}));
+
+it('should render and change key', async () => {
+ const withRouterProps = { router: { replace: jest.fn() } as any } as WithRouterProps;
+ const wrapper = shallow(<Key component={{ key: 'foo', name: 'Foo' }} {...withRouterProps} />);
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.find('UpdateForm').prop<Function>('onKeyChange')('bar');
+ await new Promise(setImmediate);
+ expect(changeKey).toBeCalledWith({ from: 'foo', to: 'bar' });
+ expect(withRouterProps.router.replace).toBeCalledWith({
+ pathname: '/project/key',
+ query: { id: 'bar' }
+ });
+});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Header.js b/server/sonar-web/src/main/js/apps/projectKey/__tests__/UpdateForm-test.tsx
index 6c14beda91b..457575b7abf 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/key/Header.js
+++ b/server/sonar-web/src/main/js/apps/projectKey/__tests__/UpdateForm-test.tsx
@@ -17,14 +17,25 @@
* 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';
+import * as React from 'react';
+import { shallow, ShallowWrapper } from 'enzyme';
+import UpdateForm from '../UpdateForm';
+import { change, click } from '../../../helpers/testUtils';
-export default function Header() {
- return (
- <header className="page-header">
- <h1 className="page-title">{translate('update_key.page')}</h1>
- <div className="page-description">{translate('update_key.page.description')}</div>
- </header>
+it('should render', () => {
+ const wrapper = shallow(
+ <UpdateForm component={{ key: 'foo', name: 'Foo' }} onKeyChange={jest.fn()} />
);
+ expect(getInner(wrapper)).toMatchSnapshot();
+
+ change(getInner(wrapper).find('input'), 'bar');
+ expect(getInner(wrapper)).toMatchSnapshot();
+
+ click(getInner(wrapper).find('Button'));
+ expect(getInner(wrapper)).toMatchSnapshot();
+});
+
+function getInner(wrapper: ShallowWrapper) {
+ // TODO find a better way to do this
+ return wrapper.dive().dive();
}
diff --git a/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/Key-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/Key-test.tsx.snap
new file mode 100644
index 00000000000..da5365e6d5c
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/Key-test.tsx.snap
@@ -0,0 +1,37 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render and change key 1`] = `
+<div
+ className="page page-limited"
+ id="project-key"
+>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="update_key.page"
+ />
+ <header
+ className="page-header"
+ >
+ <h1
+ className="page-title"
+ >
+ update_key.page
+ </h1>
+ <div
+ className="page-description"
+ >
+ update_key.page.description
+ </div>
+ </header>
+ <UpdateForm
+ component={
+ Object {
+ "key": "foo",
+ "name": "Foo",
+ }
+ }
+ onKeyChange={[Function]}
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/UpdateForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/UpdateForm-test.tsx.snap
new file mode 100644
index 00000000000..0a009777e05
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectKey/__tests__/__snapshots__/UpdateForm-test.tsx.snap
@@ -0,0 +1,112 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render 1`] = `
+<Fragment>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ className="input-super-large"
+ id="update-key-new-key"
+ onChange={[Function]}
+ placeholder="update_key.new_key"
+ required={true}
+ type="text"
+ value="foo"
+ />
+ <div
+ className="spacer-top"
+ >
+ <SubmitButton
+ disabled={true}
+ id="update-key-submit"
+ >
+ update_verb
+ </SubmitButton>
+ <Button
+ className="spacer-left"
+ disabled={true}
+ id="update-key-reset"
+ onClick={[Function]}
+ type="reset"
+ >
+ reset_verb
+ </Button>
+ </div>
+ </form>
+</Fragment>
+`;
+
+exports[`should render 2`] = `
+<Fragment>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ className="input-super-large"
+ id="update-key-new-key"
+ onChange={[Function]}
+ placeholder="update_key.new_key"
+ required={true}
+ type="text"
+ value="bar"
+ />
+ <div
+ className="spacer-top"
+ >
+ <SubmitButton
+ disabled={false}
+ id="update-key-submit"
+ >
+ update_verb
+ </SubmitButton>
+ <Button
+ className="spacer-left"
+ disabled={false}
+ id="update-key-reset"
+ onClick={[Function]}
+ type="reset"
+ >
+ reset_verb
+ </Button>
+ </div>
+ </form>
+</Fragment>
+`;
+
+exports[`should render 3`] = `
+<Fragment>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ className="input-super-large"
+ id="update-key-new-key"
+ onChange={[Function]}
+ placeholder="update_key.new_key"
+ required={true}
+ type="text"
+ value="foo"
+ />
+ <div
+ className="spacer-top"
+ >
+ <SubmitButton
+ disabled={true}
+ id="update-key-submit"
+ >
+ update_verb
+ </SubmitButton>
+ <Button
+ className="spacer-left"
+ disabled={true}
+ id="update-key-reset"
+ onClick={[Function]}
+ type="reset"
+ >
+ reset_verb
+ </Button>
+ </div>
+ </form>
+</Fragment>
+`;
diff --git a/server/sonar-web/src/main/js/components/SelectList/SelectListListContainer.tsx b/server/sonar-web/src/main/js/components/SelectList/SelectListListContainer.tsx
index 96d969a33f7..829bee3f284 100644
--- a/server/sonar-web/src/main/js/components/SelectList/SelectListListContainer.tsx
+++ b/server/sonar-web/src/main/js/components/SelectList/SelectListListContainer.tsx
@@ -91,7 +91,7 @@ export default class SelectListListContainer extends React.PureComponent<Props,
onCheck={this.handleBulkChange}
thirdState={selectedElements.length > 0 && elements.length !== selectedElements.length}>
<span className="big-spacer-left">
- {translate('update_key.bulk_update')}
+ {translate('bulk_change')}
<DeferredSpinner className="spacer-left" loading={this.state.loading} timeout={10} />
</span>
</Checkbox>
diff --git a/server/sonar-web/src/main/js/store/rootReducer.ts b/server/sonar-web/src/main/js/store/rootReducer.ts
index fa3890586fc..e4286c79a99 100644
--- a/server/sonar-web/src/main/js/store/rootReducer.ts
+++ b/server/sonar-web/src/main/js/store/rootReducer.ts
@@ -24,7 +24,6 @@ import languages, * as fromLanguages from './languages';
import metrics, * as fromMetrics from './metrics';
import organizations, * as fromOrganizations from './organizations';
import users, * as fromUsers from './users';
-import projectAdminApp, * as fromProjectAdminApp from '../apps/project-admin/store/rootReducer';
import settingsApp, * as fromSettingsApp from '../apps/settings/store/rootReducer';
export type Store = {
@@ -36,7 +35,6 @@ export type Store = {
users: fromUsers.State;
// apps
- projectAdminApp: any;
settingsApp: any;
};
@@ -49,7 +47,6 @@ export default combineReducers<Store>({
users,
// apps
- projectAdminApp,
settingsApp
});
@@ -128,7 +125,3 @@ export function isSettingsAppLoading(state: Store, key: string) {
export function getSettingsAppValidationMessage(state: Store, key: string) {
return fromSettingsApp.getValidationMessage(state.settingsApp, key);
}
-
-export function getProjectAdminProjectModules(state: Store, projectKey: string) {
- return fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey);
-}