frontend for adding new application member

- updated styling
- eliminated stray <form> tag in application team template
This commit is contained in:
dandds 2019-04-24 13:43:38 -04:00
parent ade77e6b91
commit 9c84e30172
10 changed files with 266 additions and 89 deletions

View File

@ -2,9 +2,10 @@ from wtforms.fields import FormField, FieldList, HiddenField, BooleanField
from .forms import BaseForm
from .member import NewForm as BaseNewMemberForm
from .data import ENV_ROLES
from .data import FORMATTED_ENV_ROLES as ENV_ROLES
from atst.forms.fields import SelectField
from atst.domain.permission_sets import PermissionSets
from atst.utils.localization import translate
class EnvironmentForm(BaseForm):
@ -14,9 +15,15 @@ class EnvironmentForm(BaseForm):
class PermissionsForm(BaseForm):
perms_env_mgmt = BooleanField(None, default=False)
perms_team_mgmt = BooleanField(None, default=False)
perms_del_env = BooleanField(None, default=False)
perms_env_mgmt = BooleanField(
translate("portfolios.applications.members.new.manage_envs"), default=False
)
perms_team_mgmt = BooleanField(
translate("portfolios.applications.members.new.manage_team"), default=False
)
perms_del_env = BooleanField(
translate("portfolios.applications.members.new.delete_envs"), default=False
)
@property
def data(self):

View File

@ -219,3 +219,6 @@ REQUIRED_DISTRIBUTIONS = [
]
ENV_ROLES = [(role.value, role.value) for role in CSPRole] + [(None, "No access")]
FORMATTED_ENV_ROLES = [(role.value, "- {} -".format(role.value)) for role in CSPRole] + [
(None, "- No Access -")
]

View File

@ -6,6 +6,7 @@ from atst.domain.environments import Environments
from atst.domain.applications import Applications
from atst.domain.authz.decorator import user_can_access_decorator as user_can
from atst.domain.permission_sets import PermissionSets
from atst.domain.exceptions import AlreadyExistsError
from atst.forms.application_member import NewForm as NewMemberForm
from atst.models.permissions import Permissions
from atst.services.invitation import Invitation as InvitationService
@ -45,10 +46,17 @@ def team(application_id):
),
}
env_roles = [
{"environment_id": e.id, "environment_name": e.name}
for e in application.environments
]
member_form = NewMemberForm(data={"environment_roles": env_roles})
return render_template(
"portfolios/applications/team.html",
application=application,
environment_users=environment_users,
member_form=member_form,
)

View File

@ -1,6 +1,7 @@
import FormMixin from '../../mixins/form'
import textinput from '../text_input'
import optionsinput from '../options_input'
import checkboxinput from '../checkbox_input'
import Selector from '../selector'
import Modal from '../../mixins/modal'
import toggler from '../toggler'
@ -16,6 +17,7 @@ export default {
Selector,
textinput,
optionsinput,
checkboxinput,
},
props: {

View File

@ -46,6 +46,14 @@
flex-basis: 16.66%;
}
&.form-col--quarter {
flex-basis: 25%;
}
&.form-col--three-quarters {
flex-basis: 75%;
}
.usa-input {
margin-left: ($gap * 4);
margin-right: ($gap * 4);
@ -171,3 +179,11 @@
}
}
.input__inline-fields {
margin: 1rem 0 1rem 0;
&> fieldset.usa-input__choices label {
display: inline;
font-weight: $font-normal;
}
}

View File

@ -59,3 +59,29 @@
}
}
}
.environment-roles-new {
margin-top: 5*$gap;
margin-bottom: 8*$gap;
.usa-input {
margin: 2rem 0 2rem 0;
.usa-input__title-inline {
line-height: $hit-area;
}
legend {
font-size: $lead-font-size;
padding: 0;
}
}
.form-row {
margin: 0;
}
}
.environment-roles-new__head {
font-weight: $font-bold;
}

View File

@ -1,6 +1,6 @@
{% macro CheckboxInput(
field,
label=field.label | striptags,
label=field.label,
inline=False,
classes="") -%}
<checkboxinput name='{{ field.name }}' inline-template key='{{ field.name }}'>
@ -9,9 +9,7 @@
<fieldset data-ally-disabled="true" v-on:change="onInput" class="usa-input__choices {% if inline %}usa-input__choices--inline{% endif %}">
<legend>
{{ field() }}
<label for={{field.name}}>
{{ label }}
</label>
{{ label | safe }}
{% if field.description %}
<span class='usa-input__help'>{{ field.description | safe }}</span>

View File

@ -0,0 +1,104 @@
{% from "components/icon.html" import Icon %}
{% from "components/text_input.html" import TextInput %}
{% from "components/checkbox_input.html" import CheckboxInput %}
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
{% set step_one %}
<div class="modal__form--header">
<h1>Invite new portfolio member</h1>
</div>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.user_data.first_name, validation='requiredField') }}
</div>
<div class='form-col form-col--half'>
{{ TextInput(member_form.user_data.last_name, validation='requiredField') }}
</div>
</div>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.user_data.email, validation='email') }}
</div>
<div class='form-col form-col--half'>
{{ TextInput(member_form.user_data.phone_number, validation='usPhone', optional=True) }}
</div>
</div>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.user_data.dod_id, validation='dodId') }}
</div>
<div class='form-col form-col--half'>
</div>
</div>
<div class='action-group'>
<input
type='button'
v-on:click="next()"
v-bind:disabled="invalid"
class='action-group__action usa-button'
value='Next'>
<a class='action-group__action icon-link icon-link--default' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
</div>
{% endset %}
{% set step_two %}
<div class="modal__form--padded">
<div class="modal__form--header">
<h1>{{ "portfolios.applications.members.new.assign_roles" | translate }}</h1>
<a class='icon-link'>
{{ Icon('info') }}
{{ "portfolios.applications.members.new.learn_more" | translate }}
</a>
<div class="environment-roles-new">
<div class="form-row">
<div class="form-col form-col--quarter">
<span class="environment-roles-new__head">
{{ "common.resource_names.environments" | translate }}:
</span>
</div>
<div class="form-col form-col--three-quarters">
<span class="environment-roles-new__head">
{{ "common.choose_role" | translate }}:
</span>
</div>
</div>
{% for environment_data in member_form.environment_roles %}
<div class="usa-input">
<fieldset data-ally-disabled="true" class="form-row usa-input__choices">
<div class="form-col form-col--quarter">
<legend>
<div class="usa-input__title-inline">
{{ environment_data.environment_name.data }}
</div>
</legend>
</div>
<div class="form-col form-col--three-quarters">
{{ environment_data.role() }}
</div>
</fieldset>
</div>
{{ environment_data.environment_id() }}
{% endfor %}
</div>
<h1>{{ "portfolios.applications.members.new.manage_perms" | translate({"application_name": application.name}) }}</h1>
{{ CheckboxInput(member_form.permission_sets.perms_env_mgmt, classes="input__inline-fields") }}
{{ CheckboxInput(member_form.permission_sets.perms_del_env, classes="input__inline-fields") }}
{{ CheckboxInput(member_form.permission_sets.perms_team_mgmt, classes="input__inline-fields") }}
</div>
<div class='action-group'>
<input
type="submit"
class='action-group__action usa-button'
form="add-app-mem"
value='Invite member'>
<a class='action-group__action icon-link icon-link--default' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
</div>
</div>
{% endset %}
{{ MultiStepModalForm(
'add-app-mem',
member_form,
url_for("applications.create_member", application_id=application.id),
[step_one, step_two],
button_text=("portfolios.admin.add_new_member" | translate),
button_icon="plus-circle-solid",
) }}

View File

@ -28,93 +28,95 @@
{% if g.matchesPath("application-members") %}
{% include "fragments/flash.html" %}
{% endif %}
<form>
<header>
<div class="responsive-table-wrapper__header">
<div class="responsive-table-wrapper__title">
<div class="h3">
{{ "portfolios.applications.team_settings.section.title" | translate({ "application_name": application.name }) }}
</div>
<header>
<div class="responsive-table-wrapper__header">
<div class="responsive-table-wrapper__title">
<div class="h3">
{{ "portfolios.applications.team_settings.section.title" | translate({ "application_name": application.name }) }}
</div>
<a class='icon-link'>
{{ Icon('info') }}
{{ "portfolios.admin.settings_info" | translate }}
</a>
</div>
</header>
<div class="accordion-table accordion-table-list">
<div class="accordion-table__head">
<span>
<span>
{{ "portfolios.applications.team_settings.user" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.delete_access" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.environment_management" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.team_management" | translate }}
</span>
</span>
<span class="icon-link" />
</div>
<ul class="accordion-table__items">
{% for member in application.members %}
{% set user = member.user %}
{% set user_info = environment_users[user.id] %}
{% set user_permissions = user_info["permissions"] %}
<toggler inline-template>
<li class="accordion-table__item">
<div class="accordion-table__item-content">
<span>
{{ name }}
<span>{{ user.full_name }}</span>
<span>{{ user_permissions["delete_access"] }}</span>
<span>{{ user_permissions["environment_management"] }}</span>
<span>{{ user_permissions["team_management"] }}</span>
</span>
<span class="icon-link icon-link--large accordion-table__item__toggler">
{% set open_html %}
{{ "common.show" | translate }} {{ "portfolios.applications.team_settings.environments" | translate }} ({{ user_info['environments'] | length }})
{% endset %}
{% set close_html %}
{{ "common.hide" | translate }} {{ "portfolios.applications.team_settings.environments" | translate }} ({{ user_info['environments'] | length }})
{% endset %}
{{
ToggleButton(
open_html=open_html,
close_html=close_html,
section_name="environments"
)
}}
</span>
</div>
{% call ToggleSection(section_name="environments") %}
<ul>
{% for environment in user_info["environments"] %}
<li>
<div class="accordion-table__item-content">
{{ environment.name }}
</div>
</li>
{% endfor %}
</ul>
{% endcall %}
</li>
</toggler>
{% endfor %}
</ul>
<a class='icon-link'>
{{ Icon('info') }}
{{ "portfolios.admin.settings_info" | translate }}
</a>
</div>
</header>
<div class="accordion-table accordion-table-list">
<div class="accordion-table__head">
<span>
<span>
{{ "portfolios.applications.team_settings.user" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.delete_access" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.environment_management" | translate }}
</span>
<span>
{{ "portfolios.applications.team_settings.section.table.team_management" | translate }}
</span>
</span>
<span class="icon-link" />
</div>
<ul class="accordion-table__items">
{% for member in application.members %}
{% set user = member.user %}
{% set user_info = environment_users[user.id] %}
{% set user_permissions = user_info["permissions"] %}
<toggler inline-template>
<li class="accordion-table__item">
<div class="accordion-table__item-content">
<span>
{{ name }}
<span>{{ user.full_name }}</span>
<span>{{ user_permissions["delete_access"] }}</span>
<span>{{ user_permissions["environment_management"] }}</span>
<span>{{ user_permissions["team_management"] }}</span>
</span>
<span class="icon-link icon-link--large accordion-table__item__toggler">
{% set open_html %}
{{ "common.show" | translate }} {{ "portfolios.applications.team_settings.environments" | translate }} ({{ user_info['environments'] | length }})
{% endset %}
{% set close_html %}
{{ "common.hide" | translate }} {{ "portfolios.applications.team_settings.environments" | translate }} ({{ user_info['environments'] | length }})
{% endset %}
{{
ToggleButton(
open_html=open_html,
close_html=close_html,
section_name="environments"
)
}}
</span>
</div>
{% call ToggleSection(section_name="environments") %}
<ul>
{% for environment in user_info["environments"] %}
<li>
<div class="accordion-table__item-content">
{{ environment.name }}
</div>
</li>
{% endfor %}
</ul>
{% endcall %}
</li>
</toggler>
{% endfor %}
</ul>
</div>
<div class="members-table-footer">
<div class="action-group save">
{% if user_can(permissions.CREATE_APPLICATION_MEMBER) %}
{% include "fragments/applications/add_new_application_member.html" %}
{% endif %}
</div>
</div>
</form>

View File

@ -35,6 +35,9 @@ common:
save_and_continue: Save & continue
show: Show
sign: Sign
resource_names:
environments: Environments
choose_role: Choose a role
components:
modal:
close: Close
@ -434,6 +437,14 @@ portfolios:
user: User
team_text: Team
update_button_text: Save
members:
new:
assign_roles: Assign Member Environments and Roles
learn_more: Learn more about these roles
manage_perms: 'Manage permissions for {application_name}'
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.'
index:
empty:
start_button: Start a new JEDI portfolio