{# Field rendering shared by the three editing screens, so a course, a
category and a page present the same controls in the same order and
staff only have to learn them once. #}
{% macro field(f) %}
{{ f.label(class="form-label") }}
{{ f(class="form-control", **kwargs) }}
{% for error in f.errors %}
{{ error }}
{% endfor %}
{% endmacro %}
{% macro flashes() %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% for category, message in messages %}
{{ message }}
{% endfor %}
{% endwith %}
{% endmacro %}
{% macro visibility(form) %}
{% set timezone = config['COURSES_TIMEZONE'] %}
{# The two controls, together, with the timezone spelled out. A date typed
in the wrong zone releases material early, and the field itself is the
only place that warning is any use. #}
{% endmacro %}
{# The badge asks the service, not the row.
It used to ask item.is_released(), which reads the item's own two columns
and nothing else, and it lied in both directions: a page inside a withheld
course showed as Visible while readers got a 404, and a hidden item with a
date announced a release that was never going to arrive.
Four states now, because "withheld" was hiding two different situations
and a teacher needs to know which screen to go and fix. #}
{% macro state_badge(item) %}
{%- set status = visibility_state(item) -%}
{%- if status.state == 'visible' -%}
{{ _('Visible') }}
{%- elif status.state == 'scheduled' -%}
{{ _('Withheld until %(moment)s', moment=status.moment|course_datetime) }}
{%- elif status.state == 'blocked' -%}
{# Released in itself, and still unreachable. Naming what is holding it is
the whole value of this state. #}
{{ _('Held back by %(name)s', name=status.blocked_by.name) }}
{%- else -%}
{{ _('Withheld') }}
{%- endif -%}
{% endmacro %}
{% macro delete_button(action, form, question) %}
{% endmacro %}