From b68097d665c64d0332c7189c86687e2d5e735d78 Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 20 Dec 2018 13:54:51 -0500 Subject: [PATCH 01/18] Use widgets to get checkboxes and add some vue --- atst/forms/task_order.py | 5 +++ js/components/forms/poc.js | 2 -- js/components/multi_checkbox_input.js | 44 +++++++++++++++++++++++++ js/components/other_input.js | 29 ++++++++++++++++ js/index.js | 4 +++ templates/task_orders/new/app_info.html | 12 +++++-- 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 js/components/multi_checkbox_input.js create mode 100644 js/components/other_input.js diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index 903149fe..f565cbf4 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -7,6 +7,7 @@ from wtforms.fields import ( TextAreaField, ) from wtforms.fields.html5 import DateField +from wtforms.widgets import ListWidget, CheckboxInput from .forms import CacheableForm from .data import ( @@ -46,6 +47,8 @@ class AppInfoForm(CacheableForm): description="Which of these describes how complex your team's use of the cloud will be? (Select all that apply.)", choices=PROJECT_COMPLEXITY, default="", + widget=ListWidget(prefix_label=False), + option_widget=CheckboxInput() ) complexity_other = StringField("Project Complexity Other") dev_team = SelectMultipleField( @@ -53,6 +56,8 @@ class AppInfoForm(CacheableForm): description="Which people or teams will be completing the development work for your cloud applications?", choices=DEV_TEAM, default="", + widget=ListWidget(prefix_label=False), + option_widget=CheckboxInput() ) dev_team_other = StringField("Development Team Other") team_experience = RadioField( diff --git a/js/components/forms/poc.js b/js/components/forms/poc.js index 8b60c0b6..91b5dbfc 100644 --- a/js/components/forms/poc.js +++ b/js/components/forms/poc.js @@ -1,5 +1,4 @@ import FormMixin from '../../mixins/form' -import optionsinput from '../options_input' import textinput from '../text_input' import checkboxinput from '../checkbox_input' @@ -9,7 +8,6 @@ export default { mixins: [FormMixin], components: { - optionsinput, textinput, checkboxinput, }, diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js new file mode 100644 index 00000000..f5e7ccbd --- /dev/null +++ b/js/components/multi_checkbox_input.js @@ -0,0 +1,44 @@ +import otherinput from '../components/other_input' +import optionsinput from '../components/options_input' +import textinput from '../components/text_input' + +export default { + name: 'multicheckboxinput', + + components: { + otherinput, + optionsinput, + textinput, + }, + + props: { + name: String, + initialErrors: { + type: Array, + default: () => [] + }, + initialValue: Array, + }, + + + data: function () { + const showError = (this.initialErrors && this.initialErrors.length) || false + return { + showError: showError, + showValid: !showError && !!this.initialValue, + validationError: this.initialErrors.join(' ') + } + }, + + + methods: { + onInput: function (e) { + this.$root.$emit('field-change', { + value: e.target.value, + name: this.name + }) + this.showError = false + this.showValid = true + } + } +} diff --git a/js/components/other_input.js b/js/components/other_input.js new file mode 100644 index 00000000..c2431b85 --- /dev/null +++ b/js/components/other_input.js @@ -0,0 +1,29 @@ +import FormMixin from '../mixins/form' +import textinput from '../components/text_input' + +export default { + name: 'otherinput', + + mixins: [FormMixin], + + components: { + textinput, + }, + + props: { + initialData: { + type: Array, + default: () => ({}) + } + }, + + data: function () { + const { + other = true + } = this.initialData + + return { + other + } + } +} diff --git a/js/index.js b/js/index.js index 1cfea514..39271984 100644 --- a/js/index.js +++ b/js/index.js @@ -6,6 +6,8 @@ import Vue from 'vue/dist/vue' import VTooltip from 'v-tooltip' import optionsinput from './components/options_input' +import multicheckboxinput from './components/multi_checkbox_input' +import otherinput from './components/other_input' import textinput from './components/text_input' import checkboxinput from './components/checkbox_input' import DetailsOfUse from './components/forms/details_of_use' @@ -37,6 +39,8 @@ const app = new Vue({ components: { toggler, optionsinput, + multicheckboxinput, + otherinput, textinput, checkboxinput, DetailsOfUse, diff --git a/templates/task_orders/new/app_info.html b/templates/task_orders/new/app_info.html index 09a088a7..dc8e6d02 100644 --- a/templates/task_orders/new/app_info.html +++ b/templates/task_orders/new/app_info.html @@ -28,8 +28,16 @@

About Your Project

{{ OptionsInput(form.app_migration) }} {{ OptionsInput(form.native_apps) }} -{{ OptionsInput(form.complexity) }} -{{ TextInput(form.complexity_other) }} + + +
+ {{ OptionsInput(form.complexity) }} + {{ TextInput(form.complexity_other) }} + +
{{ TextInput(form.complexity_other) }}
+
+
+

From 96df6ff4850ed180c5cf9412877fe7728a24bb5f Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Wed, 2 Jan 2019 12:04:59 -0500 Subject: [PATCH 02/18] Add macro for MultiCheckboxInput --- .../components/multi_checkbox_input.html | 52 +++++++++++++++++++ templates/task_orders/new/app_info.html | 12 +---- 2 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 templates/components/multi_checkbox_input.html diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html new file mode 100644 index 00000000..b11ec0ae --- /dev/null +++ b/templates/components/multi_checkbox_input.html @@ -0,0 +1,52 @@ +{% from "components/icon.html" import Icon %} +{% from "components/tooltip.html" import Tooltip %} + +{% macro MultiCheckboxInput(field, tooltip, inline=False) -%} + +
+ +
+ +
+ {{ field.label | striptags}} + {% if tooltip %}{{ Tooltip(tooltip) }}{% endif %} +
+ + {% if field.description %} + {{ field.description | safe }} + {% endif %} + + {{ Icon('alert',classes="icon-validation") }} + {{ Icon('ok',classes="icon-validation") }} +
+ +
    + {% for f in field.choices %} +
  • + + + {% if f[0] == 'other' %} + + {% endif %} +
  • + {% endfor %} +
+ + + + + +
+
+ +
+ +{%- endmacro %} diff --git a/templates/task_orders/new/app_info.html b/templates/task_orders/new/app_info.html index dc8e6d02..6116e153 100644 --- a/templates/task_orders/new/app_info.html +++ b/templates/task_orders/new/app_info.html @@ -3,6 +3,7 @@ {% from "components/text_input.html" import TextInput %} {% from "components/options_input.html" import OptionsInput %} {% from "components/date_input.html" import DateInput %} +{% from "components/multi_checkbox_input.html" import MultiCheckboxInput %} {% block heading %} What You're Building @@ -28,16 +29,7 @@

About Your Project

{{ OptionsInput(form.app_migration) }} {{ OptionsInput(form.native_apps) }} - - -
- {{ OptionsInput(form.complexity) }} - {{ TextInput(form.complexity_other) }} - -
{{ TextInput(form.complexity_other) }}
-
-
-
+{{ MultiCheckboxInput(form.complexity) }}
From 9ff21bb58baea518f623a7e1cd9eb28494357ed4 Mon Sep 17 00:00:00 2001 From: Montana Date: Wed, 2 Jan 2019 13:47:00 -0500 Subject: [PATCH 03/18] Toggle other text input --- js/components/multi_checkbox_input.js | 6 +++++- templates/components/multi_checkbox_input.html | 10 ++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index f5e7ccbd..1f41637b 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -18,6 +18,7 @@ export default { default: () => [] }, initialValue: Array, + otherChecked: Boolean, }, @@ -26,7 +27,7 @@ export default { return { showError: showError, showValid: !showError && !!this.initialValue, - validationError: this.initialErrors.join(' ') + validationError: this.initialErrors.join(' '), } }, @@ -39,6 +40,9 @@ export default { }) this.showError = false this.showValid = true + }, + otherToggle: function() { + this.otherChecked = !this.otherChecked } } } diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index b11ec0ae..3adc0891 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -29,10 +29,16 @@
    {% for f in field.choices %}
  • + {% if f[0] != 'other' %} - {% if f[0] == 'other' %} - + {% else %} + + + +
    + +
    {% endif %}
  • {% endfor %} From 2121e28bd3aefc130a5232e5a0941b4591698c27 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Wed, 2 Jan 2019 15:40:23 -0500 Subject: [PATCH 04/18] Update form to send data as expected by the route --- templates/components/multi_checkbox_input.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index 3adc0891..2bee3bd8 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -27,17 +27,17 @@
      - {% for f in field.choices %} + {% for choice in field.choices %}
    • - {% if f[0] != 'other' %} - - + {% if choice[0] != 'other' %} + + {% else %} - - + +
      - +
      {% endif %}
    • From 6c8974b603b7b09338290e587d8bf59831375d8b Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 3 Jan 2019 09:12:44 -0500 Subject: [PATCH 05/18] Fix vue escaping character bug --- templates/components/multi_checkbox_input.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index 2bee3bd8..f07ebcf4 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -6,7 +6,7 @@ name='{{ field.name }}' inline-template {% if field.errors %}v-bind:initial-errors='{{ field.errors | list }}'{% endif %} - {% if field.data and field.data != "None" %}v-bind:initial-value="'{{ field.data }}'"{% endif %} + {% if field.data and field.data != "None" %}v-bind:initial-value="{{ field.data }}"{% endif %} key='{{ field.name }}'>
      From f18f4404f59cb8a4c5fc875f808f0ab77d6220db Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 3 Jan 2019 09:25:16 -0500 Subject: [PATCH 06/18] Add test for task order form --- tests/forms/test_task_order_form.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/forms/test_task_order_form.py diff --git a/tests/forms/test_task_order_form.py b/tests/forms/test_task_order_form.py new file mode 100644 index 00000000..1d5b4582 --- /dev/null +++ b/tests/forms/test_task_order_form.py @@ -0,0 +1,9 @@ +import pytest +from wtforms import Form + +from atst.forms.task_order import AppInfoForm + +def test_complexity(): + form = AppInfoForm(formdata={"complexity":["other", "not_sure", "storage"]}) + + assert form.data["complexity"] == ["other", "not_sure", "storage"] From ae55e1c71da6b7500b2c0f6299205d7709d2012d Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 3 Jan 2019 10:17:14 -0500 Subject: [PATCH 07/18] Use formdata and change unfilled fields to '' instead of None --- atst/routes/task_orders/new.py | 10 +++++++++- templates/task_orders/new/app_info.html | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 9cf07f05..72936ad3 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -54,7 +54,9 @@ class ShowTaskOrderWorkflow: if self._form: pass elif self.task_order: - self._form = self._section["form"](data=self.task_order.to_dictionary()) + # None causes issues with formdata, so coerce None to '' + formdata = self.process_none_types(self.task_order.to_dictionary()) + self._form = self._section["form"](formdata=formdata) else: self._form = self._section["form"]() @@ -75,6 +77,12 @@ class ShowTaskOrderWorkflow: return screen_info + def process_none_types(task_order_dict): + for field in task_order_dict: + if field is None: + field = '' + return task_order_dict + class UpdateTaskOrderWorkflow(ShowTaskOrderWorkflow): def __init__(self, form_data, user, screen=1, task_order_id=None): diff --git a/templates/task_orders/new/app_info.html b/templates/task_orders/new/app_info.html index 6116e153..724d4265 100644 --- a/templates/task_orders/new/app_info.html +++ b/templates/task_orders/new/app_info.html @@ -34,7 +34,7 @@

      About Your Team

      -{{ OptionsInput(form.dev_team) }} +{{ MultiCheckboxInput(form.dev_team) }} {{ TextInput(form.dev_team_other) }} {{ OptionsInput(form.team_experience) }} From b1ee67a8048e4c2e3ba7abcdd1941a4d157da36a Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 3 Jan 2019 14:28:38 -0500 Subject: [PATCH 08/18] If other is checked in previous save, expand text input --- js/components/multi_checkbox_input.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index 1f41637b..9f821707 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -17,8 +17,10 @@ export default { type: Array, default: () => [] }, - initialValue: Array, - otherChecked: Boolean, + initialValue: { + type: Array, + default: () => [] + } }, @@ -28,10 +30,10 @@ export default { showError: showError, showValid: !showError && !!this.initialValue, validationError: this.initialErrors.join(' '), + otherChecked: this.initialValue.includes("other") ? true : this.otherChecked } }, - methods: { onInput: function (e) { this.$root.$emit('field-change', { From c5007d9edbadb721bfcb59f236e14e35fdd8c74b Mon Sep 17 00:00:00 2001 From: Montana Date: Thu, 3 Jan 2019 16:12:40 -0500 Subject: [PATCH 09/18] Display checked boxes after saving draft --- js/components/multi_checkbox_input.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index 9f821707..da81f31c 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -34,6 +34,14 @@ export default { } }, + mounted: function () { + for (let child of this.$el.firstChild.lastElementChild.children) { + if (this.initialValue.includes(child.firstChild.value)) { + child.firstChild.checked = true + } + } + }, + methods: { onInput: function (e) { this.$root.$emit('field-change', { From 62ac2642ae18878160825b9cef1baca6503fc3b9 Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 09:57:23 -0500 Subject: [PATCH 10/18] Persist text input for the field --- js/components/multi_checkbox_input.js | 3 ++- templates/components/multi_checkbox_input.html | 5 +++-- templates/task_orders/new/app_info.html | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index da81f31c..c23a068a 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -20,7 +20,8 @@ export default { initialValue: { type: Array, default: () => [] - } + }, + initialOtherValue: String, }, diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index f07ebcf4..5c0b5e7a 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -1,12 +1,13 @@ {% from "components/icon.html" import Icon %} {% from "components/tooltip.html" import Tooltip %} -{% macro MultiCheckboxInput(field, tooltip, inline=False) -%} +{% macro MultiCheckboxInput(field, other_input_field, tooltip, inline=False) -%}
      @@ -37,7 +38,7 @@
      - +
      {% endif %} diff --git a/templates/task_orders/new/app_info.html b/templates/task_orders/new/app_info.html index 724d4265..e07d5ce4 100644 --- a/templates/task_orders/new/app_info.html +++ b/templates/task_orders/new/app_info.html @@ -29,12 +29,12 @@

      About Your Project

      {{ OptionsInput(form.app_migration) }} {{ OptionsInput(form.native_apps) }} -{{ MultiCheckboxInput(form.complexity) }} +{{ MultiCheckboxInput(form.complexity, form.complexity_other) }}

      About Your Team

      -{{ MultiCheckboxInput(form.dev_team) }} +{{ MultiCheckboxInput(form.dev_team, form.dev_team_other) }} {{ TextInput(form.dev_team_other) }} {{ OptionsInput(form.team_experience) }} From 2743bddf0c16b8f0042eaa10e6484d44dab28049 Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 10:59:12 -0500 Subject: [PATCH 11/18] Bind other input value properly and clear it when checkbox is toggled --- js/components/multi_checkbox_input.js | 4 +++- templates/components/multi_checkbox_input.html | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index c23a068a..e548cba2 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -31,7 +31,8 @@ export default { showError: showError, showValid: !showError && !!this.initialValue, validationError: this.initialErrors.join(' '), - otherChecked: this.initialValue.includes("other") ? true : this.otherChecked + otherChecked: this.initialValue.includes("other") ? true : this.otherChecked, + otherText: this.initialOtherValue } }, @@ -54,6 +55,7 @@ export default { }, otherToggle: function() { this.otherChecked = !this.otherChecked + this.otherText = '' } } } diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index 5c0b5e7a..2ca959fa 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -7,7 +7,7 @@ inline-template {% if field.errors %}v-bind:initial-errors='{{ field.errors | list }}'{% endif %} {% if field.data and field.data != "None" %}v-bind:initial-value="{{ field.data }}"{% endif %} - {% if other_input_field.data and other_input_field.data != "None" %}v-bind:initial-other-value="{{ other_input_field.data }}"{% endif %} + {% if other_input_field.data and other_input_field.data != "None" %}initial-other-value="{{ other_input_field.data }}"{% endif %} key='{{ field.name }}'>
      @@ -38,7 +38,7 @@
      - +
      {% endif %} From 53a6c7351002f3c5343129ee647f70dde615d08c Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 13:21:50 -0500 Subject: [PATCH 12/18] Refactor to use v-model --- js/components/multi_checkbox_input.js | 9 ++++----- templates/components/multi_checkbox_input.html | 5 +++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/components/multi_checkbox_input.js b/js/components/multi_checkbox_input.js index e548cba2..7c0b822c 100644 --- a/js/components/multi_checkbox_input.js +++ b/js/components/multi_checkbox_input.js @@ -32,15 +32,14 @@ export default { showValid: !showError && !!this.initialValue, validationError: this.initialErrors.join(' '), otherChecked: this.initialValue.includes("other") ? true : this.otherChecked, - otherText: this.initialOtherValue + otherText: this.initialOtherValue, + selections: [] } }, mounted: function () { - for (let child of this.$el.firstChild.lastElementChild.children) { - if (this.initialValue.includes(child.firstChild.value)) { - child.firstChild.checked = true - } + for (let choice of this.initialValue) { + this.selections.push(choice) } }, diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index 2ca959fa..a373d53c 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -3,6 +3,7 @@ {% macro MultiCheckboxInput(field, other_input_field, tooltip, inline=False) -%} {% if choice[0] != 'other' %} - + {% else %} - +
      From a5cbffb140d44db1b71ba56881264f89f1fc2f0d Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 13:31:26 -0500 Subject: [PATCH 13/18] Delete extra text input --- templates/task_orders/new/app_info.html | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/task_orders/new/app_info.html b/templates/task_orders/new/app_info.html index e07d5ce4..9005bc2b 100644 --- a/templates/task_orders/new/app_info.html +++ b/templates/task_orders/new/app_info.html @@ -35,7 +35,6 @@

      About Your Team

      {{ MultiCheckboxInput(form.dev_team, form.dev_team_other) }} -{{ TextInput(form.dev_team_other) }} {{ OptionsInput(form.team_experience) }}
      From c718e9a0d7244293a3f6329a336f9f6027561f90 Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 14:00:27 -0500 Subject: [PATCH 14/18] Fix process-None function --- atst/routes/task_orders/new.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 72936ad3..78f6aea8 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -55,7 +55,7 @@ class ShowTaskOrderWorkflow: pass elif self.task_order: # None causes issues with formdata, so coerce None to '' - formdata = self.process_none_types(self.task_order.to_dictionary()) + formdata = self.process_none_types(task_order=self.task_order) self._form = self._section["form"](formdata=formdata) else: self._form = self._section["form"]() @@ -77,10 +77,11 @@ class ShowTaskOrderWorkflow: return screen_info - def process_none_types(task_order_dict): + def process_none_types(self, task_order): + task_order_dict = task_order.to_dictionary() for field in task_order_dict: - if field is None: - field = '' + if task_order_dict[field] is None: + task_order_dict[field] = '' return task_order_dict From 1fcd27a4e0258e397c8924617e6a23ff2708d9a6 Mon Sep 17 00:00:00 2001 From: Montana Date: Fri, 4 Jan 2019 14:08:44 -0500 Subject: [PATCH 15/18] Formatting --- atst/forms/task_order.py | 4 ++-- atst/routes/task_orders/new.py | 2 +- tests/forms/test_task_order_form.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index f565cbf4..b63ce7b0 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -48,7 +48,7 @@ class AppInfoForm(CacheableForm): choices=PROJECT_COMPLEXITY, default="", widget=ListWidget(prefix_label=False), - option_widget=CheckboxInput() + option_widget=CheckboxInput(), ) complexity_other = StringField("Project Complexity Other") dev_team = SelectMultipleField( @@ -57,7 +57,7 @@ class AppInfoForm(CacheableForm): choices=DEV_TEAM, default="", widget=ListWidget(prefix_label=False), - option_widget=CheckboxInput() + option_widget=CheckboxInput(), ) dev_team_other = StringField("Development Team Other") team_experience = RadioField( diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 78f6aea8..e6c22bf7 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -81,7 +81,7 @@ class ShowTaskOrderWorkflow: task_order_dict = task_order.to_dictionary() for field in task_order_dict: if task_order_dict[field] is None: - task_order_dict[field] = '' + task_order_dict[field] = "" return task_order_dict diff --git a/tests/forms/test_task_order_form.py b/tests/forms/test_task_order_form.py index 1d5b4582..f8b11fd2 100644 --- a/tests/forms/test_task_order_form.py +++ b/tests/forms/test_task_order_form.py @@ -3,7 +3,8 @@ from wtforms import Form from atst.forms.task_order import AppInfoForm + def test_complexity(): - form = AppInfoForm(formdata={"complexity":["other", "not_sure", "storage"]}) + form = AppInfoForm(formdata={"complexity": ["other", "not_sure", "storage"]}) assert form.data["complexity"] == ["other", "not_sure", "storage"] From c70202c33c1f5f7886ac28e2139433216d294991 Mon Sep 17 00:00:00 2001 From: Montana Date: Mon, 7 Jan 2019 09:33:08 -0500 Subject: [PATCH 16/18] Handle formdata processing in a property --- atst/models/task_order.py | 10 +++++----- atst/routes/task_orders/new.py | 19 +++++++++---------- .../components/multi_checkbox_input.html | 2 +- tests/forms/test_task_order_form.py | 10 ---------- .../routes/task_orders/test_new_task_order.py | 10 ++++++++++ 5 files changed, 25 insertions(+), 26 deletions(-) delete mode 100644 tests/forms/test_task_order_form.py diff --git a/atst/models/task_order.py b/atst/models/task_order.py index 85e4f4ba..29b220d2 100644 --- a/atst/models/task_order.py +++ b/atst/models/task_order.py @@ -52,11 +52,6 @@ class TaskOrder(Base, mixins.TimestampsMixin): filter(None, [self.clin_01, self.clin_02, self.clin_03, self.clin_04]) ) - def __repr__(self): - return "".format( - self.number, self.budget, self.end_date, self.id - ) - @property def portfolio_name(self): return self.workspace.name @@ -70,3 +65,8 @@ class TaskOrder(Base, mixins.TimestampsMixin): if c.name not in ["id"] }, } + + def __repr__(self): + return "".format( + self.number, self.budget, self.end_date, self.id + ) diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index e6c22bf7..9f0b38b4 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -49,14 +49,20 @@ class ShowTaskOrderWorkflow: return self._task_order + @property + def task_order_formdata(self): + task_order_dict = self.task_order.to_dictionary() + for field in task_order_dict: + if task_order_dict[field] is None: + task_order_dict[field] = "" + return task_order_dict + @property def form(self): if self._form: pass elif self.task_order: - # None causes issues with formdata, so coerce None to '' - formdata = self.process_none_types(task_order=self.task_order) - self._form = self._section["form"](formdata=formdata) + self._form = self._section["form"](formdata=self.task_order_formdata) else: self._form = self._section["form"]() @@ -77,13 +83,6 @@ class ShowTaskOrderWorkflow: return screen_info - def process_none_types(self, task_order): - task_order_dict = task_order.to_dictionary() - for field in task_order_dict: - if task_order_dict[field] is None: - task_order_dict[field] = "" - return task_order_dict - class UpdateTaskOrderWorkflow(ShowTaskOrderWorkflow): def __init__(self, form_data, user, screen=1, task_order_id=None): diff --git a/templates/components/multi_checkbox_input.html b/templates/components/multi_checkbox_input.html index a373d53c..3bd294c5 100644 --- a/templates/components/multi_checkbox_input.html +++ b/templates/components/multi_checkbox_input.html @@ -39,7 +39,7 @@
      - +
      {% endif %} diff --git a/tests/forms/test_task_order_form.py b/tests/forms/test_task_order_form.py deleted file mode 100644 index f8b11fd2..00000000 --- a/tests/forms/test_task_order_form.py +++ /dev/null @@ -1,10 +0,0 @@ -import pytest -from wtforms import Form - -from atst.forms.task_order import AppInfoForm - - -def test_complexity(): - form = AppInfoForm(formdata={"complexity": ["other", "not_sure", "storage"]}) - - assert form.data["complexity"] == ["other", "not_sure", "storage"] diff --git a/tests/routes/task_orders/test_new_task_order.py b/tests/routes/task_orders/test_new_task_order.py index ea023e38..09412b3d 100644 --- a/tests/routes/task_orders/test_new_task_order.py +++ b/tests/routes/task_orders/test_new_task_order.py @@ -78,6 +78,16 @@ def test_show_task_order(): assert another_workflow.task_order == task_order +def test_show_task_order_formdata(): + task_order = TaskOrderFactory.create() + workflow = ShowTaskOrderWorkflow(task_order_id=task_order.id) + + assert workflow.task_order.to_dictionary()["user_id"] is None + assert workflow.task_order_formdata["user_id"] is "" + for field in workflow.task_order_formdata: + assert not field is None + + def test_show_task_order_form(): workflow = ShowTaskOrderWorkflow() assert not workflow.form.data["app_migration"] From 64dd295e6d2bc1ce88900e37187e93f329c04c9b Mon Sep 17 00:00:00 2001 From: Montana Date: Mon, 7 Jan 2019 09:48:13 -0500 Subject: [PATCH 17/18] test prepush hook --- package.json | 3 ++- tests/routes/task_orders/test_new_task_order.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6dfc9d2a..36642931 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "build": "parcel build js/index.js -d static/assets --public-url /static/assets -o index.js", "test": "jest", "test:coverage": "jest --coverage", - "test:watch": "jest --watch --no-cache" + "test:watch": "jest --watch --no-cache", + "prepush": "script/format" }, "author": "", "license": "MIT", diff --git a/tests/routes/task_orders/test_new_task_order.py b/tests/routes/task_orders/test_new_task_order.py index 09412b3d..99edccba 100644 --- a/tests/routes/task_orders/test_new_task_order.py +++ b/tests/routes/task_orders/test_new_task_order.py @@ -83,7 +83,7 @@ def test_show_task_order_formdata(): workflow = ShowTaskOrderWorkflow(task_order_id=task_order.id) assert workflow.task_order.to_dictionary()["user_id"] is None - assert workflow.task_order_formdata["user_id"] is "" + assert workflow.task_order_formdata["user_id"] is '' for field in workflow.task_order_formdata: assert not field is None From 7bb9d47e7bdf121c3eda4415bb086dc3c23a6705 Mon Sep 17 00:00:00 2001 From: Montana Date: Mon, 7 Jan 2019 09:49:36 -0500 Subject: [PATCH 18/18] undo prepush test --- package.json | 3 +-- tests/routes/task_orders/test_new_task_order.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 36642931..6dfc9d2a 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,7 @@ "build": "parcel build js/index.js -d static/assets --public-url /static/assets -o index.js", "test": "jest", "test:coverage": "jest --coverage", - "test:watch": "jest --watch --no-cache", - "prepush": "script/format" + "test:watch": "jest --watch --no-cache" }, "author": "", "license": "MIT", diff --git a/tests/routes/task_orders/test_new_task_order.py b/tests/routes/task_orders/test_new_task_order.py index 99edccba..09412b3d 100644 --- a/tests/routes/task_orders/test_new_task_order.py +++ b/tests/routes/task_orders/test_new_task_order.py @@ -83,7 +83,7 @@ def test_show_task_order_formdata(): workflow = ShowTaskOrderWorkflow(task_order_id=task_order.id) assert workflow.task_order.to_dictionary()["user_id"] is None - assert workflow.task_order_formdata["user_id"] is '' + assert workflow.task_order_formdata["user_id"] is "" for field in workflow.task_order_formdata: assert not field is None