diff --git a/core/templates/core/_collection_toc_items.html b/core/templates/core/_collection_toc_items.html
new file mode 100644
index 0000000..70e9177
--- /dev/null
+++ b/core/templates/core/_collection_toc_items.html
@@ -0,0 +1,11 @@
+{% load markdown_extras %}
+{% for section in sections %}
+
+
- {% if can_edit %}
{% endif %}
+ {% if can_edit %}
{% endif %}
{% if collection.description %}
{{ collection.description|markdown }}
{% endif %}
{% if sections %}
-
+
{% trans "Contents" %}
{% include 'core/_collection_toc_items.html' with sections=sections %}
{% endif %}
{% if pending_item %}
@@ -35,20 +35,20 @@
{% endif %}
-
+
{% for section in sections %}
{% if section.item %}{{ section.title|default:section.item.content|markdown_title|truncatechars:100 }}{% else %}{{ section.title|default:section.sub_collection.title|truncatechars:100 }}{% endif %}
-
+
{% if section.item %}
{{ section.item|item_markdown }}
{% if section.item.comment %}
{{ section.item.comment|markdown }}
{% endif %}{% else %}
{% trans "Nested collection" %}: {{ section.sub_collection.title }}
{% endif %}
{% if can_edit %}
-
-
-
-
+
+
+
+
{% endif %}
{% empty %}
{% trans "This collection has no sections yet." %}
{% endfor %}
@@ -60,11 +60,11 @@
{% trans "Notes" %}
- {% for item in candidates %}
{{ item.content|truncatechars:180 }}
#{{ item.id }} · {{ item.get_visibility_display }}{% if item.team %} · {{ item.team.name }}{% endif %}
{% empty %}
{% trans "No matching notes." %}
{% endfor %}
+ {% for item in candidates %}
{{ item.content|truncatechars:180 }}
#{{ item.id }} · {{ item.get_visibility_display }}{% if item.team %} · {{ item.team.name }}{% endif %}
{% empty %}
{% trans "No matching notes." %}
{% endfor %}
{% trans "Collections" %}
- {% for candidate in collection_candidates %}
{{ candidate.title }}
#{{ candidate.id }} · {{ candidate.get_visibility_display }}{% if candidate.team %} · {{ candidate.team.name }}{% endif %}
{% empty %}
{% trans "No matching collections." %}
{% endfor %}
+ {% for candidate in collection_candidates %}
{{ candidate.title }}
#{{ candidate.id }} · {{ candidate.get_visibility_display }}{% if candidate.team %} · {{ candidate.team.name }}{% endif %}
{% empty %}
{% trans "No matching collections." %}
{% endfor %}
{% endif %}
diff --git a/core/tests.py b/core/tests.py
index 7323c80..f04a054 100644
--- a/core/tests.py
+++ b/core/tests.py
@@ -337,10 +337,22 @@ class CollectionTests(TestCase):
CollectionSection.objects.create(collection=collection, item=note, position=0)
manage_url = reverse('collection_manage', args=[collection.id])
response = self.client.get(manage_url)
+ self.assertContains(response, 'id="collection-manage"')
+ self.assertContains(response, 'hx-boost="true"')
+ self.assertContains(response, 'hx-swap="outerHTML show:none"')
self.assertContains(response, f'{reverse("item_editor", args=[note.id])}?next={manage_url}')
self.assertContains(response, '>Section')
self.assertNotContains(response, '>## Section')
+ def test_collection_manage_preserves_search_when_adding_note(self):
+ collection = Collection.objects.create(owner=self.user, title='Reading view')
+ note = Item.objects.create(owner=self.user, kind=Item.Kind.NOTE, content='Findable note')
+ manage_url = reverse('collection_manage', args=[collection.id])
+
+ response = self.client.post(f'{manage_url}?q=Findable', {'action': 'add', 'item_id': note.id})
+
+ self.assertRedirects(response, f'{manage_url}?q=Findable')
+
def test_collection_can_include_collection(self):
parent = Collection.objects.create(owner=self.user, title='Parent')
child = Collection.objects.create(owner=self.user, title='Child')
diff --git a/core/views.py b/core/views.py
index fad7ed8..7e2de14 100644
--- a/core/views.py
+++ b/core/views.py
@@ -800,27 +800,29 @@ def collection_manage(request, pk):
if collection.mode == Collection.Mode.TAGS:
return redirect('collection_edit', pk=collection.pk)
manage_url = reverse('collection_manage', args=[collection.pk])
+ q = request.GET.get('q', '').strip()
+ redirect_url = f'{manage_url}?q={q}' if q else manage_url
if request.method == 'POST':
action = request.POST.get('action')
if action in {'add', 'confirm_add'}:
item = get_object_or_404(editable_collection_notes(request.user), pk=request.POST.get('item_id'))
if collection_item_is_compatible(collection, item):
add_collection_section(collection, item)
- return redirect(manage_url)
+ return redirect(redirect_url)
if action == 'add':
return render(request, 'core/collection_manage.html', collection_detail_context(request, collection, item))
mode = request.POST.get('mode')
if mode == 'convert':
if not item_can_change_for_collection(request.user, item, collection):
messages.error(request, _('This note is used by an incompatible collection or cannot be edited. Create a copy instead.'))
- return redirect(manage_url)
+ return redirect(redirect_url)
item = adapt_item_for_collection(item, collection)
elif mode == 'copy':
item = copy_item_for_collection(item, collection, request.user)
else:
- return redirect(manage_url)
+ return redirect(redirect_url)
add_collection_section(collection, item)
- return redirect(manage_url)
+ return redirect(redirect_url)
if action == 'add_collection':
sub_collection = get_object_or_404(visible_collections(request.user), pk=request.POST.get('collection_id'), mode=Collection.Mode.MANUAL)
if sub_collection.pk == collection.pk or collection_contains_collection(sub_collection, collection):
@@ -829,7 +831,7 @@ def collection_manage(request, pk):
messages.error(request, _('This collection has an incompatible visibility.'))
else:
add_collection_subcollection(collection, sub_collection)
- return redirect(manage_url)
+ return redirect(redirect_url)
section = get_object_or_404(CollectionSection, pk=request.POST.get('section_id'), collection=collection)
if action == 'remove':
section.delete()
@@ -848,7 +850,7 @@ def collection_manage(request, pk):
CollectionSection.objects.filter(pk=section.pk).update(position=temporary)
CollectionSection.objects.filter(pk=other.pk).update(position=section.position)
CollectionSection.objects.filter(pk=section.pk).update(position=other.position)
- return redirect(manage_url)
+ return redirect(redirect_url)
return render(request, 'core/collection_manage.html', collection_detail_context(request, collection))