frontend for adding new application member
- updated styling - eliminated stray <form> tag in application team template
This commit is contained in:
parent
ade77e6b91
commit
9c84e30172
@ -2,9 +2,10 @@ from wtforms.fields import FormField, FieldList, HiddenField, BooleanField
|
|||||||
|
|
||||||
from .forms import BaseForm
|
from .forms import BaseForm
|
||||||
from .member import NewForm as BaseNewMemberForm
|
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.forms.fields import SelectField
|
||||||
from atst.domain.permission_sets import PermissionSets
|
from atst.domain.permission_sets import PermissionSets
|
||||||
|
from atst.utils.localization import translate
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentForm(BaseForm):
|
class EnvironmentForm(BaseForm):
|
||||||
@ -14,9 +15,15 @@ class EnvironmentForm(BaseForm):
|
|||||||
|
|
||||||
|
|
||||||
class PermissionsForm(BaseForm):
|
class PermissionsForm(BaseForm):
|
||||||
perms_env_mgmt = BooleanField(None, default=False)
|
perms_env_mgmt = BooleanField(
|
||||||
perms_team_mgmt = BooleanField(None, default=False)
|
translate("portfolios.applications.members.new.manage_envs"), default=False
|
||||||
perms_del_env = BooleanField(None, 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
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
|
@ -219,3 +219,6 @@ REQUIRED_DISTRIBUTIONS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
ENV_ROLES = [(role.value, role.value) for role in CSPRole] + [(None, "No access")]
|
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 -")
|
||||||
|
]
|
||||||
|
@ -6,6 +6,7 @@ from atst.domain.environments import Environments
|
|||||||
from atst.domain.applications import Applications
|
from atst.domain.applications import Applications
|
||||||
from atst.domain.authz.decorator import user_can_access_decorator as user_can
|
from atst.domain.authz.decorator import user_can_access_decorator as user_can
|
||||||
from atst.domain.permission_sets import PermissionSets
|
from atst.domain.permission_sets import PermissionSets
|
||||||
|
from atst.domain.exceptions import AlreadyExistsError
|
||||||
from atst.forms.application_member import NewForm as NewMemberForm
|
from atst.forms.application_member import NewForm as NewMemberForm
|
||||||
from atst.models.permissions import Permissions
|
from atst.models.permissions import Permissions
|
||||||
from atst.services.invitation import Invitation as InvitationService
|
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(
|
return render_template(
|
||||||
"portfolios/applications/team.html",
|
"portfolios/applications/team.html",
|
||||||
application=application,
|
application=application,
|
||||||
environment_users=environment_users,
|
environment_users=environment_users,
|
||||||
|
member_form=member_form,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import FormMixin from '../../mixins/form'
|
import FormMixin from '../../mixins/form'
|
||||||
import textinput from '../text_input'
|
import textinput from '../text_input'
|
||||||
import optionsinput from '../options_input'
|
import optionsinput from '../options_input'
|
||||||
|
import checkboxinput from '../checkbox_input'
|
||||||
import Selector from '../selector'
|
import Selector from '../selector'
|
||||||
import Modal from '../../mixins/modal'
|
import Modal from '../../mixins/modal'
|
||||||
import toggler from '../toggler'
|
import toggler from '../toggler'
|
||||||
@ -16,6 +17,7 @@ export default {
|
|||||||
Selector,
|
Selector,
|
||||||
textinput,
|
textinput,
|
||||||
optionsinput,
|
optionsinput,
|
||||||
|
checkboxinput,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
@ -46,6 +46,14 @@
|
|||||||
flex-basis: 16.66%;
|
flex-basis: 16.66%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.form-col--quarter {
|
||||||
|
flex-basis: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.form-col--three-quarters {
|
||||||
|
flex-basis: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
.usa-input {
|
.usa-input {
|
||||||
margin-left: ($gap * 4);
|
margin-left: ($gap * 4);
|
||||||
margin-right: ($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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% macro CheckboxInput(
|
{% macro CheckboxInput(
|
||||||
field,
|
field,
|
||||||
label=field.label | striptags,
|
label=field.label,
|
||||||
inline=False,
|
inline=False,
|
||||||
classes="") -%}
|
classes="") -%}
|
||||||
<checkboxinput name='{{ field.name }}' inline-template key='{{ field.name }}'>
|
<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 %}">
|
<fieldset data-ally-disabled="true" v-on:change="onInput" class="usa-input__choices {% if inline %}usa-input__choices--inline{% endif %}">
|
||||||
<legend>
|
<legend>
|
||||||
{{ field() }}
|
{{ field() }}
|
||||||
<label for={{field.name}}>
|
{{ label | safe }}
|
||||||
{{ label }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
{% if field.description %}
|
{% if field.description %}
|
||||||
<span class='usa-input__help'>{{ field.description | safe }}</span>
|
<span class='usa-input__help'>{{ field.description | safe }}</span>
|
||||||
|
104
templates/fragments/applications/add_new_application_member.html
Normal file
104
templates/fragments/applications/add_new_application_member.html
Normal 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",
|
||||||
|
) }}
|
@ -28,7 +28,6 @@
|
|||||||
{% if g.matchesPath("application-members") %}
|
{% if g.matchesPath("application-members") %}
|
||||||
{% include "fragments/flash.html" %}
|
{% include "fragments/flash.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form>
|
|
||||||
<header>
|
<header>
|
||||||
<div class="responsive-table-wrapper__header">
|
<div class="responsive-table-wrapper__header">
|
||||||
<div class="responsive-table-wrapper__title">
|
<div class="responsive-table-wrapper__title">
|
||||||
@ -115,6 +114,9 @@
|
|||||||
|
|
||||||
<div class="members-table-footer">
|
<div class="members-table-footer">
|
||||||
<div class="action-group save">
|
<div class="action-group save">
|
||||||
|
{% if user_can(permissions.CREATE_APPLICATION_MEMBER) %}
|
||||||
|
{% include "fragments/applications/add_new_application_member.html" %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -35,6 +35,9 @@ common:
|
|||||||
save_and_continue: Save & continue
|
save_and_continue: Save & continue
|
||||||
show: Show
|
show: Show
|
||||||
sign: Sign
|
sign: Sign
|
||||||
|
resource_names:
|
||||||
|
environments: Environments
|
||||||
|
choose_role: Choose a role
|
||||||
components:
|
components:
|
||||||
modal:
|
modal:
|
||||||
close: Close
|
close: Close
|
||||||
@ -434,6 +437,14 @@ portfolios:
|
|||||||
user: User
|
user: User
|
||||||
team_text: Team
|
team_text: Team
|
||||||
update_button_text: Save
|
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:
|
index:
|
||||||
empty:
|
empty:
|
||||||
start_button: Start a new JEDI portfolio
|
start_button: Start a new JEDI portfolio
|
||||||
|
Loading…
x
Reference in New Issue
Block a user