{% from '_rule_block.html' import pin_block with context %} {% from '_pin_sections.html' import suspended_pins, suspended_sentence with context %} {% set page_title = 'Maintenance' %} {% include '_header.html' %} {#- The full, uncapped maintenance overview (ADR-0014, ADR-0036): **every pin** — a node's own, or one of its reasons' — with what it silences, how long is left, why, and who is behind it, read from the whole snapshot so it is depth- and filter-independent. Viewer-visible and bookmarkable; the strip pill's popover "+N more" links here. A plain page (the check.html / events.html pattern), not polled — so an open editor has nothing to wait for. This page is what makes the popover's one-row-per-node summary safe: it is where *"what is silenced right now?"* is answered completely, so the capped surface is free to fold. **The same blocks as a node's own page** (ADR-0104 decision 6, `_rule_block.html`), grouped under each node's path: the node's own pin first, then its lines' in the check's order — which is information (severity, API order) that the order they were pinned in is not. Each is read here and, by an admin, changed here: *Edit* opens in the block, and a save or a clear comes back to this page with its node named — `?node=#pinned-node`, the shape `?reason=#pinned-reason` has on a node's own page. The named node's section, and only it, gets the id and the ring. The node travels in the query and not in the fragment because a refused write is answered *at* this page's own address: from there a link that differed only by its fragment would be a jump within the refusal, and load nothing. **Two texts, in two places.** What a pin covers is what its block's sentence opens with — *The whole node*, or the reason line itself — and why is the block's note. Both are called "reason" in the model and they are not the same kind of thing. A line's block stands away from its line here, so it names the line and links to it on its node's page; the slug appears in neither as text: ADR-0036 makes it opaque, so it travels only in the link's `?reason=` value and in the field of the form that changes the pin. This is also the place with room for the pin's **whole** reading (ADR-0014) for everyone — *pinned by Anna three days ago, last changed by Ben an hour ago* — under the note; a node's own page keeps it in the editor. The second sentence appears only on a pin that has actually been edited; on the common untouched pin it would just repeat the first. **A pin whose node is not reported** (ADR-0109 decision 4) stands under its path like any other, and its section says so: the check stopped returning the node, or has not written it yet since the start. Such a pin silences nothing, so its block says what it will silence *when the node is reported*; the path is no link, there being no page to open, and a line's pin names no line, the lines having gone with the node. It is edited and cleared here, where nothing else shows it. -#}

Maintenance

{% if pins %} {%- set nodes = pins | map(attribute='path') | unique | list | length %}

{{ pins | length }} {{ 'pin' if pins | length == 1 else 'pins' }} on {{ nodes }} {{ 'node' if nodes == 1 else 'nodes' }}.

{%- for path, group in pins | groupby('path') %} {#- Whether the node is pinned whole: its lines' blocks then say they are silenced on their own as well, since they stay quiet when the node's pin ends. -#} {%- set covered = group | rejectattr('slug') | list | length > 0 %} {%- set back = url_for('maintenance_overview', node=path) ~ '#pinned-node' %} {%- set place = loop.index %} {%- set suspended = group[0].suspended %}

{% if suspended %}{{ path }}{% else %}{{ path }}{% endif %}{% set shown = group[0] | node_title %}{% if shown %} {{ shown | markdown_inline }}{% endif %}

{%- if suspended %}

{{ suspended_sentence(group) }}

{%- endif %}
{%- if suspended %} {{ suspended_pins(path, group, place, back, is_admin) }} {%- endif %} {%- for pin in group if not suspended %} {%- if pin.slug %} {#- The reason line as its node writes it — rendered, and whole: a member's text is often a link, and cutting it would leave raw syntax on the page. -#} {%- set subject %}{{ pin.line | markdown_inline }} — this line{% endset %} {{ pin_block(pin.entry, 'line', path, pin.slug, 'pin-' ~ place ~ '-' ~ loop.index, is_admin, also=covered, subject=subject, record=true, next=back, of=path) }} {%- else %} {%- set subject %}The whole node{% endset %} {{ pin_block(pin.entry, 'node', path, '', 'pin-' ~ place ~ '-' ~ loop.index, is_admin, subject=subject, record=true, next=back, of=path) }} {%- endif %} {%- endfor %}
{%- endfor %}
{% else %}

No nodes are in maintenance.

{% endif %}
{% include '_page_end.html' %}