mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
A nicer look for the documents listing
This change includes a filthy hack around how Django handles change_list_results.html -- I'm not thrilled with it, but it's as elegant as I could come up with. I'm happy to field alternative ideas. More details can be found in `documents/templatetags/hacks.py` Specifically, this merge includes a significant facelift to the documents listing page, moving away from the tabular layout and toward a tileset look. I tried fiddling with the colours, but I just don't have any skills in that area, so we're all stuck with Django'd default colours until someone with an eye for colour can submit a better CSS.
This commit is contained in:
@@ -58,7 +58,7 @@ class DocumentAdmin(CommonAdmin):
|
||||
}
|
||||
|
||||
search_fields = ("correspondent__name", "title", "content")
|
||||
list_display = ("created", "title", "thumbnail", "correspondent", "tags_")
|
||||
list_display = ("title", "created", "thumbnail", "correspondent", "tags_")
|
||||
list_filter = ("tags", "correspondent", MonthListFilter)
|
||||
ordering = ["-created", "correspondent"]
|
||||
|
||||
|
6
src/documents/templates/admin/change_list_results.html
Normal file
6
src/documents/templates/admin/change_list_results.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% load hacks %}
|
||||
|
||||
{# See documents.templatetags.hacks.change_list_results for an explanation #}
|
||||
|
||||
{% change_list_results %}
|
||||
|
@@ -0,0 +1,167 @@
|
||||
{% load i18n %}
|
||||
|
||||
<style>
|
||||
.grid *, .grid *:after, .grid *:before {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.box {
|
||||
width: 12.5%;
|
||||
padding: 1em;
|
||||
float: left;
|
||||
opacity: 0.7;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.box:hover {
|
||||
opacity: 1;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.box:last-of-type {
|
||||
padding-right: 0;
|
||||
}
|
||||
.result {
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 2%;
|
||||
overflow: hidden;
|
||||
height: 300px;
|
||||
}
|
||||
.result .header {
|
||||
padding: 5px;
|
||||
background-color: #79AEC8;
|
||||
height: 6em;
|
||||
}
|
||||
.result .header .checkbox {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.result .header .checkbox{
|
||||
width: 5%;
|
||||
float: left;
|
||||
}
|
||||
.result .header .info {
|
||||
width: 90%;
|
||||
float: left;
|
||||
}
|
||||
.result .header a,
|
||||
.result a.tag {
|
||||
color: #ffffff;
|
||||
}
|
||||
.result .date {
|
||||
padding: 5px;
|
||||
}
|
||||
.result .tags {
|
||||
float: left;
|
||||
}
|
||||
.result .tags a.tag {
|
||||
padding: 2px 5px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
}
|
||||
.result .date {
|
||||
float: right;
|
||||
color: #cccccc;
|
||||
}
|
||||
.result .image img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid {
|
||||
margin-right: 260px;
|
||||
}
|
||||
.grid:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@media (max-width: 1600px) {
|
||||
.box {
|
||||
width: 25%
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.grid {
|
||||
margin-right: 220px;
|
||||
}
|
||||
.box {
|
||||
width: 50%
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.grid {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.box {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
{# This is just copypasta from the parent change_list_results.html file #}
|
||||
<table id="result_list">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for header in result_headers %}
|
||||
<th scope="col" {{ header.class_attrib }}>
|
||||
{% if header.sortable %}
|
||||
{% if header.sort_priority > 0 %}
|
||||
<div class="sortoptions">
|
||||
<a class="sortremove" href="{{ header.url_remove }}" title="{% trans "Remove from sorting" %}"></a>
|
||||
{% if num_sorted_fields > 1 %}<span class="sortpriority" title="{% blocktrans with priority_number=header.sort_priority %}Sorting priority: {{ priority_number }}{% endblocktrans %}">{{ header.sort_priority }}</span>{% endif %}
|
||||
<a href="{{ header.url_toggle }}" class="toggle {% if header.ascending %}ascending{% else %}descending{% endif %}" title="{% trans "Toggle sorting" %}"></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div class="text">{% if header.sortable %}<a href="{{ header.url_primary }}">{{ header.text|capfirst }}</a>{% else %}<span>{{ header.text|capfirst }}</span>{% endif %}</div>
|
||||
<div class="clear"></div>
|
||||
</th>{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
{# /copypasta #}
|
||||
|
||||
|
||||
<div class="grid">
|
||||
{% for result in results %}
|
||||
{# 0: Checkbox #}
|
||||
{# 1: Title #}
|
||||
{# 2: Date #}
|
||||
{# 3: Image #}
|
||||
{# 4: Correspondent #}
|
||||
{# 5: Tags #}
|
||||
<div class="box">
|
||||
<div class="result">
|
||||
<div class="header">
|
||||
<div class="checkbox">{{ result.0 }}</div>
|
||||
<div class="info">
|
||||
{{ result.4 }}<br />
|
||||
{{ result.1 }}
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<div class="tags">{{ result.5 }}</div>
|
||||
<div class="date">{{ result.2 }}</div>
|
||||
<div style="clear: both;"></div>
|
||||
<div class="image">{{ result.3 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
// We nee to re-build the select-all functionality as the old logic pointed
|
||||
// to a table and we're using divs now.
|
||||
django.jQuery("#action-toggle").on("change", function(){
|
||||
django.jQuery(".grid .box .result .checkbox input")
|
||||
.prop("checked", this.checked);
|
||||
});
|
||||
</script>
|
0
src/documents/templatetags/__init__.py
Normal file
0
src/documents/templatetags/__init__.py
Normal file
41
src/documents/templatetags/hacks.py
Normal file
41
src/documents/templatetags/hacks.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
|
||||
from django.contrib import admin
|
||||
from django.template import Library
|
||||
from django.template.loader import get_template
|
||||
|
||||
from ..models import Document
|
||||
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def change_list_results(context):
|
||||
"""
|
||||
Django has a lot of places where you can override defaults, but
|
||||
unfortunately, `change_list_results.html` is not one of them. In fact,
|
||||
it's a downright pain in the ass to override this file on a per-model basis
|
||||
and this is the cleanest way I could come up with.
|
||||
|
||||
Basically all we've done here is defined `change_list_results.html` in an
|
||||
`admin` directory which globally overrides that file for *every* model.
|
||||
That template however simply loads this templatetag which determines
|
||||
whether we're currently looking at a `Document` listing or something else
|
||||
and loads the appropriate file in each case.
|
||||
|
||||
Better work arounds for this are welcome as I hate this myself, but at the
|
||||
moment, it's all I could come up with.
|
||||
"""
|
||||
|
||||
path = os.path.join(
|
||||
os.path.dirname(admin.__file__),
|
||||
"templates",
|
||||
"admin",
|
||||
"change_list_results.html"
|
||||
)
|
||||
|
||||
if context["cl"].model == Document:
|
||||
path = "admin/documents/document/change_list_results.html"
|
||||
|
||||
return get_template(path).render(context)
|
@@ -52,18 +52,19 @@ if _allowed_hosts:
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
||||
'flat_responsive',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
|
||||
"django_extensions",
|
||||
|
||||
"documents.apps.DocumentsConfig",
|
||||
|
||||
"flat_responsive",
|
||||
"django.contrib.admin",
|
||||
|
||||
"rest_framework",
|
||||
"crispy_forms",
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
__version__ = (0, 3, 4)
|
||||
__version__ = (0, 3, 5)
|
||||
|
Reference in New Issue
Block a user