{# The parts every page is built from (docs/UI.md, section 7). A page has no markup of its own for a button, a tag, a field, a card header, a pager or a filter bar. #} {% macro empty(text) %}
{{ text }}
{% endmacro %} {# The line under a detail page's heading: where the page sits. ``trail``: (label, url) pairs, the last one the page itself. #} {% macro breadcrumb(trail) %} {% endmacro %} {# A card with a heading. ``meta``: the small line beside it, ``tags``: markup at the right, ``tight``: the body without padding, for a table. #} {% macro card(title=None, meta=None, tags=None, tight=False, id=None) %}
{% if title %}

{{ title }}

{% if meta is not none %}{{ meta }}{% endif %}{% if tags %}{{ tags }}{% endif %}
{% endif %}
{{ caller() }}
{% endmacro %} {# Whether a webhook's last post went through. ``detail``: the error under the tag. #} {% macro webhook_state(error, detail=True) %}{% if error %}failing{% if detail %}{{ error }}{% endif %}{% else %}ok{% endif %}{% endmacro %} {# Rights as tags: groups first, then single operations. #} {% macro rights_tags(groups, operations) %}{% for group in groups %}{{ group }} {% endfor %}{% for operation in operations %}{{ operation }} {% endfor %}{% endmacro %} {# A secret the service shows once, e.g. a new token: ``title``, the value in one selectable piece, and the caller says what to do with it. #} {% macro secret_card(title, value) %}

{{ title }}

shown this once

{{ caller() }}

{{ value }}
{% endmacro %} {# The first card of a detail page: what the record is, read-only. The caller gives ``fact`` lines. #} {% macro facts(title, tags=None) %}

{{ title }}

{% if tags %}{{ tags }}{% endif %}
{{ caller() }}
{% endmacro %} {% macro fact(label, value=None, cls="") %}
{{ label }}
{% if caller is defined %}{{ caller() }}{% else %}{{ value | or_missing }}{% endif %}{% endmacro %} {# A list that belongs to the record of a detail page, e.g. its tokens. The caller gives the table, and ``new_row`` as the last part. #} {% macro related(title, count=None, meta=None) %}

{{ title }}

{% if count is not none %}{{ count }}{% endif %}{% if meta %}{{ meta }}{% endif %}
{{ caller() }}
{% endmacro %} {# The form that adds one more to a related list, folded until opened. ``open``: unfolded, e.g. when the list is still empty. #} {% macro new_row(label, open=False) %}
{{ label }}
{{ caller() }}
{% endmacro %} {# The hidden field every form that changes something carries. #} {% macro csrf_field() %}{% endmacro %} {# A form that is only a button, e.g. "Delete", with a question before it. #} {% macro action(url, label, confirm=None, cls="small", fields={}) %}
{{ csrf_field() }} {% for name, value in fields.items() %}{% endfor %}
{% endmacro %} {# A labelled input. #} {% macro field(name, label, value="", type="text", hint=None, required=False, cls="", attrs="") %}
{% if hint %}{{ hint }}{% endif %}
{% endmacro %} {# The filter bar above a list (filters.py): the search first, more filters folded, the active ones as chips under it. A GET form, so a filtered list has its URL. #} {% macro filter_bar(bar, problem=None) %} {% if problem %}{% endif %} {% endmacro %} {# The links below a list: to the next page, and from a later page back to the first. ``pages``: (more, first), as ``page_links`` gives them. #} {% macro pager(pages) %} {% set more, first = pages %} {% if more or first %}
{% if first %}Newest{% endif %} {% if more %}Older{% endif %}
{% endif %} {% endmacro %} {# The options of a folder select: the tree indented by depth, without the folders in ``exclude``. #} {% macro folder_options(tree, exclude, selected=None) %} {% for folder, depth in tree %}{% if folder.id not in exclude %}{% endif %}{% endfor %} {% endmacro %} {# The tag beside an account whose user may read mail there and send it to any address: what an injected instruction needs to carry data out. #} {% macro anywhere_tag() %}reads and sends anywhere{% endmacro %} {# The stored credentials of an account, one per line. #} {% macro credentials(stored) %}{% for credential in stored %}{{ credential.field }}, changed {{ credential.updated_at | when }}{% if not loop.last %}
{% endif %}{% else %}—{% endfor %}{% endmacro %} {# The last card of a detail page, always: its one red button removes the record, after a question. ``text`` says what happens and what stays. #} {% macro danger_card(title, text, url, label, confirm) %}

{{ title }}

{{ text }} {{ action(url, label, confirm=confirm, cls="danger") }}
{% endmacro %} {# A native dialog for a form loaded into #modal. #} {% macro modal(title) %}

{{ title }}

{{ caller() }}
{% endmacro %}