Add nested collection management
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
{% load markdown_extras %}
|
||||
{% for section in sections %}
|
||||
<li>
|
||||
<a href="#section-{{ section.id }}">{% if section.item %}{{ section.title|default:section.item.content|markdown_title|truncatechars:90 }}{% else %}{{ section.title|default:section.sub_collection.title|truncatechars:90 }}{% endif %}</a>
|
||||
{% if section.sub_collection and section.sub_collection.sections.all %}
|
||||
<ol>
|
||||
{% include 'core/_collection_toc_items.html' with sections=section.sub_collection.sections.all %}
|
||||
</ol>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
@@ -22,7 +22,7 @@
|
||||
{% if sections or tag_items %}
|
||||
<nav class="collection-toc mb-5" aria-label="{% trans 'Contents' %}">
|
||||
<div class="small fw-semibold text-uppercase text-muted mb-2">{% trans "Contents" %}</div>
|
||||
<ol class="mb-0">{% if collection.mode == 'tags' %}{% for item in tag_items %}<li><a href="#item-{{ item.id }}">{{ item.content|markdown_title|truncatechars:90 }}</a></li>{% endfor %}{% else %}{% for section in sections %}<li><a href="#section-{{ section.id }}">{% if section.item %}{{ section.title|default:section.item.content|markdown_title|truncatechars:90 }}{% else %}{{ section.title|default:section.sub_collection.title|truncatechars:90 }}{% endif %}</a></li>{% endfor %}{% endif %}</ol>
|
||||
<ol class="mb-0">{% if collection.mode == 'tags' %}{% for item in tag_items %}<li><a href="#item-{{ item.id }}">{{ item.content|markdown_title|truncatechars:90 }}</a></li>{% endfor %}{% else %}{% include 'core/_collection_toc_items.html' with sections=sections %}{% endif %}</ol>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
{% load i18n markdown_extras %}
|
||||
{% block content %}
|
||||
<div class="d-md-none alert alert-info">{% trans "Collections are currently available on desktop only." %}</div>
|
||||
<div class="d-none d-md-block">
|
||||
<div id="collection-manage" class="d-none d-md-block" hx-boost="true" hx-target="#collection-manage" hx-select="#collection-manage" hx-swap="outerHTML show:none" hx-on::after-settle="if(window.collectionFocus==='__last'){document.querySelector('#collection-sections section:last-of-type')?.scrollIntoView({block:'center'})}else if(window.collectionFocus){document.getElementById(window.collectionFocus)?.scrollIntoView({block:'center'})}window.collectionFocus=null">
|
||||
<div class="d-flex justify-content-between align-items-start gap-3 mb-4">
|
||||
<div>
|
||||
<a class="btn btn-sm btn-outline-secondary mb-3" href="{{ collection.get_absolute_url }}">← {% trans "View collection" %}</a>
|
||||
<a class="btn btn-sm btn-outline-secondary mb-3" href="{{ collection.get_absolute_url }}" hx-boost="false">← {% trans "View collection" %}</a>
|
||||
<h1 class="display-6 mb-2">{{ collection.title }}</h1>
|
||||
<div class="d-flex flex-wrap gap-2 align-items-center">
|
||||
{% if collection.team %}<span class="badge text-bg-warning">{{ collection.team.name }}</span>{% else %}<span class="badge text-bg-light">{{ collection.get_visibility_display }}</span>{% endif %}
|
||||
{% for tag in collection.filter_tags.all %}<span class="badge rounded-pill text-bg-light">#{{ tag.name }}</span>{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% if can_edit %}<div class="d-flex gap-2"><a class="btn btn-outline-secondary" href="{% url 'collection_edit' collection.id %}">{% trans "Collection settings" %}</a>{% if can_delete %}<form method="post" action="{% url 'collection_delete' collection.id %}" onsubmit="return confirm('{% trans "Delete collection? The notes remain available." %}')">{% csrf_token %}<button class="btn btn-outline-danger">{% trans "Delete" %}</button></form>{% endif %}</div>{% endif %}
|
||||
{% if can_edit %}<div class="d-flex gap-2"><a class="btn btn-outline-secondary" href="{% url 'collection_edit' collection.id %}" hx-boost="false">{% trans "Collection settings" %}</a>{% if can_delete %}<form method="post" action="{% url 'collection_delete' collection.id %}" hx-boost="false" onsubmit="return confirm('{% trans "Delete collection? The notes remain available." %}')">{% csrf_token %}<button class="btn btn-outline-danger">{% trans "Delete" %}</button></form>{% endif %}</div>{% endif %}
|
||||
</div>
|
||||
|
||||
{% if collection.description %}<div class="content lead mb-4">{{ collection.description|markdown }}</div>{% endif %}
|
||||
|
||||
{% if sections %}
|
||||
<div class="card item-card mb-4"><div class="card-body"><div class="fw-semibold mb-2">{% trans "Contents" %}</div><ol class="mb-0">{% for section in sections %}<li><a href="#section-{{ section.id }}">{% if section.item %}{{ section.title|default:section.item.content|markdown_title|truncatechars:90 }}{% else %}{{ section.title|default:section.sub_collection.title|truncatechars:90 }}{% endif %}</a></li>{% endfor %}</ol></div></div>
|
||||
<div class="card item-card mb-4"><div class="card-body"><div class="fw-semibold mb-2">{% trans "Contents" %}</div><ol class="mb-0">{% include 'core/_collection_toc_items.html' with sections=sections %}</ol></div></div>
|
||||
{% endif %}
|
||||
|
||||
{% if pending_item %}
|
||||
@@ -35,20 +35,20 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="vstack gap-4 mb-5">
|
||||
<div id="collection-sections" class="vstack gap-4 mb-5">
|
||||
{% for section in sections %}
|
||||
<section id="section-{{ section.id }}" class="card item-card"><div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start gap-3 mb-3">
|
||||
<h2 class="h3 mb-0">{% if section.item %}{{ section.title|default:section.item.content|markdown_title|truncatechars:100 }}{% else %}{{ section.title|default:section.sub_collection.title|truncatechars:100 }}{% endif %}</h2>
|
||||
<div class="d-flex gap-2 align-items-center">{% if section.item %}<a class="btn btn-sm btn-outline-secondary" href="{% url 'item_editor' section.item.id %}?next={% url 'collection_manage' collection.id %}">{% trans "Edit note" %}</a><a class="small text-muted" href="{{ section.item.get_absolute_url }}">#{{ section.item.id }}</a>{% else %}<a class="btn btn-sm btn-outline-secondary" href="{% url 'collection_manage' section.sub_collection.id %}">{% trans "Edit collection" %}</a><a class="small text-muted" href="{{ section.sub_collection.get_absolute_url }}">#{{ section.sub_collection.id }}</a>{% endif %}</div>
|
||||
<div class="d-flex gap-2 align-items-center">{% if section.item %}<a class="btn btn-sm btn-outline-secondary" href="{% url 'item_editor' section.item.id %}?next={% url 'collection_manage' collection.id %}" hx-boost="false">{% trans "Edit note" %}</a><a class="small text-muted" href="{{ section.item.get_absolute_url }}">#{{ section.item.id }}</a>{% else %}<a class="btn btn-sm btn-outline-secondary" href="{% url 'collection_manage' section.sub_collection.id %}" hx-boost="false">{% trans "Edit collection" %}</a><a class="small text-muted" href="{{ section.sub_collection.get_absolute_url }}">#{{ section.sub_collection.id }}</a>{% endif %}</div>
|
||||
</div>
|
||||
{% if section.item %}<div class="content">{{ section.item|item_markdown }}</div>
|
||||
{% if section.item.comment %}<div class="content text-muted border-start ps-3 mt-3">{{ section.item.comment|markdown }}</div>{% endif %}{% else %}<div class="text-muted">{% trans "Nested collection" %}: {{ section.sub_collection.title }}</div>{% endif %}
|
||||
{% if can_edit %}<div class="border-top mt-4 pt-3 d-flex align-items-center gap-2">
|
||||
<form method="post" class="d-flex gap-2 flex-grow-1">{% csrf_token %}<input type="hidden" name="action" value="title"><input type="hidden" name="section_id" value="{{ section.id }}"><input class="form-control form-control-sm" name="title" value="{{ section.title }}" placeholder="{% trans 'Optional section title' %}"><button class="btn btn-sm btn-outline-secondary">{% trans "Save title" %}</button></form>
|
||||
<form method="post">{% csrf_token %}<input type="hidden" name="action" value="up"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-secondary" title="{% trans 'Move up' %}">↑</button></form>
|
||||
<form method="post">{% csrf_token %}<input type="hidden" name="action" value="down"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-secondary" title="{% trans 'Move down' %}">↓</button></form>
|
||||
<form method="post">{% csrf_token %}<input type="hidden" name="action" value="remove"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-danger">{% trans "Remove" %}</button></form>
|
||||
<form method="post" class="d-flex gap-2 flex-grow-1" hx-on::before-request="window.collectionFocus='section-{{ section.id }}'">{% csrf_token %}<input type="hidden" name="action" value="title"><input type="hidden" name="section_id" value="{{ section.id }}"><input class="form-control form-control-sm" name="title" value="{{ section.title }}" placeholder="{% trans 'Optional section title' %}"><button class="btn btn-sm btn-outline-secondary">{% trans "Save title" %}</button></form>
|
||||
<form method="post" hx-on::before-request="window.collectionFocus='section-{{ section.id }}'">{% csrf_token %}<input type="hidden" name="action" value="up"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-secondary" title="{% trans 'Move up' %}">↑</button></form>
|
||||
<form method="post" hx-on::before-request="window.collectionFocus='section-{{ section.id }}'">{% csrf_token %}<input type="hidden" name="action" value="down"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-secondary" title="{% trans 'Move down' %}">↓</button></form>
|
||||
<form method="post" hx-on::before-request="window.collectionFocus='collection-sections'">{% csrf_token %}<input type="hidden" name="action" value="remove"><input type="hidden" name="section_id" value="{{ section.id }}"><button class="btn btn-sm btn-outline-danger">{% trans "Remove" %}</button></form>
|
||||
</div>{% endif %}
|
||||
</div></section>
|
||||
{% empty %}<div class="text-center text-muted py-5">{% trans "This collection has no sections yet." %}</div>{% endfor %}
|
||||
@@ -60,11 +60,11 @@
|
||||
<form method="get" class="input-group mb-3"><input class="form-control" name="q" value="{{ q }}" placeholder="{% trans 'Search notes and collections' %}"><button class="btn btn-outline-secondary">{% trans "Search" %}</button></form>
|
||||
<h3 class="h6">{% trans "Notes" %}</h3>
|
||||
<div class="vstack gap-2 mb-4">
|
||||
{% for item in candidates %}<div class="border rounded p-3 d-flex justify-content-between align-items-start gap-3"><div><div>{{ item.content|truncatechars:180 }}</div><div class="small text-muted">#{{ item.id }} · {{ item.get_visibility_display }}{% if item.team %} · {{ item.team.name }}{% endif %}</div></div><form method="post">{% csrf_token %}<input type="hidden" name="action" value="add"><input type="hidden" name="item_id" value="{{ item.id }}"><button class="btn btn-sm btn-dark">{% trans "Add" %}</button></form></div>{% empty %}<div class="text-muted">{% trans "No matching notes." %}</div>{% endfor %}
|
||||
{% for item in candidates %}<div class="border rounded p-3 d-flex justify-content-between align-items-start gap-3"><div><div>{{ item.content|truncatechars:180 }}</div><div class="small text-muted">#{{ item.id }} · {{ item.get_visibility_display }}{% if item.team %} · {{ item.team.name }}{% endif %}</div></div><form method="post" hx-on::before-request="window.collectionFocus='__last'">{% csrf_token %}<input type="hidden" name="action" value="add"><input type="hidden" name="item_id" value="{{ item.id }}"><button class="btn btn-sm btn-dark">{% trans "Add" %}</button></form></div>{% empty %}<div class="text-muted">{% trans "No matching notes." %}</div>{% endfor %}
|
||||
</div>
|
||||
<h3 class="h6">{% trans "Collections" %}</h3>
|
||||
<div class="vstack gap-2">
|
||||
{% for candidate in collection_candidates %}<div class="border rounded p-3 d-flex justify-content-between align-items-start gap-3"><div><div>{{ candidate.title }}</div><div class="small text-muted">#{{ candidate.id }} · {{ candidate.get_visibility_display }}{% if candidate.team %} · {{ candidate.team.name }}{% endif %}</div></div><form method="post">{% csrf_token %}<input type="hidden" name="action" value="add_collection"><input type="hidden" name="collection_id" value="{{ candidate.id }}"><button class="btn btn-sm btn-dark">{% trans "Add" %}</button></form></div>{% empty %}<div class="text-muted">{% trans "No matching collections." %}</div>{% endfor %}
|
||||
{% for candidate in collection_candidates %}<div class="border rounded p-3 d-flex justify-content-between align-items-start gap-3"><div><div>{{ candidate.title }}</div><div class="small text-muted">#{{ candidate.id }} · {{ candidate.get_visibility_display }}{% if candidate.team %} · {{ candidate.team.name }}{% endif %}</div></div><form method="post" hx-on::before-request="window.collectionFocus='__last'">{% csrf_token %}<input type="hidden" name="action" value="add_collection"><input type="hidden" name="collection_id" value="{{ candidate.id }}"><button class="btn btn-sm btn-dark">{% trans "Add" %}</button></form></div>{% empty %}<div class="text-muted">{% trans "No matching collections." %}</div>{% endfor %}
|
||||
</div>
|
||||
</div></div>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user