diff --git a/atst/domain/environments.py b/atst/domain/environments.py index 44eaad9a..9c8e4d52 100644 --- a/atst/domain/environments.py +++ b/atst/domain/environments.py @@ -49,6 +49,13 @@ class Environments(object): .all() ) + @classmethod + def update(cls, environment, name=None): + if name is not None: + environment.name = name + db.session.add(environment) + db.session.commit() + @classmethod def get(cls, environment_id): try: diff --git a/atst/forms/application.py b/atst/forms/application.py index 745bb7f8..4fae3f1c 100644 --- a/atst/forms/application.py +++ b/atst/forms/application.py @@ -5,6 +5,12 @@ from atst.forms.validators import ListItemRequired, ListItemsUnique from atst.utils.localization import translate +class EditEnvironmentForm(BaseForm): + name = StringField( + label=translate("forms.environments.name_label"), validators=[Required()] + ) + + class ApplicationForm(BaseForm): name = StringField( label=translate("forms.application.name_label"), validators=[Required()] diff --git a/atst/routes/applications/settings.py b/atst/routes/applications/settings.py index 169af8c9..a7628ade 100644 --- a/atst/routes/applications/settings.py +++ b/atst/routes/applications/settings.py @@ -4,8 +4,8 @@ from . import applications_bp from atst.domain.environment_roles import EnvironmentRoles from atst.domain.environments import Environments from atst.domain.applications import Applications -from atst.forms.application import ApplicationForm from atst.forms.app_settings import EnvironmentRolesForm +from atst.forms.application import ApplicationForm, EditEnvironmentForm 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 @@ -15,10 +15,14 @@ def get_environments_obj_for_app(application): environments_obj = {} for env in application.environments: - environments_obj[env.name] = [] + environments_obj[env.name] = { + "edit_form": EditEnvironmentForm(obj=env), + "id": env.id, + "members": [], + } for user in env.users: env_role = EnvironmentRoles.get(user.id, env.id) - environments_obj[env.name].append( + environments_obj[env.name]["members"].append( {"name": user.full_name, "role": env_role.displayname} ) @@ -49,6 +53,7 @@ def settings(application_id): application = Applications.get(application_id) form = ApplicationForm(name=application.name, description=application.description) app_envs_data = serialize_env_member_form_data(application) + env_forms = {} for env_data in app_envs_data: env_forms[env_data["env_id"]] = EnvironmentRolesForm(data=env_data) @@ -62,6 +67,29 @@ def settings(application_id): ) +@applications_bp.route("/environments//edit", methods=["POST"]) +@user_can(Permissions.EDIT_ENVIRONMENT, message="edit application environments") +def update_environment(environment_id): + environment = Environments.get(environment_id) + application = environment.application + + form = EditEnvironmentForm(formdata=http_request.form) + + if form.validate(): + Environments.update(environment=environment, name=form.name.data) + + flash("application_environments_updated") + + return redirect( + url_for( + "applications.settings", + application_id=application.id, + fragment="application-environments", + _anchor="application-environments", + ) + ) + + @applications_bp.route("/applications//edit", methods=["POST"]) @user_can(Permissions.EDIT_APPLICATION, message="update application") def update(application_id): diff --git a/atst/utils/flash.py b/atst/utils/flash.py index 7970cc03..da021ecc 100644 --- a/atst/utils/flash.py +++ b/atst/utils/flash.py @@ -2,6 +2,11 @@ from flask import flash, render_template_string from atst.utils.localization import translate MESSAGES = { + "application_environments_updated": { + "title_template": "Application environments updated", + "message_template": "Application environments have been updated", + "category": "success", + }, "primary_point_of_contact_changed": { "title_template": translate("flash.new_ppoc_title"), "message_template": """{{ "flash.new_ppoc_message" | translate({ "ppoc_name": ppoc_name }) }}""", diff --git a/js/components/toggler.js b/js/components/toggler.js index 52f756b0..ff3d55c5 100644 --- a/js/components/toggler.js +++ b/js/components/toggler.js @@ -1,6 +1,15 @@ +import FormMixin from '../mixins/form' +import textinput from './text_input' + export default { name: 'toggler', + mixins: [FormMixin], + + components: { + textinput, + }, + data: function() { return { selectedSection: null, diff --git a/styles/components/_accordion_table.scss b/styles/components/_accordion_table.scss index 5ee20a09..7fa7312a 100644 --- a/styles/components/_accordion_table.scss +++ b/styles/components/_accordion_table.scss @@ -3,6 +3,11 @@ } .accordion-table { + .usa-alert { + margin: $gap*2; + margin-bottom: 0; + } + ul { padding-left: 0; } diff --git a/templates/fragments/applications/edit_environments.html b/templates/fragments/applications/edit_environments.html index 5660fcb6..607d854e 100644 --- a/templates/fragments/applications/edit_environments.html +++ b/templates/fragments/applications/edit_environments.html @@ -1,5 +1,7 @@ {% from "components/icon.html" import Icon %} {% from "components/toggle_list.html" import ToggleButton, ToggleSection %} +{% from "components/text_input.html" import TextInput %} +{% from "components/save_button.html" import SaveButton %}
@@ -20,7 +22,7 @@