Merge pull request #985 from dod-ccpo/to-form-step-3-styling

TO form step 3 styling
This commit is contained in:
leigh-mil 2019-07-29 14:32:34 -04:00 committed by GitHub
commit c5ec2c296f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 297 additions and 250 deletions

View File

@ -58,6 +58,14 @@
margin-bottom: $gap * 4; margin-bottom: $gap * 4;
} }
.task-order__number {
text-align: right;
}
.task-order__details {
max-width: 65%;
}
.totals-box { .totals-box {
padding: $gap * 4; padding: $gap * 4;
padding-top: $gap * 2; padding-top: $gap * 2;
@ -69,6 +77,59 @@
} }
} }
.card {
padding: ($gap * 5);
.usa-input {
margin: 0 $gap 0 0;
input {
max-width: none;
}
}
.usa-input--validation--dollars label span.icon {
left: auto;
right: -$gap * 9;
}
.form-row {
margin: 0;
}
select {
max-width: -webkit-fill-available;
font-weight: bold;
}
button {
margin-bottom: $gap * 3;
}
.task-order__loa-fieldset {
.usa-input__title {
padding: 0 0 0.4rem 0;
font-size: 1.7rem;
}
.usa-input {
margin: 0;
}
input {
margin: $gap 0;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
}
}
.usa-input__title, .usa-input__title,
.usa-input__title-inline { .usa-input__title-inline {
font-weight: $font-normal; font-weight: $font-normal;
@ -135,24 +196,6 @@
} }
} }
.task-order__loa-fieldset {
.usa-input {
margin: 0;
}
input {
margin: $gap 0;
}
input:first-child {
margin-top: 0;
}
input:last-child {
margin-bottom: 0;
}
}
button.icon-link { button.icon-link {
margin-top: 0; margin-top: 0;
margin-left: 0; margin-left: 0;

View File

@ -1,7 +1,7 @@
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from "components/tooltip.html" import Tooltip %} {% from "components/tooltip.html" import Tooltip %}
{% macro OptionsInput(field, tooltip, inline=False, label=True, disabled=False, watch=False, optional=True) -%} {% macro OptionsInput(field, tooltip, inline=False, label=True, show_validation=True, disabled=False, watch=False, optional=True) -%}
<optionsinput <optionsinput
name='{{ field.name }}' name='{{ field.name }}'
inline-template inline-template
@ -27,8 +27,10 @@
<span class='usa-input__help'>{{ field.description | safe }}</span> <span class='usa-input__help'>{{ field.description | safe }}</span>
{% endif %} {% endif %}
<span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span> {% if show_validation %}
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span> <span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span>
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span>
{% endif %}
</legend> </legend>
{% endif %} {% endif %}

View File

@ -16,7 +16,8 @@
noMaxWidth=False, noMaxWidth=False,
optional=True, optional=True,
showLabel=True, showLabel=True,
watch=False) -%} watch=False,
show_validation=True) -%}
<textinput <textinput
v-cloak v-cloak
@ -101,12 +102,14 @@
{% endif %} {% endif %}
/> />
<template v-if='showError'> {% if show_validation %}
<span class='usa-input__message' v-html='validationError'></span> <template v-if='showError'>
</template> <span class='usa-input__message' v-html='validationError'></span>
<template v-else> </template>
<span class='usa-input__message'></span> <template v-else>
</template> <span class='usa-input__message'></span>
</template>
{% endif %}
</div> </div>
</textinput> </textinput>

View File

@ -6,7 +6,7 @@
{{ title }} {{ title }}
</div> </div>
</div> </div>
<div class="form-col form-col--third"> <div class="form-col form-col--third task-order__number">
{% if to_number %} {% if to_number %}
<strong>Task Order Number:</strong> {{ to_number }} <strong>Task Order Number:</strong> {{ to_number }}
{% endif %} {% endif %}

View File

@ -30,13 +30,6 @@
</masked-input> </masked-input>
<input type='hidden' v-bind:value='rawValue' :name='name' /> <input type='hidden' v-bind:value='rawValue' :name='name' />
<template v-if='showError'>
<span class='usa-input__message' v-html='validationError'></span>
</template>
<template v-else>
<span class='usa-input__message'></span>
</template>
</div> </div>
</textinput> </textinput>
</div> </div>
@ -50,137 +43,109 @@
</button> </button>
{% endmacro %} {% endmacro %}
{% macro CLINFields(fields, index) %} {% macro CLINFields(fields=None, index=None) %}
{% if index != 0 %}
<hr>
{% endif %}
<clin-fields <clin-fields
v-bind:initial-clin-index='{{ index }}' {% if fields %}
v-bind:initial-loa-count="{{ fields.loas.data | length or 0 }}" v-bind:initial-clin-index='{{ index }}'
v-bind:initial-clin-type="'{{ fields.jedi_clin_type.data }}'" v-bind:initial-loa-count="{{ fields.loas.data | length or 0 }}"
v-bind:initial-amount='{{ fields.obligated_amount.data or 0 }}' v-bind:initial-clin-type="'{{ fields.jedi_clin_type.data }}'"
v-bind:initial-amount='{{ fields.obligated_amount.data or 0 }}'
{% else %}
v-bind:initial-clin-index='clinIndex'
v-bind:initial-clin-type="'JEDI_CLIN_1'"
{% endif %}
inline-template> inline-template>
<div> <div class="card">
<div class="h3">
{{ 'task_orders.form.base_clin_title' | translate }}
</div>
<div class="form-row"> <div class="form-row">
<div class="form-col form-col--two-thirds"> <div class="form-col form-col--two-thirds">
{{ OptionsInput(fields.jedi_clin_type, watch=True) }} {% if fields %}
{{ OptionsInput(fields.jedi_clin_type, watch=True, show_validation=False) }}
{% else %}
<optionsinput :name="'clins-' + clinIndex + '-jedi_clin_type'" :watch='true' :optional='false' inline-template>
<div class="usa-input">
<fieldset data-ally-disabled="true" class="usa-input__choices" v-on:change="onInput">
<legend>
<div class="usa-input__title">
{{ 'task_orders.form.clin_type_label' | translate }}
</div>
</legend>
<select :id='name' :name='name'>
<option value="JEDI_CLIN_1">{{ "forms.task_order.clin_01_label" | translate }}</option>
<option value="JEDI_CLIN_2">{{ "forms.task_order.clin_02_label" | translate }}</option>
<option value="JEDI_CLIN_3">{{ "forms.task_order.clin_03_label" | translate }}</option>
<option value="JEDI_CLIN_4">{{ "forms.task_order.clin_04_label" | translate }}</option>
</select>
</fieldset>
</div>
</optionsinput>
{% endif %}
</div> </div>
<div class="form-col form-col--third"> <div class="form-col form-col--third">
{{ TextInput(fields.number, watch=True) }} {% if fields %}
{{ TextInput(fields.number, watch=True) }}
{% else %}
<textinput :name="'clins-' + clinIndex + '-number'" :watch='true' inline-template>
<div class="usa-input">
<label :for="name">
<span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span>
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span>
<div class="usa-input__title">{{ 'task_orders.form.clin_number_label' | translate }}</div>
</label>
<masked-input
v-on:input='onInput'
v-on:blur='onBlur'
v-on:change='onChange'
v-bind:value='value'
v-bind:mask='mask'
v-bind:pipe='pipe'
v-bind:keep-char-positions='keepCharPositions'
v-bind:aria-invalid='showError'
type='text'
:id='name'
ref='input'>
</masked-input>
<input type='hidden' v-bind:value='rawValue' :name='name' />
<template v-if='showError'>
<span class='usa-input__message' v-html='validationError'></span>
</template>
<template v-else>
<span class='usa-input__message'></span>
</template>
</div>
</textinput>
{% endif %}
</div> </div>
</div> </div>
<div class="usa-input"> <fieldset class="task-order__loa-fieldset">
<fieldset class="usa-input__choices task-order__loa-fieldset"> <legend>
<legend> <div class="usa-input__title">
<div class="usa-input__title"> {{ 'task_orders.form.loa_label' | translate }}
{{ 'task_orders.form.loa_label' | translate }} </div>
</div> </legend>
</legend> {% for loa in fields.loas %}
{% for loa in fields.loas %} {{ TextInput(loa, showLabel=False, watch=True, show_validation=False) }}
{{ TextInput(loa, showLabel=False, watch=True) }}
{% endfor %}
{{ LOAInput() }}
</fieldset>
</div>
{{ DatePicker(fields.start_date, watch=True, optional=False) }}
{{ DatePicker(fields.end_date, watch=True, optional=False) }}
{{ TextInput(fields.obligated_amount, validation='dollars', watch=True) }}
</div>
</clin-fields>
{% endmacro %}
{% block to_builder_form_field %}
<to-form
inline-template
v-bind:initial-clin-count="{{ form.clins.data | length }}">
<div>
{{ TOFormStepHeader('task_orders.form.base_clin_title' | translate, 'task_orders.form.base_clin_description' | translate, task_order.number) }}
{% for clin in form.clins %}
{{ CLINFields(clin, index=loop.index - 1) }}
{% endfor %} {% endfor %}
<div v-for="clin in clins"> {{ LOAInput() }}
<hr v-if="clinIndex !== 0"> </fieldset>
<clin-fields
v-bind:initial-clin-index='clinIndex'
v-bind:initial-clin-type="'JEDI_CLIN_1'"
inline-template>
<div>
<div class="form-row">
<div class="form-col form-col--two-thirds">
<optionsinput :name="'clins-' + clinIndex + '-jedi_clin_type'" :watch='true' :optional='false' inline-template>
<div class="usa-input">
<fieldset data-ally-disabled="true" class="usa-input__choices" v-on:change="onInput">
<legend>
<div class="usa-input__title">
{{ 'task_orders.form.clin_type_label' | translate }}
</div>
</legend>
<select :id='name' :name='name'>
<option value="JEDI_CLIN_1">{{ "forms.task_order.clin_01_label" | translate }}</option>
<option value="JEDI_CLIN_2">{{ "forms.task_order.clin_02_label" | translate }}</option>
<option value="JEDI_CLIN_3">{{ "forms.task_order.clin_03_label" | translate }}</option>
<option value="JEDI_CLIN_4">{{ "forms.task_order.clin_04_label" | translate }}</option>
</select>
</fieldset>
</div>
</optionsinput>
</div>
<div class="form-col form-col--third">
<textinput :name="'clins-' + clinIndex + '-number'" :watch='true' inline-template>
<div class="usa-input">
<label :for="name">
<span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span>
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span>
<div class="usa-input__title">{{ 'task_orders.form.clin_number_label' | translate }}</div>
</label>
<masked-input
v-on:input='onInput'
v-on:blur='onBlur'
v-on:change='onChange'
v-bind:value='value'
v-bind:mask='mask'
v-bind:pipe='pipe'
v-bind:keep-char-positions='keepCharPositions'
v-bind:aria-invalid='showError'
type='text'
:id='name'
ref='input'>
</masked-input>
<input type='hidden' v-bind:value='rawValue' :name='name' />
<template v-if='showError'>
<span class='usa-input__message' v-html='validationError'></span>
</template>
<template v-else>
<span class='usa-input__message'></span>
</template>
</div>
</textinput>
</div>
</div>
<div class="usa-input">
<fieldset class="usa-input__choices task-order__loa-fieldset">
<legend>
<div class="usa-input__title">
{{ 'task_orders.form.loa_label' | translate }}
</div>
</legend>
{{ LOAInput() }}
</fieldset>
</div>
<div class="form-row">
{% if fields %}
<div class="form-col">
{{ DatePicker(fields.start_date, watch=True, optional=False) }}
</div>
<div class="form-col">
{{ DatePicker(fields.end_date, watch=True, optional=False) }}
</div>
{% else %}
<div class="form-col">
<date-selector :name-tag="'clins-' + clinIndex + '-start_date'" :watch='true' :optional='false' inline-template> <date-selector :name-tag="'clins-' + clinIndex + '-start_date'" :watch='true' :optional='false' inline-template>
<fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }"> <fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }">
<legend> <legend>
@ -203,7 +168,7 @@
v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }" v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }"
v-model="month" v-model="month"
v-on:change="onInput" v-on:change="onInput"
/> />
</div> </div>
<div class="usa-form-group usa-form-group-day"> <div class="usa-form-group usa-form-group-day">
@ -217,7 +182,7 @@
v-bind:max="daysMaxCalculation" v-bind:max="daysMaxCalculation"
v-model="day" v-model="day"
v-on:change="onInput" v-on:change="onInput"
/> />
</div> </div>
<div class="usa-form-group usa-form-group-year"> <div class="usa-form-group usa-form-group-year">
@ -228,17 +193,23 @@
type="number" type="number"
v-model="year" v-model="year"
v-on:change="onInput" v-on:change="onInput"
/> />
</div> </div>
<div class="usa-form-group-date-ok" v-if="isDateValid"> <div class="usa-form-group-date-ok" v-if="isDateValid">
{{ Icon("ok", classes="icon--green") }} {{ Icon("ok", classes="icon--green") }}
</div> </div>
</div> </div>
<p class="usa-input-error-message" v-bind:class="{ 'form-has-errors': !isWithinDateRange }">
{% if maxdate and mindate %}Date must be between {{mindate.strftime("%m/%d/%Y")}} and {{maxdate.strftime("%m/%d/%Y")}}{% endif %}
{% if maxdate and not mindate %}Date must be before or on {{maxdate.strftime("%m/%d/%Y")}}{% endif %}
{% if mindate and not maxdate %}Date must be after or on {{mindate.strftime("%m/%d/%Y")}}{% endif %}
</p>
</fieldset> </fieldset>
</date-selector> </date-selector>
</div>
<div class="form-col">
<date-selector :name-tag="'clins-' + clinIndex + '-end_date'" :watch='true' :optional='false' inline-template> <date-selector :name-tag="'clins-' + clinIndex + '-end_date'" :watch='true' :optional='false' inline-template>
<fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }"> <fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }">
<legend> <legend>
@ -250,93 +221,120 @@
<div class="date-picker-component"> <div class="date-picker-component">
<input :name="name" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" /> <input :name="name" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
<div class="usa-form-group usa-form-group-month"> <div class="usa-form-group usa-form-group-month">
<label>{{ 'components.date_selector.month' | translate }}</label> <label>{{ 'components.date_selector.month' | translate }}</label>
<input <input
name="date-month" name="date-month"
max="12" max="12"
maxlength="2" maxlength="2"
min="1" min="1"
type="number" type="number"
v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }" v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }"
v-model="month" v-model="month"
v-on:change="onInput" v-on:change="onInput"
/> />
</div> </div>
<div class="usa-form-group usa-form-group-day"> <div class="usa-form-group usa-form-group-day">
<label>{{ 'components.date_selector.day' | translate }}</label> <label>{{ 'components.date_selector.day' | translate }}</label>
<input <input
name="date-day" name="date-day"
maxlength="2" maxlength="2"
min="1" min="1"
type="number" type="number"
v-bind:class="{ 'usa-input-error': (day && !isDayValid) }" v-bind:class="{ 'usa-input-error': (day && !isDayValid) }"
v-bind:max="daysMaxCalculation" v-bind:max="daysMaxCalculation"
v-model="day" v-model="day"
v-on:change="onInput" v-on:change="onInput"
/> />
</div> </div>
<div class="usa-form-group usa-form-group-year"> <div class="usa-form-group usa-form-group-year">
<label>{{ 'components.date_selector.year' | translate }}</label> <label>{{ 'components.date_selector.year' | translate }}</label>
<input <input
name="date-year" name="date-year"
maxlength="4" maxlength="4"
type="number" type="number"
v-model="year" v-model="year"
v-on:change="onInput" v-on:change="onInput"
/> />
</div>
</div>
<div class="usa-form-group-date-ok" v-if="isDateValid"> <div class="usa-form-group-date-ok" v-if="isDateValid">
{{ Icon("ok", classes="icon--green") }} {{ Icon("ok", classes="icon--green") }}
</div> </div>
</div> </div>
<p class="usa-input-error-message" v-bind:class="{ 'form-has-errors': !isWithinDateRange }">
{% if maxdate and mindate %}Date must be between {{mindate.strftime("%m/%d/%Y")}} and {{maxdate.strftime("%m/%d/%Y")}}{% endif %}
{% if maxdate and not mindate %}Date must be before or on {{maxdate.strftime("%m/%d/%Y")}}{% endif %}
{% if mindate and not maxdate %}Date must be after or on {{mindate.strftime("%m/%d/%Y")}}{% endif %}
</p>
</fieldset> </fieldset>
</date-selector> </date-selector>
<textinput
v-cloak
inline-template
:name="'clins-' + clinIndex + '-obligated_amount'"
validation="dollars"
:watch='true'>
<div class="usa-input usa-input--validation--dollars noMaxWidth">
<label :for="name">
<div class="usa-input__title">{{ 'task_orders.form.obligated_funds_label' | translate }}</div>
<span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span>
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span>
</label>
<masked-input
v-on:input='onInput'
v-on:blur='onBlur'
v-on:change='onChange'
v-bind:value='value'
v-bind:mask='mask'
v-bind:pipe='pipe'
v-bind:keep-char-positions='keepCharPositions'
v-bind:aria-invalid='showError'
v-bind:show-mask='false'
type='text'
:id='name'
ref='input'>
</masked-input>
<input type='hidden' v-bind:value='rawValue' :name='name' />
<template v-if='showError'>
<span class='usa-input__message' v-html='validationError'></span>
</template>
<template v-else>
<span class='usa-input__message'></span>
</template>
</div>
</textinput>
</div> </div>
</clin-fields> {% endif %}
</div>
{% if fields %}
{{ TextInput(fields.obligated_amount, validation='dollars', watch=True) }}
{% else %}
<textinput
v-cloak
inline-template
:name="'clins-' + clinIndex + '-obligated_amount'"
validation="dollars"
:watch='true'>
<div class="usa-input usa-input--validation--dollars">
<label :for="name">
<div class="usa-input__title">{{ 'task_orders.form.obligated_funds_label' | translate }}</div>
<span v-show='showError'>{{ Icon('alert',classes="icon-validation") }}</span>
<span v-show='showValid'>{{ Icon('ok',classes="icon-validation") }}</span>
</label>
<masked-input
v-on:input='onInput'
v-on:blur='onBlur'
v-on:change='onChange'
v-bind:value='value'
v-bind:mask='mask'
v-bind:pipe='pipe'
v-bind:keep-char-positions='keepCharPositions'
v-bind:aria-invalid='showError'
v-bind:show-mask='false'
type='text'
:id='name'
ref='input'>
</masked-input>
<input type='hidden' v-bind:value='rawValue' :name='name' />
<template v-if='showError'>
<span class='usa-input__message' v-html='validationError'></span>
</template>
<template v-else>
<span class='usa-input__message'></span>
</template>
</div>
</textinput>
{% endif %}
</div>
</clin-fields>
{% endmacro %}
{% block to_builder_form_field %}
<to-form
inline-template
v-bind:initial-clin-count="{{ form.clins.data | length }}">
<div>
{{ TOFormStepHeader('task_orders.form.clin_title' | translate, 'task_orders.form.clin_description' | translate, task_order.number) }}
{% for clin in form.clins %}
{{ CLINFields(clin, index=loop.index - 1) }}
{% endfor %}
<div v-for="clin in clins">
{{ CLINFields() }}
</div> </div>
<button <button

View File

@ -140,10 +140,10 @@ forms:
none: Not planning to migrate any applications none: Not planning to migrate any applications
not_sure: Not sure not_sure: Not sure
on_premise: 'Yes, migrating from an on-premise data center' on_premise: 'Yes, migrating from an on-premise data center'
clin_01_label: 'CLIN 01 : Unclassified' clin_01_label: '0001: Unclassified IaaS and PaaS'
clin_02_label: 'CLIN 02: Classified' clin_02_label: '0002'
clin_03_label: 'CLIN 03: Unclassified' clin_03_label: '0003'
clin_04_label: 'CLIN 04: Classified' clin_04_label: '0004'
complexity: complexity:
conus: CONUS access conus: CONUS access
data_analytics: Data analytics data_analytics: Data analytics
@ -337,22 +337,23 @@ task_orders:
pop_end: PoP End pop_end: PoP End
loa: LOA loa: LOA
form: form:
add_clin: Add another CLIN or Sub-CLIN add_clin: Enter another CLIN
add_loa: Add another line of accounting add_loa: Enter another line of accounting
add_to_header: Add your task order add_to_header: Add your task order
add_to_description: Now, refer to your document to find the 13-digit task order number. It should be located at lorem ipsum dolar. From now on we'll refer to this portion of funding by the recorded task order number. add_to_description: Now, refer to your document to find the 13-digit task order number. It should be located at lorem ipsum dolar. From now on we'll refer to this portion of funding by the recorded task order number.
base_clin_title: Add Base CLIN clin_title: Enter CLINs
base_clin_description: Next, continue to refer to your document to locate your CLINs (Contract Line Item Numbers). CLINs are how you break the contract down by the commodities being procured (labor hours of services, funding for travel, quantity product A, etc.). clin_description: "Continue to refer to your TO to locate your Contract Line Item Numbers (CLINs). You must add CLINs one at a time, and select a corresponding ID/IQ description for each."
clin_number_label: CLIN base_clin_title: Base CLIN Information
clin_type_label: CLIN type clin_number_label: Enter task order CLIN
clin_type_label: "Select ID/IQ CLIN description"
cloud_funding_header: Add the summary of cloud funding cloud_funding_header: Add the summary of cloud funding
cloud_funding_text: Data must match with what is in your uploaded document. cloud_funding_text: Data must match with what is in your uploaded document.
draft_alert_title: Your information has been saved draft_alert_title: Your information has been saved
draft_alert_message: You can return to the Task Order Builder to enter missing information. Once you are finished, youll be ready to submit this request. draft_alert_message: You can return to the Task Order Builder to enter missing information. Once you are finished, youll be ready to submit this request.
loa_label: 'Line of accounting (43 characters)' loa_label: 'Enter line of accounting (43 characters)'
obligated_funds_label: Funds obligated for cloud obligated_funds_label: Enter obligated funds for Base CLIN
pop_end: 'End of period of performance (PoP)' pop_end: 'Period of Performance (PoP) end date'
pop_start: 'Start of period of performance (PoP)' pop_start: 'Period of Performance (PoP) start date'
review_button: Review task order review_button: Review task order
supporting_docs_header: Upload your supporting documentation supporting_docs_header: Upload your supporting documentation
supporting_docs_size_limit: Your file may not exceed 1MB supporting_docs_size_limit: Your file may not exceed 1MB