Merge pull request #1111 from dod-ccpo/multistep-app-provisioning-design-tweaks

More multistep app provisioning design tweaks
This commit is contained in:
graham-dds 2019-10-14 15:40:04 -04:00 committed by GitHub
commit e8595e592a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 147 additions and 121 deletions

View File

@ -183,11 +183,7 @@ def handle_create_member(application_id, form_data):
token=invite.token,
)
flash(
"new_application_member",
user_name=invite.user_name,
application_name=application.name,
)
flash("new_application_member", user_name=invite.first_name)
except AlreadyExistsError:
return render_template(

View File

@ -8,9 +8,9 @@ MESSAGES = {
"category": "success",
},
"application_created": {
"title_template": translate("flash.success"),
"title_template": translate("flash.application.created.title"),
"message_template": """
{{ "flash.application.created" | translate({"application_name": application_name}) }}
{{ "flash.application.created.message" | translate({"application_name": application_name}) }}
""",
"category": "success",
},
@ -104,9 +104,9 @@ MESSAGES = {
"category": "warning",
},
"new_application_member": {
"title_template": translate("flash.success"),
"title_template": """{{ "flash.new_application_member.title" | translate({ "user_name": user_name }) }}""",
"message_template": """
<p>{{ "flash.new_application_member" | translate({ "user_name": user_name, "application_name": application_name }) }}</p>
<p>{{ "flash.new_application_member.message" | translate({ "user_name": user_name }) }}</p>
""",
"category": "success",
},

View File

@ -10,6 +10,10 @@ export default {
components: {
textinput,
},
created: function() {
this.$root.$on('field-change', this.handleFieldChange)
if (this.initialData) this.changed = true
},
data: function() {
return {

View File

@ -1,4 +1,5 @@
.app-footer {
z-index: 3;
background-color: $color-white;
border-top: 1px solid $color-gray-lightest;
display: flex;

View File

@ -1,6 +1,9 @@
.global-navigation {
z-index: 2;
background-color: $color-white;
height: auto;
box-shadow: $box-shadow;
margin-bottom: -$footer-height * 2.5;
.sidenav__link {
padding-right: $gap * 2;

View File

@ -219,6 +219,8 @@
}
.application-content {
margin-top: $gap * 4;
.subheading {
@include subheading;
position: relative;

View File

@ -29,3 +29,24 @@
}
}
}
.action-group-footer {
@extend .action-group;
&:last-child {
margin-bottom: 0;
}
margin-top: 0;
margin-bottom: 0;
padding-top: $gap;
padding-bottom: $gap;
position: fixed;
bottom: $footer-height;
background: white;
right: 0;
padding-right: $gap * 4;
border-top: 1px solid $color-gray-light;
width: 100%;
z-index: 1;
}

View File

@ -23,29 +23,28 @@
<application-name-and-description inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<form method="POST" action="{{ action }}" v-on:submit="handleSubmit">
<div class="panel__content">
{{ form.csrf_token }}
<div class="form-row">
<div class="form-col form-col--two-thirds">
{{ TextInput(form.name, optional=False) }}
{{ ('portfolios.applications.new.step_1_form_help_text.description' | translate | safe) }}
</div>
</div>
<hr>
<div class="form-row">
<div class="form-col form-col--two-thirds">
{{ TextInput(form.description, paragraph=True, optional=True) }}
{{ ('portfolios.applications.new.step_1_form_help_text.description' | translate | safe) }}
</div>
</div>
{{ form.csrf_token }}
<div class="form-row">
<div class="form-col">
{{ TextInput(form.name, optional=False) }}
{{ ('portfolios.applications.new.step_1_form_help_text.name' | translate | safe) }}
</div>
</div>
<hr class="panel__break">
<div class="form-row">
<div class="form-col form-col--two-thirds">
{{ TextInput(form.description, paragraph=True, optional=True) }}
{{ ('portfolios.applications.new.step_1_form_help_text.description' | translate | safe) }}
</div>
</div>
<span class="action-group">
<span class="action-group-footer">
{% block next_button %}
{{ SaveButton(text=('portfolios.applications.new.step_1_button_text' | translate)) }}
{% endblock %}
<a class="usa-button usa-button-secondary" href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
<button disabled class="usa-button usa-button-secondary">Previous</button>
<a href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
Cancel
</a>
</span>

View File

@ -16,66 +16,63 @@
{% set modalName = "newApplicationConfirmation" %}
{% include "fragments/flash.html" %}
<div class="panel__content">
<p>
{{ 'portfolios.applications.new.step_2_description' | translate }}
</p>
<hr>
<application-environments inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<form method="POST" action="{{ url_for('applications.update_new_application_step_2', portfolio_id=portfolio.id, application_id=application.id) }}" v-on:submit="handleSubmit">
<div class="subheading">{{ 'portfolios.applications.environments_heading' | translate }}</div>
<div class="panel">
<div class="panel__content">
{{ form.csrf_token }}
<div> {# this extra div prevents this bug: https://www.pivotaltracker.com/story/show/160768940 #}
<div v-cloak v-for="title in errors" :key="title">
{{ Alert(message=None, level="error", vue_template=True) }}
</div>
<p>
{{ 'portfolios.applications.new.step_2_description' | translate }}
</p>
<hr class="panel__break">
<application-environments inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<form method="POST" action="{{ url_for('applications.update_new_application_step_2', portfolio_id=portfolio.id, application_id=application.id) }}" v-on:submit="handleSubmit">
<div class="subheading">{{ 'portfolios.applications.environments_heading' | translate }}</div>
<div class="panel">
<div class="panel__content">
{{ form.csrf_token }}
<div> {# this extra div prevents this bug: https://www.pivotaltracker.com/story/show/160768940 #}
<div v-cloak v-for="title in errors" :key="title">
{{ Alert(message=None, level="error", vue_template=True) }}
</div>
<div class="application-list-item">
<ul>
<li v-for="(environment, i) in environments" class="application-edit__env-list-item">
<div class="usa-input">
<label :for="'environment_names-' + i">Environment Name</label>
<input type="text" :id="'environment_names-' + i" v-model="environment.name" @input="onInput" placeholder="e.g. Development, Staging, Production"/> <input type="hidden" :name="'environment_names-' + i" v-model="environment.name"/>
</div>
<div class="application-edit__env-list-item-block">
<button v-on:click="removeEnvironment(i)" v-if="environments.length > 1" type="button" class="application-edit__env-list-item__remover">
{{ Icon('trash') }}
<span>Remove</span>
</button>
</div>
</li>
</ul>
<div class="block-list__footer">
<button
v-on:click="addEnvironment"
class="icon-link"
tabindex="0"
type="button">
{{ 'portfolios.applications.add_another_environment' | translate }}
{{ Icon("plus") }}
</button>
</div>
</div>
</div>
</div>
<span class="action-group">
{% block next_button %}
{{ SaveButton(text=('portfolios.applications.new.step_2_button_text' | translate)) }}
{% endblock %}
<a class="usa-button usa-button-secondary" href="{{ url_for('applications.view_new_application_step_1', application_id=application.id) }}">
Previous
</a>
<a href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
Cancel
</a>
</span>
</form>
</application-environments>
</div>
</div>
<div class="application-list-item">
<ul>
<li v-for="(environment, i) in environments" class="application-edit__env-list-item">
<div class="usa-input">
<label :for="'environment_names-' + i">Environment Name</label>
<input type="text" :id="'environment_names-' + i" v-model="environment.name" @input="onInput" placeholder="e.g. Development, Staging, Production"/> <input type="hidden" :name="'environment_names-' + i" v-model="environment.name"/>
</div>
<div class="application-edit__env-list-item-block">
<button v-on:click="removeEnvironment(i)" v-if="environments.length > 1" type="button" class="application-edit__env-list-item__remover">
{{ Icon('trash') }}
<span>Remove</span>
</button>
</div>
</li>
</ul>
<div class="block-list__footer">
<button
v-on:click="addEnvironment"
class="icon-link"
tabindex="0"
type="button">
{{ 'portfolios.applications.add_another_environment' | translate }}
{{ Icon("plus") }}
</button>
</div>
</div>
</div>
</div>
<span class="action-group-footer">
{% block next_button %}
{{ SaveButton(text=('portfolios.applications.new.step_2_button_text' | translate)) }}
{% endblock %}
<a class="usa-button usa-button-secondary" href="{{ url_for('applications.view_new_application_step_1', application_id=application.id) }}">
Previous
</a>
<a href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
Cancel
</a>
</span>
</form>
</application-environments>
{% endblock %}

View File

@ -11,31 +11,30 @@
{% block application_content %}
{% include "fragments/flash.html" %}
<div class="panel__content">
<p>
{{ ('portfolios.applications.new.step_3_description' | translate) }}
</p>
<hr>
{{ MemberManagementTemplate(
application,
members,
new_member_form,
"applications.update_new_application_step_3",
user_can(permissions.CREATE_APPLICATION_MEMBER)) }}
<p>
{{ ('portfolios.applications.new.step_3_description' | translate) }}
</p>
<hr class="panel__break">
{{ MemberManagementTemplate(
application,
members,
new_member_form,
"applications.update_new_application_step_3",
user_can(permissions.CREATE_APPLICATION_MEMBER)) }}
<span class="action-group-footer">
<a class="usa-button" href="{{ url_for('applications.settings', application_id=application_id) }}">
Return to Application Settings
</a>
<a class="usa-button usa-button-secondary" href="{{ url_for('applications.view_new_application_step_2', application_id=application.id) }}">
Previous
</a>
<a href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
Cancel
</a>
</span>
<span class="action-group">
<a class="usa-button" href="{{ url_for('applications.settings', application_id=application_id) }}">
Return to Application Settings
</a>
<a class="usa-button usa-button-secondary" href="{{ url_for('applications.view_new_application_step_2', application_id=application.id) }}">
Previous
</a>
<a href="{{ url_for('applications.portfolio_applications', portfolio_id=portfolio.id) }}">
Cancel
</a>
</span>
</div>
{% endblock %}

View File

@ -27,7 +27,7 @@
{% if vue_template %}
<h3 class='usa-alert-heading' v-html='title'></h3>
{% elif title %}
<h3 class='usa-alert-heading'>{{title}}</h3>
<h3 class='usa-alert-heading'>{{ title | safe }}</h3>
{% endif %}
{% if message %}

View File

@ -107,7 +107,9 @@ email:
environment_ready: JEDI cloud environment ready
flash:
application:
created: 'You have successfully created the {application_name} application.'
created:
title: Application Saved
message: '{application_name} has been successfully created. You may continue on to provision environments and assign team members now, or come back and complete these tasks at a later time.'
updated: 'You have successfully updated the {application_name} application.'
deleted: 'You have successfully deleted the {application_name} application. To view the retained activity log, visit the portfolio administration page.'
delete_member_success: 'You have successfully deleted {member_name} from the portfolio.'
@ -119,7 +121,9 @@ flash:
new_ppoc_message: 'You have successfully added {ppoc_name} as the primary point of contact. You are no longer the PPoC.'
new_ppoc_title: Primary point of contact updated
success: Success!
new_application_member: '{user_name} has been added to {application_name}. They will not have access until they accept the invitation e-mailed to them and CSP processing is complete.'
new_application_member:
title: "{user_name}'s invitation has been sent"
message: "{user_name}'s access to this Application is pending until they sign in for the first time."
updated_application_team_settings: 'You have updated the {application_name} team settings.'
logged_out: Logged out
footer:
@ -311,12 +315,12 @@ portfolios:
app_settings_text: App settings
new:
step_1_header: Name and Describe New Application
step_1_button_text: "Save and Add Environments"
step_1_button_text: "Next: Add Environments"
step_1_form_help_text:
name: |
<div style="margin-top: -3rem;">
<p>
The name of your application should be intuitive and easily recognizable for all of your team members.
The name of your Application should be intuitive and easily recognizable for all of your team members.
</p>
<p>
<strong>Writer's Block? A naming example includes:</strong>
@ -331,7 +335,7 @@ portfolios:
Add a brief one to two sentence description of your application. You should be able to reference your TO Description of Work.
</p>
<p>
<strong>Writer's Block? A naming example includes:</strong>
<strong>Writer's Block? A description example includes:</strong>
<ul>
<li>Build security applications for FOB Clark</li>
</ul>
@ -339,9 +343,9 @@ portfolios:
</div>
step_2_header: Add Environments to {application_name}
step_2_description: "Production, Staging, Testing, and Development environments are included by default. However, you can add, edit, and delete environments based on the needs of your Application."
step_2_button_text: "Save and Add Members"
step_3_header: Invite Members to {application_name}
step_3_description: "To proceed, you will need each member's email address and DOD ID. Within this section, you will also assign application-level permissions and environment-level roles for each member."
step_2_button_text: "Next: Add Members"
step_3_header: Add Members to {application_name}
step_3_description: "To proceed, you will need each member's email address and DOD ID. Within this section, you will also assign Application-level permissions and environment-level roles for each member."
step_3_button_text: Save Application
create_new_env: Create a new environment.
create_new_env_info: Creating an environment gives you access to the Cloud Service Provider. This environment will function within the constraints of the task order, and any costs will be billed against the portfolio.