Merge pull request #806 from dod-ccpo/delete-environment

Delete environments from an application
This commit is contained in:
George Drummond 2019-05-07 10:18:32 -04:00 committed by GitHub
commit d9ed8ed2f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 116 additions and 27 deletions

View File

@ -191,3 +191,21 @@ def delete(application_id):
"applications.portfolio_applications", portfolio_id=application.portfolio_id
)
)
@applications_bp.route("/environments/<environment_id>/delete", methods=["POST"])
@user_can(Permissions.DELETE_ENVIRONMENT, message="delete environment")
def delete_environment(environment_id):
environment = Environments.get(environment_id)
Environments.delete(environment=environment, commit=True)
flash("environment_deleted", environment_name=environment.name)
return redirect(
url_for(
"applications.settings",
application_id=environment.application_id,
_anchor="application-environments",
fragment="application-environments",
)
)

View File

@ -2,6 +2,11 @@ from flask import flash, render_template_string
from atst.utils.localization import translate
MESSAGES = {
"environment_deleted": {
"title_template": "{{ environment_name }} deleted",
"message_template": 'The environment "{{ environment_name }}" has been deleted',
"category": "success",
},
"application_environments_updated": {
"title_template": "Application environments updated",
"message_template": "Application environments have been updated",

View File

@ -0,0 +1,25 @@
{% macro DeleteConfirmation(modal_id, delete_text, delete_action, form) %}
<delete-confirmation inline-template>
<div>
<div class="usa-input">
<label for="deleted-text">
<span class="usa-input__help">
{{ "common.delete_confirm" | translate }}
</span>
</label>
<input id="deleted-text" v-model="deleteText">
</div>
<div class="action-group">
<form method="POST" action="{{ delete_action }}">
{{ form.csrf_token }}
<button class="usa-button button-danger" v-bind:disabled="!valid">
{{ delete_text }}
</button>
</form>
<div class="action-group">
<a v-on:click="deleteText = ''; $root.closeModal({{ modal_id }})" class="action-group__action icon-link icon-link--default">{{ "common.cancel" | translate }}</a>
</div>
</div>
</div>
</delete-confirmation>
{% endmacro %}

View File

@ -1,7 +1,9 @@
{% from "components/delete_confirmation.html" import DeleteConfirmation %}
{% from "components/icon.html" import Icon %}
{% from "components/toggle_list.html" import ToggleButton, ToggleSection %}
{% from "components/text_input.html" import TextInput %}
{% from "components/modal.html" import Modal %}
{% from "components/save_button.html" import SaveButton %}
{% from "components/text_input.html" import TextInput %}
{% from "components/toggle_list.html" import ToggleButton, ToggleSection %}
{% macro RolePanel(users=[], role='no_access') %}
{% if role == 'no_access' %}
@ -52,6 +54,7 @@
{% set member_count = env['members_form'].data['team_roles'] | length %}
{% set members_by_role = env['members'] %}
{% set unassigned = members_by_role['no_access'] %}
{% set delete_environment_modal_id = "delete_modal_environment{}".format(env['id']) %}
<toggler inline-template {% if edit_form.errors %}initial-selected-section="edit"{% endif %}>
<li class="accordion-table__item">
@ -75,7 +78,7 @@
</span>
</div>
<div class="col col--grow">
<span class="icon-link icon-link--danger">
<span class="icon-link icon-link--danger" alt="Delete environment" v-on:click="openModal('{{ delete_environment_modal_id }}')">
{{ Icon('trash') }}
</span>
</div>
@ -122,6 +125,27 @@
{% endcall %}
</li>
</toggler>
{% call Modal(name=delete_environment_modal_id, dismissable=True) %}
<h1>Are you sure you want to delete this environment?</h1>
{{
Alert(
level="warning",
title="Warning! This action is permanent",
message="You will no longer be able to access this environment",
)
}}
{{
DeleteConfirmation(
modal_id=delete_modal_environment_id,
delete_text=('portfolios.applications.environments.delete.button' | translate),
delete_action= url_for('applications.delete_environment', environment_id=env['id']),
form=form
)
}}
{% endcall %}
{% endfor %}
</ul>
</div>

View File

@ -1,9 +1,10 @@
{% extends "portfolios/applications/base.html" %}
{% from "components/alert.html" import Alert %}
{% from "components/text_input.html" import TextInput %}
{% from "components/delete_confirmation.html" import DeleteConfirmation %}
{% from "components/icon.html" import Icon %}
{% from "components/modal.html" import Modal %}
{% from "components/text_input.html" import TextInput %}
{% set secondary_breadcrumb = 'portfolios.applications.existing_application_title' | translate({ "application_name": application.name }) %}
@ -94,29 +95,14 @@
)
}}
<delete-confirmation inline-template>
<div>
<div class="usa-input">
<label for="deleted-text">
<span class="usa-input__help">
{{ "common.delete_confirm" | translate }}
</span>
</label>
<input id="deleted-text" v-model="deleteText">
</div>
<div class="action-group">
<form method="POST" action="{{ url_for('applications.delete', application_id=application.id) }}">
{{ form.csrf_token }}
<button class="usa-button button-danger" v-bind:disabled="!valid">
{{ "portfolios.applications.delete.button" | translate }}
</button>
</form>
<div class="action-group">
<a v-on:click="deleteText = ''; $root.closeModal('delete-application')" class="action-group__action icon-link icon-link--default">{{ "common.cancel" | translate }}</a>
</div>
</div>
</div>
</delete-confirmation>
{{
DeleteConfirmation(
modal_id=delete_modal_environment_id,
delete_text=('portfolios.applications.delete.button' | translate),
delete_action= url_for('applications.delete', application_id=application.id),
form=form
)
}}
{% endcall %}
{% endif %}

View File

@ -326,3 +326,32 @@ def test_delete_application(client, user_session):
# app and envs are soft deleted
assert len(port.applications) == 0
assert len(application.environments) == 0
def test_delete_environment(client, user_session):
user = UserFactory.create()
portfolio = PortfolioFactory(owner=user)
application = ApplicationFactory.create(portfolio=portfolio)
environment = EnvironmentFactory.create(application=application)
user_session(user)
response = client.post(
url_for("applications.delete_environment", environment_id=environment.id)
)
# appropriate response and redirect
assert response.status_code == 302
assert response.location == url_for(
"applications.settings",
application_id=application.id,
_anchor="application-environments",
_external=True,
fragment="application-environments",
)
# appropriate flash message
message = get_flashed_messages()[0]
assert "deleted" in message["message"]
assert environment.name in message["message"]
# deletes environment
assert len(application.environments) == 0

View File

@ -413,6 +413,8 @@ portfolios:
header: Are you sure you want to delete this application?
environments:
name: Name
delete:
button: Delete environment
edit_name: Edit name
environments_description: Each environment created within an application is logically separated from one another for easier management and security.
environments_heading: Application environments