This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git
The following commit(s) were added to refs/heads/main by this push:
new d94f16f Improve the form rendering macros
d94f16f is described below
commit d94f16f62777028119fde20694b90c038609fd77
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue May 13 16:30:01 2025 +0100
Improve the form rendering macros
---
atr/routes/projects.py | 31 ++++++++++++++----
atr/templates/macros/forms.html | 54 +++++++++++++++++--------------
atr/templates/release-policy-form.html | 58 +++++++++++++++++-----------------
3 files changed, 85 insertions(+), 58 deletions(-)
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index f6165a0..e81558a 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -57,28 +57,47 @@ class ReleasePolicyForm(util.QuartFormTyped):
wtforms.validators.Email(),
],
render_kw={"size": 30},
+ description="Note: This field determines where vote and finished
release announcement emails are sent."
+ " You can set this value to your own mailing list, but ATR will
currently only let you send to"
+ " [email protected].",
),
min_entries=1,
)
min_hours = wtforms.IntegerField(
- "Minimum voting period:",
+ "Minimum voting period",
validators=[
wtforms.validators.InputRequired("Please provide a minimum voting
period"),
util.validate_vote_duration,
],
default=72,
+ description="The minimum time to run the vote, in hours. Must be 0 or
between 72 and 144 inclusive."
+ " If 0, then wait until 3 +1 votes and more +1 than -1.",
+ )
+ manual_vote = wtforms.BooleanField(
+ "Voting process",
+ description="If this is set then the vote will be completely manual
and following policy is ignored.",
)
- manual_vote = wtforms.BooleanField("Voting process:")
release_checklist = wtforms.StringField(
- "Release checklist:", widget=wtforms.widgets.TextArea(),
render_kw={"rows": 10}
+ "Release checklist",
+ widget=wtforms.widgets.TextArea(),
+ render_kw={"rows": 10},
+ description="Markdown text describing how to test release candidates.",
)
start_vote_template = wtforms.StringField(
- "Start vote template:", widget=wtforms.widgets.TextArea(),
render_kw={"rows": 10}
+ "Start vote template",
+ widget=wtforms.widgets.TextArea(),
+ render_kw={"rows": 10},
+ description="Email template for messages to start a vote on a
release.",
)
announce_release_template = wtforms.StringField(
- "Announce release template:", widget=wtforms.widgets.TextArea(),
render_kw={"rows": 10}
+ "Announce release template",
+ widget=wtforms.widgets.TextArea(),
+ render_kw={"rows": 10},
+ description="Email template for messages to announce a finished
release.",
+ )
+ pause_for_rm = wtforms.BooleanField(
+ "Pause for RM", description="If enabled, RM can confirm manually if
the vote has passed."
)
- pause_for_rm = wtforms.BooleanField("Pause for RM:")
submit = wtforms.SubmitField("Save")
diff --git a/atr/templates/macros/forms.html b/atr/templates/macros/forms.html
index aaaeb67..e6d7583 100644
--- a/atr/templates/macros/forms.html
+++ b/atr/templates/macros/forms.html
@@ -1,29 +1,37 @@
-{% macro render_field(field, label=False, class_='form-control') %}
- {% if label and field.label %}{{ field.label(class="form-label") }}{% endif
%}
- {% set field_class = class_ + (' is-invalid' if field.errors else '') %}
- {{ field(class_=field_class) }}
- {% if field.errors %}
- <div class="invalid-feedback">
- {% for error in field.errors %}
- {{ error }}
- {% if not loop.last %}<br />{% endif %}
- {% endfor %}
- </div>
+{% macro label(field, classes="form-label", col=False) %}
+ {% if field.label %}
+ {% set final_classes = classes %}
+ {% if col %}
+ {% set col_classes = "col-sm-3 col-form-label text-sm-end" %}
+ {% if final_classes and final_classes != "" %}
+ {% set final_classes = col_classes + " " + final_classes %}
+ {% else %}
+ {% set final_classes = col_classes %}
+ {% endif %}
+ {% endif %}
+ {{ field.label(class=final_classes) }}
{% endif %}
- {% if field.description %}<div class="form-text text-muted">{{
field.description }}</div>{% endif %}
{% endmacro %}
-{% macro render_checkbox(field, label=False, class_='form-check-input') %}
- {% set field_class = class_ + (' is-invalid' if field.errors else '') %}
- {{ field(class_=field_class) }}
- {% if label and field.label %}{{ field.label(class="form-check-label") }}{%
endif %}
+{% macro widget(field, classes="form-control") %}
+ {% set widget_class = classes %}
{% if field.errors %}
- <div class="invalid-feedback d-block">
- {% for error in field.errors %}
- {{ error }}
- {% if not loop.last %}<br />{% endif %}
- {% endfor %}
- </div>
+ {% set widget_class = widget_class + ' is-invalid' %}
{% endif %}
- {% if field.description %}<div class="form-text text-muted">{{
field.description }}</div>{% endif %}
+ {{ field(class_=widget_class) }}
+{% endmacro %}
+
+{% macro errors(field, classes="invalid-feedback", item_separator="<br />") %}
+{% if field.errors %}
+ <div class="{{ classes }}">
+ {% for error in field.errors %}
+ {{ error }}
+ {% if not loop.last %}{{ item_separator|safe }}{% endif %}
+ {% endfor %}
+ </div>
+{% endif %}
+{% endmacro %}
+
+{% macro description(field, classes="form-text text-muted") %}
+ {% if field.description %}<div id="{{ field.id }}-help" class="{{ classes
}}">{{ field.description }}</div>{% endif %}
{% endmacro %}
diff --git a/atr/templates/release-policy-form.html
b/atr/templates/release-policy-form.html
index 7d38b9f..7662bb8 100644
--- a/atr/templates/release-policy-form.html
+++ b/atr/templates/release-policy-form.html
@@ -6,18 +6,18 @@
<input type="hidden" name="form_type" value="single" />
<div class="mb-3 pb-3 row border-bottom">
- <label for="project_name_text" class="col-sm-3 col-form-label
text-sm-end">Project:</label>
+ <label for="project_name_text" class="col-sm-3 col-form-label
text-sm-end">Project</label>
<div class="col-sm-8">
<p id="project_name_text" class="form-control-plaintext">{{
project.display_name }}</p>
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.mailto_addresses.entries[0].id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.mailto_addresses.entries[0].label.text }}:</label>
+ {{ forms.label(form.mailto_addresses.entries[0], col=True) }}
<div class="col-sm-8">
- {{ forms.render_field(form.mailto_addresses.entries[0]) }}
- <span class="form-text text-muted">Note: This field determines where
vote and finished release announcement emails are sent. You can set this value
to your own mailing list, but ATR will currently only let you send to
<code>[email protected]</code>.</span>
+ {{ forms.widget(form.mailto_addresses.entries[0]) }}
+ {{ forms.errors(form.mailto_addresses.entries[0]) }}
+ {{ forms.description(form.mailto_addresses.entries[0]) }}
</div>
<!--
<div class="col-sm-1">
@@ -27,62 +27,62 @@
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.manual_vote.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.manual_vote.label.text }}</label>
+ {{ forms.label(form.manual_vote, col=True) }}
<div class="col-sm-8">
<div class="form-check">
- {{ forms.render_checkbox(form.manual_vote) }}
+ {{ forms.widget(form.manual_vote, classes="form-check-input") }}
+ {{ forms.errors(form.manual_vote, classes="invalid-feedback d-block")
}}
<label class="form-check-label" for="{{ form.manual_vote.id
}}">Manual</label>
</div>
- <span id="manual_vote-help" class="form-text text-muted">If this is set
then the vote will be completely manual and following policy is ignored.</span>
+ {{ forms.description(form.manual_vote) }}
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.min_hours.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.min_hours.label.text }}</label>
+ {{ forms.label(form.min_hours, col=True) }}
<div class="col-sm-8">
- {{ forms.render_field(form.min_hours) }}
- <span id="min_hours-help" class="form-text text-muted">The minimum time
to run the vote, in hours. Must be 0 or between 72 and 144 inclusive. If 0,
then wait until 3 +1 votes and more +1 than -1.</span>
+ {{ forms.widget(form.min_hours) }}
+ {{ forms.errors(form.min_hours) }}
+ {{ forms.description(form.min_hours) }}
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.release_checklist.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.release_checklist.label.text }}</label>
+ {{ forms.label(form.release_checklist, col=True) }}
<div class="col-sm-8">
- {{ forms.render_field(form.release_checklist) }}
- <span id="release_checklist-help" class="form-text text-muted">Markdown
text describing how to test release candidates.</span>
+ {{ forms.widget(form.release_checklist) }}
+ {{ forms.errors(form.release_checklist) }}
+ {{ forms.description(form.release_checklist) }}
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.start_vote_template.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.start_vote_template.label.text }}</label>
+ {{ forms.label(form.start_vote_template, col=True) }}
<div class="col-sm-8">
- {{ forms.render_field(form.start_vote_template) }}
- <span id="start_vote_template-help" class="form-text text-muted">Email
template for messages to start a vote on a release.</span>
+ {{ forms.widget(form.start_vote_template) }}
+ {{ forms.errors(form.start_vote_template) }}
+ {{ forms.description(form.start_vote_template) }}
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.announce_release_template.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.announce_release_template.label.text }}</label>
+ {{ forms.label(form.announce_release_template, col=True) }}
<div class="col-sm-8">
- {{ forms.render_field(form.announce_release_template) }}
- <span id="announce_release_template-help" class="form-text
text-muted">Email template for messages to announce a finished release.</span>
+ {{ forms.widget(form.announce_release_template) }}
+ {{ forms.errors(form.announce_release_template) }}
+ {{ forms.description(form.announce_release_template) }}
</div>
</div>
<div class="mb-3 pb-3 row border-bottom">
- <label for="{{ form.pause_for_rm.id }}"
- class="col-sm-3 col-form-label text-sm-end">{{
form.pause_for_rm.label.text }}</label>
+ {{ forms.label(form.pause_for_rm, col=True) }}
<div class="col-sm-8">
<div class="form-check">
- {{ forms.render_checkbox(form.pause_for_rm) }}
+ {{ forms.widget(form.pause_for_rm, classes="form-check-input") }}
+ {{ forms.errors(form.pause_for_rm, classes="invalid-feedback d-block")
}}
<label class="form-check-label" for="{{ form.pause_for_rm.id
}}">Enabled</label>
</div>
- <span id="pause_for_rm-help" class="form-text text-muted">If enabled, RM
can confirm manually if the vote has passed.</span>
+ {{ forms.description(form.pause_for_rm) }}
</div>
</div>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]