Merge pull request #1161 from dod-ccpo/app-members-edit-menu
App members edit menu
This commit is contained in:
commit
eb617ef68a
1
static/icons/ellipsis.svg
Normal file
1
static/icons/ellipsis.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="ellipsis-h" class="svg-inline--fa fa-ellipsis-h fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"></path></svg>
|
After Width: | Height: | Size: 457 B |
@ -94,6 +94,10 @@
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid $color-blue-light;
|
||||
}
|
||||
|
||||
&--active {
|
||||
background-color: $color-gray-lightest;
|
||||
}
|
||||
}
|
||||
|
||||
&-toggle-content {
|
||||
|
@ -149,6 +149,7 @@
|
||||
.member-list {
|
||||
.responsive-table-wrapper {
|
||||
margin-bottom: 0;
|
||||
overflow: visible;
|
||||
|
||||
table.atat-table {
|
||||
table-layout: fixed;
|
||||
@ -213,12 +214,13 @@
|
||||
}
|
||||
|
||||
.env_role {
|
||||
width: 50%;
|
||||
}
|
||||
&--th {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.form-col--two-thirds {
|
||||
width: 66.66%;
|
||||
flex-basis: unset;
|
||||
&--td {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
@ -236,6 +238,47 @@
|
||||
.env-role__role {
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
margin-right: $gap * 6;
|
||||
}
|
||||
}
|
||||
|
||||
.app-member-menu {
|
||||
position: absolute;
|
||||
top: $gap;
|
||||
right: $gap * 2;
|
||||
|
||||
.accordion-table__item__toggler {
|
||||
padding: $gap / 3;
|
||||
border: 1px solid $color-gray-lighter;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
margin: $gap / 2;
|
||||
}
|
||||
}
|
||||
|
||||
&__toggle {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 30px;
|
||||
background-color: $color-white;
|
||||
border: 1px solid $color-gray-light;
|
||||
z-index: 1;
|
||||
margin-top: 0;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: $gap;
|
||||
border-bottom: 1px solid $color-gray-lighter;
|
||||
text-decoration: none;
|
||||
color: $color-black;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ table.atat-table {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
background: $color-white;
|
||||
|
||||
th,
|
||||
td {
|
||||
&.table-cell {
|
||||
@ -46,7 +48,7 @@ table.atat-table {
|
||||
tr {
|
||||
th,
|
||||
td {
|
||||
background-color: $color-white;
|
||||
background: none;
|
||||
margin: 0;
|
||||
padding: $gap * 2;
|
||||
border: 1px solid $color-gray-lighter;
|
||||
|
@ -118,69 +118,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.environment-role {
|
||||
padding: ($gap * 2) 0;
|
||||
|
||||
h4 {
|
||||
margin-bottom: $gap / 4;
|
||||
}
|
||||
|
||||
&__users {
|
||||
background-color: $color-gray-lightest;
|
||||
padding: ($gap * 1.2) ($gap * 0.6);
|
||||
font-size: $small-font-size;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.environment-role__user {
|
||||
background-color: $color-white;
|
||||
border-radius: 0.5rem;
|
||||
padding: ($gap / 2) $gap;
|
||||
border: solid 2px $color-blue;
|
||||
margin: $gap;
|
||||
white-space: nowrap;
|
||||
width: 20rem;
|
||||
position: relative;
|
||||
height: 3.6rem;
|
||||
|
||||
&-field {
|
||||
position: absolute;
|
||||
background-color: $color-white;
|
||||
margin-top: $gap * 2;
|
||||
padding: $gap;
|
||||
left: -0.1rem;
|
||||
border: solid 1px $color-gray-light;
|
||||
width: 20rem;
|
||||
z-index: 3;
|
||||
|
||||
.usa-input {
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
background-color: $color-white;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.unassigned {
|
||||
border: solid 1px $color-gray-light;
|
||||
}
|
||||
|
||||
.icon-link {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.environment-role__no-user {
|
||||
margin: $gap;
|
||||
padding: ($gap / 2) $gap;
|
||||
font-weight: $font-normal;
|
||||
height: 3.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.environment-name--gray {
|
||||
font-weight: $font-normal;
|
||||
color: $color-gray-medium;
|
||||
|
@ -6,6 +6,7 @@
|
||||
{% from "components/modal.html" import Modal %}
|
||||
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
|
||||
{% from "components/save_button.html" import SaveButton %}
|
||||
{% from "components/toggle_list.html" import ToggleButton, ToggleSection %}
|
||||
|
||||
{% macro MemberManagementTemplate(
|
||||
application,
|
||||
@ -54,7 +55,7 @@
|
||||
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
||||
{% call Modal(resend_invite_modal, classes="form-content--app-mem") %}
|
||||
<div class="modal__form--header">
|
||||
<h1>Verify Member Information</h1>
|
||||
<h1>{{ "portfolios.applications.members.new.verify" | translate }}</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<base-form inline-template :enable-save="true">
|
||||
@ -90,67 +91,84 @@
|
||||
|
||||
<section class="member-list application-list">
|
||||
<div class='responsive-table-wrapper'>
|
||||
<table class="atat-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Application Permissions</th>
|
||||
<th class="env_role">Environment Access</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members %}
|
||||
{% set modal_name = "edit_member-{}".format(loop.index) %}
|
||||
<toggler inline-template>
|
||||
<table class="atat-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ member.user_name }}</strong>
|
||||
<a class="icon-link" v-on:click="openModal('{{ modal_name }}')">
|
||||
{{ Icon('edit') }}
|
||||
</a>
|
||||
<br>
|
||||
{% if member.role_status == 'pending' %}
|
||||
{{ Label('envelope', 'invite pending', 'success', classes='label--below') }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% for perm, value in member.permission_sets.items() %}
|
||||
<div>
|
||||
{{ ("portfolios.applications.members.{}.{}".format(perm, value)) | translate }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-row">
|
||||
<div class="form-col form-col--two-thirds">
|
||||
{% for env in member.environment_roles %}
|
||||
<div class="row">
|
||||
<span class="env-role__environment">
|
||||
{{ env.environment_name }}
|
||||
</span>
|
||||
<span class="env-role__role">
|
||||
: {{ env.role }}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="form-col form-col--one-third">
|
||||
{% if member.role_status == 'pending' -%}
|
||||
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
||||
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
||||
<a v-on:click='openModal("{{ resend_invite_modal }}")'>Resend Invite</a><br>
|
||||
{% if user_can(permissions.DELETE_APPLICATION_MEMBER) -%}
|
||||
<a v-on:click='openModal("{{ revoke_invite_modal }}")'>{{ 'invites.revoke' | translate }}</a>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<th>{{ "common.name" | translate }}</th>
|
||||
<th>{{ "portfolios.applications.members.form.app_perms.title" | translate }}</th>
|
||||
<th class="env_role--th">{{ 'portfolios.applications.members.form.env_access.table_header' | translate }}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members %}
|
||||
{% set perms_modal = "edit_member-{}".format(loop.index) %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ member.user_name }}</strong>
|
||||
{% if member.role_status == 'pending' %}
|
||||
<br>
|
||||
{{ Label('envelope', 'invite pending', 'success', classes='label--below') }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% for perm, value in member.permission_sets.items() %}
|
||||
<div>
|
||||
{{ ("portfolios.applications.members.{}.{}".format(perm, value)) | translate }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="env_role--td">
|
||||
{% for env in member.environment_roles %}
|
||||
<div class="row">
|
||||
<span class="env-role__environment">
|
||||
{{ env.environment_name }}
|
||||
</span>
|
||||
<span class="env-role__role">
|
||||
: {{ env.role }}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="app-member-menu">
|
||||
{% set toggle_button -%}
|
||||
{{ Icon('ellipsis')}}
|
||||
{%- endset %}
|
||||
{% set section = "app_member_edit-{}".format(member.role_id) %}
|
||||
|
||||
{{
|
||||
ToggleButton(
|
||||
open_html=toggle_button,
|
||||
close_html=toggle_button,
|
||||
section_name=section,
|
||||
active_style=True
|
||||
)
|
||||
}}
|
||||
{% call ToggleSection(section_name=section, classes="app-member-menu__toggle") %}
|
||||
{% if user_can(permissions.EDIT_APPLICATION_MEMBER) -%}
|
||||
<a v-on:click="openModal('{{ perms_modal }}')">
|
||||
{{ "portfolios.applications.members.menu.edit" | translate }}
|
||||
</a>
|
||||
{%- endif %}
|
||||
{% if member.role_status == 'pending' -%}
|
||||
{% set revoke_invite_modal = "revoke_invite_{}".format(member.role_id) %}
|
||||
{% set resend_invite_modal = "resend_invite-{}".format(member.role_id) %}
|
||||
<a v-on:click='openModal("{{ resend_invite_modal }}")'>
|
||||
{{ "portfolios.applications.members.menu.resend" | translate }}
|
||||
</a>
|
||||
{% if user_can(permissions.DELETE_APPLICATION_MEMBER) -%}
|
||||
<a v-on:click='openModal("{{ revoke_invite_modal }}")'>{{ 'invites.revoke' | translate }}</a>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{% endcall %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</toggler>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
@ -1,9 +1,9 @@
|
||||
{% macro ToggleButton(action, open_html, close_html, section_name, classes="") %}
|
||||
<span v-on:click="toggleSection('{{ section_name }}')" class="accordion-table__item__toggler {{ classes }}">
|
||||
<span v-if="selectedSection === '{{ section_name }}'">
|
||||
{% macro ToggleButton(action, open_html, close_html, section_name, classes="", active_style=False) %}
|
||||
<span v-on:click="toggleSection('{{ section_name }}')">
|
||||
<span v-if="selectedSection === '{{ section_name }}'" class="accordion-table__item__toggler {{ classes }}{% if active_style -%} accordion-table__item__toggler--active{%- endif %}">
|
||||
{{ close_html }}
|
||||
</span>
|
||||
<span v-else>
|
||||
<span v-else class="accordion-table__item__toggler {{ classes }}">
|
||||
{{ open_html }}
|
||||
</span>
|
||||
</span>
|
||||
|
@ -107,7 +107,7 @@ email:
|
||||
environment_ready: JEDI cloud environment ready
|
||||
flash:
|
||||
application:
|
||||
created:
|
||||
created:
|
||||
title: Application Saved
|
||||
message: '{application_name} has been successfully created. You may continue on to provision environments and assign team members now, or come back and complete these tasks at a later time.'
|
||||
updated: 'You have successfully updated the {application_name} application.'
|
||||
@ -121,7 +121,7 @@ flash:
|
||||
new_ppoc_message: 'You have successfully added {ppoc_name} as the primary point of contact. You are no longer the PPoC.'
|
||||
new_ppoc_title: Primary point of contact updated
|
||||
success: Success!
|
||||
new_application_member:
|
||||
new_application_member:
|
||||
title: "{user_name}'s invitation has been sent"
|
||||
message: "{user_name}'s access to this Application is pending until they sign in for the first time."
|
||||
updated_application_team_settings: 'You have updated the {application_name} team settings.'
|
||||
@ -342,7 +342,7 @@ portfolios:
|
||||
</p>
|
||||
</div>
|
||||
step_2_header: Add Environments to {application_name}
|
||||
step_2_description: Development, Testing, Staging, and Production environments are included by default. However, you can add, edit, and delete environments based on the needs of your Application.
|
||||
step_2_description: Development, Testing, Staging, and Production environments are included by default. However, you can add, edit, and delete environments based on the needs of your Application.
|
||||
step_2_button_text: "Next: Add Members"
|
||||
step_3_header: Add Members to {application_name}
|
||||
step_3_description: "To proceed, you will need each member's email address and DOD ID. Within this section, you will also assign Application-level permissions and environment-level roles for each member."
|
||||
@ -401,14 +401,18 @@ portfolios:
|
||||
del_env:
|
||||
label: Delete Application
|
||||
description: Delete this application.
|
||||
env_access:
|
||||
env_access:
|
||||
title: Environment Roles
|
||||
table_header: Environment Access
|
||||
description: Additional role controls are available in the CSP console. <a href="#"> Learn More </a>
|
||||
next_button: "Next: Permissions"
|
||||
app_perms:
|
||||
title: Application Permissions
|
||||
description: Application permissions allow users to provision and modify applications and teams. <a href="#"> Learn More </a>
|
||||
add_member: Add Member
|
||||
menu:
|
||||
edit: Edit Roles and Permissions
|
||||
resend: Resend Invite
|
||||
new:
|
||||
assign_roles: Assign Member Environments and Roles
|
||||
learn_more: Learn more about these roles
|
||||
@ -416,6 +420,7 @@ portfolios:
|
||||
manage_envs: 'Allow member to <strong>add</strong> and <strong>rename environments</strong> within the application.'
|
||||
delete_envs: 'Allow member to <strong>delete environments</strong> within the application.'
|
||||
manage_team: 'Allow member to <strong>add, update,</strong> and <strong>remove members</strong> from the application team.'
|
||||
verify: Verify Member Information
|
||||
perms_team_mgmt:
|
||||
'False': View Team
|
||||
'True': Edit Team
|
||||
|
Loading…
x
Reference in New Issue
Block a user