diff --git a/atst/forms/application.py b/atst/forms/application.py index 80bb0858..745bb7f8 100644 --- a/atst/forms/application.py +++ b/atst/forms/application.py @@ -1,11 +1,11 @@ -from flask_wtf import FlaskForm +from .forms import BaseForm from wtforms.fields import StringField, TextAreaField, FieldList from wtforms.validators import Required from atst.forms.validators import ListItemRequired, ListItemsUnique from atst.utils.localization import translate -class ApplicationForm(FlaskForm): +class ApplicationForm(BaseForm): name = StringField( label=translate("forms.application.name_label"), validators=[Required()] ) diff --git a/atst/forms/ccpo_review.py b/atst/forms/ccpo_review.py index 4fd31205..639bfeef 100644 --- a/atst/forms/ccpo_review.py +++ b/atst/forms/ccpo_review.py @@ -2,13 +2,13 @@ from wtforms.fields.html5 import EmailField, TelField from wtforms.fields import StringField, TextAreaField from wtforms.validators import Email, Optional -from .forms import CacheableForm +from .forms import BaseForm from .validators import Name, PhoneNumber from atst.utils.localization import translate -class CCPOReviewForm(CacheableForm): +class CCPOReviewForm(BaseForm): comment = TextAreaField( translate("forms.ccpo_review.comment_label"), description=translate("forms.ccpo_review.comment_description"), diff --git a/atst/forms/dd_254.py b/atst/forms/dd_254.py index 5d03f861..8397442c 100644 --- a/atst/forms/dd_254.py +++ b/atst/forms/dd_254.py @@ -5,12 +5,12 @@ from wtforms.validators import Required from atst.forms.validators import PhoneNumber -from .forms import CacheableForm +from .forms import BaseForm from .data import REQUIRED_DISTRIBUTIONS from atst.utils.localization import translate -class DD254Form(CacheableForm): +class DD254Form(BaseForm): certifying_official = StringField( translate("forms.dd_254.certifying_official.label"), description=translate("forms.dd_254.certifying_official.description"), diff --git a/atst/forms/edit_member.py b/atst/forms/edit_member.py index 56d7f499..766ed65c 100644 --- a/atst/forms/edit_member.py +++ b/atst/forms/edit_member.py @@ -1,13 +1,13 @@ -from flask_wtf import FlaskForm from wtforms.validators import Required +from .forms import BaseForm from atst.forms.fields import SelectField from atst.utils.localization import translate from .data import PORTFOLIO_ROLES -class EditMemberForm(FlaskForm): +class EditMemberForm(BaseForm): # This form also accepts a field for each environment in each application # that the user is a member of diff --git a/atst/forms/edit_user.py b/atst/forms/edit_user.py index 729f41fa..04158212 100644 --- a/atst/forms/edit_user.py +++ b/atst/forms/edit_user.py @@ -5,7 +5,7 @@ from wtforms.fields import RadioField, StringField from wtforms.validators import Email, DataRequired, Optional from .fields import SelectField -from .forms import CacheableForm +from .forms import BaseForm from .data import SERVICE_BRANCHES from atst.models.user import User from atst.utils.localization import translate @@ -84,7 +84,7 @@ def inherit_user_field(field_name): return inherit_field(USER_FIELDS[field_name], required=required) -class EditUserForm(CacheableForm): +class EditUserForm(BaseForm): first_name = inherit_user_field("first_name") last_name = inherit_user_field("last_name") diff --git a/atst/forms/forms.py b/atst/forms/forms.py index 5d6d37c4..e3f2081f 100644 --- a/atst/forms/forms.py +++ b/atst/forms/forms.py @@ -3,24 +3,26 @@ from flask import current_app, request as http_request from atst.utils.flash import formatted_flash as flash +EMPTY_LIST_FIELD = ["", None] -class ValidatedForm(FlaskForm): - EMPTY_LIST_FIELD = ["", None] - def perform_extra_validation(self, *args, **kwargs): - """Performs any applicable extra validation. Must - return True if the form is valid or False otherwise.""" - return True +class BaseForm(FlaskForm): + def __init__(self, formdata=None, **kwargs): + # initialize the form with data from the cache + formdata = formdata or {} + cached_data = current_app.form_cache.from_request(http_request) + cached_data.update(formdata) + super().__init__(cached_data, **kwargs) @property def data(self): + # remove 'csrf_token' key/value pair + # remove empty strings and None from list fields _data = super().data + _data.pop("csrf_token", None) for field in _data: if _data[field].__class__.__name__ == "list": - _data[field] = [ - el for el in _data[field] if el not in self.EMPTY_LIST_FIELD - ] - _data.pop("csrf_token", None) + _data[field] = [el for el in _data[field] if el not in EMPTY_LIST_FIELD] return _data def validate(self, *args, **kwargs): @@ -28,11 +30,3 @@ class ValidatedForm(FlaskForm): if not valid: flash("form_errors") return valid - - -class CacheableForm(ValidatedForm): - def __init__(self, formdata=None, **kwargs): - formdata = formdata or {} - cached_data = current_app.form_cache.from_request(http_request) - cached_data.update(formdata) - super().__init__(cached_data, **kwargs) diff --git a/atst/forms/internal_comment.py b/atst/forms/internal_comment.py index 11ad15aa..b8470139 100644 --- a/atst/forms/internal_comment.py +++ b/atst/forms/internal_comment.py @@ -1,11 +1,11 @@ from wtforms.fields import TextAreaField from wtforms.validators import InputRequired -from .forms import CacheableForm +from .forms import BaseForm from atst.utils.localization import translate -class InternalCommentForm(CacheableForm): +class InternalCommentForm(BaseForm): text = TextAreaField( translate("forms.internal_comment.text_label"), default="", diff --git a/atst/forms/ko_review.py b/atst/forms/ko_review.py index 672cad2e..4bd73ade 100644 --- a/atst/forms/ko_review.py +++ b/atst/forms/ko_review.py @@ -4,12 +4,12 @@ from wtforms.fields.html5 import DateField from wtforms.fields import StringField, TextAreaField, FileField, FieldList from wtforms.validators import Optional, Length -from .forms import CacheableForm +from .forms import BaseForm from atst.utils.localization import translate -class KOReviewForm(CacheableForm): +class KOReviewForm(BaseForm): start_date = DateField( translate("forms.ko_review.start_date_label"), format="%m/%d/%Y" ) diff --git a/atst/forms/new_member.py b/atst/forms/new_member.py index 90795a2b..cdea0c56 100644 --- a/atst/forms/new_member.py +++ b/atst/forms/new_member.py @@ -1,8 +1,8 @@ -from flask_wtf import FlaskForm from wtforms.fields import StringField from wtforms.fields.html5 import EmailField from wtforms.validators import Required, Email, Length +from .forms import BaseForm from atst.forms.validators import IsNumber from atst.forms.fields import SelectField from atst.utils.localization import translate @@ -10,7 +10,7 @@ from atst.utils.localization import translate from .data import PORTFOLIO_ROLES -class NewMemberForm(FlaskForm): +class NewMemberForm(BaseForm): first_name = StringField( label=translate("forms.new_member.first_name_label"), validators=[Required()] diff --git a/atst/forms/officers.py b/atst/forms/officers.py index 4f98da69..5f6b0e02 100644 --- a/atst/forms/officers.py +++ b/atst/forms/officers.py @@ -1,15 +1,14 @@ -from flask_wtf import FlaskForm from wtforms.fields import StringField, BooleanField from wtforms.fields.html5 import TelField from wtforms.validators import Email, Length, Optional from atst.forms.validators import IsNumber, PhoneNumber -from .forms import CacheableForm +from .forms import BaseForm from .fields import FormFieldWrapper -class OfficerForm(FlaskForm): +class OfficerForm(BaseForm): first_name = StringField("First Name") last_name = StringField("Last Name") email = StringField("Email", validators=[Optional(), Email()]) @@ -18,7 +17,7 @@ class OfficerForm(FlaskForm): invite = BooleanField("Invite to Task Order Builder") -class EditTaskOrderOfficersForm(CacheableForm): +class EditTaskOrderOfficersForm(BaseForm): contracting_officer = FormFieldWrapper(OfficerForm) contracting_officer_representative = FormFieldWrapper(OfficerForm) diff --git a/atst/forms/portfolio.py b/atst/forms/portfolio.py index ec26072d..16abdf03 100644 --- a/atst/forms/portfolio.py +++ b/atst/forms/portfolio.py @@ -1,11 +1,11 @@ from wtforms.fields import StringField from wtforms.validators import Length -from .forms import CacheableForm +from .forms import BaseForm from atst.utils.localization import translate -class PortfolioForm(CacheableForm): +class PortfolioForm(BaseForm): name = StringField( translate("forms.portfolio.name_label"), validators=[ diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index b731e2bd..b70e4f99 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -15,7 +15,7 @@ from flask_wtf.file import FileAllowed from atst.forms.validators import IsNumber, PhoneNumber, RequiredIf -from .forms import CacheableForm +from .forms import BaseForm from .data import ( SERVICE_BRANCHES, APP_MIGRATION, @@ -27,7 +27,7 @@ from .data import ( from atst.utils.localization import translate -class AppInfoForm(CacheableForm): +class AppInfoForm(BaseForm): portfolio_name = StringField( translate("forms.task_order.portfolio_name_label"), description=translate("forms.task_order.portfolio_name_description"), @@ -88,7 +88,7 @@ class AppInfoForm(CacheableForm): ) -class FundingForm(CacheableForm): +class FundingForm(BaseForm): performance_length = SelectField( translate("forms.task_order.performance_length.label"), choices=PERIOD_OF_PERFORMANCE_LENGTH, @@ -134,7 +134,7 @@ class UnclassifiedFundingForm(FundingForm): ) -class OversightForm(CacheableForm): +class OversightForm(BaseForm): ko_first_name = StringField( translate("forms.task_order.oversight_first_name_label") ) @@ -220,11 +220,11 @@ class OversightForm(CacheableForm): ) -class ReviewForm(CacheableForm): +class ReviewForm(BaseForm): pass -class SignatureForm(CacheableForm): +class SignatureForm(BaseForm): level_of_warrant = DecimalField( translate("task_orders.sign.level_of_warrant_label"), description=translate("task_orders.sign.level_of_warrant_description"),