aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--it/it-tests/src/test/resources/projectAdministration/ProjectAdministrationTest/project-deletion/project-deletion.html32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json1
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json1
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json1
-rw-r--r--server/sonar-web/src/main/js/api/components.js6
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/app.js41
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js47
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModalTemplate.hbs13
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js37
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js47
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js36
-rw-r--r--server/sonar-web/src/main/js/main/nav/app.js6
-rw-r--r--server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js13
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb61
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/project/_delete_form.html.erb34
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/project/deletion.html.erb21
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/project/pending_deletion.html.erb2
-rw-r--r--server/sonar-web/webpack.config.js1
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties6
21 files changed, 257 insertions, 154 deletions
diff --git a/it/it-tests/src/test/resources/projectAdministration/ProjectAdministrationTest/project-deletion/project-deletion.html b/it/it-tests/src/test/resources/projectAdministration/ProjectAdministrationTest/project-deletion/project-deletion.html
index 16a057b896a..c77796182ba 100644
--- a/it/it-tests/src/test/resources/projectAdministration/ProjectAdministrationTest/project-deletion/project-deletion.html
+++ b/it/it-tests/src/test/resources/projectAdministration/ProjectAdministrationTest/project-deletion/project-deletion.html
@@ -55,43 +55,33 @@
</tr>
<tr>
<td>open</td>
- <td>/dashboard/index/sample</td>
+ <td>/project/deletion?id=sample</td>
<td></td>
</tr>
<tr>
- <td>click</td>
- <td>css=#context-navigation .navbar-admin-link</td>
- <td></td>
-</tr>
-<tr>
<td>waitForElementPresent</td>
- <td>link=Deletion</td>
+ <td>css=#delete-project</td>
<td></td>
</tr>
<tr>
- <td>clickAndWait</td>
- <td>link=Deletion</td>
+ <td>click</td>
+ <td>css=#delete-project</td>
<td></td>
</tr>
<tr>
- <td>click</td>
- <td>delete_resource</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForText</td>
- <td>delete-project-form</td>
- <td>*Delete Project*</td>
+ <td>waitForElementPresent</td>
+ <td>css=#delete-project-confirm</td>
+ <td></td>
</tr>
<tr>
<td>click</td>
- <td>delete-project-submit</td>
+ <td>css=#delete-project-confirm</td>
<td></td>
</tr>
<tr>
- <td>pause</td>
- <td>3000</td>
- <td>NOTE: necessary as the deletion is asynchronous</td>
+ <td>waitForElementNotPresent</td>
+ <td>css=#delete-project-confirm</td>
+ <td></td>
</tr>
<tr>
<td>open</td>
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
index f7aca74f29e..4d824d7806e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
@@ -66,7 +66,6 @@ public class ComponentNavigationAction implements NavigationWsAction {
private static final String PROPERTY_HAS_ROLE_POLICY = "hasRolePolicy";
private static final String PROPERTY_MODIFIABLE_HISTORY = "modifiable_history";
private static final String PROPERTY_UPDATABLE_KEY = "updatable_key";
- private static final String PROPERTY_DELETABLE = "deletable";
private final DbClient dbClient;
private final Views views;
@@ -221,7 +220,6 @@ public class ComponentNavigationAction implements NavigationWsAction {
json.prop("showPermissions", isAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY));
json.prop("showHistory", isAdmin && componentTypeHasProperty(component, PROPERTY_MODIFIABLE_HISTORY));
json.prop("showUpdateKey", isAdmin && componentTypeHasProperty(component, PROPERTY_UPDATABLE_KEY));
- json.prop("showDeletion", isAdmin && componentTypeHasProperty(component, PROPERTY_DELETABLE));
json.prop("showBackgroundTasks", ActivityAction.isAllowedOnComponentUuid(userSession, component.uuid()));
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json
index 19646c8fa00..51e9d413003 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json
@@ -15,7 +15,6 @@
"showPermissions": false,
"showHistory": false,
"showUpdateKey": false,
- "showDeletion": false,
"extensions": []
},
"breadcrumbs": [
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json
index 3e6474a4420..594a12562e6 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json
@@ -14,8 +14,7 @@
"showLinks": false,
"showPermissions": false,
"showHistory": false,
- "showUpdateKey": false,
- "showDeletion": false
+ "showUpdateKey": false
},
"breadcrumbs": [
{
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json
index e60ff54767d..c213ac06368 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json
@@ -15,7 +15,6 @@
"showPermissions": false,
"showHistory": false,
"showUpdateKey": false,
- "showDeletion": false,
"extensions": [
{
"name": "First Page",
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json
index 2352e48e484..930df6729ef 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json
@@ -15,7 +15,6 @@
"showPermissions": true,
"showHistory": true,
"showUpdateKey": true,
- "showDeletion": true,
"extensions": []
},
"breadcrumbs": [
diff --git a/server/sonar-web/src/main/js/api/components.js b/server/sonar-web/src/main/js/api/components.js
index 3c7581dba9b..f0f49a636b4 100644
--- a/server/sonar-web/src/main/js/api/components.js
+++ b/server/sonar-web/src/main/js/api/components.js
@@ -39,6 +39,12 @@ export function deleteComponents (data) {
return post(url, data);
}
+export function deleteProject (key) {
+ const url = '/api/projects/delete';
+ const data = { key };
+ return post(url, data);
+}
+
export function createProject (data) {
const url = '/api/projects/create';
return postJSON(url, data);
diff --git a/server/sonar-web/src/main/js/apps/project-admin/app.js b/server/sonar-web/src/main/js/apps/project-admin/app.js
new file mode 100644
index 00000000000..ee3493544d3
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/app.js
@@ -0,0 +1,41 @@
+/*
+ * 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 { render } from 'react-dom';
+import { Router, Route, useRouterHistory } from 'react-router';
+import { createHistory } from 'history';
+import Deletion from './deletion/Deletion';
+
+window.sonarqube.appStarted.then(options => {
+ const el = document.querySelector(options.el);
+
+ const history = useRouterHistory(createHistory)({
+ basename: window.baseUrl + '/project'
+ });
+
+ const withComponent = ComposedComponent => props =>
+ <ComposedComponent {...props} component={options.component}/>;
+
+ render((
+ <Router history={history}>
+ <Route path="/deletion" component={withComponent(Deletion)}/>
+ </Router>
+ ), el);
+});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js
new file mode 100644
index 00000000000..e5e6f712c02
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js
@@ -0,0 +1,47 @@
+/*
+ * 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 './ConfirmationModalTemplate.hbs';
+import { deleteProject } from '../../../api/components';
+
+export default ModalForm.extend({
+ template: Template,
+
+ onFormSubmit () {
+ ModalForm.prototype.onFormSubmit.apply(this, arguments);
+ this.disableForm();
+
+ deleteProject(this.options.project.key)
+ .then(() => {
+ this.trigger('done');
+ })
+ .catch(function (e) {
+ e.response.json().then(r => {
+ this.showErrors(r.errors, r.warnings);
+ this.enableForm();
+ });
+ });
+ },
+
+ serializeData () {
+ return { project: this.options.project };
+ }
+});
+
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModalTemplate.hbs b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModalTemplate.hbs
new file mode 100644
index 00000000000..5da393e8d75
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModalTemplate.hbs
@@ -0,0 +1,13 @@
+<form id="deactivate-user-form" autocomplete="off">
+ <div class="modal-head">
+ <h2>{{t 'qualifiers.delete.TRK'}}</h2>
+ </div>
+ <div class="modal-body">
+ <div class="js-modal-messages"></div>
+ {{tp 'project_deletion.delete_resource_confirmation' project.name}}
+ </div>
+ <div class="modal-foot">
+ <button id="delete-project-confirm" class="button-red">{{t 'delete'}}</button>
+ <a href="#" class="js-modal-close">{{t 'cancel'}}</a>
+ </div>
+</form>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
new file mode 100644
index 00000000000..67563891ade
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
@@ -0,0 +1,37 @@
+/*
+ * 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 Header from './Header';
+import Form from './Form';
+
+export default class Deletion extends React.Component {
+ static propTypes = {
+ component: React.PropTypes.object.isRequired
+ };
+
+ render () {
+ return (
+ <div className="page page-limited">
+ <Header/>
+ <Form component={this.props.component}/>
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js
new file mode 100644
index 00000000000..81d52fb3ba2
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js
@@ -0,0 +1,47 @@
+/*
+ * 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 ConfirmationModal from './ConfirmationModal';
+import { translate } from '../../../helpers/l10n';
+
+export default class Form extends React.Component {
+ static propTypes = {
+ component: React.PropTypes.object.isRequired
+ };
+
+ handleDelete (e) {
+ e.preventDefault();
+ new ConfirmationModal({ project: this.props.component })
+ .on('done', () => {
+ window.location = window.baseUrl + '/';
+ })
+ .render();
+ }
+
+ render () {
+ return (
+ <form onSubmit={this.handleDelete.bind(this)}>
+ <button id="delete-project" className="button-red">
+ {translate('delete')}
+ </button>
+ </form>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js
new file mode 100644
index 00000000000..39bd303693f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/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 (
+ <header className="page-header">
+ <h1 className="page-title">
+ {translate('deletion.page')}
+ </h1>
+ <div className="page-description">
+ {translate('project_deletion.page.description')}
+ </div>
+ </header>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/main/nav/app.js b/server/sonar-web/src/main/js/main/nav/app.js
index 9c0526f57a0..902e6ea07ef 100644
--- a/server/sonar-web/src/main/js/main/nav/app.js
+++ b/server/sonar-web/src/main/js/main/nav/app.js
@@ -67,8 +67,12 @@ export default class App {
static renderComponentNav (options) {
return getComponentNavigation(options.componentKey).then(component => {
const el = document.getElementById('context-navigation');
+ const nextComponent = {
+ ...component,
+ qualifier: _.last(component.breadcrumbs).qualifier
+ };
if (el) {
- ReactDOM.render(<ComponentNav component={component} conf={component.configuration || {}}/>, el);
+ ReactDOM.render(<ComponentNav component={nextComponent} conf={component.configuration || {}}/>, el);
}
return component;
});
diff --git a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
index 4aaf6ff239e..ad6ad6c6e76 100644
--- a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
+++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
@@ -42,12 +42,11 @@ export default React.createClass({
mixins: [LinksMixin],
isDeveloper() {
- const qualifier = _.last(this.props.component.breadcrumbs).qualifier;
- return qualifier === 'DEV';
+ return this.props.component.qualifier === 'DEV';
},
isView() {
- const qualifier = _.last(this.props.component.breadcrumbs).qualifier;
+ const { qualifier } = this.props.component;
return qualifier === 'VW' || qualifier === 'SVW';
},
@@ -100,7 +99,6 @@ export default React.createClass({
renderAdministration() {
const shouldShowAdministration =
this.props.conf.showBackgroundTasks ||
- this.props.conf.showDeletion ||
this.props.conf.showHistory ||
this.props.conf.showLinks ||
this.props.conf.showManualMeasures ||
@@ -132,8 +130,8 @@ export default React.createClass({
{this.renderHistoryLink()}
{this.renderBackgroundTasksLink()}
{this.renderUpdateKeyLink()}
- {this.renderDeletionLink()}
{this.renderExtensions()}
+ {this.renderDeletionLink()}
</ul>
</li>
);
@@ -212,9 +210,12 @@ export default React.createClass({
},
renderDeletionLink() {
- if (!this.props.conf.showDeletion) {
+ const { qualifier } = this.props.component;
+
+ if (qualifier !== 'TRK' && qualifier !== 'VW') {
return null;
}
+
const url = `/project/deletion?id=${encodeURIComponent(this.props.component.key)}`;
return this.renderLink(url, translate('deletion.page'), '/project/deletion');
},
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
index a85983ebede..ab0d5400963 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
@@ -20,7 +20,6 @@
class ProjectController < ApplicationController
verify :method => :post, :only => [:set_links, :set_exclusions, :delete_exclusions, :update_key, :perform_key_bulk_update],
:redirect_to => {:action => :index}
- verify :method => :delete, :only => [:delete], :redirect_to => {:action => :index}
SECTION=Navigation::SECTION_RESOURCE
@@ -29,56 +28,8 @@ class ProjectController < ApplicationController
redirect_to :overwrite_params => {:controller => :dashboard, :action => 'index'}
end
- def delete_form
- @project = get_current_project(params[:id])
- render :partial => 'delete_form'
- end
-
- def delete
- @project = get_current_project(params[:id])
-
- # Ask the resource deletion manager to start the migration
- # => this is an asynchronous AJAX call
- ResourceDeletionManager.instance.delete_resources([@project.id])
-
- # and return some text that will actually never be displayed
- render :text => ResourceDeletionManager.instance.message
- end
-
def deletion
@project = get_current_project(params[:id])
-
- if java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'deletable')
- deletion_manager = ResourceDeletionManager.instance
- if deletion_manager.currently_deleting_resources? ||
- (!deletion_manager.currently_deleting_resources? && deletion_manager.deletion_failures_occured?)
- # a deletion is happening or it has just finished with errors => display the message from the Resource Deletion Manager
- render :template => 'project/pending_deletion'
- else
- @snapshot=@project.last_snapshot
- end
- else
- redirect_to :action => 'index', :id => params[:id]
- end
- end
-
- def pending_deletion
- deletion_manager = ResourceDeletionManager.instance
-
- if deletion_manager.currently_deleting_resources? ||
- (!deletion_manager.currently_deleting_resources? && deletion_manager.deletion_failures_occured?)
- # display the same page again and again
- # => implicit render "pending_deletion.html.erb"
- else
- redirect_to_default
- end
- end
-
- def dismiss_deletion_message
- # It is important to reinit the ResourceDeletionManager so that the deletion screens can be available again
- ResourceDeletionManager.instance.reinit
-
- redirect_to :action => 'deletion', :id => params[:id]
end
# GET /project/profile?id=<project id>
@@ -227,18 +178,6 @@ class ProjectController < ApplicationController
@project = get_current_project(params[:id])
end
- def delete_snapshot_history
- @project = get_current_project(params[:id])
-
- sid = params[:snapshot_id]
- if sid
- Snapshot.update_all("status='U'", ["id=?", sid.to_i])
- flash[:notice] = message('project_history.snapshot_deleted')
- end
-
- redirect_to :action => 'history', :id => @project.id
- end
-
def links
@project = get_current_project(params[:id])
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/_delete_form.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/_delete_form.html.erb
deleted file mode 100644
index 79c73cd6f82..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/_delete_form.html.erb
+++ /dev/null
@@ -1,34 +0,0 @@
-<% resource_qualifier = message('qualifier.' + @project.qualifier) %>
-<form id="delete-project-form" method="post" action="<%= ApplicationController.root_context -%>/project/delete">
- <fieldset>
- <div class="modal-head">
- <h2><%= message('project_deletion.page', :params => resource_qualifier) -%></h2>
- </div>
- <div class="modal-body">
- <%= message('project_deletion.delete_resource_confirmation', :params => resource_qualifier) %>
- </div>
- <div class="modal-foot">
- <span id="delete-project-loading-image" class="loading-image hidden"><%= image_tag 'loading.gif' %></span>
- <input type="submit" value="<%= message('delete') -%>" id="delete-project-submit" onclick="return displayLoadingImage()"/>
- <a href="#" onclick="return closeModalWindow()" id="delete-project-cancel"><%= message('cancel') -%></a>
- </div>
- </fieldset>
-</form>
-<script>
- $j("#delete-project-form").modalForm({
- success: function () {
- $j.ajax({
- url: "<%= ApplicationController.root_context-%>/project/delete/<%= h(@project.id) -%>",
- success: function (request) {
- window.location = '<%= url_for(:action => 'pending_deletion',:id => @project.id)-%>';
- },
- data: $j(this).serialize(),
- type: 'delete'
- });
- }
- });
-
- function displayLoadingImage() {
- $j('#delete-project-loading-image').removeClass("hidden");
- }
-</script>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/deletion.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/deletion.html.erb
index da66ac28b95..e9dd9ae3410 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/deletion.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/deletion.html.erb
@@ -1,18 +1,3 @@
-<div class="page">
- <%
- if !@snapshot || @project.root?
- resource_qualifier = message('qualifier.' + @project.qualifier)
- delete_resource_message = message('project_deletion.page', :params => resource_qualifier)
- %>
- <header class="page-header">
- <h1 class="page-title"><%= delete_resource_message -%></h1>
- <p class="page-description"><%= message('project_deletion.page.description') -%></p>
- </header>
-
- <div class="yui-g widget" id="widget_delete_project">
- <div class="alert alert-warning spacer-bottom"><%= message('project_deletion.operation_cannot_be_undone') -%></div>
- <a id="delete_resource" class="open-modal button button-red"
- href="<%= ApplicationController.root_context -%>/project/delete_form/<%= h(@project.id) -%>"><%= delete_resource_message -%></a>
- </div>
- <% end %>
-</div>
+<% content_for :extra_script do %>
+ <script src="<%= ApplicationController.root_context -%>/js/bundles/project-admin.js?v=<%= sonar_version -%>"></script>
+<% end %>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/pending_deletion.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/pending_deletion.html.erb
deleted file mode 100644
index 7d96f93b194..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project/pending_deletion.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= render :partial => 'bulk_deletion/pending_deletions_screen',
- :locals => {:url_after_dismiss => url_for(:action => 'dismiss_deletion_message', :id => params[:id])} -%> \ No newline at end of file
diff --git a/server/sonar-web/webpack.config.js b/server/sonar-web/webpack.config.js
index d64f64ab975..cea911812e7 100644
--- a/server/sonar-web/webpack.config.js
+++ b/server/sonar-web/webpack.config.js
@@ -45,6 +45,7 @@ module.exports = {
'metrics': './src/main/js/apps/metrics/app.js',
'overview': './src/main/js/apps/overview/app.js',
'permission-templates': './src/main/js/apps/permission-templates/app.js',
+ 'project-admin': './src/main/js/apps/project-admin/app.js',
'project-permissions': './src/main/js/apps/permissions/project/app.js',
'projects': './src/main/js/apps/projects/app.js',
'quality-gates': './src/main/js/apps/quality-gates/app.js',
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index c2ed6ed763c..94cab9055d4 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -508,8 +508,7 @@ bulk_deletion.page.description=Use this page to delete multiple projects at once
update_key.page=Update Key
update_key.page.description=Edit the keys of a project and/or its modules. Key changes must be made here BEFORE analyzing the project with the new keys, otherwise the analysis will simply create another project with the new key, rather than updating the existing project.
deletion.page=Deletion
-project_deletion.page=Delete {0}
-project_deletion.page.description=Delete this project from the SonarQube database.
+project_deletion.page.description=Delete this project from SonarQube. The operation cannot be undone.
provisioning.page=Provisioning
provisioning.page.description=Use this page to initialize projects if you would like to configure them before the first analysis. Once a project is provisioned, you have access to perform all project configurations on it.
@@ -1640,8 +1639,7 @@ project_quality_gate.default_qgate=Default
#
#------------------------------------------------------------------------------
-project_deletion.operation_cannot_be_undone=This operation can not be undone.
-project_deletion.delete_resource_confirmation=Are you sure you want to delete this {0}?
+project_deletion.delete_resource_confirmation=Are you sure you want to delete "{0}"?
#------------------------------------------------------------------------------