diff --git a/atst/domain/portfolio_roles.py b/atst/domain/portfolio_roles.py index 153d4707..cb123b4a 100644 --- a/atst/domain/portfolio_roles.py +++ b/atst/domain/portfolio_roles.py @@ -121,6 +121,15 @@ class PortfolioRoles(object): ) return PermissionSets.get_many(perms_set_names) + @classmethod + def disable(cls, portfolio_role): + portfolio_role.status = PortfolioRoleStatus.DISABLED + + db.session.add(portfolio_role) + db.session.commit() + + return portfolio_role + @classmethod def update(cls, portfolio_role, set_names): new_permission_sets = PortfolioRoles._permission_sets_for_names(set_names) diff --git a/atst/routes/portfolios/index.py b/atst/routes/portfolios/index.py index 541a8194..767f56aa 100644 --- a/atst/routes/portfolios/index.py +++ b/atst/routes/portfolios/index.py @@ -15,6 +15,7 @@ import atst.forms.portfolio_member as member_forms from atst.models.permissions import Permissions from atst.domain.permission_sets import PermissionSets from atst.domain.authz.decorator import user_can_access_decorator as user_can +from atst.utils.flash import formatted_flash as flash @portfolios_bp.route("/portfolios") @@ -174,3 +175,30 @@ def portfolio_reports(portfolio_id): expiration_date=expiration_date, remaining_days=remaining_days, ) + + +@portfolios_bp.route( + "/portfolios//members//delete", methods=["POST"] +) +@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="update portfolio members") +def remove_member(portfolio_id, member_id): + if member_id == str(g.current_user.id): + raise UnauthorizedError( + user=user, message="you cant remove yourself from the portfolio" + ) + + portfolio = Portfolios.get(g.current_user, portfolio_id) + portfolio_role = PortfolioRoles.get(portfolio_id=portfolio_id, user_id=member_id) + + PortfolioRoles.disable(portfolio_role=portfolio_role) + + flash("portfolio_member_removed", member_name=portfolio_role.user.full_name) + + return redirect( + url_for( + "portfolios.portfolio_admin", + portfolio_id=portfolio.id, + _anchor="portfolio-members", + fragment="portfolio-members", + ) + ) diff --git a/atst/utils/flash.py b/atst/utils/flash.py index 89f81132..1fc6a740 100644 --- a/atst/utils/flash.py +++ b/atst/utils/flash.py @@ -138,6 +138,11 @@ MESSAGES = { """, "category": "error", }, + "portfolio_member_removed": { + "title_template": "Portfolio Member Removed", + "message_template": "You have successfully removed {{ member_name }} from the portfolio.", + "category": "success", + }, } diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 539ef47b..7a33345b 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -291,6 +291,10 @@ height: 4rem; } + .usa-button-danger { + background: $color-red; + } + .members-table-footer { float: right; padding: 3 * $gap; diff --git a/templates/fragments/admin/members_edit.html b/templates/fragments/admin/members_edit.html index 0d873622..04d2ed21 100644 --- a/templates/fragments/admin/members_edit.html +++ b/templates/fragments/admin/members_edit.html @@ -1,3 +1,7 @@ +{% from "components/confirmation_button.html" import ConfirmationButton %} + +{% set modal_id = "portfolio_id_{}_user_id_{}".format(portfolio.id, user.id) %} + {% for subform in member_perms_form.members_permissions %} {{ subform.member.data }} @@ -14,7 +18,10 @@ {{ OptionsInput(subform.perms_reporting, label=False) }} {{ OptionsInput(subform.perms_portfolio_mgmt, label=False) }} - + + + {{ "portfolios.members.archive_button" | translate }} + {{ subform.user_id() }} diff --git a/templates/fragments/admin/portfolio_members.html b/templates/fragments/admin/portfolio_members.html index 08e856e0..da980c3d 100644 --- a/templates/fragments/admin/portfolio_members.html +++ b/templates/fragments/admin/portfolio_members.html @@ -1,6 +1,9 @@ {% from "components/icon.html" import Icon %} {% from "components/options_input.html" import OptionsInput %} +{% from "components/modal.html" import Modal %} +{% from "components/alert.html" import Alert %} +
{% if g.matchesPath("portfolio-members") %} @@ -51,6 +54,34 @@ {% endif %} + + {% if user_can(permissions.EDIT_PORTFOLIO_USERS) %} + {% for member in portfolio.members %} + {% set modal_id = "portfolio_id_{}_user_id_{}".format(portfolio.id, user.id) %} + {% call Modal(name=modal_id, dismissable=False) %} +

Are you sure you want to archive this user?

+ + {{ + Alert( + title="Warning! You are about to archive a user from the portfolio admin.", + message="User will be removed from the portfolio, but their log history will be retained.", + level="warning" + ) + }} + +
+
+ {{ member_perms_form.csrf_token }} + +
+ Cancel +
+ {% endcall %} + {% endfor %} + {% endif %} +