Merge pull request #590 from dod-ccpo/update-officer-multiple-changes

Better updating of multiple officers
This commit is contained in:
patricksmithdds 2019-01-31 17:17:15 -05:00 committed by GitHub
commit 50f0843caf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 8 deletions

View File

@ -1,4 +1,4 @@
from wtforms.fields import Field, StringField, SelectField as SelectField_ from wtforms.fields import Field, FormField, StringField, SelectField as SelectField_
from wtforms.widgets import TextArea from wtforms.widgets import TextArea
@ -39,3 +39,14 @@ class NumberStringField(StringField):
self.data = str(value) self.data = str(value)
else: else:
self.data = value self.data = value
class FormFieldWrapper(FormField):
def has_changes(self):
if not self.object_data:
return False
for (attr, field) in self._fields.items():
if attr in self.object_data and self.object_data[attr] != field.data:
return True
return False

View File

@ -1,11 +1,12 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms.fields import FormField, StringField from wtforms.fields import StringField
from wtforms.fields.html5 import TelField from wtforms.fields.html5 import TelField
from wtforms.validators import Length, Optional from wtforms.validators import Length, Optional
from atst.forms.validators import IsNumber, PhoneNumber from atst.forms.validators import IsNumber, PhoneNumber
from .forms import CacheableForm from .forms import CacheableForm
from .fields import FormFieldWrapper
class OfficerForm(FlaskForm): class OfficerForm(FlaskForm):
@ -18,9 +19,9 @@ class OfficerForm(FlaskForm):
class EditTaskOrderOfficersForm(CacheableForm): class EditTaskOrderOfficersForm(CacheableForm):
contracting_officer = FormField(OfficerForm) contracting_officer = FormFieldWrapper(OfficerForm)
contracting_officer_representative = FormField(OfficerForm) contracting_officer_representative = FormFieldWrapper(OfficerForm)
security_officer = FormField(OfficerForm) security_officer = FormFieldWrapper(OfficerForm)
OFFICER_PREFIXES = { OFFICER_PREFIXES = {
"contracting_officer": "ko", "contracting_officer": "ko",

View File

@ -22,6 +22,13 @@ describe('EditOfficerForm', () => {
expect(wrapper.vm.$data.editing).toEqual(true) expect(wrapper.vm.$data.editing).toEqual(true)
}) })
it('does start in editing mode when the form has changes', () => {
const wrapper = shallowMount(EditOfficerForm, {
propsData: { hasChanges: true },
})
expect(wrapper.vm.$data.editing).toEqual(true)
})
it('starts editing when edit method called', () => { it('starts editing when edit method called', () => {
const wrapper = shallowMount(EditOfficerForm) const wrapper = shallowMount(EditOfficerForm)
wrapper.vm.edit({ preventDefault: () => null }) wrapper.vm.edit({ preventDefault: () => null })

View File

@ -13,6 +13,10 @@ export default {
}, },
props: { props: {
hasChanges: {
type: Boolean,
default: () => false,
},
hasErrors: { hasErrors: {
type: Boolean, type: Boolean,
default: () => false, default: () => false,
@ -21,7 +25,7 @@ export default {
data: function() { data: function() {
return { return {
editing: this.hasErrors, editing: this.hasErrors || this.hasChanges,
} }
}, },

View File

@ -56,7 +56,7 @@
<h2 class="officer__title">{{ ("task_orders.invitations." + officer_type + ".title") | translate }}</h2> <h2 class="officer__title">{{ ("task_orders.invitations." + officer_type + ".title") | translate }}</h2>
<p class="officer__description">{{ ("task_orders.invitations." + officer_type + ".description") | translate }}</p> <p class="officer__description">{{ ("task_orders.invitations." + officer_type + ".description") | translate }}</p>
<edit-officer-form v-bind:has-errors='{{ ((form.errors|length) > 0)|tojson }}' inline-template> <edit-officer-form v-bind:has-errors='{{ ((form.errors|length) > 0)|tojson }}' v-bind:has-changes='{{ form.has_changes() | tojson }}' inline-template>
<div> <div>
{% set prefix = { "contracting_officer": "ko", "contracting_officer_representative": "cor", "security_officer": "so" }[officer_type] %} {% set prefix = { "contracting_officer": "ko", "contracting_officer_representative": "cor", "security_officer": "so" }[officer_type] %}

View File

@ -1,9 +1,10 @@
import pytest import pytest
from wtforms import Form from wtforms import Form
from wtforms.fields import StringField
import pendulum import pendulum
from werkzeug.datastructures import ImmutableMultiDict from werkzeug.datastructures import ImmutableMultiDict
from atst.forms.fields import NewlineListField from atst.forms.fields import NewlineListField, FormFieldWrapper
class NewlineListForm(Form): class NewlineListForm(Form):
@ -38,3 +39,37 @@ def test_newline_list_value(input_, expected):
assert form.validate() assert form.validate()
assert form.newline_list._value() == expected assert form.newline_list._value() == expected
class PersonForm(Form):
first_name = StringField("first_name")
class FormWithFormField(Form):
person = FormFieldWrapper(PersonForm)
class TestFormFieldWrapper:
class Foo:
person = {"first_name": "Luke"}
obj = Foo()
def test_form_data_does_not_match_object_data(self):
form_data = ImmutableMultiDict({"person-first_name": "Han"})
form = FormWithFormField(form_data, obj=self.obj)
assert form.person.has_changes()
def test_when_no_form_data(self):
form = FormWithFormField(None, obj=self.obj)
assert not form.person.has_changes()
def test_when_no_obj_data(self):
form_data = ImmutableMultiDict({"person-first_name": "Han"})
form = FormWithFormField(form_data)
assert not form.person.has_changes()
def test_when_form_data_matches_obj_dta(self):
form_data = ImmutableMultiDict({"person-first_name": "Luke"})
form = FormWithFormField(form_data, obj=self.obj)
assert not form.person.has_changes()