Put app strings into a YAML file for easy editing by product owner
This commit is contained in:
@@ -5,20 +5,31 @@ from wtforms.validators import Email, Optional
|
||||
from .forms import CacheableForm
|
||||
from .validators import Name, PhoneNumber
|
||||
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class CCPOReviewForm(CacheableForm):
|
||||
comment = TextAreaField(
|
||||
"Instructions or comments",
|
||||
description="Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. <strong>This message will be shared with the person making the JEDI request.</strong>.",
|
||||
translate("forms.ccpo_review.comment_label"),
|
||||
description=("forms.ccpo_review.comment_description"),
|
||||
)
|
||||
fname_mao = StringField(
|
||||
translate("forms.ccpo_review.fname_mao_label"), validators=[Optional(), Name()]
|
||||
)
|
||||
lname_mao = StringField(
|
||||
translate("forms.ccpo_review.lname_mao_label"), validators=[Optional(), Name()]
|
||||
)
|
||||
fname_mao = StringField("First Name (optional)", validators=[Optional(), Name()])
|
||||
lname_mao = StringField("Last Name (optional)", validators=[Optional(), Name()])
|
||||
email_mao = EmailField(
|
||||
"Mission Owner e-mail (optional)", validators=[Optional(), Email()]
|
||||
translate("forms.ccpo_review.email_mao_label"), validators=[Optional(), Email()]
|
||||
)
|
||||
phone_mao = TelField(
|
||||
"Mission Owner phone number (optional)", validators=[Optional(), PhoneNumber()]
|
||||
translate("forms.ccpo_review.phone_mao_label"),
|
||||
validators=[Optional(), PhoneNumber()],
|
||||
)
|
||||
phone_ext_mao = StringField(translate("forms.ccpo_review.phone_ext_mao_label"))
|
||||
fname_ccpo = StringField(
|
||||
translate("forms.ccpo_review.fname_ccpo_label"), validators=[Optional(), Name()]
|
||||
)
|
||||
lname_ccpo = StringField(
|
||||
translate("forms.ccpo_review.lname_ccpo_label"), validators=[Optional(), Name()]
|
||||
)
|
||||
phone_ext_mao = StringField("Extension (optional)")
|
||||
fname_ccpo = StringField("First Name (optional)", validators=[Optional(), Name()])
|
||||
lname_ccpo = StringField("Last Name (optional)", validators=[Optional(), Name()])
|
||||
|
@@ -2,6 +2,7 @@ from flask_wtf import FlaskForm
|
||||
from wtforms.validators import Required
|
||||
|
||||
from atst.forms.fields import SelectField
|
||||
from atst.utils.localization import translate
|
||||
|
||||
from .data import WORKSPACE_ROLES
|
||||
|
||||
@@ -11,5 +12,7 @@ class EditMemberForm(FlaskForm):
|
||||
# that the user is a member of
|
||||
|
||||
workspace_role = SelectField(
|
||||
"Workspace Role", choices=WORKSPACE_ROLES, validators=[Required()]
|
||||
translate("forms.edit_member.workspace_role_label"),
|
||||
choices=WORKSPACE_ROLES,
|
||||
validators=[Required()],
|
||||
)
|
||||
|
@@ -8,27 +8,34 @@ from .fields import SelectField
|
||||
from .forms import CacheableForm
|
||||
from .data import SERVICE_BRANCHES
|
||||
from atst.models.user import User
|
||||
from atst.utils.localization import translate
|
||||
|
||||
from .validators import Name, DateRange, PhoneNumber
|
||||
|
||||
|
||||
USER_FIELDS = {
|
||||
"first_name": StringField("First Name", validators=[Name()]),
|
||||
"last_name": StringField("Last Name", validators=[Name()]),
|
||||
"first_name": StringField(
|
||||
translate("forms.edit_user.first_name_label"), validators=[Name()]
|
||||
),
|
||||
"last_name": StringField(
|
||||
translate("forms.edit_user.last_name_label"), validators=[Name()]
|
||||
),
|
||||
"email": EmailField(
|
||||
"E-mail Address",
|
||||
description="Enter your preferred contact e-mail address",
|
||||
translate("forms.edit_user.email_label"),
|
||||
description=translate("forms.edit_user.email_description"),
|
||||
validators=[Email()],
|
||||
),
|
||||
"phone_number": TelField("Phone Number", validators=[PhoneNumber()]),
|
||||
"phone_number": TelField(
|
||||
translate("forms.edit_user.phone_number_label"), validators=[PhoneNumber()]
|
||||
),
|
||||
"phone_ext": StringField("Extension"),
|
||||
"service_branch": SelectField(
|
||||
"Service Branch or Agency",
|
||||
description="Which service or organization do you belong to within the DoD?",
|
||||
translate("forms.edit_user.service_branch_label"),
|
||||
description=translate("forms.edit_user.service_branch_description"),
|
||||
choices=SERVICE_BRANCHES,
|
||||
),
|
||||
"citizenship": RadioField(
|
||||
description="What is your citizenship status?",
|
||||
description=translate("forms.edit_user.citizenship_description"),
|
||||
choices=[
|
||||
("United States", "United States"),
|
||||
("Foreign National", "Foreign National"),
|
||||
@@ -36,8 +43,8 @@ USER_FIELDS = {
|
||||
],
|
||||
),
|
||||
"designation": RadioField(
|
||||
"Designation of Person",
|
||||
description="What is your designation within the DoD?",
|
||||
translate("forms.edit_user.designation_label"),
|
||||
description=translate("forms.edit_user.designation_description"),
|
||||
choices=[
|
||||
("military", "Military"),
|
||||
("civilian", "Civilian"),
|
||||
@@ -45,8 +52,8 @@ USER_FIELDS = {
|
||||
],
|
||||
),
|
||||
"date_latest_training": DateField(
|
||||
"Latest Information Assurance (IA) Training Completion Date",
|
||||
description='To complete the training, you can find it in <a class="icon-link" href="https://iatraining.disa.mil/eta/disa_cac2018/launchPage.htm" target="_blank">Information Assurance Cyber Awareness Challange</a> website.',
|
||||
translate("forms.edit_user.date_latest_training_label"),
|
||||
description=translate("forms.edit_user.date_latest_training_description"),
|
||||
validators=[
|
||||
DateRange(
|
||||
lower_bound=pendulum.duration(years=1),
|
||||
|
@@ -1,6 +1,9 @@
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class FormValidationError(Exception):
|
||||
|
||||
message = "Form validation failed."
|
||||
message = translate("forms.exceptions.message")
|
||||
|
||||
def __init__(self, form):
|
||||
self.form = form
|
||||
|
@@ -8,6 +8,7 @@ from werkzeug.datastructures import FileStorage
|
||||
|
||||
from .fields import NewlineListField, SelectField, NumberStringField
|
||||
from atst.forms.forms import CacheableForm
|
||||
from atst.utils.localization import translate
|
||||
from .data import FUNDING_TYPES
|
||||
from .validators import DateRange
|
||||
|
||||
@@ -46,24 +47,26 @@ class TaskOrderForm(CacheableForm):
|
||||
return valid
|
||||
|
||||
number = StringField(
|
||||
"Task Order Number associated with this request",
|
||||
description="Include the original Task Order number (including the 000X at the end). Do not include any modification numbers. Note that there may be a lag between approving a task order and when it becomes available in our system.",
|
||||
translate("forms.financial.number_label"),
|
||||
description=translate("forms.financial.number_description"),
|
||||
validators=[InputRequired()],
|
||||
)
|
||||
|
||||
funding_type = SelectField(
|
||||
description="What is the source of funding?",
|
||||
description=translate("forms.financial.funding_type_description"),
|
||||
choices=FUNDING_TYPES,
|
||||
validators=[InputRequired()],
|
||||
coerce=coerce_choice,
|
||||
render_kw={"required": False},
|
||||
)
|
||||
|
||||
funding_type_other = StringField("If other, please specify")
|
||||
funding_type_other = StringField(
|
||||
translate("forms.financial.funding_type_other_label")
|
||||
)
|
||||
|
||||
expiration_date = DateField(
|
||||
"Task Order Expiration Date",
|
||||
description="Please enter the expiration date for the Task Order",
|
||||
translate("forms.financial.expiration_date_label"),
|
||||
description=translate("forms.financial.expiration_date_description"),
|
||||
validators=[
|
||||
InputRequired(),
|
||||
DateRange(
|
||||
@@ -76,51 +79,51 @@ class TaskOrderForm(CacheableForm):
|
||||
)
|
||||
|
||||
clin_0001 = NumberStringField(
|
||||
"<dl><dt>CLIN 0001</dt> - <dd>Unclassified IaaS and PaaS Amount</dd></dl>",
|
||||
translate("forms.financial.clin_0001_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_0001_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
clin_0003 = NumberStringField(
|
||||
"<dl><dt>CLIN 0003</dt> - <dd>Unclassified Cloud Support Package</dd></dl>",
|
||||
translate("forms.financial.clin_0003_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_0003_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
clin_1001 = NumberStringField(
|
||||
"<dl><dt>CLIN 1001</dt> - <dd>Unclassified IaaS and PaaS Amount <br> OPTION PERIOD 1</dd></dl>",
|
||||
translate("forms.financial.clin_1001_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_1001_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
clin_1003 = NumberStringField(
|
||||
"<dl><dt>CLIN 1003</dt> - <dd>Unclassified Cloud Support Package <br> OPTION PERIOD 1</dd></dl>",
|
||||
translate("forms.financial.clin_1003_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_1003_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
clin_2001 = NumberStringField(
|
||||
"<dl><dt>CLIN 2001</dt> - <dd>Unclassified IaaS and PaaS Amount <br> OPTION PERIOD 2</dd></dl>",
|
||||
translate("forms.financial.clin_2001_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_2001_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
clin_2003 = NumberStringField(
|
||||
"<dl><dt>CLIN 2003</dt> - <dd>Unclassified Cloud Support Package <br> OPTION PERIOD 2</dd></dl>",
|
||||
translate("forms.financial.clin_2003_label"),
|
||||
validators=[InputRequired()],
|
||||
description="Review your task order document, the amounts for each CLIN must match exactly here",
|
||||
description=translate("forms.financial.clin_2003_description"),
|
||||
filters=[number_to_int],
|
||||
)
|
||||
|
||||
pdf = FileField(
|
||||
"Upload a copy of your Task Order",
|
||||
translate("forms.financial.pdf_label"),
|
||||
validators=[
|
||||
FileAllowed(["pdf"], "Only PDF documents can be uploaded."),
|
||||
FileAllowed(["pdf"], translate("forms.financial.pdf_allowed_description")),
|
||||
InputRequired(),
|
||||
],
|
||||
render_kw={"required": False},
|
||||
@@ -129,42 +132,60 @@ class TaskOrderForm(CacheableForm):
|
||||
|
||||
class RequestFinancialVerificationForm(CacheableForm):
|
||||
uii_ids = NewlineListField(
|
||||
"Unique Item Identifier (UII)s related to your application(s) if you already have them.",
|
||||
description="If you have more than one UII, place each one on a new line.",
|
||||
translate("forms.financial.uii_ids_label"),
|
||||
description=translate("forms.financial.uii_ids_description"),
|
||||
)
|
||||
|
||||
pe_id = StringField(
|
||||
"Program Element Number",
|
||||
description="PE numbers help the Department of Defense identify which offices' budgets are contributing towards this resource use. <br/><em>It should be 7 digits followed by 1-3 letters, and should have a zero as the first and third digits.</em>",
|
||||
translate("forms.financial.pe_id_label"),
|
||||
description=translate("forms.financial.pe_id_description"),
|
||||
validators=[InputRequired()],
|
||||
)
|
||||
|
||||
treasury_code = StringField(
|
||||
"Program Treasury Code",
|
||||
description="Program Treasury Code (or Appropriations Code) identifies resource types. <br/> <em>It should be a four digit or six digit number, optionally prefixed by one or more zeros.</em>",
|
||||
translate("forms.financial.treasury_code_label"),
|
||||
description=translate("forms.financial.treasury_code_description"),
|
||||
validators=[InputRequired(), Regexp(TREASURY_CODE_REGEX)],
|
||||
)
|
||||
|
||||
ba_code = StringField(
|
||||
"Program Budget Activity (BA) Code",
|
||||
description="BA Code is used to identify the purposes, projects, or types of activities financed by the appropriation fund. <br/><em>It should be two digits, followed by an optional letter.</em>",
|
||||
translate("forms.financial.ba_code_label"),
|
||||
description=translate("forms.financial.ba_code_description"),
|
||||
validators=[InputRequired(), Regexp(BA_CODE_REGEX)],
|
||||
)
|
||||
|
||||
fname_co = StringField("KO First Name", validators=[InputRequired()])
|
||||
lname_co = StringField("KO Last Name", validators=[InputRequired()])
|
||||
fname_co = StringField(
|
||||
translate("forms.financial.fname_co_label"), validators=[InputRequired()]
|
||||
)
|
||||
lname_co = StringField(
|
||||
translate("forms.financial.lname_co_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
email_co = EmailField("KO Email", validators=[InputRequired(), Email()])
|
||||
email_co = EmailField(
|
||||
translate("forms.financial.email_co_label"),
|
||||
validators=[InputRequired(), Email()],
|
||||
)
|
||||
|
||||
office_co = StringField("KO Office", validators=[InputRequired()])
|
||||
office_co = StringField(
|
||||
translate("forms.financial.office_co_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
fname_cor = StringField("COR First Name", validators=[InputRequired()])
|
||||
fname_cor = StringField(
|
||||
translate("forms.financial.fname_cor_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
lname_cor = StringField("COR Last Name", validators=[InputRequired()])
|
||||
lname_cor = StringField(
|
||||
translate("forms.financial.lname_cor_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
email_cor = EmailField("COR Email", validators=[InputRequired(), Email()])
|
||||
email_cor = EmailField(
|
||||
translate("forms.financial.email_cor_label"),
|
||||
validators=[InputRequired(), Email()],
|
||||
)
|
||||
|
||||
office_cor = StringField("COR Office", validators=[InputRequired()])
|
||||
office_cor = StringField(
|
||||
translate("forms.financial.office_cor_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
|
@@ -2,12 +2,13 @@ from wtforms.fields import TextAreaField
|
||||
from wtforms.validators import InputRequired
|
||||
|
||||
from .forms import CacheableForm
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class InternalCommentForm(CacheableForm):
|
||||
text = TextAreaField(
|
||||
"CCPO Internal Notes",
|
||||
translate("forms.internal_comment.text_label"),
|
||||
default="",
|
||||
description="Add comments or notes for internal CCPO reference and follow-up here. <strong>These comments <em>will not</em> be visible to the person making the JEDI request.</strong>",
|
||||
description=translate("forms.internal_comment.text_description"),
|
||||
validators=[InputRequired()],
|
||||
)
|
||||
|
@@ -5,20 +5,30 @@ from wtforms.validators import Required, Email, Length
|
||||
|
||||
from atst.forms.validators import IsNumber
|
||||
from atst.forms.fields import SelectField
|
||||
from atst.utils.localization import translate
|
||||
|
||||
from .data import WORKSPACE_ROLES
|
||||
|
||||
|
||||
class NewMemberForm(FlaskForm):
|
||||
|
||||
first_name = StringField(label="First Name", validators=[Required()])
|
||||
last_name = StringField(label="Last Name", validators=[Required()])
|
||||
email = EmailField("Email Address", validators=[Required(), Email()])
|
||||
dod_id = StringField("DOD ID", validators=[Required(), Length(min=10), IsNumber()])
|
||||
first_name = StringField(
|
||||
label=translate("forms.new_member.first_name_label"), validators=[Required()]
|
||||
)
|
||||
last_name = StringField(
|
||||
label=translate("forms.new_member.last_name_label"), validators=[Required()]
|
||||
)
|
||||
email = EmailField(
|
||||
translate("forms.new_member.email_label"), validators=[Required(), Email()]
|
||||
)
|
||||
dod_id = StringField(
|
||||
translate("forms.new_member.dod_id_label"),
|
||||
validators=[Required(), Length(min=10), IsNumber()],
|
||||
)
|
||||
workspace_role = SelectField(
|
||||
"Workspace Role",
|
||||
translate("forms.new_member.workspace_role_label"),
|
||||
choices=WORKSPACE_ROLES,
|
||||
validators=[Required()],
|
||||
default="",
|
||||
description="The workspace role controls whether a member is permitted to organize a workspace into projects and environments, add members to this workspace, and view billing information.",
|
||||
description=translate("forms.new_member.workspace_role_description"),
|
||||
)
|
||||
|
@@ -14,6 +14,7 @@ from .data import (
|
||||
)
|
||||
from .validators import DateRange, IsNumber
|
||||
from atst.domain.requests import Requests
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class DetailsOfUseForm(CacheableForm):
|
||||
@@ -43,120 +44,126 @@ class DetailsOfUseForm(CacheableForm):
|
||||
|
||||
# Details of Use: General
|
||||
dod_component = SelectField(
|
||||
"DoD Component",
|
||||
description="Identify the DoD component that is requesting access to the JEDI Cloud",
|
||||
translate("forms.new_request.dod_component_label"),
|
||||
description=translate("forms.new_request.dod_component_description"),
|
||||
choices=SERVICE_BRANCHES,
|
||||
validators=[InputRequired()],
|
||||
)
|
||||
|
||||
jedi_usage = TextAreaField(
|
||||
"JEDI Usage",
|
||||
description="Your answer will help us provide tangible examples to DoD leadership how and why commercial cloud resources are accelerating the Department's missions",
|
||||
translate("forms.new_request.jedi_usage_label"),
|
||||
description=translate("forms.new_request.jedi_usage_description"),
|
||||
validators=[InputRequired()],
|
||||
)
|
||||
|
||||
# Details of Use: Cloud Readiness
|
||||
num_software_systems = IntegerField(
|
||||
"Number of Software Systems",
|
||||
description="Estimate the number of software systems that will be supported by this JEDI Cloud access request",
|
||||
translate("forms.new_request.num_software_systems_label"),
|
||||
description=translate("forms.new_request.num_software_systems_description"),
|
||||
)
|
||||
|
||||
jedi_migration = RadioField(
|
||||
"JEDI Migration",
|
||||
description="Are you using the JEDI Cloud to migrate existing systems?",
|
||||
translate("forms.new_request.jedi_migration_label"),
|
||||
description=translate("forms.new_request.jedi_migration_description"),
|
||||
choices=[("yes", "Yes"), ("no", "No")],
|
||||
default="",
|
||||
)
|
||||
|
||||
rationalization_software_systems = RadioField(
|
||||
description="Have you completed a “rationalization” of your software systems to move to the cloud?",
|
||||
description=translate(
|
||||
"forms.new_request.rationalization_software_systems_description"
|
||||
),
|
||||
choices=[("yes", "Yes"), ("no", "No"), ("In Progress", "In Progress")],
|
||||
default="",
|
||||
)
|
||||
|
||||
technical_support_team = RadioField(
|
||||
description="Are you working with a technical support team experienced in cloud migrations?",
|
||||
description=translate("forms.new_request.technical_support_team_description"),
|
||||
choices=[("yes", "Yes"), ("no", "No")],
|
||||
default="",
|
||||
)
|
||||
|
||||
organization_providing_assistance = RadioField( # this needs to be updated to use checkboxes instead of radio
|
||||
description="If you are receiving migration assistance, what is the type of organization providing assistance?",
|
||||
description=translate(
|
||||
"forms.new_request.organization_providing_assistance_description"
|
||||
),
|
||||
choices=ASSISTANCE_ORG_TYPES,
|
||||
default="",
|
||||
)
|
||||
|
||||
engineering_assessment = RadioField(
|
||||
description="Have you completed an engineering assessment of your systems for cloud readiness?",
|
||||
description=translate("forms.new_request.engineering_assessment_description"),
|
||||
choices=[("yes", "Yes"), ("no", "No"), ("In Progress", "In Progress")],
|
||||
default="",
|
||||
)
|
||||
|
||||
data_transfers = SelectField(
|
||||
description="How much data is being transferred to the cloud?",
|
||||
description=translate("forms.new_request.data_transfers_description"),
|
||||
choices=DATA_TRANSFER_AMOUNTS,
|
||||
validators=[DataRequired()],
|
||||
)
|
||||
|
||||
expected_completion_date = SelectField(
|
||||
description="When do you expect to complete your migration to the JEDI Cloud?",
|
||||
description=translate("forms.new_request.expected_completion_date_description"),
|
||||
choices=COMPLETION_DATE_RANGES,
|
||||
validators=[DataRequired()],
|
||||
)
|
||||
|
||||
cloud_native = RadioField(
|
||||
description="Are your software systems being developed cloud native?",
|
||||
description=translate("forms.new_request.cloud_native_description"),
|
||||
choices=[("yes", "Yes"), ("no", "No")],
|
||||
default="",
|
||||
)
|
||||
|
||||
# Details of Use: Financial Usage
|
||||
estimated_monthly_spend = IntegerField(
|
||||
"Estimated Monthly Spend",
|
||||
description='Use the <a href="/jedi-csp-calculator" target="_blank" class="icon-link">JEDI CSP Calculator</a> to estimate your <b>monthly</b> cloud resource usage and enter the dollar amount below. Note these estimates are for initial approval only. After the request is approved, you will be asked to provide a valid Task Order number with specific CLIN amounts for cloud services.',
|
||||
translate("forms.new_request.estimated_monthly_spend_label"),
|
||||
description=translate("forms.new_request.estimated_monthly_spend_description"),
|
||||
)
|
||||
|
||||
dollar_value = IntegerField(
|
||||
"Total Spend",
|
||||
description="What is your total expected budget for this JEDI Cloud Request?",
|
||||
translate("forms.new_request.dollar_value_label"),
|
||||
description=translate("forms.new_request.dollar_value_description"),
|
||||
)
|
||||
|
||||
number_user_sessions = IntegerField(
|
||||
description="How many user sessions do you expect on these systems each day?"
|
||||
description=translate("forms.new_request.number_user_sessions_description")
|
||||
)
|
||||
|
||||
average_daily_traffic = IntegerField(
|
||||
"Average Daily Traffic (Number of Requests)",
|
||||
description="What is the average daily traffic you expect the systems under this cloud contract to use?",
|
||||
translate("forms.new_request.average_daily_traffic_label"),
|
||||
description=translate("forms.new_request.average_daily_traffic_description"),
|
||||
)
|
||||
|
||||
average_daily_traffic_gb = IntegerField(
|
||||
"Average Daily Traffic (GB)",
|
||||
description="What is the average daily traffic you expect the systems under this cloud contract to use?",
|
||||
translate("forms.new_request.average_daily_traffic_gb_label"),
|
||||
description=translate("forms.new_request.average_daily_traffic_gb_description"),
|
||||
)
|
||||
|
||||
start_date = DateField(
|
||||
description="When do you expect to start using the JEDI Cloud (not for billing purposes)?",
|
||||
description=translate("forms.new_request.start_date_label"),
|
||||
validators=[
|
||||
InputRequired(),
|
||||
DateRange(
|
||||
lower_bound=pendulum.duration(days=1),
|
||||
upper_bound=None,
|
||||
message="Must be a date in the future.",
|
||||
message=translate(
|
||||
"forms.new_request.start_date_date_range_validation_message"
|
||||
),
|
||||
),
|
||||
],
|
||||
format="%m/%d/%Y",
|
||||
)
|
||||
|
||||
name = StringField(
|
||||
"Name Your Request",
|
||||
description="This name serves as a reference for your initial request and the associated workspace that will be created once this request is approved. You may edit this name later.",
|
||||
translate("forms.new_request.name_label"),
|
||||
description=translate("forms.new_request.name_description"),
|
||||
validators=[
|
||||
InputRequired(),
|
||||
Length(
|
||||
min=4,
|
||||
max=100,
|
||||
message="Request names must be at least 4 and not more than 100 characters",
|
||||
message=translate("forms.new_request.name_length_validation_message"),
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -187,21 +194,29 @@ class WorkspaceOwnerForm(CacheableForm):
|
||||
return super().validate(*args, **kwargs)
|
||||
|
||||
am_poc = BooleanField(
|
||||
"I am the Workspace Owner",
|
||||
translate("forms.new_request.am_poc_label"),
|
||||
default=False,
|
||||
false_values=(False, "false", "False", "no", ""),
|
||||
)
|
||||
|
||||
fname_poc = StringField("First Name", validators=[InputRequired()])
|
||||
fname_poc = StringField(
|
||||
translate("forms.new_request.fname_poc_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
lname_poc = StringField("Last Name", validators=[InputRequired()])
|
||||
lname_poc = StringField(
|
||||
translate("forms.new_request.lname_poc_label"), validators=[InputRequired()]
|
||||
)
|
||||
|
||||
email_poc = EmailField("Email Address", validators=[InputRequired(), Email()])
|
||||
email_poc = EmailField(
|
||||
translate("forms.new_request.email_poc_label"),
|
||||
validators=[InputRequired(), Email()],
|
||||
)
|
||||
|
||||
dodid_poc = StringField(
|
||||
"DoD ID", validators=[InputRequired(), Length(min=10), IsNumber()]
|
||||
translate("forms.new_request.dodid_poc_label"),
|
||||
validators=[InputRequired(), Length(min=10), IsNumber()],
|
||||
)
|
||||
|
||||
|
||||
class ReviewAndSubmitForm(CacheableForm):
|
||||
reviewed = BooleanField("I have reviewed this data and it is correct.")
|
||||
reviewed = BooleanField(translate("forms.new_request.reviewed_label"))
|
||||
|
@@ -2,21 +2,34 @@ from flask_wtf import FlaskForm
|
||||
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 ProjectForm(FlaskForm):
|
||||
name = StringField(label="Project Name", validators=[Required()])
|
||||
description = TextAreaField(label="Description", validators=[Required()])
|
||||
name = StringField(
|
||||
label=translate("forms.project.name_label"), validators=[Required()]
|
||||
)
|
||||
description = TextAreaField(
|
||||
label=translate("forms.project.description_label"), validators=[Required()]
|
||||
)
|
||||
|
||||
|
||||
class NewProjectForm(ProjectForm):
|
||||
EMPTY_ENVIRONMENT_NAMES = ["", None]
|
||||
|
||||
environment_names = FieldList(
|
||||
StringField(label="Environment Name"),
|
||||
StringField(label=translate("forms.project.environment_names_label")),
|
||||
validators=[
|
||||
ListItemRequired(message="Provide at least one environment name."),
|
||||
ListItemsUnique(message="Environment names must be unique."),
|
||||
ListItemRequired(
|
||||
message=translate(
|
||||
"forms.project.environment_names_required_validation_message"
|
||||
)
|
||||
),
|
||||
ListItemsUnique(
|
||||
message=translate(
|
||||
"forms.project.environment_names_unique_validation_message"
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -2,6 +2,7 @@ import re
|
||||
from wtforms.validators import ValidationError
|
||||
import pendulum
|
||||
from datetime import datetime
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
def DateRange(lower_bound=None, upper_bound=None, message=None):
|
||||
@@ -27,7 +28,7 @@ def DateRange(lower_bound=None, upper_bound=None, message=None):
|
||||
return _date_range
|
||||
|
||||
|
||||
def IsNumber(message="Please enter a valid number."):
|
||||
def IsNumber(message=translate("forms.validators.is_number_message")):
|
||||
def _is_number(form, field):
|
||||
try:
|
||||
int(field.data)
|
||||
@@ -37,7 +38,7 @@ def IsNumber(message="Please enter a valid number."):
|
||||
return _is_number
|
||||
|
||||
|
||||
def PhoneNumber(message="Please enter a valid 5 or 10 digit phone number."):
|
||||
def PhoneNumber(message=translate("forms.validators.phone_number_message")):
|
||||
def _is_phone_number(form, field):
|
||||
digits = re.sub(r"\D", "", field.data)
|
||||
if len(digits) not in [5, 10]:
|
||||
@@ -50,9 +51,7 @@ def PhoneNumber(message="Please enter a valid 5 or 10 digit phone number."):
|
||||
return _is_phone_number
|
||||
|
||||
|
||||
def Name(
|
||||
message="This field accepts letters, numbers, commas, apostrophes, hyphens, and periods."
|
||||
):
|
||||
def Name(message=translate("forms.validators.name_message")):
|
||||
def _name(form, field):
|
||||
match = re.match(r"[\w \,\.\'\-]+", field.data)
|
||||
if not match or match.group() != field.data:
|
||||
@@ -61,7 +60,10 @@ def Name(
|
||||
return _name
|
||||
|
||||
|
||||
def ListItemRequired(message="Please provide at least one.", empty_values=("", None)):
|
||||
def ListItemRequired(
|
||||
message=translate("forms.validators.list_item_required_message"),
|
||||
empty_values=("", None),
|
||||
):
|
||||
def _list_item_required(form, field):
|
||||
non_empty_values = [v for v in field.data if v not in empty_values]
|
||||
if len(non_empty_values) == 0:
|
||||
@@ -70,7 +72,7 @@ def ListItemRequired(message="Please provide at least one.", empty_values=("", N
|
||||
return _list_item_required
|
||||
|
||||
|
||||
def ListItemsUnique(message="Items must be unique"):
|
||||
def ListItemsUnique(message=translate("forms.validators.list_items_unique_message")):
|
||||
def _list_items_unique(form, field):
|
||||
if len(field.data) > len(set(field.data)):
|
||||
raise ValidationError(message)
|
||||
|
@@ -2,16 +2,17 @@ from wtforms.fields import StringField
|
||||
from wtforms.validators import Length
|
||||
|
||||
from .forms import CacheableForm
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class WorkspaceForm(CacheableForm):
|
||||
name = StringField(
|
||||
"Workspace Name",
|
||||
translate("forms.workspace.name_label"),
|
||||
validators=[
|
||||
Length(
|
||||
min=4,
|
||||
max=100,
|
||||
message="Workspace names must be at least 4 and not more than 50 characters",
|
||||
message=translate("forms.workspace.name_length_validation_message"),
|
||||
)
|
||||
],
|
||||
)
|
||||
|
Reference in New Issue
Block a user