Update app member status labels to accurately reflect member's current status
This commit is contained in:
parent
3f146c7da8
commit
9f90f5abbd
@ -102,6 +102,14 @@ class ApplicationRole(
|
|||||||
"portfolio": self.application.portfolio.name,
|
"portfolio": self.application.portfolio.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_pending(self):
|
||||||
|
return self.status == Status.PENDING
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_active(self):
|
||||||
|
return self.status == Status.ACTIVE
|
||||||
|
|
||||||
|
|
||||||
Index(
|
Index(
|
||||||
"application_role_user_application",
|
"application_role_user_application",
|
||||||
|
@ -70,6 +70,10 @@ class EnvironmentRole(
|
|||||||
def disabled(self):
|
def disabled(self):
|
||||||
return self.status == EnvironmentRole.Status.DISABLED
|
return self.status == EnvironmentRole.Status.DISABLED
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_pending(self):
|
||||||
|
return self.status == EnvironmentRole.Status.PENDING
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def event_details(self):
|
def event_details(self):
|
||||||
return {
|
return {
|
||||||
|
@ -153,6 +153,7 @@ def view_new_application_step_3(application_id):
|
|||||||
application=application,
|
application=application,
|
||||||
members=members,
|
members=members,
|
||||||
new_member_form=new_member_form,
|
new_member_form=new_member_form,
|
||||||
|
label_info=LABEL_INFO,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,19 @@ from atst.utils.localization import translate
|
|||||||
from atst.jobs import send_mail
|
from atst.jobs import send_mail
|
||||||
|
|
||||||
|
|
||||||
|
LABEL_INFO = {
|
||||||
|
"pending": {"icon": "envelope", "text": "invite pending", "type": "success",},
|
||||||
|
"expired": {"icon": "envelope", "text": "invite expired", "type": "error",},
|
||||||
|
"env_changes_pending": {
|
||||||
|
"icon": "exchange",
|
||||||
|
"text": "changes pending",
|
||||||
|
"type": "default",
|
||||||
|
},
|
||||||
|
"active": None,
|
||||||
|
"disabled": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_environments_obj_for_app(application):
|
def get_environments_obj_for_app(application):
|
||||||
return sorted(
|
return sorted(
|
||||||
[
|
[
|
||||||
@ -98,6 +111,20 @@ def filter_env_roles_form_data(member, environments):
|
|||||||
return env_roles_form_data
|
return env_roles_form_data
|
||||||
|
|
||||||
|
|
||||||
|
def get_app_role_status(app_role):
|
||||||
|
status = app_role.status.value
|
||||||
|
|
||||||
|
if app_role.is_pending and app_role.latest_invitation.is_expired:
|
||||||
|
status = "expired"
|
||||||
|
|
||||||
|
if app_role.is_active and any(
|
||||||
|
env_role.is_pending for env_role in app_role.environment_roles
|
||||||
|
):
|
||||||
|
status = "env_changes_pending"
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
def get_members_data(application):
|
def get_members_data(application):
|
||||||
members_data = []
|
members_data = []
|
||||||
for member in application.members:
|
for member in application.members:
|
||||||
@ -122,7 +149,7 @@ def get_members_data(application):
|
|||||||
"user_name": member.user_name,
|
"user_name": member.user_name,
|
||||||
"permission_sets": permission_sets,
|
"permission_sets": permission_sets,
|
||||||
"environment_roles": environment_roles,
|
"environment_roles": environment_roles,
|
||||||
"role_status": member.status.value,
|
"role_status": get_app_role_status(member),
|
||||||
"form": form,
|
"form": form,
|
||||||
"update_invite_form": update_invite_form,
|
"update_invite_form": update_invite_form,
|
||||||
}
|
}
|
||||||
@ -164,6 +191,7 @@ def render_settings_page(application, **kwargs):
|
|||||||
audit_events=audit_events,
|
audit_events=audit_events,
|
||||||
new_member_form=new_member_form,
|
new_member_form=new_member_form,
|
||||||
members=members,
|
members=members,
|
||||||
|
label_info=LABEL_INFO,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
&--default {
|
||||||
|
background-color: $color-gray-dark;
|
||||||
|
}
|
||||||
|
|
||||||
&--info {
|
&--info {
|
||||||
background-color: $color-primary;
|
background-color: $color-primary;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
</base-form>
|
</base-form>
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|
||||||
{%- if member.role_status == 'pending' %}
|
{%- if member.role_status == 'pending' or member.role_status == 'expired' %}
|
||||||
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
||||||
{% call Modal(resend_invite_modal, classes="form-content--app-mem") %}
|
{% call Modal(resend_invite_modal, classes="form-content--app-mem") %}
|
||||||
<div class="modal__form--header">
|
<div class="modal__form--header">
|
||||||
@ -73,7 +73,7 @@
|
|||||||
{% endif -%}
|
{% endif -%}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
|
||||||
{% if user_can(permissions.DELETE_APPLICATION_MEMBER) and member.role_status == 'pending' -%}
|
{% if user_can(permissions.DELETE_APPLICATION_MEMBER) and (member.role_status == 'pending' or member.role_status == 'expired') -%}
|
||||||
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
||||||
{% call Modal(name=revoke_invite_modal) %}
|
{% call Modal(name=revoke_invite_modal) %}
|
||||||
<form method="post" action="{{ url_for('applications.revoke_invite', application_id=application.id, application_role_id=member.role_id) }}">
|
<form method="post" action="{{ url_for('applications.revoke_invite', application_id=application.id, application_role_id=member.role_id) }}">
|
||||||
@ -107,11 +107,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<strong>{{ member.user_name }}</strong>
|
<strong>{{ member.user_name }}</strong>
|
||||||
{% if member.role_status == 'pending' %}
|
<br>
|
||||||
<br>
|
{% if label_info[member.role_status] -%}
|
||||||
{{ Label('envelope', 'invite pending', 'success', classes='label--below') }}
|
{{ Label(classes='label--below', **label_info[member.role_status]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
@ -148,10 +147,10 @@
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
{% call ToggleSection(section_name=section, classes="app-member-menu__toggle") %}
|
{% call ToggleSection(section_name=section, classes="app-member-menu__toggle") %}
|
||||||
<a v-on:click="openModal('{{ perms_modal }}')">
|
<a v-on:click="openModal('{{ perms_modal }}')">
|
||||||
{{ "portfolios.applications.members.menu.edit" | translate }}
|
{{ "portfolios.applications.members.menu.edit" | translate }}
|
||||||
</a>
|
</a>
|
||||||
{% if member.role_status == 'pending' -%}
|
{% if member.role_status == 'pending' or member.role_status == 'expired' -%}
|
||||||
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
||||||
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
||||||
<a v-on:click='openModal("{{ resend_invite_modal }}")'>
|
<a v-on:click='openModal("{{ resend_invite_modal }}")'>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{% from "components/icon.html" import Icon %}
|
{% from "components/icon.html" import Icon %}
|
||||||
|
|
||||||
{% macro Label(icon_name, text, type=None, classes="") -%}
|
{% macro Label(icon, text, type=None, classes="") -%}
|
||||||
|
|
||||||
<span class='label {% if type %}label--{{ type }}{% endif %} {{ classes }}'>
|
<span class='label {% if type %}label--{{ type }}{% endif %} {{ classes }}'>
|
||||||
{{ Icon(icon_name) }} {{ text }}
|
{{ Icon(icon) }} {{ text }}
|
||||||
</span>
|
</span>
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
@ -202,7 +202,7 @@ class EnvironmentFactory(Base):
|
|||||||
for member in with_members:
|
for member in with_members:
|
||||||
user = member.get("user", UserFactory.create())
|
user = member.get("user", UserFactory.create())
|
||||||
application_role = ApplicationRoleFactory.create(
|
application_role = ApplicationRoleFactory.create(
|
||||||
application=environment.application, user=user
|
application=environment.application, user=user, invite=True
|
||||||
)
|
)
|
||||||
role_name = member["role_name"]
|
role_name = member["role_name"]
|
||||||
EnvironmentRoleFactory.create(
|
EnvironmentRoleFactory.create(
|
||||||
@ -233,6 +233,16 @@ class ApplicationRoleFactory(Base):
|
|||||||
status = ApplicationRoleStatus.PENDING
|
status = ApplicationRoleStatus.PENDING
|
||||||
permission_sets = factory.LazyFunction(base_application_permission_sets)
|
permission_sets = factory.LazyFunction(base_application_permission_sets)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _create(cls, model_class, *args, **kwargs):
|
||||||
|
with_invite = kwargs.pop("invite", False)
|
||||||
|
app_role = super()._create(model_class, *args, **kwargs)
|
||||||
|
|
||||||
|
if with_invite:
|
||||||
|
ApplicationInvitationFactory.create(role=app_role)
|
||||||
|
|
||||||
|
return app_role
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentRoleFactory(Base):
|
class EnvironmentRoleFactory(Base):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -10,10 +10,11 @@ from tests.factories import *
|
|||||||
from atst.domain.applications import Applications
|
from atst.domain.applications import Applications
|
||||||
from atst.domain.application_roles import ApplicationRoles
|
from atst.domain.application_roles import ApplicationRoles
|
||||||
from atst.domain.environment_roles import EnvironmentRoles
|
from atst.domain.environment_roles import EnvironmentRoles
|
||||||
|
from atst.domain.invitations import ApplicationInvitations
|
||||||
from atst.domain.common import Paginator
|
from atst.domain.common import Paginator
|
||||||
from atst.domain.permission_sets import PermissionSets
|
from atst.domain.permission_sets import PermissionSets
|
||||||
from atst.models.application_role import Status as ApplicationRoleStatus
|
from atst.models.application_role import Status as ApplicationRoleStatus
|
||||||
from atst.models.environment_role import CSPRole
|
from atst.models.environment_role import CSPRole, EnvironmentRole
|
||||||
from atst.models.permissions import Permissions
|
from atst.models.permissions import Permissions
|
||||||
from atst.forms.application import EditEnvironmentForm
|
from atst.forms.application import EditEnvironmentForm
|
||||||
from atst.forms.application_member import UpdateMemberForm
|
from atst.forms.application_member import UpdateMemberForm
|
||||||
@ -109,12 +110,13 @@ def test_edit_application_environments_obj(app, client, user_session):
|
|||||||
{"env"},
|
{"env"},
|
||||||
)
|
)
|
||||||
env = application.environments[0]
|
env = application.environments[0]
|
||||||
app_role1 = ApplicationRoleFactory.create(application=application)
|
app_role1 = ApplicationRoleFactory.create(application=application, invite=True)
|
||||||
env_role1 = EnvironmentRoleFactory.create(
|
env_role1 = EnvironmentRoleFactory.create(
|
||||||
application_role=app_role1, environment=env, role=CSPRole.BASIC_ACCESS.value
|
application_role=app_role1, environment=env, role=CSPRole.BASIC_ACCESS.value
|
||||||
)
|
)
|
||||||
app_role2 = ApplicationRoleFactory.create(application=application, user=None)
|
app_role2 = ApplicationRoleFactory.create(
|
||||||
invite = ApplicationInvitationFactory.create(role=app_role2)
|
application=application, user=None, invite=True
|
||||||
|
)
|
||||||
env_role2 = EnvironmentRoleFactory.create(
|
env_role2 = EnvironmentRoleFactory.create(
|
||||||
application_role=app_role2, environment=env, role=CSPRole.NETWORK_ADMIN.value
|
application_role=app_role2, environment=env, role=CSPRole.NETWORK_ADMIN.value
|
||||||
)
|
)
|
||||||
@ -165,7 +167,7 @@ def test_get_members_data(app, client, user_session):
|
|||||||
"name": "testing",
|
"name": "testing",
|
||||||
"members": [{"user": user, "role_name": CSPRole.BASIC_ACCESS.value}],
|
"members": [{"user": user, "role_name": CSPRole.BASIC_ACCESS.value}],
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
environment = application.environments[0]
|
environment = application.environments[0]
|
||||||
app_role = ApplicationRoles.get(user_id=user.id, application_id=application.id)
|
app_role = ApplicationRoles.get(user_id=user.id, application_id=application.id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user