Portfolio manager invite updates:
- Update the form to use BooleanFields for the permissions and make the form more similar to the Application Members form - Use MemberFormTemplate macro in the portfolio settings template - fix tests affected by the form changes
This commit is contained in:
parent
4d2a175136
commit
79b2773852
@ -75,10 +75,10 @@ class Portfolios(object):
|
|||||||
permission_sets = PortfolioRoles._permission_sets_for_names(
|
permission_sets = PortfolioRoles._permission_sets_for_names(
|
||||||
member_data.get("permission_sets", [])
|
member_data.get("permission_sets", [])
|
||||||
)
|
)
|
||||||
role = PortfolioRole(portfolio_id=portfolio.id, permission_sets=permission_sets)
|
role = PortfolioRole(portfolio=portfolio, permission_sets=permission_sets)
|
||||||
|
|
||||||
invitation = PortfolioInvitations.create(
|
invitation = PortfolioInvitations.create(
|
||||||
inviter=inviter, role=role, member_data=member_data
|
inviter=inviter, role=role, member_data=member_data["user_data"]
|
||||||
)
|
)
|
||||||
|
|
||||||
PortfoliosQuery.add_and_commit(role)
|
PortfoliosQuery.add_and_commit(role)
|
||||||
|
@ -1,76 +1,59 @@
|
|||||||
from wtforms.validators import Required
|
from wtforms.validators import Required
|
||||||
from wtforms.fields import StringField, FormField, FieldList, HiddenField
|
from wtforms.fields import BooleanField, FormField
|
||||||
|
|
||||||
from atst.domain.permission_sets import PermissionSets
|
|
||||||
from .forms import BaseForm
|
from .forms import BaseForm
|
||||||
from .member import NewForm as BaseNewMemberForm
|
from .member import NewForm as BaseNewMemberForm
|
||||||
|
from atst.domain.permission_sets import PermissionSets
|
||||||
from atst.forms.fields import SelectField
|
from atst.forms.fields import SelectField
|
||||||
from atst.utils.localization import translate
|
from atst.utils.localization import translate
|
||||||
|
|
||||||
|
|
||||||
class PermissionsForm(BaseForm):
|
class PermissionsForm(BaseForm):
|
||||||
member_name = StringField()
|
perms_app_mgmt = BooleanField(
|
||||||
member_id = HiddenField()
|
|
||||||
perms_app_mgmt = SelectField(
|
|
||||||
translate("forms.new_member.app_mgmt"),
|
translate("forms.new_member.app_mgmt"),
|
||||||
choices=[
|
default=False,
|
||||||
(
|
description="Add, remove and edit applications in this Portfolio.",
|
||||||
PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT,
|
|
||||||
translate("common.view"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT,
|
|
||||||
translate("common.edit"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
perms_funding = SelectField(
|
perms_funding = BooleanField(
|
||||||
translate("forms.new_member.funding"),
|
translate("forms.new_member.funding"),
|
||||||
choices=[
|
default=False,
|
||||||
(PermissionSets.VIEW_PORTFOLIO_FUNDING, translate("common.view")),
|
description="Add and Modify Task Orders to fund this Portfolio.",
|
||||||
(PermissionSets.EDIT_PORTFOLIO_FUNDING, translate("common.edit")),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
perms_reporting = SelectField(
|
perms_reporting = BooleanField(
|
||||||
translate("forms.new_member.reporting"),
|
translate("forms.new_member.reporting"),
|
||||||
choices=[
|
default=False,
|
||||||
(PermissionSets.VIEW_PORTFOLIO_REPORTS, translate("common.view")),
|
description="View and export reports about this Portfolio's funding.",
|
||||||
(PermissionSets.EDIT_PORTFOLIO_REPORTS, translate("common.edit")),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
perms_portfolio_mgmt = SelectField(
|
perms_portfolio_mgmt = BooleanField(
|
||||||
translate("forms.new_member.portfolio_mgmt"),
|
translate("forms.new_member.portfolio_mgmt"),
|
||||||
choices=[
|
default=False,
|
||||||
(PermissionSets.VIEW_PORTFOLIO_ADMIN, translate("common.view")),
|
description="Edit this Portfolio's settings.",
|
||||||
(PermissionSets.EDIT_PORTFOLIO_ADMIN, translate("common.edit")),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
_data = super().data
|
_data = super().data
|
||||||
_data["permission_sets"] = []
|
_data.pop("csrf_token", None)
|
||||||
for field in _data:
|
perm_sets = []
|
||||||
if "perms" in field:
|
|
||||||
_data["permission_sets"].append(_data[field])
|
|
||||||
|
|
||||||
|
if _data["perms_app_mgmt"]:
|
||||||
|
perm_sets.append(PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT)
|
||||||
|
|
||||||
|
if _data["perms_funding"]:
|
||||||
|
perm_sets.append(PermissionSets.EDIT_PORTFOLIO_FUNDING)
|
||||||
|
|
||||||
|
if _data["perms_reporting"]:
|
||||||
|
perm_sets.append(PermissionSets.EDIT_PORTFOLIO_REPORTS)
|
||||||
|
|
||||||
|
if _data["perms_portfolio_mgmt"]:
|
||||||
|
perm_sets.append(PermissionSets.EDIT_PORTFOLIO_ADMIN)
|
||||||
|
|
||||||
|
_data["permission_sets"] = perm_sets
|
||||||
return _data
|
return _data
|
||||||
|
|
||||||
|
|
||||||
class MembersPermissionsForm(BaseForm):
|
class NewForm(PermissionsForm):
|
||||||
members_permissions = FieldList(FormField(PermissionsForm))
|
|
||||||
|
|
||||||
|
|
||||||
class NewForm(BaseForm):
|
|
||||||
user_data = FormField(BaseNewMemberForm)
|
user_data = FormField(BaseNewMemberForm)
|
||||||
permission_sets = FormField(PermissionsForm)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def update_data(self):
|
|
||||||
return {
|
|
||||||
"permission_sets": self.data.get("permission_sets").get("permission_sets"),
|
|
||||||
**self.data.get("user_data"),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AssignPPOCForm(PermissionsForm):
|
class AssignPPOCForm(PermissionsForm):
|
||||||
|
@ -77,7 +77,7 @@ def render_admin_page(portfolio, form=None):
|
|||||||
portfolio_form=portfolio_form,
|
portfolio_form=portfolio_form,
|
||||||
ppoc=ppoc,
|
ppoc=ppoc,
|
||||||
members=filter_members_data(member_list),
|
members=filter_members_data(member_list),
|
||||||
member_form=member_forms.NewForm(),
|
new_manager_form=member_forms.NewForm(),
|
||||||
assign_ppoc_form=assign_ppoc_form,
|
assign_ppoc_form=assign_ppoc_form,
|
||||||
portfolio=portfolio,
|
portfolio=portfolio,
|
||||||
audit_events=audit_events,
|
audit_events=audit_events,
|
||||||
|
@ -79,7 +79,7 @@ def invite_member(portfolio_id):
|
|||||||
|
|
||||||
if form.validate():
|
if form.validate():
|
||||||
try:
|
try:
|
||||||
invite = Portfolios.invite(portfolio, g.current_user, form.update_data)
|
invite = Portfolios.invite(portfolio, g.current_user, form.data)
|
||||||
send_portfolio_invitation(
|
send_portfolio_invitation(
|
||||||
invitee_email=invite.email,
|
invitee_email=invite.email,
|
||||||
inviter_name=g.current_user.full_name,
|
inviter_name=g.current_user.full_name,
|
||||||
|
@ -185,6 +185,7 @@
|
|||||||
modal=new_member_modal_name,
|
modal=new_member_modal_name,
|
||||||
),
|
),
|
||||||
member_form.SubmitStep(
|
member_form.SubmitStep(
|
||||||
|
name=new_member_modal_name,
|
||||||
form=member_fields.PermsFields(form=new_member_form, new=True),
|
form=member_fields.PermsFields(form=new_member_form, new=True),
|
||||||
submit_text="portfolios.applications.members.form.add_member"|translate,
|
submit_text="portfolios.applications.members.form.add_member"|translate,
|
||||||
modal=new_member_modal_name,
|
modal=new_member_modal_name,
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro SubmitStep(
|
{% macro SubmitStep(
|
||||||
|
name=name,
|
||||||
title=None,
|
title=None,
|
||||||
form=form,
|
form=form,
|
||||||
submit_text=submit_text,
|
submit_text=submit_text,
|
||||||
@ -51,7 +52,7 @@
|
|||||||
<input
|
<input
|
||||||
type="submit"
|
type="submit"
|
||||||
class='action-group__action usa-button'
|
class='action-group__action usa-button'
|
||||||
form="add-app-mem"
|
form="{{ name }}"
|
||||||
v-bind:disabled="!canSave"
|
v-bind:disabled="!canSave"
|
||||||
value='{{ submit_text }}'>
|
value='{{ submit_text }}'>
|
||||||
{% endset %}
|
{% endset %}
|
||||||
|
@ -1,79 +1,41 @@
|
|||||||
|
{% from "components/checkbox_input.html" import CheckboxInput %}
|
||||||
{% from "components/icon.html" import Icon %}
|
{% from "components/icon.html" import Icon %}
|
||||||
|
{% from "components/phone_input.html" import PhoneInput %}
|
||||||
{% from "components/text_input.html" import TextInput %}
|
{% from "components/text_input.html" import TextInput %}
|
||||||
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
|
|
||||||
|
|
||||||
{% macro SimpleOptionsInput(field) %}
|
{% macro PermsFields(form, member_role_id=None) %}
|
||||||
<div class="usa-input">
|
<h2>Assign member permissions</h2>
|
||||||
<fieldset data-ally-disabled="true" class="usa-input__choices">
|
|
||||||
<legend>
|
|
||||||
<div class="usa-input__title-inline">
|
|
||||||
{{ field.label | striptags}}
|
|
||||||
</div>
|
|
||||||
</legend>
|
|
||||||
{{ field() }}
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% set step_one %}
|
|
||||||
<hr class="full-width">
|
|
||||||
<h1>Invite new portfolio member</h1>
|
|
||||||
<div class='form-row'>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
{{ TextInput(member_form.user_data.first_name, validation='requiredField', optional=False) }}
|
|
||||||
</div>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
{{ TextInput(member_form.user_data.last_name, validation='requiredField', optional=False) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='form-row'>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
{{ TextInput(member_form.user_data.email, validation='email', optional=False) }}
|
|
||||||
</div>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
{{ TextInput(member_form.user_data.phone_number, validation='usPhone') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='form-row'>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
{{ TextInput(member_form.user_data.dod_id, validation='dodId', optional=False) }}
|
|
||||||
</div>
|
|
||||||
<div class='form-col form-col--half'>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='action-group'>
|
|
||||||
<input
|
|
||||||
type='button'
|
|
||||||
v-on:click="next()"
|
|
||||||
v-bind:disabled="!canSave"
|
|
||||||
class='action-group__action usa-button usa-button-primary'
|
|
||||||
value='Next'>
|
|
||||||
<a class='action-group__action' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
|
|
||||||
</div>
|
|
||||||
{% endset %}
|
|
||||||
{% set step_two %}
|
|
||||||
<hr class="full-width">
|
|
||||||
<h1>Assign member permissions</h1>
|
|
||||||
<a class='icon-link'>
|
<a class='icon-link'>
|
||||||
{{ Icon('info') }}
|
{{ Icon('info') }}
|
||||||
{{ "portfolios.admin.permissions_info" | translate }}
|
{{ "portfolios.admin.permissions_info" | translate }}
|
||||||
</a>
|
</a>
|
||||||
{{ SimpleOptionsInput(member_form.permission_sets.perms_app_mgmt) }}
|
<div class="application-perms">
|
||||||
{{ SimpleOptionsInput(member_form.permission_sets.perms_funding) }}
|
{% if new %}
|
||||||
{{ SimpleOptionsInput(member_form.permission_sets.perms_reporting) }}
|
{% set app_mgmt = form.perms_app_mgmt.name %}
|
||||||
{{ SimpleOptionsInput(member_form.permission_sets.perms_portfolio_mgmt) }}
|
{% set funding = form.perms_funding.name %}
|
||||||
<div class='action-group'>
|
{% set reporting = form.perms_reporting.name %}
|
||||||
<input
|
{% set portfolio_mgmt = form.perms_portfolio_mgmt.name %}
|
||||||
type="submit"
|
{% else %}
|
||||||
class='action-group__action usa-button usa-button-primary'
|
{% set app_mgmt = "perms_app_mgmt-{}".format(member_role_id) %}
|
||||||
form="add-port-mem"
|
{% set funding = "perms_funding-{}".format(member_role_id) %}
|
||||||
value='Invite member'>
|
{% set reporting = "perms_reporting-{}".format(member_role_id) %}
|
||||||
<a class='action-group__action' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
|
{% set portfolio_mgmt = "perms_portfolio_mgmt-{}".format(member_role_id) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ CheckboxInput(form.perms_app_mgmt, classes="input__inline-fields", key=app_mgmt, id=app_mgmt, optional=True) }}
|
||||||
|
{{ CheckboxInput(form.perms_funding, classes="input__inline-fields", key=funding, id=funding, optional=True) }}
|
||||||
|
{{ CheckboxInput(form.perms_reporting, classes="input__inline-fields", key=reporting, id=reporting, optional=True) }}
|
||||||
|
{{ CheckboxInput(form.perms_portfolio_mgmt, classes="input__inline-fields", key=portfolio_mgmt, id=portfolio_mgmt, optional=True) }}
|
||||||
</div>
|
</div>
|
||||||
{% endset %}
|
{% endmacro %}
|
||||||
{{ MultiStepModalForm(
|
|
||||||
'add-port-mem',
|
{% macro InfoFields(member_form) %}
|
||||||
member_form,
|
<div class="application-member__user-info">
|
||||||
url_for("portfolios.invite_member", portfolio_id=portfolio.id),
|
{{ TextInput(member_form.first_name, validation='requiredField', optional=False) }}
|
||||||
[step_one, step_two],
|
{{ TextInput(member_form.last_name, validation='requiredField', optional=False) }}
|
||||||
) }}
|
{{ TextInput(member_form.email, validation='email', optional=False) }}
|
||||||
|
{{ PhoneInput(member_form.phone_number, member_form.phone_ext)}}
|
||||||
|
{{ TextInput(member_form.dod_id, validation='dodId', optional=False) }}
|
||||||
|
<a href="#">How do I find the DoD ID?</a>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
{% from "components/icon.html" import Icon %}
|
|
||||||
{% from 'components/save_button.html' import SaveButton %}
|
|
||||||
{% from "components/modal.html" import Modal %}
|
|
||||||
{% from "components/alert.html" import Alert %}
|
{% from "components/alert.html" import Alert %}
|
||||||
|
{% from "components/icon.html" import Icon %}
|
||||||
|
{% import "components/member_form_template.html" as member_form %}
|
||||||
|
{% from "components/modal.html" import Modal %}
|
||||||
|
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
|
||||||
|
{% from 'components/save_button.html' import SaveButton %}
|
||||||
|
{% import "portfolios/fragments/add_new_portfolio_member.html" as member_form_fields %}
|
||||||
|
|
||||||
<h3>Portfolio Managers</h3>
|
<h3>Portfolio Managers</h3>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
@ -43,7 +46,30 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% if user_can(permissions.CREATE_PORTFOLIO_USERS) %}
|
{% if user_can(permissions.CREATE_PORTFOLIO_USERS) %}
|
||||||
<a href="#" class="usa-button usa-button-secondary add-new-button">Add Portfolio Manager</a>
|
{% set new_manager_modal = "add-portfolio-manager" %}
|
||||||
{% include "portfolios/fragments/add_new_portfolio_member.html" %}
|
<a class="usa-button usa-button-secondary add-new-button" v-on:click="openModal('{{ new_manager_modal }}')">
|
||||||
|
Add Portfolio Manager
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{{ MultiStepModalForm(
|
||||||
|
name=new_manager_modal,
|
||||||
|
form=new_manager_form,
|
||||||
|
form_action=url_for("portfolios.invite_member", portfolio_id=portfolio.id),
|
||||||
|
steps=[
|
||||||
|
member_form.BasicStep(
|
||||||
|
title="Add Manager",
|
||||||
|
form=member_form_fields.InfoFields(new_manager_form.user_data),
|
||||||
|
next_button_text="Next: Permissions",
|
||||||
|
previous=False,
|
||||||
|
modal=new_manager_modal_name,
|
||||||
|
),
|
||||||
|
member_form.SubmitStep(
|
||||||
|
name=new_manager_modal,
|
||||||
|
form=member_form_fields.PermsFields(new_manager_form),
|
||||||
|
submit_text="Invite member",
|
||||||
|
modal=new_manager_modal_name,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -205,7 +205,7 @@ def test_invite():
|
|||||||
inviter = UserFactory.create()
|
inviter = UserFactory.create()
|
||||||
member_data = UserFactory.dictionary()
|
member_data = UserFactory.dictionary()
|
||||||
|
|
||||||
invitation = Portfolios.invite(portfolio, inviter, member_data)
|
invitation = Portfolios.invite(portfolio, inviter, {"user_data": member_data})
|
||||||
|
|
||||||
assert invitation.role
|
assert invitation.role
|
||||||
assert invitation.role.portfolio == portfolio
|
assert invitation.role.portfolio == portfolio
|
||||||
|
@ -269,10 +269,10 @@ def test_existing_member_invite_resent_to_email_submitted_in_form(
|
|||||||
|
|
||||||
|
|
||||||
_DEFAULT_PERMS_FORM_DATA = {
|
_DEFAULT_PERMS_FORM_DATA = {
|
||||||
"permission_sets-perms_app_mgmt": PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT,
|
"permission_sets-perms_app_mgmt": False,
|
||||||
"permission_sets-perms_funding": PermissionSets.VIEW_PORTFOLIO_FUNDING,
|
"permission_sets-perms_funding": False,
|
||||||
"permission_sets-perms_reporting": PermissionSets.VIEW_PORTFOLIO_REPORTS,
|
"permission_sets-perms_reporting": False,
|
||||||
"permission_sets-perms_portfolio_mgmt": PermissionSets.VIEW_PORTFOLIO_ADMIN,
|
"permission_sets-perms_portfolio_mgmt": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user