multi-step form modal with basic implementation for adding new member

This commit is contained in:
dandds 2019-03-22 13:36:21 -04:00
parent 6b59ab800b
commit 1bc434be8c
7 changed files with 159 additions and 5 deletions

View File

@ -1,10 +1,10 @@
from wtforms.fields import StringField, FormField, FieldList
from wtforms.fields.html5 import EmailField
from wtforms.validators import Required, Email, Length
from wtforms.fields.html5 import EmailField, TelField
from wtforms.validators import Required, Email, Length, Optional
from atst.domain.permission_sets import PermissionSets
from .forms import BaseForm
from atst.forms.validators import IsNumber
from atst.forms.validators import IsNumber, PhoneNumber
from atst.forms.fields import SelectField
from atst.utils.localization import translate
@ -71,6 +71,10 @@ class NewForm(PermissionsForm):
email = EmailField(
translate("forms.new_member.email_label"), validators=[Required(), Email()]
)
phone_number = TelField(
translate("forms.new_member.phone_number_label"),
validators=[Optional(), PhoneNumber()],
)
dod_id = StringField(
translate("forms.new_member.dod_id_label"),
validators=[Required(), Length(min=10), IsNumber()],

View File

@ -8,7 +8,7 @@ from atst.domain.portfolios import Portfolios
from atst.domain.audit_log import AuditLog
from atst.domain.common import Paginator
from atst.forms.portfolio import PortfolioForm
from atst.forms.portfolio_member import MembersPermissionsForm
import atst.forms.portfolio_member as member_forms
from atst.models.permissions import Permissions
from atst.domain.permission_sets import PermissionSets
from atst.domain.authz.decorator import user_can_access_decorator as user_can
@ -63,7 +63,7 @@ def render_admin_page(portfolio, form=None):
members_data = [serialize_member_form_data(member) for member in portfolio.members]
portfolio_form = PortfolioForm(data={"name": portfolio.name})
member_perms_form = MembersPermissionsForm(
member_perms_form = member_forms.MembersPermissionsForm(
data={"members_permissions": members_data}
)
return render_template(
@ -71,6 +71,7 @@ def render_admin_page(portfolio, form=None):
form=form,
portfolio_form=portfolio_form,
member_perms_form=member_perms_form,
member_form=member_forms.NewForm(),
portfolio=portfolio,
audit_events=audit_events,
user=g.current_user,

View File

@ -0,0 +1,43 @@
import FormMixin from '../../mixins/form'
import textinput from '../text_input'
import optionsinput from '../options_input'
import Selector from '../selector'
import Modal from '../../mixins/modal'
import toggler from '../toggler'
export default {
name: 'multi-step-modal-form',
mixins: [FormMixin, Modal],
components: {
toggler,
Modal,
Selector,
textinput,
optionsinput,
},
props: {},
data: function() {
return {
step: 0,
}
},
mounted: function() {
return {}
},
methods: {
next: function() {
this.step += 1
},
goToStep: function(step) {
this.step = step
},
},
computed: {},
}

View File

@ -18,6 +18,7 @@ import toggler from './components/toggler'
import NewApplication from './components/forms/new_application'
import EditEnvironmentRole from './components/forms/edit_environment_role'
import EditApplicationRoles from './components/forms/edit_application_roles'
import MultiStepModalForm from './components/forms/multi_step_modal_form'
import funding from './components/forms/funding'
import uploadinput from './components/upload_input'
import Modal from './mixins/modal'
@ -59,6 +60,7 @@ const app = new Vue({
LocalDatetime,
EditEnvironmentRole,
EditApplicationRoles,
MultiStepModalForm,
ConfirmationPopover,
funding,
uploadinput,

View File

@ -0,0 +1,45 @@
{% from "components/modal.html" import Modal %}
{% set numbers = ['one', 'two', 'three', 'four', 'five'] %}
{% macro FormSteps(step_count, current_step) -%}
{% set count = numbers[step_count - 1] %}
<div class="progress-menu progress-menu--{{ count }}">
<ul>
{% for step in range(step_count) %}
<li class="progress-menu__item
{% if loop.index < current_step %}
progress-menu__item--complete
{% elif loop.index == current_step %}
progress-menu__item--active
{% else %}
progress-menu__item--incomplete
{% endif %}">
<a v-on:click="goToStep({{ step }})">
Step {{ loop.index }}
</a>
</li>
{% endfor %}
</ul>
</div>
{% endmacro %}
{% macro MultiStepModalForm(name, form, form_action, steps, button_text="", dismissable=False) -%}
{% set step_count = steps|length %}
<multi-step-modal-form inline-template>
<div>
<button v-on:click="openModal('{{ name }}')" type="button" class="icon-link">{{ button_text }}</button>
<form action="{{ form_action }}" method="POST">
{{ form.csrf_token }}
{% call Modal(name=name, dismissable=dismissable) %}
{% for step in steps %}
<div v-show="step === {{ loop.index0 }}">
{{ FormSteps(step_count, loop.index) }}
{{ step }}
</div>
{% endfor %}
{% endcall %}
</form>
</div>
</multi-step-modal-form>
{% endmacro %}

View File

@ -3,6 +3,8 @@
{% from "components/pagination.html" import Pagination %}
{% from "components/icon.html" import Icon %}
{% from "components/text_input.html" import TextInput %}
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
{% from "components/options_input.html" import OptionsInput %}
{% set secondary_breadcrumb = "navigation.portfolio_navigation.portfolio_admin" | translate %}
@ -50,6 +52,61 @@
{% include "fragments/admin/portfolio_members.html" %}
{% endif %}
{% set step_one %}
<h1>Invite New Portfolio Member</h1>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.first_name, validation='requiredField') }}
</div>
<div class='form-col form-col--half'>
{{ TextInput(member_form.last_name, validation='requiredField') }}
</div>
</div>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.email, validation='email') }}
</div>
<div class='form-col form-col--half'>
{{ TextInput(member_form.phone_number, validation='usPhone') }}
</div>
</div>
<div class='form-row'>
<div class='form-col form-col--half'>
{{ TextInput(member_form.dod_id, validation='dodId') }}
</div>
<div class='form-col form-col--half'>
</div>
</div>
<div class='action-group'>
<a v-on:click="next()" class='action-group__action usa-button'>Next Step</a>
<a class='action-group__action icon-link icon-link--danger' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
</div>
{% endset %}
{% set step_two %}
<h1>Assign Member Permissions</h1>
<a class='icon-link'>
<span class='icon'>{{ Icon('info') }}</span>
{{ "portfolios.admin.permissions_info" | translate }}
</a>
{{ OptionsInput(member_form.perms_app_mgmt) }}
{{ OptionsInput(member_form.perms_funding) }}
{{ OptionsInput(member_form.perms_reporting) }}
{{ OptionsInput(member_form.perms_portfolio_mgmt) }}
<div class='action-group'>
<input type="submit" v-on:click="closeModal('{{ new_port_mem }}')" class='action-group__action usa-button' value='Invite Member'>
<a class='action-group__action icon-link icon-link--danger' v-on:click="closeModal('{{ new_port_mem }}')">Cancel</a>
</div>
{% endset %}
{{ MultiStepModalForm(
'add-port-mem',
member_form,
url_for("portfolios.create_member", portfolio_id=portfolio.id),
[step_one, step_two],
button_text="add new member")
}}
{% include "fragments/audit_events_log.html" %}
{% if user_can(permissions.VIEW_PORTFOLIO_ACTIVITY_LOG) %}
{% include "fragments/audit_events_log.html" %}
{{ Pagination(audit_events, 'portfolios.portfolio_admin', portfolio_id=portfolio.id) }}

View File

@ -134,6 +134,7 @@ forms:
new_member:
dod_id_label: DOD ID
email_label: Email Address
phone_number_label: Phone Number (Optional)
first_name_label: First Name
last_name_label: Last Name
portfolio_role_description: 'The portfolio role controls whether a member is permitted to organize a portfolio into applications and environments, add members to this portfolio, and view billing information.'
@ -568,6 +569,7 @@ portfolios:
portfolio_members_subheading: These members have different levels of access to the portfolio.
settings_info: Learn more about these settings
add_member: Add a New Member
permissions_info: Learn more about these permissions
activity_log_title: Activity Log
members:
archive_button: Archive User