Merge pull request #1088 from dod-ccpo/make-application-creation-multistep

Make application creation multistep
This commit is contained in:
graham-dds
2019-09-24 13:56:36 -04:00
committed by GitHub
17 changed files with 419 additions and 134 deletions

View File

@@ -1,4 +1,5 @@
from . import BaseDomainClass
from flask import g
from atst.database import db
from atst.domain.application_roles import ApplicationRoles
from atst.domain.environment_roles import EnvironmentRoles
@@ -19,13 +20,14 @@ class Applications(BaseDomainClass):
resource_name = "application"
@classmethod
def create(cls, user, portfolio, name, description, environment_names):
def create(cls, user, portfolio, name, description, environment_names=None):
application = Application(
portfolio=portfolio, name=name, description=description
)
db.session.add(application)
Environments.create_many(user, application, environment_names)
if environment_names:
Environments.create_many(user, application, environment_names)
db.session.commit()
return application
@@ -48,7 +50,10 @@ class Applications(BaseDomainClass):
application.name = new_data["name"]
if "description" in new_data:
application.description = new_data["description"]
if "environment_names" in new_data:
Environments.create_many(
g.current_user, application, new_data["environment_names"]
)
db.session.add(application)
db.session.commit()

View File

@@ -11,7 +11,7 @@ class EditEnvironmentForm(BaseForm):
)
class ApplicationForm(BaseForm):
class NameAndDescriptionForm(BaseForm):
name = StringField(
label=translate("forms.application.name_label"), validators=[Required()]
)
@@ -20,7 +20,7 @@ class ApplicationForm(BaseForm):
)
class NewApplicationForm(ApplicationForm):
class EnvironmentsForm(BaseForm):
environment_names = FieldList(
StringField(label=translate("forms.application.environment_names_label")),
validators=[

View File

@@ -3,35 +3,130 @@ from flask import redirect, render_template, request as http_request, url_for, g
from . import applications_bp
from atst.domain.applications import Applications
from atst.domain.portfolios import Portfolios
from atst.forms.application import NewApplicationForm
from atst.forms.application import NameAndDescriptionForm, EnvironmentsForm
from atst.domain.authz.decorator import user_can_access_decorator as user_can
from atst.models.permissions import Permissions
from atst.utils.flash import formatted_flash as flash
def get_new_application_form(form_data, form_class, application_id=None):
if application_id:
application = Applications.get(application_id)
return form_class(form_data, obj=application)
else:
return form_class(form_data)
def render_new_application_form(
template, form_class, portfolio_id=None, application_id=None, form=None
):
render_args = {"application_id": application_id}
if application_id:
application = Applications.get(application_id)
render_args["form"] = form or form_class(obj=application)
else:
render_args["form"] = form or form_class()
return render_template(template, **render_args)
@applications_bp.route("/portfolios/<portfolio_id>/applications/new")
@applications_bp.route(
"/portfolios/<portfolio_id>/applications/<application_id>/step_1"
)
@user_can(Permissions.CREATE_APPLICATION, message="view create new application form")
def new(portfolio_id):
form = NewApplicationForm()
return render_template("portfolios/applications/new.html", form=form)
def view_new_application_step_1(portfolio_id, application_id=None):
return render_new_application_form(
"portfolios/applications/new/step_1.html",
NameAndDescriptionForm,
portfolio_id=portfolio_id,
application_id=application_id,
)
@applications_bp.route("/portfolios/<portfolio_id>/applications", methods=["POST"])
@user_can(Permissions.CREATE_APPLICATION, message="create new application")
def create(portfolio_id):
@applications_bp.route(
"/portfolios/<portfolio_id>/applications/new",
endpoint="create_new_application_step_1",
methods=["POST"],
)
@applications_bp.route(
"/portfolios/<portfolio_id>/applications/<application_id>/step_1",
endpoint="update_new_application_step_1",
methods=["POST"],
)
@user_can(Permissions.CREATE_APPLICATION, message="view create new application form")
def create_or_update_new_application_step_1(portfolio_id, application_id=None):
portfolio = Portfolios.get_for_update(portfolio_id)
form = NewApplicationForm(http_request.form)
form = get_new_application_form(
{**http_request.form}, NameAndDescriptionForm, application_id
)
if form.validate():
application_data = form.data
Applications.create(
g.current_user,
portfolio,
application_data["name"],
application_data["description"],
application_data["environment_names"],
)
application = None
if application_id:
application = Applications.get(application_id)
application = Applications.update(application, form.data)
else:
application = Applications.create(g.current_user, portfolio, **form.data)
return redirect(
url_for("applications.portfolio_applications", portfolio_id=portfolio_id)
url_for(
"applications.update_new_application_step_2",
portfolio_id=portfolio_id,
application_id=application.id,
)
)
else:
return render_template("portfolios/applications/new.html", form=form)
return (
render_new_application_form(
"portfolios/applications/new/step_1.html",
NameAndDescriptionForm,
portfolio_id,
application_id,
form,
),
400,
)
@applications_bp.route(
"/portfolios/<portfolio_id>/applications/<application_id>/step_2"
)
@user_can(Permissions.CREATE_APPLICATION, message="view create new application form")
def view_new_application_step_2(portfolio_id, application_id):
return render_new_application_form(
"portfolios/applications/new/step_2.html",
EnvironmentsForm,
portfolio_id=portfolio_id,
application_id=application_id,
)
@applications_bp.route(
"/portfolios/<portfolio_id>/applications/<application_id>/step_2", methods=["POST"]
)
@user_can(Permissions.CREATE_APPLICATION, message="view create new application form")
def update_new_application_step_2(portfolio_id, application_id):
form = get_new_application_form(
{**http_request.form}, EnvironmentsForm, application_id
)
if form.validate():
application = Applications.get(application_id)
application = Applications.update(application, form.data)
flash("application_created", application_name=application.name)
return redirect(
url_for(
"applications.portfolio_applications",
portfolio_id=application.portfolio_id,
)
)
else:
return (
render_new_application_form(
"portfolios/applications/new/step_2.html",
EnvironmentsForm,
portfolio_id,
application_id,
form,
),
400,
)

View File

@@ -8,8 +8,8 @@ from atst.domain.application_roles import ApplicationRoles
from atst.domain.audit_log import AuditLog
from atst.domain.common import Paginator
from atst.domain.environment_roles import EnvironmentRoles
from atst.forms.application import ApplicationForm, EditEnvironmentForm
from atst.forms.application_member import NewForm as NewMemberForm, UpdateMemberForm
from atst.forms.application import NameAndDescriptionForm, EditEnvironmentForm
from atst.forms.data import ENV_ROLE_NO_ACCESS as NO_ACCESS
from atst.domain.authz.decorator import user_can_access_decorator as user_can
from atst.models.permissions import Permissions
@@ -125,7 +125,7 @@ def render_settings_page(application, **kwargs):
members = get_members_data(application)
if "application_form" not in kwargs:
kwargs["application_form"] = ApplicationForm(
kwargs["application_form"] = NameAndDescriptionForm(
name=application.name, description=application.description
)
@@ -229,7 +229,7 @@ def new_environment(application_id):
@user_can(Permissions.EDIT_APPLICATION, message="update application")
def update(application_id):
application = Applications.get(application_id)
form = ApplicationForm(http_request.form)
form = NameAndDescriptionForm(http_request.form)
if form.validate():
application_data = form.data
Applications.update(application, application_data)

View File

@@ -7,6 +7,13 @@ MESSAGES = {
"message_template": "Portfolio '{{portfolio_name}}' has been deleted",
"category": "success",
},
"application_created": {
"title_template": translate("flash.success"),
"message_template": """
{{ "flash.application.created" | translate({"application_name": application_name}) }}
""",
"category": "success",
},
"application_deleted": {
"title_template": translate("flash.success"),
"message_template": """