diff --git a/bookmarks/api/routes.py b/bookmarks/api/routes.py index 41f7321..5249c51 100644 --- a/bookmarks/api/routes.py +++ b/bookmarks/api/routes.py @@ -11,6 +11,7 @@ from bookmarks.api.serializers import ( UserProfileSerializer, ) from bookmarks.models import Bookmark, BookmarkSearch, Tag, User +from bookmarks.services import auto_tagging from bookmarks.services.bookmarks import ( archive_bookmark, unarchive_bookmark, @@ -107,8 +108,18 @@ class BookmarkViewSet( else: metadata = website_loader.load_website_metadata(url) + # Return tags that would be automatically applied to the bookmark + profile = request.user.profile + auto_tags = [] + if profile.auto_tagging_rules: + auto_tags = auto_tagging.get_tags(profile.auto_tagging_rules, url) + return Response( - {"bookmark": existing_bookmark_data, "metadata": metadata.to_dict()}, + { + "bookmark": existing_bookmark_data, + "metadata": metadata.to_dict(), + "auto_tags": auto_tags, + }, status=status.HTTP_200_OK, ) diff --git a/bookmarks/e2e/e2e_test_bookmark_form.py b/bookmarks/e2e/e2e_test_bookmark_form.py index c4da421..8c031d5 100644 --- a/bookmarks/e2e/e2e_test_bookmark_form.py +++ b/bookmarks/e2e/e2e_test_bookmark_form.py @@ -85,3 +85,25 @@ class BookmarkFormE2ETestCase(LinkdingE2ETestCase): page.get_by_label("URL").fill(bookmark.url) expect(details).to_have_attribute("open", value="") + + def test_create_should_preview_auto_tags(self): + profile = self.get_or_create_test_user().profile + profile.auto_tagging_rules = "github.com dev github" + profile.save() + + with sync_playwright() as p: + # Open page with URL that should have auto tags + browser = self.setup_browser(p) + page = browser.new_page() + url = self.live_server_url + reverse("bookmarks:new") + url += f"?url=https%3A%2F%2Fgithub.com%2Fsissbruecker%2Flinkding" + page.goto(url) + + auto_tags_hint = page.locator(".form-input-hint.auto-tags") + expect(auto_tags_hint).to_be_visible() + expect(auto_tags_hint).to_have_text("Auto tags: dev github") + + # Change to URL without auto tags + page.get_by_label("URL").fill("https://example.com") + + expect(auto_tags_hint).to_be_hidden() diff --git a/bookmarks/styles/bookmark-form.scss b/bookmarks/styles/bookmark-form.scss index e80af60..1b31754 100644 --- a/bookmarks/styles/bookmark-form.scss +++ b/bookmarks/styles/bookmark-form.scss @@ -36,12 +36,11 @@ .form-input-hint.bookmark-exists { display: none; color: $warning-color; + } - a { - color: $warning-color; - text-decoration: underline; - font-weight: bold; - } + .form-input-hint.auto-tags { + display: none; + color: $success-color; } details.notes textarea { diff --git a/bookmarks/templates/bookmarks/form.html b/bookmarks/templates/bookmarks/form.html index 2dd05f8..d9beb61 100644 --- a/bookmarks/templates/bookmarks/form.html +++ b/bookmarks/templates/bookmarks/form.html @@ -23,10 +23,10 @@ {{ form.tag_string|add_class:"form-input"|attr:"ld-tag-autocomplete"|attr:"autocomplete:off"|attr:"autocapitalize:off" }}
- Enter any number of tags separated by space and without the hash (#). If a tag does not - exist it will be - automatically created. + Enter any number of tags separated by space and without the hash (#). + If a tag does not exist it will be automatically created.
+
{{ form.tag_string.errors }}
@@ -197,6 +197,18 @@ } else { bookmarkExistsHint.style['display'] = 'none'; } + + // Preview auto tags + const autoTags = data.auto_tags; + const autoTagsHint = document.querySelector('.form-input-hint.auto-tags'); + + if (autoTags.length > 0) { + autoTags.sort(); + autoTagsHint.style['display'] = 'block'; + autoTagsHint.innerHTML = `Auto tags: ${autoTags.join(" ")}`; + } else { + autoTagsHint.style['display'] = 'none'; + } }); } diff --git a/bookmarks/tests/test_bookmarks_api.py b/bookmarks/tests/test_bookmarks_api.py index 4c58d2c..58448df 100644 --- a/bookmarks/tests/test_bookmarks_api.py +++ b/bookmarks/tests/test_bookmarks_api.py @@ -742,6 +742,34 @@ class BookmarksApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin): self.assertEqual(bookmark.website_description, metadata["description"]) self.assertIsNone(metadata["preview_image"]) + def test_check_returns_no_auto_tags_if_none_configured(self): + self.authenticate() + + url = reverse("bookmarks:bookmark-check") + check_url = urllib.parse.quote_plus("https://example.com") + response = self.get( + f"{url}?url={check_url}", expected_status_code=status.HTTP_200_OK + ) + auto_tags = response.data["auto_tags"] + + self.assertCountEqual(auto_tags, []) + + def test_check_returns_matching_auto_tags(self): + self.authenticate() + + profile = self.get_or_create_test_user().profile + profile.auto_tagging_rules = "example.com tag1 tag2" + profile.save() + + url = reverse("bookmarks:bookmark-check") + check_url = urllib.parse.quote_plus("https://example.com") + response = self.get( + f"{url}?url={check_url}", expected_status_code=status.HTTP_200_OK + ) + auto_tags = response.data["auto_tags"] + + self.assertCountEqual(auto_tags, ["tag1", "tag2"]) + def test_can_only_access_own_bookmarks(self): self.authenticate() self.setup_bookmark()