Display tags in bookmark list
This commit is contained in:
parent
4a16e4d64c
commit
accc360ae5
|
@ -8,6 +8,9 @@ class Tag(models.Model):
|
||||||
date_added = models.DateTimeField()
|
date_added = models.DateTimeField()
|
||||||
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Bookmark(models.Model):
|
class Bookmark(models.Model):
|
||||||
url = models.URLField()
|
url = models.URLField()
|
||||||
|
@ -22,6 +25,10 @@ class Bookmark(models.Model):
|
||||||
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
||||||
tags = models.ManyToManyField(Tag)
|
tags = models.ManyToManyField(Tag)
|
||||||
|
|
||||||
|
# Attributes might be calculated in query
|
||||||
|
tag_count = 0
|
||||||
|
tag_string = ''
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def resolved_title(self):
|
def resolved_title(self):
|
||||||
return self.website_title if not self.title else self.title
|
return self.website_title if not self.title else self.title
|
||||||
|
@ -30,6 +37,12 @@ class Bookmark(models.Model):
|
||||||
def resolved_description(self):
|
def resolved_description(self):
|
||||||
return self.website_description if not self.description else self.description
|
return self.website_description if not self.description else self.description
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tag_names(self):
|
||||||
|
tag_names = self.tag_string.strip().split(',') if self.tag_string else []
|
||||||
|
tag_names.sort(key=str.lower)
|
||||||
|
return tag_names
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.resolved_title + ' (' + self.url[:30] + '...)'
|
return self.resolved_title + ' (' + self.url[:30] + '...)'
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,10 @@ class Concat(Aggregate):
|
||||||
|
|
||||||
|
|
||||||
def query_bookmarks(user: User, query_string: str):
|
def query_bookmarks(user: User, query_string: str):
|
||||||
|
|
||||||
# Add aggregated tag info to bookmark instances
|
# Add aggregated tag info to bookmark instances
|
||||||
query_set = Bookmark.objects \
|
query_set = Bookmark.objects \
|
||||||
.annotate(tags_count=Count('tags')) \
|
.annotate(tag_count=Count('tags'),
|
||||||
.annotate(tags_string=Concat('tags__name'))
|
tag_string=Concat('tags__name'))
|
||||||
|
|
||||||
# Sanitize query params
|
# Sanitize query params
|
||||||
if not query_string:
|
if not query_string:
|
||||||
|
|
|
@ -5,11 +5,15 @@ ul.bookmark-list {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
color: $gray-color;
|
color: $gray-color-dark;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $alternative-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions .btn-link {
|
.actions .btn-link {
|
||||||
color: $gray-color-dark;
|
color: $gray-color;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
|
|
||||||
|
@ -17,7 +21,7 @@ ul.bookmark-list {
|
||||||
&:hover,
|
&:hover,
|
||||||
&:active,
|
&:active,
|
||||||
&.active {
|
&.active {
|
||||||
color: darken($gray-color-dark, 10%);
|
color: darken($gray-color, 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
// Font sizes
|
// Font sizes
|
||||||
$html-font-size: 18px !default;
|
$html-font-size: 18px !default;
|
||||||
|
|
||||||
|
$alternative-color: #f45d00;
|
||||||
|
$alternative-color: #FF84E8;
|
||||||
|
$alternative-color: #98C1D9;
|
||||||
|
$alternative-color: #7B287D;
|
||||||
|
$alternative-color: #06c5c2;
|
||||||
|
|
||||||
// Import Spectre CSS lib
|
// Import Spectre CSS lib
|
||||||
@import "../../node_modules/spectre.css/src/spectre";
|
@import "../../node_modules/spectre.css/src/spectre";
|
||||||
// Import Spectre icons
|
// Import Spectre icons
|
||||||
|
|
|
@ -24,14 +24,25 @@
|
||||||
<div class="title truncate">
|
<div class="title truncate">
|
||||||
<a href="{{ bookmark.url }}" target="_blank">{{ bookmark.resolved_title }}</a>
|
<a href="{{ bookmark.url }}" target="_blank">{{ bookmark.resolved_title }}</a>
|
||||||
</div>
|
</div>
|
||||||
{% if bookmark.resolved_description is not None %}
|
<div class="description truncate">
|
||||||
<div class="description truncate">{{ bookmark.resolved_description }}</div>
|
{% if bookmark.tag_names %}
|
||||||
{% endif %}
|
<span>
|
||||||
|
{% for tag_name in bookmark.tag_names %}
|
||||||
|
<a href="?{% append_query_param q=tag_name %}">#{{ tag_name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if bookmark.tag_names and bookmark.resolved_description %} | {% endif %}
|
||||||
|
|
||||||
|
{% if bookmark.resolved_description %}
|
||||||
|
<span>{{ bookmark.resolved_description }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="{% url 'bookmarks:edit' bookmark.id %}"
|
<a href="{% url 'bookmarks:edit' bookmark.id %}"
|
||||||
class="btn btn-link">Edit</a>
|
class="btn btn-link btn-sm">Edit</a>
|
||||||
<a href="{% url 'bookmarks:remove' bookmark.id %}"
|
<a href="{% url 'bookmarks:remove' bookmark.id %}"
|
||||||
class="btn btn-link"
|
class="btn btn-link btn-sm"
|
||||||
onclick="return confirm('Do you really want to delete this bookmark?')">Remove</a>
|
onclick="return confirm('Do you really want to delete this bookmark?')">Remove</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -12,3 +12,19 @@ def update_query_string(context, **kwargs):
|
||||||
query.__setitem__(key, kwargs[key])
|
query.__setitem__(key, kwargs[key])
|
||||||
|
|
||||||
return query.urlencode()
|
return query.urlencode()
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True)
|
||||||
|
def append_query_param(context, **kwargs):
|
||||||
|
query = context['request'].GET.copy()
|
||||||
|
|
||||||
|
# Append to or create query param
|
||||||
|
for key in kwargs:
|
||||||
|
if query.__contains__(key):
|
||||||
|
value = query.__getitem__(key) + ' '
|
||||||
|
else:
|
||||||
|
value = ''
|
||||||
|
value = value + kwargs[key]
|
||||||
|
query.__setitem__(key, value)
|
||||||
|
|
||||||
|
return query.urlencode()
|
||||||
|
|
|
@ -17,6 +17,11 @@ def index(request):
|
||||||
paginator = Paginator(query_set, _default_page_size)
|
paginator = Paginator(query_set, _default_page_size)
|
||||||
bookmarks = paginator.get_page(page)
|
bookmarks = paginator.get_page(page)
|
||||||
|
|
||||||
|
if request.GET.get('tag'):
|
||||||
|
mod = request.GET.copy()
|
||||||
|
mod.pop('tag')
|
||||||
|
request.GET = mod
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'bookmarks': bookmarks,
|
'bookmarks': bookmarks,
|
||||||
'query': query_string if query_string else '',
|
'query': query_string if query_string else '',
|
||||||
|
|
Loading…
Reference in New Issue