| 1 |
{% extends "base.html" %} |
| 2 |
{% block title %}{{ project.title }} · Projects · {{ project.owner }}{% endblock %} |
| 3 |
{% block mainclass %} class="wide"{% endblock %} |
| 4 |
{% macro burnup(v) %}<svg class="burnup" viewBox="0 0 {{ crate::web::projects::BURN_W }} {{ crate::web::projects::BURN_H }}" preserveAspectRatio="none" role="img" aria-label="Burn-up: {{ v.done }} card{% if v.done != 1 %}s{% endif %} done over {{ v.so_far }} of {{ v.days }} days"><line x1="0" y1="{{ crate::web::projects::BURN_H }}" x2="{{ crate::web::projects::BURN_W }}" y2="{{ crate::web::projects::BURN_H }}"></line><polyline points="{{ v.points }}"></polyline></svg>{% endmacro %} |
| 5 |
{% macro card(c, colid) %} |
| 6 |
<li class="card-item{% if c.card.kind == "note" %} note{% endif %}" tabindex="-1" data-card="{{ c.card.id }}"{% if !c.url.is_empty() %} data-href="{{ c.url }}"{% endif %}> |
| 7 |
{% if c.card.kind == "note" %}<p>{{ c.title }}</p> |
| 8 |
{% else %}<a href="{{ c.url }}">{{ c.title }}</a> |
| 9 |
<p class="small mute"><span class="glyph" aria-hidden="true">{% if c.card.kind == "issue" %}◇{% else %}⇄{% endif %}</span> {{ c.reference }} · <span class="state-{{ c.state }}">{{ c.state }}</span>{% for a in c.assignees %} · <a class="card-who" href="/projects/{{ project.owner }}/{{ project.number }}?q=assignee:{{ a|urlencode }}" title="Cards assigned to {{ a }}">@{{ a }}</a>{% endfor %}</p> |
| 10 |
{% if compact %}{% if !c.labels.is_empty() %}<p class="card-dots">{% for l in c.labels %}<span class="dot" style="--c: {{ l.colour }}" title="{{ l.name }}"></span>{% endfor %}</p>{% endif %}{% else if !c.labels.is_empty() %}<p class="card-labels">{% for l in c.labels %}<a class="label" style="--c: {{ l.colour }}" href="/projects/{{ project.owner }}/{{ project.number }}?q=label:{{ l.name|urlencode }}" title="{% if l.description.is_empty() %}Cards labelled {{ l.name }}{% else %}{{ l.description }}{% endif %}">{{ l.name }}</a>{% endfor %}</p>{% endif %}{% endif %} |
| 11 |
{% if let Some(t) = c.card.archived_ms %}<p class="small mute">archived <time title="{{ t|when_i }}">{{ t|ago_i }}</time></p>{% endif %} |
| 12 |
{% if can_edit && archived %} |
| 13 |
<form class="tiny card-actions" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="card" value="{{ c.card.id }}"><button name="action" value="restore">restore</button></form> |
| 14 |
{% else if can_edit %} |
| 15 |
<form class="tiny card-actions" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="card" value="{{ c.card.id }}"> |
| 16 |
<label class="visually-hidden" for="mv-{{ c.card.id }}">Column</label> |
| 17 |
<select id="mv-{{ c.card.id }}" name="column">{% for o in columns %}<option value="{{ o.column.id }}"{% if o.column.id == colid %} selected{% endif %}>{{ o.column.name }}</option>{% endfor %}</select> |
| 18 |
<button name="action" value="move">move</button><button name="action" value="up" aria-label="Up">↑</button><button name="action" value="down" aria-label="Down">↓</button><button name="action" value="archive" title="Archive: off the board, kept and restorable">archive</button><button name="action" value="remove" aria-label="Remove from the project" title="Remove from the project">✕</button> |
| 19 |
</form>{% endif %} |
| 20 |
</li> |
| 21 |
{% endmacro %} |
| 22 |
{% block content %} |
| 23 |
<div class="head"><h1>{{ project.title }} <small><a href="/projects/{{ project.owner }}">{{ project.owner }}'s projects</a> · #{{ project.number }}{% if !project.public %} · private{% endif %}{% if project.closed %} · closed{% endif %}</small></h1> |
| 24 |
{% if !project.description.is_empty() %}<p class="mute">{{ project.description }}</p>{% endif %}</div> |
| 25 |
{% if let Some(n) = notice %}<p class="note">{{ n }}</p>{% endif %} |
| 26 |
{% if let Some(e) = error %}<p class="error">{{ e }}</p>{% endif %} |
| 27 |
<nav class="board-tabs" aria-label="Views of this board"> |
| 28 |
<a class="board-tab{% if view_name.is_empty() %} on{% endif %}" href="/projects/{{ project.owner }}/{{ project.number }}"{% if view_name.is_empty() %} aria-current="page"{% endif %}>Board</a> |
| 29 |
{% for v in views %}<a class="board-tab{% if v.name == *view_name %} on{% endif %}" href="/projects/{{ project.owner }}/{{ project.number }}?view={{ v.name|urlencode }}"{% if v.name == *view_name %} aria-current="page"{% endif %}>{{ v.name }} <span class="small mute">{{ v.layout }}</span></a>{% endfor %} |
| 30 |
</nav> |
| 31 |
{% if let Some(v) = shown_iteration %} |
| 32 |
<section class="iteration past" aria-label="Iteration {{ v.it.name }}"> |
| 33 |
<div><h2>{{ v.it.name }}</h2><p class="small mute">{{ v.first }} to {{ v.last }} · {{ v.done }} card{% if v.done != 1 %}s{% endif %} done, archived when it closed{% if can_edit %}; restore one to put it back on the board{% endif %} · <a href="/projects/{{ project.owner }}/{{ project.number }}">back to the board</a></p></div> |
| 34 |
{% call burnup(v) %} |
| 35 |
</section> |
| 36 |
{% else if archived %}<p class="note board-archive-note">Archived cards: off the board, kept and searchable{% if can_edit %}; restore one to put it back at the end of its column{% endif %}. <a href="/projects/{{ project.owner }}/{{ project.number }}">Back to the board</a></p> |
| 37 |
{% else %} |
| 38 |
<section class="iteration" aria-label="Iteration"> |
| 39 |
{% if let Some(v) = current %} |
| 40 |
<div><h2>{{ v.it.name }}</h2><p class="small mute">{{ v.first }} to {{ v.last }} · day {{ v.so_far }} of {{ v.days }} · {{ v.done }} card{% if v.done != 1 %}s{% endif %} done</p> |
| 41 |
{% if can_edit %}<form class="tiny" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="iteration" value="{{ v.it.id }}"><button name="action" value="close_iteration" class="small" data-confirm="Close {{ v.it.name }}? The cards in the Done column are archived under it.">CLOSE ITERATION</button></form>{% endif %}</div> |
| 42 |
{% call burnup(v) %} |
| 43 |
{% else if can_edit %} |
| 44 |
<details class="iteration-new"><summary class="small">start an iteration</summary> |
| 45 |
<form method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="action" value="start_iteration"> |
| 46 |
<label for="it-name">Name</label><input type="text" id="it-name" name="name" maxlength="60" placeholder="Sprint 1" required> |
| 47 |
<div class="inline-fields"><label>First day <input type="date" name="start" value="{{ next_first }}" required></label><label>Last day <input type="date" name="end" value="{{ next_last }}" required></label></div> |
| 48 |
<p class="small mute">Closing it archives the cards in the Done column under it.</p> |
| 49 |
<button type="submit" class="small">START</button> |
| 50 |
</form> |
| 51 |
</details> |
| 52 |
{% endif %} |
| 53 |
{% if !past.is_empty() %}<details class="iteration-past"><summary class="small">past iterations ({{ past.len() }})</summary><ul>{% for v in past %}<li><a href="/projects/{{ project.owner }}/{{ project.number }}?iteration={{ v.it.id }}">{{ v.it.name }}</a> <span class="small mute">{{ v.first }} to {{ v.last }} · {{ v.done }} done</span></li>{% endfor %}</ul></details>{% endif %} |
| 54 |
</section> |
| 55 |
{% endif %} |
| 56 |
<form class="board-filter" method="get" action="/projects/{{ project.owner }}/{{ project.number }}" role="search">{% if let Some(v) = shown_iteration %}<input type="hidden" name="iteration" value="{{ v.it.id }}">{% else if archived %}<input type="hidden" name="archived" value="1">{% endif %} |
| 57 |
{% if !view_name.is_empty() %}<input type="hidden" name="view" value="{{ view_name }}">{% endif %} |
| 58 |
<label class="visually-hidden" for="board-q">Filter cards</label><input type="search" id="board-q" name="q" value="{{ q }}" placeholder="filter: words, repo:, assignee:, label:, milestone:, is:open, age:>14d" title="Words in the title or reference; repo:NAME, assignee:NAME, label:NAME, milestone:TITLE (quote a title with spaces), state:STATE, is:open or is:closed, age:>14d or age:<7d. Press / to come here." data-board-filter> |
| 59 |
<label class="visually-hidden" for="board-layout">Layout</label><select id="board-layout" name="layout"><option value="board"{% if layout == "board" %} selected{% endif %}>board</option><option value="table"{% if layout == "table" %} selected{% endif %}>table</option></select> |
| 60 |
<label class="visually-hidden" for="board-lane">{% if layout == "table" %}Group by{% else %}Swimlanes{% endif %}</label><select id="board-lane" name="lane"><option value="">{% if layout == "table" %}no groups{% else %}no lanes{% endif %}</option>{% for l in ["repo", "assignee", "label", "milestone"] %}<option value="{{ l }}"{% if lane == *l %} selected{% endif %}>by {{ l }}</option>{% endfor %}</select> |
| 61 |
{% if layout == "table" %}<label class="visually-hidden" for="board-sort">Order</label><select id="board-sort" name="sort"><option value="">board order</option>{% for o in ["title", "reference", "state", "column", "age", "-age"] %}<option value="{{ o }}"{% if sort == *o %} selected{% endif %}>{% if *o == "-age" %}oldest first{% else if *o == "age" %}newest first{% else %}by {{ o }}{% endif %}</option>{% endfor %}</select>{% else %}<label class="small"><input type="checkbox" name="compact" value="1"{% if compact %} checked{% endif %}> compact</label>{% endif %} |
| 62 |
<label class="visually-hidden" for="board-state">State</label><select id="board-state" name="state"><option value="">any state</option>{% for s in ["open", "closed", "landed", "draft"] %}<option{% if state == *s %} selected{% endif %}>{{ s }}</option>{% endfor %}</select> |
| 63 |
<button type="submit" class="small">SHOW</button>{% if filtered %} <a class="small" href="/projects/{{ project.owner }}/{{ project.number }}{% if archived %}?archived=1{% endif %}">clear</a>{% endif %} |
| 64 |
{% if !archived && archived_total > 0 %}<a class="small board-archived-link" href="/projects/{{ project.owner }}/{{ project.number }}?archived=1">{{ archived_total }} archived card{% if archived_total != 1 %}s{% endif %}</a>{% endif %} |
| 65 |
</form> |
| 66 |
{% if can_edit && !archived %}<details class="board-save-view"><summary class="small">{% if view_name.is_empty() %}save as a view{% else %}save view{% endif %}</summary> |
| 67 |
<form method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="layout" value="{{ layout }}"><input type="hidden" name="q" value="{{ q }}"><input type="hidden" name="lane" value="{{ lane }}"><input type="hidden" name="sort" value="{{ sort }}"> |
| 68 |
<label for="view-name">Name</label><input type="text" id="view-name" name="name" value="{{ view_name }}" maxlength="40" required placeholder="My open work"> |
| 69 |
<p class="small mute">Keeps this layout, filter{% if !lane.is_empty() %}, {% if layout == "table" %}groups{% else %}lanes{% endif %}{% endif %}{% if !sort.is_empty() %} and order{% endif %} as a tab anyone with the board sees; its address can be shared.</p> |
| 70 |
<button name="action" value="save_view" class="small">SAVE</button> |
| 71 |
</form> |
| 72 |
{% for v in views %}{% if v.name == *view_name %}<form class="tiny" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="view" value="{{ v.id }}"><button name="action" value="delete_view" class="small danger-btn" data-confirm="Delete the view {{ v.name }}? The cards are not touched.">DELETE VIEW</button></form>{% endif %}{% endfor %} |
| 73 |
</details>{% endif %} |
| 74 |
{% if layout == "table" %} |
| 75 |
<div class="table-wrap"><table class="board-table" aria-label="Cards"> |
| 76 |
<thead><tr><th scope="col">Title</th><th scope="col">Reference</th><th scope="col">State</th><th scope="col">Column</th><th scope="col">Assignees</th><th scope="col">Labels</th><th scope="col">Milestone</th><th scope="col">Opened</th></tr></thead> |
| 77 |
<tbody> |
| 78 |
{% for r in rows %} |
| 79 |
{% if r.starts_group %}<tr class="group-row"><th colspan="8" scope="colgroup">{{ r.group }}</th></tr>{% endif %} |
| 80 |
<tr class="card-item" tabindex="-1" data-card="{{ r.c.card.id }}"{% if !r.c.url.is_empty() %} data-href="{{ r.c.url }}"{% endif %}> |
| 81 |
<td>{% if r.c.url.is_empty() %}{{ r.c.title }}{% else %}<a href="{{ r.c.url }}">{{ r.c.title }}</a>{% endif %}</td> |
| 82 |
<td class="small mute">{{ r.c.reference }}</td> |
| 83 |
<td><span class="state-{{ r.c.state }}">{{ r.c.state }}</span></td> |
| 84 |
<td>{% if can_edit %}<form class="tiny" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="card" value="{{ r.c.card.id }}"><label class="visually-hidden" for="tmv-{{ r.c.card.id }}">Column</label><select id="tmv-{{ r.c.card.id }}" name="column" data-autosubmit>{% for o in columns %}<option value="{{ o.column.id }}"{% if o.column.name == r.column %} selected{% endif %}>{{ o.column.name }}</option>{% endfor %}</select><button name="action" value="move" class="small">move</button></form>{% else %}{{ r.column }}{% endif %}</td> |
| 85 |
<td class="small">{% for a in r.c.assignees %}@{{ a }} {% endfor %}</td> |
| 86 |
<td>{% for l in r.c.labels %}<span class="label" style="--c: {{ l.colour }}">{{ l.name }}</span>{% endfor %}</td> |
| 87 |
<td class="small">{{ r.c.milestone }}</td> |
| 88 |
<td class="small mute"><time title="{{ r.c.opened_ms|when_i }}">{{ r.c.opened_ms|ago_i }}</time></td> |
| 89 |
</tr> |
| 90 |
{% endfor %} |
| 91 |
</tbody> |
| 92 |
</table></div> |
| 93 |
{% if rows.is_empty() %}<p class="mute">No cards{% if filtered %} match this filter{% endif %}.</p>{% endif %} |
| 94 |
{% if pages > 1 %}<nav class="pager small" aria-label="Pages">{% if page > 1 %}<a href="?{{ look }}&layout=table&page={{ page - 1 }}">← previous</a>{% endif %} page {{ page }} of {{ pages }} {% if page < pages %}<a href="?{{ look }}&layout=table&page={{ page + 1 }}">next →</a>{% endif %}</nav>{% endif %} |
| 95 |
{% else if !lanes.is_empty() %} |
| 96 |
{% for ln in lanes %} |
| 97 |
<section class="lane" aria-label="{{ ln.name }}"> |
| 98 |
<h2 class="lane-head">{{ ln.name }} <span class="count-chip">{{ ln.count }}</span></h2> |
| 99 |
<div class="board{% if compact %} compact{% endif %}" role="list" aria-label="Columns of {{ ln.name }}"> |
| 100 |
{% for col in ln.columns %} |
| 101 |
<section class="board-col" role="listitem" aria-label="{{ col.column.name }}"><header><h3>{{ col.column.name }} <span class="count-chip">{{ col.cards.len() }}</span></h3></header> |
| 102 |
<ul class="cards">{% for c in col.cards %}{% call card(c, col.column.id) %}{% endfor %}</ul> |
| 103 |
</section> |
| 104 |
{% endfor %} |
| 105 |
</div> |
| 106 |
</section> |
| 107 |
{% endfor %} |
| 108 |
{% else %} |
| 109 |
<div class="board{% if compact %} compact{% endif %}" role="list" aria-label="Columns"> |
| 110 |
{% for col in columns %} |
| 111 |
<section class="board-col" role="listitem" aria-labelledby="col-{{ col.column.id }}"> |
| 112 |
<header{% if col.over_wip %} class="over-wip"{% endif %}><h2 id="col-{{ col.column.id }}">{{ col.column.name }} <span class="count-chip"{% if col.over_wip %} title="Over its limit of {% if let Some(w) = col.column.wip_limit %}{{ w }}{% endif %} cards in progress"{% endif %}>{% if filtered %}{{ col.cards.len() }} of {{ col.total }}{% else %}{{ col.total }}{% endif %}{% if let Some(w) = col.column.wip_limit %} / {{ w }}{% endif %}</span></h2> |
| 113 |
{% if can_edit && !archived %}<form class="tiny" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"><button name="action" value="left" title="Move the column left" aria-label="Move {{ col.column.name }} left">←</button><button name="action" value="right" title="Move the column right" aria-label="Move {{ col.column.name }} right">→</button></form>{% endif %}</header> |
| 114 |
{% if !archived %}{% match col.column.archive_after_days %}{% when Some(-1) %}{% when Some(d) %}<p class="small mute col-archives">archives cards {{ d }} day{% if *d != 1 %}s{% endif %} after they reach it</p>{% when None %}{% if col.finished %}<p class="small mute col-archives">finished cards are archived after {{ crate::db::projects::FINISHED_KEPT_DAYS }} days</p>{% endif %}{% endmatch %}{% endif %} |
| 115 |
{% if col.before_iteration > 0 %}<p class="small mute col-hidden">{{ col.before_iteration }} done before this iteration, shown when it closes in its archive · <a href="/projects/{{ project.owner }}/{{ project.number }}?archived=1">archived cards</a></p>{% endif %} |
| 116 |
{% if col.hidden > 0 && !filtered && !archived %}<p class="small mute col-hidden">{{ col.hidden }} older card{% if col.hidden != 1 %}s{% endif %} not shown · <a href="/projects/{{ project.owner }}/{{ project.number }}?all={{ col.column.id }}#col-{{ col.column.id }}">show all {{ col.total }}</a></p>{% endif %} |
| 117 |
<ul class="cards"> |
| 118 |
{% for c in col.cards %} |
| 119 |
{% call card(c, col.column.id) %} |
| 120 |
{% endfor %} |
| 121 |
</ul> |
| 122 |
{% if can_edit && !archived %} |
| 123 |
<details class="add-card"><summary class="small">add a card</summary> |
| 124 |
<form method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"><input type="hidden" name="action" value="add"> |
| 125 |
<label for="ref-{{ col.column.id }}">Issue or proposal</label> |
| 126 |
<div class="inline-fields"><select name="repo" aria-label="Repository">{% for r in repos %}<option>{{ r }}</option>{% endfor %}</select><input type="text" id="ref-{{ col.column.id }}" name="reference" placeholder="#12 or repo#12"></div> |
| 127 |
<label for="note-{{ col.column.id }}">or a note</label><textarea id="note-{{ col.column.id }}" name="note" rows="2" maxlength="500"></textarea> |
| 128 |
<button type="submit" class="small">ADD</button> |
| 129 |
</form> |
| 130 |
</details> |
| 131 |
<details class="add-card"><summary class="small">column</summary> |
| 132 |
<form method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"> |
| 133 |
<input type="text" name="name" value="{{ col.column.name }}" aria-label="Column name" maxlength="40"><button name="action" value="rename_column" class="small">RENAME</button> <button name="action" value="remove_column" class="small danger-btn" data-confirm="Remove this column? Its cards move to the first column.">REMOVE</button> |
| 134 |
</form> |
| 135 |
<form class="col-archive" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"> |
| 136 |
<label for="wip-{{ col.column.id }}">Work in progress limit</label> |
| 137 |
<div class="inline-fields"><input type="number" id="wip-{{ col.column.id }}" name="limit" min="0" max="999" placeholder="none"{% if let Some(w) = col.column.wip_limit %} value="{{ w }}"{% endif %}><span class="small mute">cards</span><button name="action" value="wip" class="small">SAVE</button></div> |
| 138 |
</form> |
| 139 |
<form class="col-archive" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"> |
| 140 |
<label for="older-{{ col.column.id }}">Archive cards here more than</label> |
| 141 |
<div class="inline-fields"><input type="number" id="older-{{ col.column.id }}" name="days" min="0" max="3650" value="14" required><span class="small mute">days</span><button name="action" value="archive_older" class="small">ARCHIVE</button></div> |
| 142 |
</form> |
| 143 |
<form class="col-archive" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"><input type="hidden" name="action" value="takes_finished"> |
| 144 |
{% if col.column.takes_finished %}<p class="small">Finished work comes here: a card moves here when its issue closes or its proposal lands or closes.</p><button name="mode" value="off" class="small">STOP</button>{% else %}<label>Finished work</label><button name="mode" value="on" class="small" title="A card moves here when its issue closes or its proposal lands or closes (one column of the board)">MOVE IT HERE</button>{% endif %} |
| 145 |
</form> |
| 146 |
<form class="col-archive" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><input type="hidden" name="column" value="{{ col.column.id }}"> |
| 147 |
<label for="mode-{{ col.column.id }}">Archive automatically</label> |
| 148 |
<div class="inline-fields"><select id="mode-{{ col.column.id }}" name="mode" aria-label="Archive automatically"><option value="finished"{% if col.column.archive_after_days.is_none() %} selected{% endif %}>finished cards after {{ crate::db::projects::FINISHED_KEPT_DAYS }} days</option><option value="days"{% if col.column.archive_after_days.unwrap_or(-1) >= 0 %} selected{% endif %}>every card after</option><option value="never"{% if col.column.archive_after_days == Some(-1) %} selected{% endif %}>never</option></select><input type="number" id="after-{{ col.column.id }}" name="days" min="0" max="3650" placeholder="days" aria-label="Days"{% if let Some(d) = col.column.archive_after_days %}{% if *d >= 0 %} value="{{ d }}"{% endif %}{% endif %}><button name="action" value="archive_after" class="small">SAVE</button></div> |
| 149 |
</form> |
| 150 |
</details> |
| 151 |
{% endif %} |
| 152 |
</section> |
| 153 |
{% endfor %} |
| 154 |
{% if can_edit && !archived %} |
| 155 |
<section class="board-col add-col"><form method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"><label for="newcol">New column</label><input type="text" id="newcol" name="name" maxlength="40" required><button name="action" value="add_column" class="small">ADD COLUMN</button></form></section> |
| 156 |
{% endif %} |
| 157 |
</div> |
| 158 |
{% endif %} |
| 159 |
<p class="small mute board-keys">Keys: <kbd>j</kbd>/<kbd>k</kbd> move between cards, <kbd>Enter</kbd> opens one, <kbd>m</kbd> moves it to another column, <kbd>/</kbd> filters.</p> |
| 160 |
{% if can_manage %} |
| 161 |
<details class="panel"><summary>Settings</summary> |
| 162 |
<form class="card" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"> |
| 163 |
<label for="ptitle">Title</label><input type="text" id="ptitle" name="title" value="{{ project.title }}" maxlength="100"> |
| 164 |
<label for="pdesc">Description</label><input type="text" id="pdesc" name="description" value="{{ project.description }}"> |
| 165 |
<div class="choice"><label><input type="checkbox" name="private" value="1"{% if !project.public %} checked{% endif %}> private</label> <label><input type="checkbox" name="closed" value="1"{% if project.closed %} checked{% endif %}> closed (read-only)</label></div> |
| 166 |
<button name="action" value="settings">SAVE</button> <button name="action" value="delete" class="danger-btn" data-confirm="Delete this project? Issues and proposals are not touched.">DELETE PROJECT</button> |
| 167 |
</form> |
| 168 |
{% if !transfer_to.is_empty() %} |
| 169 |
<form class="card" method="post" action="/projects/{{ project.owner }}/{{ project.number }}"><input type="hidden" name="_csrf" value="{{ shell.csrf }}"> |
| 170 |
<h3>Transfer</h3> |
| 171 |
<p class="small mute">Move this project to another owner. It takes the next number there, with its columns and cards; this address goes on redirecting to it.</p> |
| 172 |
<label for="pto">New owner</label> |
| 173 |
<select id="pto" name="to">{% for o in transfer_to %}<option value="{{ o }}">{{ o }}</option>{% endfor %}</select> |
| 174 |
<button name="action" value="transfer" data-confirm="Transfer this project?">TRANSFER</button> |
| 175 |
</form> |
| 176 |
{% endif %} |
| 177 |
</details> |
| 178 |
{% endif %} |
| 179 |
{% endblock %} |