Merge pull request #590 from dod-ccpo/update-officer-multiple-changes
Better updating of multiple officers
This commit is contained in:
commit
50f0843caf
@ -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
|
||||
|
||||
|
||||
@ -39,3 +39,14 @@ class NumberStringField(StringField):
|
||||
self.data = str(value)
|
||||
else:
|
||||
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
|
||||
|
@ -1,11 +1,12 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms.fields import FormField, StringField
|
||||
from wtforms.fields import StringField
|
||||
from wtforms.fields.html5 import TelField
|
||||
from wtforms.validators import Length, Optional
|
||||
|
||||
from atst.forms.validators import IsNumber, PhoneNumber
|
||||
|
||||
from .forms import CacheableForm
|
||||
from .fields import FormFieldWrapper
|
||||
|
||||
|
||||
class OfficerForm(FlaskForm):
|
||||
@ -18,9 +19,9 @@ class OfficerForm(FlaskForm):
|
||||
|
||||
class EditTaskOrderOfficersForm(CacheableForm):
|
||||
|
||||
contracting_officer = FormField(OfficerForm)
|
||||
contracting_officer_representative = FormField(OfficerForm)
|
||||
security_officer = FormField(OfficerForm)
|
||||
contracting_officer = FormFieldWrapper(OfficerForm)
|
||||
contracting_officer_representative = FormFieldWrapper(OfficerForm)
|
||||
security_officer = FormFieldWrapper(OfficerForm)
|
||||
|
||||
OFFICER_PREFIXES = {
|
||||
"contracting_officer": "ko",
|
||||
|
@ -22,6 +22,13 @@ describe('EditOfficerForm', () => {
|
||||
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', () => {
|
||||
const wrapper = shallowMount(EditOfficerForm)
|
||||
wrapper.vm.edit({ preventDefault: () => null })
|
||||
|
@ -13,6 +13,10 @@ export default {
|
||||
},
|
||||
|
||||
props: {
|
||||
hasChanges: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
hasErrors: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
@ -21,7 +25,7 @@ export default {
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
editing: this.hasErrors,
|
||||
editing: this.hasErrors || this.hasChanges,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
<h2 class="officer__title">{{ ("task_orders.invitations." + officer_type + ".title") | translate }}</h2>
|
||||
<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>
|
||||
|
||||
{% set prefix = { "contracting_officer": "ko", "contracting_officer_representative": "cor", "security_officer": "so" }[officer_type] %}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
from wtforms import Form
|
||||
from wtforms.fields import StringField
|
||||
import pendulum
|
||||
from werkzeug.datastructures import ImmutableMultiDict
|
||||
|
||||
from atst.forms.fields import NewlineListField
|
||||
from atst.forms.fields import NewlineListField, FormFieldWrapper
|
||||
|
||||
|
||||
class NewlineListForm(Form):
|
||||
@ -38,3 +39,37 @@ def test_newline_list_value(input_, expected):
|
||||
|
||||
assert form.validate()
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user