Merge pull request #1055 from dod-ccpo/clin-card-styling

TO Form Step 3/CLIN page styling
This commit is contained in:
leigh-mil 2019-09-04 11:36:51 -04:00 committed by GitHub
commit 1cbefb099b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 365 additions and 246 deletions

View File

@ -34,12 +34,14 @@ class CLINForm(FlaskForm):
label=translate("task_orders.form.clin_number_label"), validators=[Optional()] label=translate("task_orders.form.clin_number_label"), validators=[Optional()]
) )
start_date = DateField( start_date = DateField(
translate("forms.task_order.start_date_label"), translate("task_orders.form.pop_start"),
description=translate("task_orders.form.pop_example"),
format="%m/%d/%Y", format="%m/%d/%Y",
validators=[Optional()], validators=[Optional()],
) )
end_date = DateField( end_date = DateField(
translate("forms.task_order.end_date_label"), translate("task_orders.form.pop_end"),
description=translate("task_orders.form.pop_example"),
format="%m/%d/%Y", format="%m/%d/%Y",
validators=[Optional()], validators=[Optional()],
) )

View File

@ -8,6 +8,7 @@ const OBLIGATED_AMOUNT = 'obligated_amount'
const START_DATE = 'start_date' const START_DATE = 'start_date'
const END_DATE = 'end_date' const END_DATE = 'end_date'
const POP = 'period_of_performance' const POP = 'period_of_performance'
const NUMBER = 'number'
export default { export default {
name: 'clin-fields', name: 'clin-fields',
@ -33,6 +34,10 @@ export default {
type: String, type: String,
default: null, default: null,
}, },
initialClinNumber: {
type: String,
default: null,
},
}, },
data: function() { data: function() {
@ -44,6 +49,9 @@ export default {
: undefined : undefined
const popValidation = !this.initialStartDate ? false : start < end const popValidation = !this.initialStartDate ? false : start < end
const showPopValidation = !this.initialStartDate ? false : !popValidation const showPopValidation = !this.initialStartDate ? false : !popValidation
const clinNumber = !!this.initialClinNumber
? this.initialClinNumber
: undefined
return { return {
clinIndex: this.initialClinIndex, clinIndex: this.initialClinIndex,
@ -53,6 +61,7 @@ export default {
endDate: end, endDate: end,
popValid: popValidation, popValid: popValidation,
showPopError: showPopValidation, showPopError: showPopValidation,
clinNumber: clinNumber,
} }
}, },
@ -113,8 +122,20 @@ export default {
} else if (event.name.includes(END_DATE)) { } else if (event.name.includes(END_DATE)) {
if (!!event.value) this.endDate = new Date(event.value) if (!!event.value) this.endDate = new Date(event.value)
this.validatePop() this.validatePop()
} else if (event.name.includes(NUMBER)) {
this.clinNumber = event.value
} }
} }
}, },
}, },
computed: {
clinTitle: function() {
if (!!this.clinNumber) {
return `CLIN ${this.clinNumber}`
} else {
return `CLIN`
}
},
},
} }

View File

@ -11,7 +11,7 @@
<div> <div>
<div v-show="hasAttachment" class="uploaded-file"> <div v-show="hasAttachment" class="uploaded-file">
<span class="icon icon--check-circle-solid " aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span> <span class="icon icon--ok " aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span>
<a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a> <a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a>
<a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a> <a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a>

View File

@ -12,7 +12,7 @@
<div> <div>
<div v-show="hasAttachment" class="uploaded-file"> <div v-show="hasAttachment" class="uploaded-file">
<span class="icon icon--check-circle-solid " aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span> <span class="icon icon--ok " aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span>
<a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a> <a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a>
<a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a> <a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a>

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg>

Before

Width:  |  Height:  |  Size: 600 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8 12c-.266 0-.522-.106-.71-.296L3.915 8.297c-.389-.392-.386-1.025.006-1.414.392-.387 1.026-.386 1.414.007l2.574 2.597 6.302-8.101c.339-.435.967-.514 1.403-.176.436.339.515.968.175 1.403l-7 9c-.177.227-.442.367-.729.384L8 12zm0 4c-4.411 0-8-3.589-8-8s3.589-8 8-8c.964 0 1.906.17 2.803.505.517.193.779.77.586 1.287s-.765.783-1.287.586C9.431 2.127 8.724 2 8 2 4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6c0-.552.447-1 1-1s1 .448 1 1c0 4.411-3.589 8-8 8z"/></svg> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg>

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 600 B

View File

@ -16,6 +16,11 @@
} }
} }
&__title {
padding: $gap * 2;
background-color: $color-gray-lightest;
}
&__header h3 { &__header h3 {
margin-top: 0; margin-top: 0;
} }

View File

@ -50,6 +50,13 @@
} }
} }
&__header {
.h2,
p {
margin-bottom: $gap * 0.5;
}
}
.col { .col {
flex-grow: 1; flex-grow: 1;
} }
@ -84,19 +91,15 @@
} }
.card { .card {
padding: ($gap * 5); padding: ($gap * 4) ($gap * 5) 0;
.usa-input { .usa-input {
margin: 0 $gap 0 0; margin: 0 $gap 0 0;
width: 45rem;
input {
max-width: none;
}
} }
.usa-input--validation--dollars label span.icon { fieldset.date-picker {
left: auto; width: auto;
right: -$gap * 9;
} }
.form-row { .form-row {
@ -111,6 +114,39 @@
button { button {
margin-bottom: $gap * 3; margin-bottom: $gap * 3;
} }
.date-picker {
padding-bottom: $gap * 3;
.usa-input__title {
padding-bottom: $gap;
font-weight: $font-bold;
}
.usa-input__help {
font-style: italic;
color: $color-gray;
margin-bottom: 1rem;
}
.usa-alert {
padding: $gap * 0.5;
margin: 0 0 $gap;
background-size: 3rem;
background-position-x: 1.5rem;
background-position-y: 1.25rem;
&-body {
padding-left: 5rem;
padding-right: $gap * 2;
}
&-text {
font-weight: 550;
margin-bottom: 0.5rem;
}
}
}
} }
.usa-input__title, .usa-input__title,
@ -243,3 +279,12 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.clin-card {
width: 62rem;
&__title.h4 {
margin-top: 0;
padding-bottom: $gap * 2.5;
}
}

View File

@ -1,3 +1,4 @@
{% from "components/alert.html" import Alert %}
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% macro DatePicker( {% macro DatePicker(
@ -26,6 +27,10 @@
{{ label }} {{ label }}
</div> </div>
{% if caller %}
{{ caller() }}
{% endif %}
{% if description %} {% if description %}
<p class='usa-input__help'> <p class='usa-input__help'>
{{ description | safe }} {{ description | safe }}

View File

@ -16,7 +16,7 @@
> >
<div> <div>
<div v-show="hasAttachment" class="uploaded-file"> <div v-show="hasAttachment" class="uploaded-file">
{{ Icon("check-circle-solid") }} {{ Icon("ok") }}
<a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a> <a class="uploaded-file__name" v-html="baseName" v-bind:href="downloadLink"></a>
<a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a> <a href="#" class="uploaded-file__remove" v-on:click="removeAttachment">Remove</a>
</div> </div>

View File

@ -14,7 +14,7 @@
{{ 'task_orders.review.pdf_title' | translate }} {{ 'task_orders.review.pdf_title' | translate }}
</div> </div>
<a class="icon-link icon-link--download" href="{{ pdf_download_url }}"> <a class="icon-link icon-link--download" href="{{ pdf_download_url }}">
{{ Icon('check-circle-solid') }} {{ Icon('ok') }}
{{ task_order.pdf.filename }} {{ task_order.pdf.filename }}
</a> </a>

View File

@ -1,21 +1,15 @@
{% macro TOFormStepHeader(title, description, to_number=None) %} {% macro TOFormStepHeader(title, description, to_number=None) %}
<div class="column"> <div class="task-order__header">
<div class="form-row"> <div class="h2">
<div class="form-col form-col--two-thirds"> {{ title }}
<div class="h2">
{{ title }}
</div>
</div>
<div class="form-col form-col--third task-order__number">
{% if to_number %}
<strong>Task Order Number:</strong> {{ to_number }}
{% endif %}
</div>
</div> </div>
<div class="form-row"> {% if to_number %}
<p> <p>
{{ description }} <strong>Task Order Number:</strong> {{ to_number }}
</p> </p>
</div> {% endif %}
<p>
{{ description }}
</p>
</div> </div>
{% endmacro %} {% endmacro %}

View File

@ -1,5 +1,6 @@
{% extends "task_orders/builder_base.html" %} {% extends "task_orders/builder_base.html" %}
{% from 'components/alert.html' import Alert %}
{% from 'components/date_picker.html' import DatePicker %} {% from 'components/date_picker.html' import DatePicker %}
{% from 'components/icon.html' import Icon %} {% from 'components/icon.html' import Icon %}
{% from 'components/options_input.html' import OptionsInput %} {% from 'components/options_input.html' import OptionsInput %}
@ -7,7 +8,7 @@
{% from 'task_orders/form_header.html' import TOFormStepHeader %} {% from 'task_orders/form_header.html' import TOFormStepHeader %}
{% set action = url_for("task_orders.submit_form_step_three_add_clins", task_order_id=task_order_id) %} {% set action = url_for("task_orders.submit_form_step_three_add_clins", task_order_id=task_order_id) %}
{% set next_button_text = "Next: Review Funding" %} {% set next_button_text = "task_orders.form.step_3.next_button" | translate %}
{% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %} {% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %}
{% set step = "3" %} {% set step = "3" %}
@ -19,159 +20,177 @@
v-bind:initial-amount='{{ fields.obligated_amount.data or 0 }}' v-bind:initial-amount='{{ fields.obligated_amount.data or 0 }}'
v-bind:initial-start-date="'{{ fields.start_date.data | string }}'" v-bind:initial-start-date="'{{ fields.start_date.data | string }}'"
v-bind:initial-end-date="'{{ fields.end_date.data | string }}'" v-bind:initial-end-date="'{{ fields.end_date.data | string }}'"
v-bind:initial-clin-number="'{{ fields.number.data | string }}'"
{% else %} {% else %}
v-bind:initial-clin-index='clinIndex' v-bind:initial-clin-index='clinIndex'
v-bind:initial-clin-type="'JEDI_CLIN_1'" v-bind:initial-clin-type="'JEDI_CLIN_1'"
{% endif %} {% endif %}
inline-template> inline-template>
<div class="card"> <div class="clin-card">
<div class="h3"> <div class="card__title h4" v-html='clinTitle'></div>
{{ 'task_orders.form.base_clin_title' | translate }} <div class="card">
</div> <div class="form-row">
<div class="form-row"> <div class="h4 clin-card__title">
<div class="form-col form-col--two-thirds"> {{ 'task_orders.form.clin_details' | translate }}
{% 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 class="form-col form-col--third">
{% 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 class="form-row">
{% if fields %}
<div class="form-col form-col--half">
{{ DatePicker(fields.start_date, watch=True, optional=False) }}
</div>
<div class="form-col form-col--half">
{{ DatePicker(fields.end_date, watch=True, optional=False) }}
</div> </div>
</div>
<div class="form-row">
<div class="form-col">
{% if fields %}
{{ TextInput(fields.number, watch=True) }}
{% else %}
<textinput :name="'clins-' + clinIndex + '-number'" :watch='true'
inline-template>
<div v-bind:class="['usa-input usa-input--validation--' + validation, { 'usa-input--error': showError, 'usa-input--success': showValid, 'usa-input--validation--paragraph': paragraph, 'no-max-width': noMaxWidth }]">
<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>
{% else %} <masked-input
<div class="form-col form-col--half"> v-on:input='onInput'
<date-selector :name-tag="'clins-' + clinIndex + '-start_date'" :watch='true' :optional='false' inline-template> v-on:blur='onBlur'
<fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }"> v-on:change='onChange'
<legend> v-bind:value='value'
<div class="usa-input__title"> v-bind:mask='mask'
{{ 'task_orders.form.pop_start' | translate }} v-bind:pipe='pipe'
</div> v-bind:keep-char-positions='keepCharPositions'
</legend> v-bind:aria-invalid='showError'
type='text'
:id='name'
ref='input'>
</masked-input>
<div class="date-picker-component"> <input type='hidden' v-bind:value='rawValue' :name='name' />
<input :name="name" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
<div class="usa-form-group usa-form-group-month"> <template v-if='showError'>
<label>{{ 'components.date_selector.month' | translate }}</label> <span class='usa-input__message' v-html='validationError'></span>
<input </template>
name="date-month" <template v-else>
max="12" <span class='usa-input__message'></span>
maxlength="2" </template>
min="1"
type="number"
v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }"
v-model="month"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group usa-form-group-day">
<label>{{ 'components.date_selector.day' | translate }}</label>
<input
name="date-day"
maxlength="2"
min="1"
type="number"
v-bind:class="{ 'usa-input-error': (day && !isDayValid) }"
v-bind:max="daysMaxCalculation"
v-model="day"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group usa-form-group-year">
<label>{{ 'components.date_selector.year' | translate }}</label>
<input
name="date-year"
maxlength="4"
type="number"
v-model="year"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group-date-ok" v-if="isDateValid">
{{ Icon("ok", classes="icon--green") }}
</div>
</div> </div>
</fieldset> </textinput>
</date-selector> {% endif %}
</div> </div>
</div>
<div class="form-row">
<div class="form-col">
{% 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 v-bind:class="['usa-input', { 'usa-input--error': showError, 'usa-input--success': showValid }]">
<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>
<hr>
<div class="form-row">
<div class="h4 clin-card__title">
{{ 'task_orders.form.clin_funding' | translate }}
</div>
</div>
{% if fields %}
<div class="form-row">
<div class="form-col">
{{ TextInput(fields.obligated_amount, validation='dollars', watch=True) }}
</div>
</div>
{% else %}
<div class="form-row">
<div class="form-col">
<textinput
v-cloak
inline-template
:name="'clins-' + clinIndex + '-obligated_amount'"
validation="dollars"
:watch='true'>
<div v-bind:class="['usa-input usa-input--validation--' + validation, { 'usa-input--error': showError, 'usa-input--success': showValid, 'usa-input--validation--paragraph': paragraph, 'no-max-width': 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>
<div class="form-col form-col--half"> <masked-input
<date-selector :name-tag="'clins-' + clinIndex + '-end_date'" :watch='true' :optional='false' inline-template> v-on:input='onInput'
<fieldset class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid }"> v-on:blur='onBlur'
<legend> v-on:change='onChange'
<div class="usa-input__title"> v-bind:value='value'
{{ 'task_orders.form.pop_end' | translate }} v-bind:mask='mask'
</div> v-bind:pipe='pipe'
</legend> v-bind:keep-char-positions='keepCharPositions'
v-bind:aria-invalid='showError'
v-bind:show-mask='false'
type='text'
:id='name'
ref='input'>
</masked-input>
<div class="date-picker-component"> <input type='hidden' v-bind:value='rawValue' :name='name' />
<input :name="name" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
<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>
{% endif %}
<hr>
<div class="form-row">
<div class="h4 clin-card__title">
{{ 'task_orders.form.pop' | translate }}
</div>
</div>
{% if fields %}
<div class="form-row">
<div class="form-col">
{{ DatePicker(fields.start_date, watch=True, optional=False) }}
</div>
</div>
<div class="form-row">
<div class="form-col">
{% call DatePicker(fields.end_date, watch=True, optional=False) %}
{{ Alert(message="task_orders.form.pop_end_alert" | translate) }}
{% endcall %}
</div>
</div>
{% else %}
<div class="form-row">
<div class="form-col">
<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 && showValidation }">
<legend>
<div class="usa-input__title">
{{ 'task_orders.form.pop_start' | translate }}
</div>
<p class='usa-input__help'>
{{ 'task_orders.form.pop_example' | translate }}
</p>
</legend>
<div class="date-picker-component">
<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>
@ -212,69 +231,93 @@
/> />
</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> </fieldset>
</fieldset> </date-selector>
</date-selector> </div>
</div>
<div class="form-row">
<div class="form-col">
<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 && showValidation }">
<legend>
<div class="usa-input__title">
{{ 'task_orders.form.pop_end' | translate }}
</div>
{{ Alert(message="A CLIN's period of performance must end before September 14, 2022.") }}
<p class='usa-input__help'>
{{ 'task_orders.form.pop_example' | translate }}
</p>
</legend>
<div class="date-picker-component">
<input :name="name" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
<div class="usa-form-group usa-form-group-month">
<label>{{ 'components.date_selector.month' | translate }}</label>
<input
name="date-month"
max="12"
maxlength="2"
min="1"
type="number"
v-bind:class="{ 'usa-input-error': (month && !isMonthValid) }"
v-model="month"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group usa-form-group-day">
<label>{{ 'components.date_selector.day' | translate }}</label>
<input
name="date-day"
maxlength="2"
min="1"
type="number"
v-bind:class="{ 'usa-input-error': (day && !isDayValid) }"
v-bind:max="daysMaxCalculation"
v-model="day"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group usa-form-group-year">
<label>{{ 'components.date_selector.year' | translate }}</label>
<input
name="date-year"
maxlength="4"
type="number"
v-model="year"
v-on:change="onInput"
/>
</div>
<div class="usa-form-group-date-ok" v-if="isDateValid">
{{ Icon("ok", classes="icon--green") }}
</div>
</div>
</fieldset>
</date-selector>
</div>
</div> </div>
{% endif %} {% endif %}
</div> <div class="form-row">
<div class="form-row"> <p class="usa-input-error-message form-has-errors">
<p class="usa-input-error-message form-has-errors"> <template v-if='showPopError'>
<template v-if='showPopError'> {% if fields and fields.start_date.errors %}
{% if fields and fields.start_date.errors %} {{ fields.start_date.errors[0] }}
{{ fields.start_date.errors[0] }} {% else %}
{% else %} {{ "forms.task_order.start_date_error" | translate }}
{{ "forms.task_order.start_date_error" | translate }} {% endif %}
{% endif %}
</template>
</p>
</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>
<template v-else> </p>
<span class='usa-input__message'></span> </div>
</template> </div>
</div>
</textinput>
{% endif %}
</div> </div>
</clin-fields> </clin-fields>
{% endmacro %} {% endmacro %}

View File

@ -165,10 +165,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: '0001: Unclassified IaaS and PaaS' clin_01_label: 'IaaS/PaaS (IDIQ CLIN 0001)'
clin_02_label: '0002' clin_02_label: 'IDIQ CLIN 0002'
clin_03_label: '0003' clin_03_label: 'IDIQ CLIN 0003'
clin_04_label: '0004' clin_04_label: 'IDIQ CLIN 0004'
complexity: complexity:
conus: CONUS access conus: CONUS access
data_analytics: Data analytics data_analytics: Data analytics
@ -189,7 +189,6 @@ forms:
military: Military military: Military
other: Other <em class='description'>(E.g. University or other partner)</em> other: Other <em class='description'>(E.g. University or other partner)</em>
dev_team_other_label: Development Team Other dev_team_other_label: Development Team Other
end_date_label: End of period of performance (PoP)
file_format_not_allowed: Only PDF or PNG files can be uploaded. file_format_not_allowed: Only PDF or PNG files can be uploaded.
native_apps: native_apps:
description: Do you plan to develop any applications in the cloud? description: Do you plan to develop any applications in the cloud?
@ -201,7 +200,6 @@ forms:
scope_description: 'What do you plan to do on the cloud? Some examples might include migrating an existing application or creating a prototype. You dont need to include a detailed plan of execution, but should list key requirements. This section will be reviewed by your contracting officer, but wont be sent to the CCPO. <p>Not sure how to describe your scope? <a href="#">Read some examples</a> to get some inspiration.</p>' scope_description: 'What do you plan to do on the cloud? Some examples might include migrating an existing application or creating a prototype. You dont need to include a detailed plan of execution, but should list key requirements. This section will be reviewed by your contracting officer, but wont be sent to the CCPO. <p>Not sure how to describe your scope? <a href="#">Read some examples</a> to get some inspiration.</p>'
scope_label: Cloud project scope scope_label: Cloud project scope
start_date_error: PoP start date must be before end date. start_date_error: PoP start date must be before end date.
start_date_label: Start of period of performance (PoP)
team_experience: team_experience:
built_1: Built, migrated, or consulted on 1-2 applications built_1: Built, migrated, or consulted on 1-2 applications
built_3: Built, migrated, or consulted on 3-5 applications built_3: Built, migrated, or consulted on 3-5 applications
@ -362,25 +360,32 @@ task_orders:
pop_start: PoP Start pop_start: PoP Start
pop_end: PoP End pop_end: PoP End
form: form:
add_clin: Enter another CLIN add_clin: Add another CLIN
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.
clin_title: Enter CLINs base_clin_title: CLIN
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_title: Enter Contract Line Items
base_clin_title: Base CLIN Information clin_description: "Refer to your task order to locate your Contract Line Item Numbers (CLINs)."
clin_number_label: Enter task order CLIN clin_details: CLIN Details
clin_type_label: "Select ID/IQ CLIN description" clin_funding: CLIN Funding
clin_number_label: CLIN Number
clin_type_label: Corresponding IDIQ CLIN
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.
obligated_funds_label: Enter obligated funds for Base CLIN obligated_funds_label: Obligated Funds
pop_end: 'Period of Performance (PoP) end date' pop: Period of Performance
pop_start: 'Period of Performance (PoP) start date' pop_end: End Date
pop_end_alert: "A CLIN's period of performance must end before September 14, 2022."
pop_example: "For example: 07 04 1776"
pop_start: 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 64MB supporting_docs_size_limit: Your file may not exceed 64MB
supporting_docs_text: Upload a single PDF containing all relevant information. supporting_docs_text: Upload a single PDF containing all relevant information.
step_3:
next_button: 'Next: Review Task Order'
step_5: step_5:
title: Confirm Signature title: Confirm Signature
description: Finally, plase confirm that your uploaded document representing the information you've entered contains the required signature from your Contracting Officer. You will be informed as soon as CCPO completes their review. description: Finally, plase confirm that your uploaded document representing the information you've entered contains the required signature from your Contracting Officer. You will be informed as soon as CCPO completes their review.