Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
12dd969581 Bump devalue from 5.6.1 to 5.6.3 in /docs
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.1 to 5.6.3.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/devalue/compare/v5.6.1...v5.6.3)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.6.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-20 19:14:37 +00:00
15 changed files with 5 additions and 305 deletions

View File

@@ -278,8 +278,6 @@ class AdminBookmarkBundle(admin.ModelAdmin):
"any_tags",
"all_tags",
"excluded_tags",
"filter_shared",
"filter_unread",
"date_created",
)
search_fields = ["name", "search", "any_tags", "all_tags", "excluded_tags"]

View File

@@ -44,8 +44,6 @@ class BookmarkBundleSerializer(serializers.ModelSerializer):
"any_tags",
"all_tags",
"excluded_tags",
"filter_unread",
"filter_shared",
"order",
"date_created",
"date_modified",

View File

@@ -218,28 +218,10 @@ class BookmarkBundleForm(forms.ModelForm):
any_tags = forms.CharField(required=False, widget=TagAutocomplete)
all_tags = forms.CharField(required=False, widget=TagAutocomplete)
excluded_tags = forms.CharField(required=False, widget=TagAutocomplete)
filter_unread = forms.ChoiceField(
choices=BookmarkBundle.FILTER_UNREAD_CHOICES,
required=False,
widget=FormSelect,
)
filter_shared = forms.ChoiceField(
choices=BookmarkBundle.FILTER_SHARED_CHOICES,
required=False,
widget=FormSelect,
)
class Meta:
model = BookmarkBundle
fields = [
"name",
"search",
"any_tags",
"all_tags",
"excluded_tags",
"filter_unread",
"filter_shared",
]
fields = ["name", "search", "any_tags", "all_tags", "excluded_tags"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs, error_class=FormErrorList)

View File

@@ -1,30 +0,0 @@
# Generated by Django 6.0 on 2026-02-28 09:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bookmarks", "0053_migrate_api_tokens"),
]
operations = [
migrations.AddField(
model_name="bookmarkbundle",
name="filter_shared",
field=models.CharField(
choices=[("off", "All"), ("yes", "Shared"), ("no", "Unshared")],
default="off",
max_length=3,
),
),
migrations.AddField(
model_name="bookmarkbundle",
name="filter_unread",
field=models.CharField(
choices=[("off", "All"), ("yes", "Unread"), ("no", "Read")],
default="off",
max_length=3,
),
),
]

View File

@@ -181,37 +181,11 @@ def bookmark_asset_deleted(sender, instance, **kwargs):
class BookmarkBundle(models.Model):
FILTER_STATE_OFF = "off"
FILTER_STATE_YES = "yes"
FILTER_STATE_NO = "no"
FILTER_UNREAD_CHOICES = [
(FILTER_STATE_OFF, "All"),
(FILTER_STATE_YES, "Unread"),
(FILTER_STATE_NO, "Read"),
]
FILTER_SHARED_CHOICES = [
(FILTER_STATE_OFF, "All"),
(FILTER_STATE_YES, "Shared"),
(FILTER_STATE_NO, "Unshared"),
]
name = models.CharField(max_length=256, blank=False)
search = models.CharField(max_length=256, blank=True)
any_tags = models.CharField(max_length=1024, blank=True)
all_tags = models.CharField(max_length=1024, blank=True)
excluded_tags = models.CharField(max_length=1024, blank=True)
filter_unread = models.CharField(
max_length=3,
choices=FILTER_UNREAD_CHOICES,
blank=False,
default=FILTER_STATE_OFF,
)
filter_shared = models.CharField(
max_length=3,
choices=FILTER_SHARED_CHOICES,
blank=False,
default=FILTER_STATE_OFF,
)
order = models.IntegerField(null=False, default=0)
date_created = models.DateTimeField(auto_now_add=True, null=False)
date_modified = models.DateTimeField(auto_now=True, null=False)

View File

@@ -211,16 +211,6 @@ def _filter_bundle(query_set: QuerySet, bundle: BookmarkBundle) -> QuerySet:
Exists(Bookmark.objects.filter(tag_conditions, id=OuterRef("id")))
)
if bundle.filter_unread == BookmarkBundle.FILTER_STATE_YES:
query_set = query_set.filter(unread=True)
elif bundle.filter_unread == BookmarkBundle.FILTER_STATE_NO:
query_set = query_set.filter(unread=False)
if bundle.filter_shared == BookmarkBundle.FILTER_STATE_YES:
query_set = query_set.filter(shared=True)
elif bundle.filter_shared == BookmarkBundle.FILTER_STATE_NO:
query_set = query_set.filter(shared=False)
return query_set

View File

@@ -157,7 +157,6 @@
{% if bookmark_item.preview_image_file %}
<img class="preview-image"
src="{% static bookmark_item.preview_image_file %}"
alt=""
loading="lazy" />
{% else %}
<div class="preview-image placeholder">

View File

@@ -33,20 +33,6 @@
None of these tags must be present in a bookmark to match.
{% endformhelp %}
</div>
<div class="form-group">
{% formlabel form.filter_unread "Reading State" %}
{% formfield form.filter_unread has_help=True %}
{% formhelp form.filter_unread %}
Limit matches to unread or read bookmarks.
{% endformhelp %}
</div>
<div class="form-group">
{% formlabel form.filter_shared "Sharing State" %}
{% formfield form.filter_shared has_help=True %}
{% formhelp form.filter_shared %}
Limit matches to shared or unshared bookmarks.
{% endformhelp %}
</div>
<div class="form-footer d-flex mt-4">
<input type="submit"
name="save"

View File

@@ -179,8 +179,6 @@ class BookmarkFactoryMixin:
any_tags: str = "",
all_tags: str = "",
excluded_tags: str = "",
filter_unread: str = BookmarkBundle.FILTER_STATE_OFF,
filter_shared: str = BookmarkBundle.FILTER_STATE_OFF,
order: int = 0,
):
if user is None:
@@ -195,8 +193,6 @@ class BookmarkFactoryMixin:
any_tags=any_tags,
all_tags=all_tags,
excluded_tags=excluded_tags,
filter_unread=filter_unread,
filter_shared=filter_shared,
order=order,
)
bundle.save()

View File

@@ -13,8 +13,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
self.assertEqual(bundle.any_tags, data["any_tags"])
self.assertEqual(bundle.all_tags, data["all_tags"])
self.assertEqual(bundle.excluded_tags, data["excluded_tags"])
self.assertEqual(bundle.filter_unread, data["filter_unread"])
self.assertEqual(bundle.filter_shared, data["filter_shared"])
self.assertEqual(bundle.order, data["order"])
self.assertEqual(
bundle.date_created.isoformat().replace("+00:00", "Z"), data["date_created"]
@@ -73,8 +71,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
any_tags="tag1 tag2",
all_tags="required-tag",
excluded_tags="excluded-tag",
filter_unread=BookmarkBundle.FILTER_STATE_YES,
filter_shared=BookmarkBundle.FILTER_STATE_NO,
order=5,
)
@@ -106,8 +102,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
"any_tags": "tag1 tag2",
"all_tags": "required-tag",
"excluded_tags": "excluded-tag",
"filter_unread": BookmarkBundle.FILTER_STATE_YES,
"filter_shared": BookmarkBundle.FILTER_STATE_NO,
}
url = reverse("linkding:bundle-list")
@@ -121,8 +115,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
self.assertEqual(bundle.any_tags, bundle_data["any_tags"])
self.assertEqual(bundle.all_tags, bundle_data["all_tags"])
self.assertEqual(bundle.excluded_tags, bundle_data["excluded_tags"])
self.assertEqual(bundle.filter_unread, bundle_data["filter_unread"])
self.assertEqual(bundle.filter_shared, bundle_data["filter_shared"])
self.assertEqual(bundle.owner, self.user)
self.assertEqual(bundle.order, 0)
@@ -209,8 +201,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
"any_tags": "updated-tag1 updated-tag2",
"all_tags": "required-updated-tag",
"excluded_tags": "excluded-updated-tag",
"filter_unread": BookmarkBundle.FILTER_STATE_YES,
"filter_shared": BookmarkBundle.FILTER_STATE_NO,
"order": 5,
}
@@ -223,8 +213,6 @@ class BundlesApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
self.assertEqual(bundle.any_tags, updated_data["any_tags"])
self.assertEqual(bundle.all_tags, updated_data["all_tags"])
self.assertEqual(bundle.excluded_tags, updated_data["excluded_tags"])
self.assertEqual(bundle.filter_unread, updated_data["filter_unread"])
self.assertEqual(bundle.filter_shared, updated_data["filter_shared"])
self.assertEqual(bundle.order, updated_data["order"])
self.assertBundle(bundle, response.data)

View File

@@ -1,7 +1,6 @@
from django.test import TestCase
from django.urls import reverse
from bookmarks.models import BookmarkBundle
from bookmarks.tests.helpers import BookmarkFactoryMixin
@@ -19,8 +18,6 @@ class BundleEditViewTestCase(TestCase, BookmarkFactoryMixin):
"any_tags": "tag1 tag2",
"all_tags": "required-tag",
"excluded_tags": "excluded-tag",
"filter_unread": BookmarkBundle.FILTER_STATE_YES,
"filter_shared": BookmarkBundle.FILTER_STATE_NO,
}
return {**form_data, **overrides}
@@ -41,8 +38,6 @@ class BundleEditViewTestCase(TestCase, BookmarkFactoryMixin):
self.assertEqual(bundle.any_tags, updated_data["any_tags"])
self.assertEqual(bundle.all_tags, updated_data["all_tags"])
self.assertEqual(bundle.excluded_tags, updated_data["excluded_tags"])
self.assertEqual(bundle.filter_unread, updated_data["filter_unread"])
self.assertEqual(bundle.filter_shared, updated_data["filter_shared"])
def test_should_render_edit_form_with_prefilled_fields(self):
bundle = self.setup_bundle(
@@ -51,8 +46,6 @@ class BundleEditViewTestCase(TestCase, BookmarkFactoryMixin):
any_tags="tag1 tag2 tag3",
all_tags="required-tag all-tag",
excluded_tags="excluded-tag banned-tag",
filter_unread=BookmarkBundle.FILTER_STATE_YES,
filter_shared=BookmarkBundle.FILTER_STATE_NO,
)
response = self.client.get(reverse("linkding:bundles.edit", args=[bundle.id]))
@@ -102,30 +95,6 @@ class BundleEditViewTestCase(TestCase, BookmarkFactoryMixin):
html,
)
self.assertInHTML(
"""
<select name="filter_unread" class="form-select"
aria-describedby="id_filter_unread_help" id="id_filter_unread">
<option value="off">All</option>
<option value="yes" selected>Unread</option>
<option value="no">Read</option>
</select>
""",
html,
)
self.assertInHTML(
"""
<select name="filter_shared" class="form-select"
aria-describedby="id_filter_shared_help" id="id_filter_shared">
<option value="off">All</option>
<option value="yes">Shared</option>
<option value="no" selected>Unshared</option>
</select>
""",
html,
)
def test_should_return_422_with_invalid_form(self):
bundle = self.setup_bundle(
name="Test Bundle",

View File

@@ -21,8 +21,6 @@ class BundleNewViewTestCase(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
"any_tags": "tag1 tag2",
"all_tags": "required-tag",
"excluded_tags": "excluded-tag",
"filter_unread": BookmarkBundle.FILTER_STATE_YES,
"filter_shared": BookmarkBundle.FILTER_STATE_NO,
}
return {**form_data, **overrides}
@@ -40,8 +38,6 @@ class BundleNewViewTestCase(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
self.assertEqual(bundle.any_tags, form_data["any_tags"])
self.assertEqual(bundle.all_tags, form_data["all_tags"])
self.assertEqual(bundle.excluded_tags, form_data["excluded_tags"])
self.assertEqual(bundle.filter_unread, form_data["filter_unread"])
self.assertEqual(bundle.filter_shared, form_data["filter_shared"])
self.assertRedirects(response, reverse("linkding:bundles.index"))

View File

@@ -1,7 +1,6 @@
from django.test import TestCase
from django.urls import reverse
from bookmarks.models import BookmarkBundle
from bookmarks.tests.helpers import BookmarkFactoryMixin, HtmlTestMixin
@@ -94,68 +93,6 @@ class BundlePreviewViewTestCase(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
self.assertContains(response, active_bookmark.title)
self.assertNotContains(response, archived_bookmark.title)
def test_preview_with_filter_unread(self):
unread_bookmark = self.setup_bookmark(title="Unread Bookmark", unread=True)
read_bookmark = self.setup_bookmark(title="Read Bookmark", unread=False)
# Filter unread
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_unread": BookmarkBundle.FILTER_STATE_YES},
)
self.assertContains(response, "Found 1 bookmarks matching this bundle")
self.assertContains(response, unread_bookmark.title)
self.assertNotContains(response, read_bookmark.title)
# Filter read
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_unread": BookmarkBundle.FILTER_STATE_NO},
)
self.assertContains(response, "Found 1 bookmarks matching this bundle")
self.assertNotContains(response, unread_bookmark.title)
self.assertContains(response, read_bookmark.title)
# Filter off
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_unread": BookmarkBundle.FILTER_STATE_OFF},
)
self.assertContains(response, "Found 2 bookmarks matching this bundle")
self.assertContains(response, unread_bookmark.title)
self.assertContains(response, read_bookmark.title)
def test_preview_with_filter_shared(self):
shared_bookmark = self.setup_bookmark(title="Shared Bookmark", shared=True)
unshared_bookmark = self.setup_bookmark(title="Unshared Bookmark", shared=False)
# Filter shared
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_shared": BookmarkBundle.FILTER_STATE_YES},
)
self.assertContains(response, "Found 1 bookmarks matching this bundle")
self.assertContains(response, shared_bookmark.title)
self.assertNotContains(response, unshared_bookmark.title)
# Filter unshared
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_shared": BookmarkBundle.FILTER_STATE_NO},
)
self.assertContains(response, "Found 1 bookmarks matching this bundle")
self.assertNotContains(response, shared_bookmark.title)
self.assertContains(response, unshared_bookmark.title)
# Filter off
response = self.client.get(
reverse("linkding:bundles.preview"),
{"filter_shared": BookmarkBundle.FILTER_STATE_OFF},
)
self.assertContains(response, "Found 2 bookmarks matching this bundle")
self.assertContains(response, shared_bookmark.title)
self.assertContains(response, unshared_bookmark.title)
def test_preview_requires_authentication(self):
self.client.logout()

View File

@@ -6,7 +6,7 @@ from django.test import TestCase
from django.utils import timezone
from bookmarks import queries
from bookmarks.models import BookmarkBundle, BookmarkSearch, UserProfile
from bookmarks.models import BookmarkSearch, UserProfile
from bookmarks.tests.helpers import BookmarkFactoryMixin, random_sentence
from bookmarks.utils import unique
@@ -1501,89 +1501,6 @@ class QueriesBasicTestCase(TestCase, BookmarkFactoryMixin):
)
self.assertQueryResult(query, [matching_bookmarks])
def test_query_bookmarks_with_bundle_filter_unread(self):
unread_bookmarks = [
self.setup_bookmark(unread=True),
self.setup_bookmark(unread=True),
]
read_bookmarks = [
self.setup_bookmark(unread=False),
self.setup_bookmark(unread=False),
]
# Filter unread
bundle = self.setup_bundle(filter_unread=BookmarkBundle.FILTER_STATE_YES)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [unread_bookmarks])
# Filter read
bundle = self.setup_bundle(filter_unread=BookmarkBundle.FILTER_STATE_NO)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [read_bookmarks])
# Filter off
bundle = self.setup_bundle(filter_unread=BookmarkBundle.FILTER_STATE_OFF)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [unread_bookmarks, read_bookmarks])
def test_query_bookmarks_with_bundle_filter_shared(self):
shared_bookmarks = [
self.setup_bookmark(shared=True),
self.setup_bookmark(shared=True),
]
unshared_bookmarks = [
self.setup_bookmark(shared=False),
self.setup_bookmark(shared=False),
]
# Filter shared
bundle = self.setup_bundle(filter_shared=BookmarkBundle.FILTER_STATE_YES)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [shared_bookmarks])
# Filter unshared
bundle = self.setup_bundle(filter_shared=BookmarkBundle.FILTER_STATE_NO)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [unshared_bookmarks])
# Filter off
bundle = self.setup_bundle(filter_shared=BookmarkBundle.FILTER_STATE_OFF)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [shared_bookmarks, unshared_bookmarks])
def test_query_bookmarks_with_bundle_unread_shared_filters_combined(self):
bundle = self.setup_bundle(
search="python",
filter_unread=BookmarkBundle.FILTER_STATE_YES,
filter_shared=BookmarkBundle.FILTER_STATE_NO,
)
matching_bookmarks = [
self.setup_bookmark(title="Python Tutorial", unread=True, shared=False),
]
# Bookmarks that should not match
self.setup_bookmark(title="Python Guide", unread=False, shared=False)
self.setup_bookmark(title="Python Docs", unread=True, shared=True)
self.setup_bookmark(title="Java Guide", unread=True, shared=False)
query = queries.query_bookmarks(
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
)
self.assertQueryResult(query, [matching_bookmarks])
def test_query_archived_bookmarks_with_bundle(self):
bundle = self.setup_bundle(any_tags="bundleTag1 bundleTag2")

View File

@@ -2541,9 +2541,9 @@
}
},
"node_modules/devalue": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.1.tgz",
"integrity": "sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==",
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz",
"integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==",
"license": "MIT"
},
"node_modules/devlop": {