Merge pull request #1090 from dod-ccpo/clin-fields-test
Add a JS test for the clin-fields Vue component.
This commit is contained in:
commit
07b287e9aa
48
js/components/__tests__/clin_fields.test.js
Normal file
48
js/components/__tests__/clin_fields.test.js
Normal file
@ -0,0 +1,48 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import clinFields from '../clin_fields'
|
||||
|
||||
import { makeTestWrapper } from '../../test_utils/component_test_helpers'
|
||||
|
||||
const ClinFieldsWrapper = makeTestWrapper({
|
||||
components: { clinFields },
|
||||
templatePath: 'clin_fields.html',
|
||||
})
|
||||
|
||||
describe('ClinFields Test', () => {
|
||||
it('should calculate the percentage of obligated funds', () => {
|
||||
const wrapper = mount(ClinFieldsWrapper, {
|
||||
propsData: {
|
||||
initialData: {},
|
||||
},
|
||||
})
|
||||
const percentObligatedElement = wrapper.find('#percent-obligated')
|
||||
// test starts at zero
|
||||
expect(percentObligatedElement.text()).toBe('0%')
|
||||
|
||||
// test greater than 100%
|
||||
wrapper.find('input#obligated_amount').setValue('2')
|
||||
wrapper.find('input#total_amount').setValue('1')
|
||||
expect(percentObligatedElement.text()).toBe('>100%')
|
||||
|
||||
// test greater than 99% but less than 100%
|
||||
wrapper.find('input#obligated_amount').setValue('999')
|
||||
wrapper.find('input#total_amount').setValue('1000')
|
||||
expect(percentObligatedElement.text()).toBe('>99%')
|
||||
|
||||
// test a normal percentage
|
||||
wrapper.find('input#obligated_amount').setValue('1')
|
||||
wrapper.find('input#total_amount').setValue('2')
|
||||
expect(percentObligatedElement.text()).toBe('50%')
|
||||
|
||||
// test less than 1%
|
||||
wrapper.find('input#obligated_amount').setValue('1')
|
||||
wrapper.find('input#total_amount').setValue('1000')
|
||||
expect(percentObligatedElement.text()).toBe('<1%')
|
||||
|
||||
// test resets to zero
|
||||
wrapper.find('input#obligated_amount').setValue('0')
|
||||
wrapper.find('input#total_amount').setValue('0')
|
||||
expect(percentObligatedElement.text()).toBe('0%')
|
||||
})
|
||||
})
|
571
js/test_templates/clin_fields.html
Normal file
571
js/test_templates/clin_fields.html
Normal file
@ -0,0 +1,571 @@
|
||||
|
||||
<clin-fields
|
||||
|
||||
v-bind:initial-clin-index='0'
|
||||
v-bind:initial-total='0'
|
||||
v-bind:initial-obligated='0'
|
||||
v-bind:initial-start-date="'None'"
|
||||
v-bind:initial-end-date="'None'"
|
||||
v-bind:initial-clin-number="'None'"
|
||||
|
||||
v-bind:contract-start="'2019-09-14'"
|
||||
v-bind:contract-end="'2022-09-14'"
|
||||
inline-template>
|
||||
<div class="clin-card" v-if="showClin">
|
||||
<div class="card__title">
|
||||
<span class="h4" v-html='clinTitle'></span>
|
||||
<button
|
||||
v-if='$parent.clinIndex > 0'
|
||||
class="icon-link icon-link__remove-clin"
|
||||
v-on:click="openModal(removeModalId)"
|
||||
type="button">
|
||||
|
||||
<span class="icon icon--x " aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M2 2l12 12M14 15c-.256 0-.512-.098-.707-.293l-12-12c-.391-.391-.391-1.023 0-1.414s1.023-.391 1.414 0l12 12c.391.391.391 1.023 0 1.414-.195.195-.451.293-.707.293zm0-13L2 14"/><path d="M2 15c-.256 0-.512-.098-.707-.293-.391-.391-.391-1.023 0-1.414l12-12c.391-.391 1.023-.391 1.414 0s.391 1.023 0 1.414l-12 12C2.512 14.902 2.256 15 2 15z"/></svg>
|
||||
</span>
|
||||
|
||||
</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
CLIN Details
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
|
||||
<textinput
|
||||
v-cloak
|
||||
name='number'
|
||||
validation='anything'
|
||||
|
||||
|
||||
|
||||
|
||||
v-bind:optional=false
|
||||
key='number'
|
||||
:watch='true'
|
||||
inline-template>
|
||||
|
||||
<div
|
||||
class=' '
|
||||
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=number>
|
||||
<div class="usa-input__title">
|
||||
CLIN
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<span v-show='showError'>
|
||||
<span class="icon icon--alert icon-validation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-show='showValid'>
|
||||
<span class="icon icon--ok icon-validation" 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>
|
||||
|
||||
|
||||
</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='number'
|
||||
|
||||
ref='input'
|
||||
placeholder=''>
|
||||
</masked-input>
|
||||
|
||||
|
||||
|
||||
<input
|
||||
type='hidden'
|
||||
v-bind:value='rawValue'
|
||||
|
||||
name='number'
|
||||
|
||||
/>
|
||||
|
||||
|
||||
<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="form-row">
|
||||
<div class="form-col">
|
||||
|
||||
<optionsinput
|
||||
name='jedi_clin_type'
|
||||
inline-template
|
||||
|
||||
|
||||
key='jedi_clin_type'
|
||||
v-bind:watch='true'
|
||||
v-bind:optional=false
|
||||
v-bind:null-option="'None'"
|
||||
>
|
||||
<div
|
||||
v-bind:class="['usa-input', { 'usa-input--error': showError, 'usa-input--success': showValid }]">
|
||||
|
||||
<fieldset data-ally-disabled="true" v-on:change="onInput" class="usa-input__choices ">
|
||||
|
||||
<legend>
|
||||
<div class="usa-input__title-inline">
|
||||
Corresponding IDIQ CLIN
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</legend>
|
||||
|
||||
|
||||
<select id="jedi_clin_type" name="jedi_clin_type"><option value="JEDI_CLIN_1">IaaS/PaaS (IDIQ CLIN 0001)</option><option value="JEDI_CLIN_2">IDIQ CLIN 0002</option><option value="JEDI_CLIN_3">IDIQ CLIN 0003</option><option value="JEDI_CLIN_4">IDIQ CLIN 0004</option></select>
|
||||
|
||||
<template v-if='showError'>
|
||||
<span class='usa-input__message' v-html='validationError'></span>
|
||||
</template>
|
||||
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</optionsinput>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
CLIN Funding
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<clindollaramount
|
||||
v-cloak
|
||||
inline-template
|
||||
|
||||
:funding-valid='true'
|
||||
|
||||
|
||||
name='total_amount'
|
||||
|
||||
|
||||
key='total_amount'
|
||||
|
||||
|
||||
validation="clinDollars"
|
||||
:watch='true'>
|
||||
<div v-bind:class="['usa-input usa-input--validation--dollars', { 'usa-input--error': showFundingError, 'usa-input--success': showFundingValid}]">
|
||||
|
||||
<label for='total_amount'>
|
||||
|
||||
|
||||
|
||||
<div class="usa-input__title">Total CLIN Value</div>
|
||||
|
||||
<span v-show='showFundingError'>
|
||||
<span class="icon icon--alert icon-validation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-show='showFundingValid'>
|
||||
<span class="icon icon--ok icon-validation" 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>
|
||||
</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='!fundingValid'>
|
||||
<span class='usa-input__message'>Obligated amount must be less than or equal to total amount</span>
|
||||
</template>
|
||||
<template v-else-if='showError'>
|
||||
<span class='usa-input__message' v-html='validationError'></span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class='usa-input__message'></span>
|
||||
</template>
|
||||
</div>
|
||||
</clindollaramount>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<clindollaramount
|
||||
v-cloak
|
||||
inline-template
|
||||
|
||||
:funding-valid='fundingValid'
|
||||
|
||||
|
||||
name='obligated_amount'
|
||||
|
||||
|
||||
key='obligated_amount'
|
||||
|
||||
|
||||
validation="clinDollars"
|
||||
:watch='true'>
|
||||
<div v-bind:class="['usa-input usa-input--validation--dollars', { 'usa-input--error': showFundingError, 'usa-input--success': showFundingValid}]">
|
||||
|
||||
<label for='obligated_amount'>
|
||||
|
||||
|
||||
|
||||
<div class="usa-input__title">Obligated Funds</div>
|
||||
|
||||
<span v-show='showFundingError'>
|
||||
<span class="icon icon--alert icon-validation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span v-show='showFundingValid'>
|
||||
<span class="icon icon--ok icon-validation" 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>
|
||||
</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='!fundingValid'>
|
||||
<span class='usa-input__message'>Obligated amount must be less than or equal to total amount</span>
|
||||
</template>
|
||||
<template v-else-if='showError'>
|
||||
<span class='usa-input__message' v-html='validationError'></span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class='usa-input__message'></span>
|
||||
</template>
|
||||
</div>
|
||||
</clindollaramount>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="h5 clin-card__title">Percent Obligated</div>
|
||||
<p id="percent-obligated" v-html='percentObligated'></p>
|
||||
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
Period of Performance
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<date-selector
|
||||
|
||||
|
||||
name-tag='start_date'
|
||||
initialmonth=""
|
||||
initialday=""
|
||||
initialyear=""
|
||||
v-bind: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">
|
||||
Start Date
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class='usa-input__help'>
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
</legend>
|
||||
|
||||
<div class="date-picker-component">
|
||||
<input name="start_date" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
|
||||
|
||||
<div class="usa-form-group usa-form-group-month">
|
||||
<label>Month</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>Day</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>Year</label>
|
||||
<input
|
||||
id="date-year"
|
||||
maxlength="4"
|
||||
type="number"
|
||||
v-model="year"
|
||||
|
||||
|
||||
v-on:change="onInput"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="showValidation">
|
||||
<div class="usa-form-group-date-ok" v-if="isDateValid">
|
||||
|
||||
<span class="icon icon--ok icon--green" 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>
|
||||
|
||||
</div>
|
||||
<div class="usa-form-group-date-ok" v-else>
|
||||
|
||||
<span class="icon icon--alert icon--red" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</date-selector>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<date-selector
|
||||
|
||||
|
||||
name-tag='end_date'
|
||||
initialmonth=""
|
||||
initialday=""
|
||||
initialyear=""
|
||||
v-bind: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">
|
||||
End Date
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class='usa-alert usa-alert-info' role='alert' aria-live='polite'>
|
||||
|
||||
<div class='usa-alert-body'>
|
||||
|
||||
|
||||
|
||||
<p class='usa-alert-text'>
|
||||
A CLIN's period of performance must end before September 14, 2022.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class='usa-input__help'>
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
</legend>
|
||||
|
||||
<div class="date-picker-component">
|
||||
<input name="end_date" v-bind:value="formattedDate" v-on:change="onInput" type="hidden" />
|
||||
|
||||
<div class="usa-form-group usa-form-group-month">
|
||||
<label>Month</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>Day</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>Year</label>
|
||||
<input
|
||||
id="date-year"
|
||||
maxlength="4"
|
||||
type="number"
|
||||
v-model="year"
|
||||
|
||||
|
||||
v-on:change="onInput"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="showValidation">
|
||||
<div class="usa-form-group-date-ok" v-if="isDateValid">
|
||||
|
||||
<span class="icon icon--ok icon--green" 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>
|
||||
|
||||
</div>
|
||||
<div class="usa-form-group-date-ok" v-else>
|
||||
|
||||
<span class="icon icon--alert icon--red" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</date-selector>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="usa-input-error-message form-has-errors">
|
||||
<p v-for="error in popErrors" :key="error" v-html='error'></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="$root.activeModal === removeModalId" v-cloak>
|
||||
<div :id='"modal--" + removeModalId' class='modal modal--dismissable'>
|
||||
<div class='modal__container'>
|
||||
<div class='modal__dialog' role='dialog' aria-modal='true'>
|
||||
<div class='modal__body'>
|
||||
<div class="task-order__modal-cancel">
|
||||
<h1 v-html='"Do you want to remove " + clinTitle + "?"'></h1>
|
||||
<div class="task-order__modal-cancel_buttons">
|
||||
<button
|
||||
v-on:click='closeModal(removeModalId)'
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
No, go back
|
||||
</button>
|
||||
<button
|
||||
v-on:click="removeClin()"
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
Yes, remove CLIN
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type='button' class='icon-link modal__dismiss' v-on:click='closeModal(removeModalId)'>
|
||||
|
||||
<span class="icon icon--x " aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M2 2l12 12M14 15c-.256 0-.512-.098-.707-.293l-12-12c-.391-.391-.391-1.023 0-1.414s1.023-.391 1.414 0l12 12c.391.391.391 1.023 0 1.414-.195.195-.451.293-.707.293zm0-13L2 14"/><path d="M2 15c-.256 0-.512-.098-.707-.293-.391-.391-.391-1.023 0-1.414l12-12c.391-.391 1.023-.391 1.414 0s.391 1.023 0 1.414l-12 12C2.512 14.902 2.256 15 2 15z"/></svg>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</clin-fields>
|
319
templates/components/clin_fields.html
Normal file
319
templates/components/clin_fields.html
Normal file
@ -0,0 +1,319 @@
|
||||
{% from "components/clin_dollar_amount.html" import CLINDollarAmount %}
|
||||
{% from 'components/alert.html' import Alert %}
|
||||
{% from 'components/date_picker.html' import DatePicker %}
|
||||
{% from 'components/icon.html' import Icon %}
|
||||
{% from 'components/options_input.html' import OptionsInput %}
|
||||
{% from 'components/text_input.html' import TextInput %}
|
||||
|
||||
{% macro CLINFields(contract_start, contract_end, fields=None, index=None) %}
|
||||
<clin-fields
|
||||
{% if fields %}
|
||||
v-bind:initial-clin-index='{{ index }}'
|
||||
v-bind:initial-total='{{ fields.total_amount.data or 0 }}'
|
||||
v-bind:initial-obligated='{{ fields.obligated_amount.data or 0 }}'
|
||||
v-bind:initial-start-date="'{{ fields.start_date.data | string }}'"
|
||||
v-bind:initial-end-date="'{{ fields.end_date.data | string }}'"
|
||||
v-bind:initial-clin-number="'{{ fields.number.data | string }}'"
|
||||
{% else %}
|
||||
v-bind:initial-clin-index='clinIndex'
|
||||
v-bind:initial-clin-type="'JEDI_CLIN_1'"
|
||||
{% endif %}
|
||||
v-bind:contract-start="'{{ contract_start | string }}'"
|
||||
v-bind:contract-end="'{{ contract_end | string }}'"
|
||||
inline-template>
|
||||
<div class="clin-card" v-if="showClin">
|
||||
<div class="card__title">
|
||||
<span class="h4" v-html='clinTitle'></span>
|
||||
<button
|
||||
v-if='clinIndex > 0'
|
||||
class="icon-link icon-link__remove-clin"
|
||||
v-on:click="openModal(removeModalId)"
|
||||
type="button">
|
||||
{{ Icon(name='x') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
{{ 'task_orders.form.clin_details' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
{% if fields %}
|
||||
{{ TextInput(fields.number, watch=True, optional=False) }}
|
||||
{% 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>
|
||||
|
||||
<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">
|
||||
<div class="form-col">
|
||||
{% if fields %}
|
||||
{{ OptionsInput(fields.jedi_clin_type, watch=True, show_validation=False, optional=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 %}
|
||||
{{ CLINDollarAmount("total", field=fields.total_amount) }}
|
||||
{{ CLINDollarAmount("obligated", field=fields.obligated_amount, funding_validation=True) }}
|
||||
{% else %}
|
||||
{{ CLINDollarAmount("total") }}
|
||||
{{ CLINDollarAmount("obligated", funding_validation=True) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="h5 clin-card__title">Percent Obligated</div>
|
||||
<p id="percent-obligated" v-html='percentObligated'></p>
|
||||
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
{{ 'task_orders.form.pop' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
{% set contract_end_formatted = contract_end | dateFromString(formatter="%Y-%m-%d") | formattedDate(formatter="%B %d, %Y") %}
|
||||
{% 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({'end_date': contract_end_formatted})) }}
|
||||
{% 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">
|
||||
<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 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="task_orders.form.pop_end_alert" | translate({'end_date': contract_end_formatted})) }}
|
||||
|
||||
<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>
|
||||
{% endif %}
|
||||
<div class="form-row">
|
||||
<div class="usa-input-error-message form-has-errors">
|
||||
<p v-for="error in popErrors" :key="error" v-html='error'></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="$root.activeModal === removeModalId" v-cloak>
|
||||
<div :id='"modal--" + removeModalId' class='modal modal--dismissable'>
|
||||
<div class='modal__container'>
|
||||
<div class='modal__dialog' role='dialog' aria-modal='true'>
|
||||
<div class='modal__body'>
|
||||
<div class="task-order__modal-cancel">
|
||||
<h1 v-html='"{{ 'task_orders.form.clin_remove_text' | translate }}" + clinTitle + "?"'></h1>
|
||||
<div class="task-order__modal-cancel_buttons">
|
||||
<button
|
||||
v-on:click='closeModal(removeModalId)'
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
{{ 'task_orders.form.clin_remove_cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
v-on:click="removeClin()"
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
{{ 'task_orders.form.clin_remove_confirm' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type='button' class='icon-link modal__dismiss' v-on:click='closeModal(removeModalId)'>
|
||||
{{ Icon('x') }}
|
||||
<span>
|
||||
{{ "common.close" | translate }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</clin-fields>
|
||||
{% endmacro %}
|
@ -1,11 +1,7 @@
|
||||
{% extends "task_orders/builder_base.html" %}
|
||||
|
||||
{% from 'components/alert.html' import Alert %}
|
||||
{% from 'components/date_picker.html' import DatePicker %}
|
||||
{% from 'components/icon.html' import Icon %}
|
||||
{% from 'components/options_input.html' import OptionsInput %}
|
||||
{% from 'components/text_input.html' import TextInput %}
|
||||
{% from "components/clin_dollar_amount.html" import CLINDollarAmount %}
|
||||
{% from "components/clin_fields.html" import CLINFields %}
|
||||
{% 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) %}
|
||||
@ -13,330 +9,17 @@
|
||||
{% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %}
|
||||
{% set step = "3" %}
|
||||
|
||||
{% macro CLINFields(fields=None, index=None) %}
|
||||
<clin-fields
|
||||
{% if fields %}
|
||||
v-bind:initial-clin-index='{{ index }}'
|
||||
v-bind:initial-total='{{ fields.total_amount.data or 0 }}'
|
||||
v-bind:initial-obligated='{{ fields.obligated_amount.data or 0 }}'
|
||||
v-bind:initial-start-date="'{{ fields.start_date.data | string }}'"
|
||||
v-bind:initial-end-date="'{{ fields.end_date.data | string }}'"
|
||||
v-bind:initial-clin-number="'{{ fields.number.data | string }}'"
|
||||
{% else %}
|
||||
v-bind:initial-clin-index='clinIndex'
|
||||
v-bind:initial-clin-type="'JEDI_CLIN_1'"
|
||||
{% endif %}
|
||||
v-bind:contract-start="'{{ contract_start | string }}'"
|
||||
v-bind:contract-end="'{{ contract_end | string }}'"
|
||||
inline-template>
|
||||
<div class="clin-card" v-if="showClin">
|
||||
<div class="card__title">
|
||||
<span class="h4" v-html='clinTitle'></span>
|
||||
<button
|
||||
v-if='$parent.clinIndex > 0'
|
||||
class="icon-link icon-link__remove-clin"
|
||||
v-on:click="openModal(removeModalId)"
|
||||
type="button">
|
||||
{{ Icon(name='x') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
{{ 'task_orders.form.clin_details' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
{% if fields %}
|
||||
{{ TextInput(fields.number, watch=True, optional=False) }}
|
||||
{% 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>
|
||||
|
||||
<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">
|
||||
<div class="form-col">
|
||||
{% if fields %}
|
||||
{{ OptionsInput(fields.jedi_clin_type, watch=True, show_validation=False, optional=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 %}
|
||||
{{ CLINDollarAmount("total", field=fields.total_amount) }}
|
||||
{{ CLINDollarAmount("obligated", field=fields.obligated_amount, funding_validation=True) }}
|
||||
{% else %}
|
||||
{{ CLINDollarAmount("total") }}
|
||||
{{ CLINDollarAmount("obligated", funding_validation=True) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="h5 clin-card__title">Percent Obligated</div>
|
||||
<p v-html='percentObligated'></p>
|
||||
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="h4 clin-card__title">
|
||||
{{ 'task_orders.form.pop' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
{% set contract_end_formatted = contract_end | dateFromString(formatter="%Y-%m-%d") | formattedDate(formatter="%B %d, %Y") %}
|
||||
{% 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({'end_date': contract_end_formatted})) }}
|
||||
{% 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">
|
||||
<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 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="task_orders.form.pop_end_alert" | translate({'end_date': contract_end_formatted})) }}
|
||||
|
||||
<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>
|
||||
{% endif %}
|
||||
<div class="form-row">
|
||||
<div class="usa-input-error-message form-has-errors">
|
||||
<p v-for="error in popErrors" :key="error" v-html='error'></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="$root.activeModal === removeModalId" v-cloak>
|
||||
<div :id='"modal--" + removeModalId' class='modal modal--dismissable'>
|
||||
<div class='modal__container'>
|
||||
<div class='modal__dialog' role='dialog' aria-modal='true'>
|
||||
<div class='modal__body'>
|
||||
<div class="task-order__modal-cancel">
|
||||
<h1 v-html='"{{ 'task_orders.form.clin_remove_text' | translate }}" + clinTitle + "?"'></h1>
|
||||
<div class="task-order__modal-cancel_buttons">
|
||||
<button
|
||||
v-on:click='closeModal(removeModalId)'
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
{{ 'task_orders.form.clin_remove_cancel' | translate }}
|
||||
</button>
|
||||
<button
|
||||
v-on:click="removeClin()"
|
||||
class="usa-button usa-button-primary"
|
||||
type="button">
|
||||
{{ 'task_orders.form.clin_remove_confirm' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type='button' class='icon-link modal__dismiss' v-on:click='closeModal(removeModalId)'>
|
||||
{{ Icon('x') }}
|
||||
<span>
|
||||
{{ "common.close" | translate }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</clin-fields>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% block to_builder_form_field %}
|
||||
<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) }}
|
||||
{{ CLINFields(contract_start, contract_end, clin, index=loop.index - 1) }}
|
||||
{% endfor %}
|
||||
|
||||
<div v-for="clin in clins">
|
||||
{{ CLINFields() }}
|
||||
{{ CLINFields(contract_start, contract_end) }}
|
||||
</div>
|
||||
|
||||
<button
|
||||
|
@ -1,11 +1,12 @@
|
||||
import pytest
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from wtforms.widgets import CheckboxInput
|
||||
from wtforms import Form, FormField
|
||||
from wtforms.fields import StringField
|
||||
from wtforms.validators import InputRequired
|
||||
from wtforms import Form, FormField
|
||||
from wtforms.widgets import CheckboxInput
|
||||
|
||||
from atst.forms.task_order import CLINForm
|
||||
from atst.forms.task_order import TaskOrderForm
|
||||
from atst.models import Permissions
|
||||
from atst.routes.task_orders.new import render_task_orders_edit
|
||||
@ -92,7 +93,7 @@ def test_make_upload_input_error_template(upload_input_macro, task_order_form):
|
||||
write_template(rendered_upload_macro, "upload_input_error_template.html")
|
||||
|
||||
|
||||
def test_make_task_order_step3_template(app, request_ctx):
|
||||
def test_make_task_order_with_clin_form_template(app, request_ctx):
|
||||
request_ctx.g.current_user = factories.UserFactory.create()
|
||||
request_ctx.g.application = None
|
||||
request_ctx.g.portfolio = None
|
||||
@ -122,3 +123,15 @@ def test_make_task_order_step3_template(app, request_ctx):
|
||||
dom = BeautifulSoup(step3, "html.parser")
|
||||
to_form = dom.find("to-form")
|
||||
write_template(str(to_form), "to_form.html")
|
||||
|
||||
|
||||
def test_make_clin_fields(env, app):
|
||||
step3_template = env.get_template("components/clin_fields.html")
|
||||
clin_fields_macro = getattr(step3_template.module, "CLINFields")
|
||||
clin_fields = clin_fields_macro(
|
||||
app.config.get("CONTRACT_START_DATE"),
|
||||
app.config.get("CONTRACT_END_DATE"),
|
||||
CLINForm(),
|
||||
0,
|
||||
)
|
||||
write_template(clin_fields, "clin_fields.html")
|
||||
|
Loading…
x
Reference in New Issue
Block a user