multi-step form modal with basic implementation for adding new member
This commit is contained in:
parent
6b59ab800b
commit
1bc434be8c
@ -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()],
|
||||
|
@ -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,
|
||||
|
43
js/components/forms/multi_step_modal_form.js
Normal file
43
js/components/forms/multi_step_modal_form.js
Normal 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: {},
|
||||
}
|
@ -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,
|
||||
|
45
templates/components/multi_step_modal_form.html
Normal file
45
templates/components/multi_step_modal_form.html
Normal 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 %}
|
@ -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) }}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user