Introduce private docs and flatpages preview (#26)

* Add support for private documents
* Fix migrations after merge
* Rebase fixtures
* Filter private decoder docs
* Enable preview of unpublished pages
This commit is contained in:
2023-10-07 22:38:20 +02:00
committed by GitHub
parent a21baac10c
commit c73efb01e4
10 changed files with 86 additions and 38 deletions

View File

@@ -15,6 +15,7 @@ from metadata.models import (
@admin.register(Property) @admin.register(Property)
class PropertyAdmin(admin.ModelAdmin): class PropertyAdmin(admin.ModelAdmin):
list_display = ("name", "private")
search_fields = ("name",) search_fields = ("name",)

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2023-10-06 19:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("metadata", "0012_alter_decoder_manufacturer_decoderdocument"),
]
operations = [
migrations.AddField(
model_name="decoderdocument",
name="private",
field=models.BooleanField(default=False),
),
]

View File

@@ -66,12 +66,11 @@ class Flatpage(models.Model):
return reverse("flatpage", kwargs={"flatpage": self.path}) return reverse("flatpage", kwargs={"flatpage": self.path})
def get_link(self): def get_link(self):
if self.published: return mark_safe(
return mark_safe( '<a href="{0}" target="_blank">Link</a>'.format(
'<a href="{0}" target="_blank">Link</a>'.format( self.get_absolute_url()
self.get_absolute_url()
)
) )
)
@receiver(models.signals.pre_save, sender=Flatpage) @receiver(models.signals.pre_save, sender=Flatpage)

View File

@@ -1,7 +1,7 @@
{% load static %} {% load static %}
<div class="col"> <div class="col">
<div class="card shadow-sm"> <div class="card shadow-sm">
{% if d.item.image.count > 0 %} {% if d.item.image.exists %}
<a href="{{d.item.get_absolute_url}}"><img class="card-img-top" src="{{ d.item.image.first.image.url }}" alt="{{ d }}"></a> <a href="{{d.item.get_absolute_url}}"><img class="card-img-top" src="{{ d.item.image.first.image.url }}" alt="{{ d }}"></a>
{% else %} {% else %}
<!-- Do not show the "Coming soon" image when running in a single card column mode (e.g. on mobile) --> <!-- Do not show the "Coming soon" image when running in a single card column mode (e.g. on mobile) -->

View File

@@ -48,8 +48,8 @@
<button class="nav-link" id="nav-model-tab" data-bs-toggle="tab" data-bs-target="#nav-model" type="button" role="tab" aria-controls="nav-model" aria-selected="false">Model data</button> <button class="nav-link" id="nav-model-tab" data-bs-toggle="tab" data-bs-target="#nav-model" type="button" role="tab" aria-controls="nav-model" aria-selected="false">Model data</button>
<button class="nav-link" id="nav-class-tab" data-bs-toggle="tab" data-bs-target="#nav-class" type="button" role="tab" aria-controls="nav-class" aria-selected="false">Class data</button> <button class="nav-link" id="nav-class-tab" data-bs-toggle="tab" data-bs-target="#nav-class" type="button" role="tab" aria-controls="nav-class" aria-selected="false">Class data</button>
{% if rolling_stock.decoder %}<button class="nav-link" id="nav-dcc-tab" data-bs-toggle="tab" data-bs-target="#nav-dcc" type="button" role="tab" aria-controls="nav-dcc" aria-selected="false">DCC</button>{% endif %} {% if rolling_stock.decoder %}<button class="nav-link" id="nav-dcc-tab" data-bs-toggle="tab" data-bs-target="#nav-dcc" type="button" role="tab" aria-controls="nav-dcc" aria-selected="false">DCC</button>{% endif %}
{% if rolling_stock.document.count > 0 or rolling_stock.decoder.document.count > 0 %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %} {% if documents or decoder_documents %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %}
{% if rolling_stock_journal.count > 0 %}<button class="nav-link" id="nav-journal-tab" data-bs-toggle="tab" data-bs-target="#nav-journal" type="button" role="tab" aria-controls="nav-journal" aria-selected="false">Journal</button>{% endif %} {% if journal %}<button class="nav-link" id="nav-journal-tab" data-bs-toggle="tab" data-bs-target="#nav-journal" type="button" role="tab" aria-controls="nav-journal" aria-selected="false">Journal</button>{% endif %}
{% if rolling_stock.notes %}<button class="nav-link" id="nav-notes-tab" data-bs-toggle="tab" data-bs-target="#nav-notes" type="button" role="tab" aria-controls="nav-notes" aria-selected="false">Notes</button>{% endif %} {% if rolling_stock.notes %}<button class="nav-link" id="nav-notes-tab" data-bs-toggle="tab" data-bs-target="#nav-notes" type="button" role="tab" aria-controls="nav-notes" aria-selected="false">Notes</button>{% endif %}
</nav> </nav>
<div class="tab-content" id="nav-tabContent"> <div class="tab-content" id="nav-tabContent">
@@ -170,7 +170,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
{% if rolling_stock_properties %} {% if properties %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@@ -178,7 +178,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="table-group-divider"> <tbody class="table-group-divider">
{% for p in rolling_stock_properties %} {% for p in properties %}
<tr> <tr>
<th class="w-33" scope="row">{{ p.property }}</th> <th class="w-33" scope="row">{{ p.property }}</th>
<td>{{ p.value }}</td> <td>{{ p.value }}</td>
@@ -276,7 +276,7 @@
</table> </table>
</div> </div>
<div class="tab-pane" id="nav-documents" role="tabpanel" aria-labelledby="nav-documents-tab"> <div class="tab-pane" id="nav-documents" role="tabpanel" aria-labelledby="nav-documents-tab">
{% if rolling_stock.document.count > 0 %} {% if documents %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@@ -284,7 +284,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="table-group-divider"> <tbody class="table-group-divider">
{% for d in rolling_stock.document.all %} {% for d in documents.all %}
<tr> <tr>
<td class="w-33">{{ d.description }}</td> <td class="w-33">{{ d.description }}</td>
<td><a href="{{ d.file.url }}" target="_blank">{{ d.filename }}</a></td> <td><a href="{{ d.file.url }}" target="_blank">{{ d.filename }}</a></td>
@@ -294,7 +294,7 @@
</tbody> </tbody>
</table> </table>
{% endif %} {% endif %}
{% if rolling_stock.decoder.document.count > 0 %} {% if decoder_documents %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@@ -302,7 +302,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="table-group-divider"> <tbody class="table-group-divider">
{% for d in rolling_stock.decoder.document.all %} {% for d in decoder_documents.all %}
<tr> <tr>
<td class="w-33">{{ d.description }}</td> <td class="w-33">{{ d.description }}</td>
<td><a href="{{ d.file.url }}" target="_blank">{{ d.filename }}</a></td> <td><a href="{{ d.file.url }}" target="_blank">{{ d.filename }}</a></td>
@@ -321,7 +321,7 @@
</tr> </tr>
</thead> </thead>
<tbody class="table-group-divider"> <tbody class="table-group-divider">
{% for j in rolling_stock_journal %} {% for j in journal %}
<tr> <tr>
<th class="w-33" scope="row">{{ j.date }}</th> <th class="w-33" scope="row">{{ j.date }}</th>
<td>{{ j.log | safe }}</a></td> <td>{{ j.log | safe }}</a></td>

View File

@@ -16,7 +16,9 @@ from portal.models import Flatpage
from roster.models import RollingStock from roster.models import RollingStock
from consist.models import Consist from consist.models import Consist
from bookshelf.models import Book from bookshelf.models import Book
from metadata.models import Company, Manufacturer, Scale, RollingStockType, Tag from metadata.models import (
Company, Manufacturer, Scale, DecoderDocument, RollingStockType, Tag
)
def order_by_fields(): def order_by_fields():
@@ -305,24 +307,29 @@ class GetRollingStock(View):
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404 raise Http404
class_properties = ( # FIXME there's likely a better and more efficient way of doing this
rolling_stock.rolling_class.property.all() # but keeping KISS for now
if request.user.is_authenticated decoder_documents = []
else rolling_stock.rolling_class.property.filter( if request.user.is_authenticated:
class_properties = rolling_stock.rolling_class.property.all()
properties = rolling_stock.property.all()
documents = rolling_stock.document.all()
journal = rolling_stock.journal.all()
if rolling_stock.decoder:
decoder_documents = rolling_stock.decoder.document.all()
else:
class_properties = rolling_stock.rolling_class.property.filter(
property__private=False property__private=False
) )
) properties = rolling_stock.property.filter(
rolling_stock_properties = ( property__private=False
rolling_stock.property.all() )
if request.user.is_authenticated documents = rolling_stock.document.filter(private=False)
else rolling_stock.property.filter(property__private=False) journal = rolling_stock.journal.filter(private=False)
) if rolling_stock.decoder:
decoder_documents = rolling_stock.decoder.document.filter(
rolling_stock_journal = ( private=False
rolling_stock.journal.all() )
if request.user.is_authenticated
else rolling_stock.journal.filter(private=False)
)
return render( return render(
request, request,
@@ -331,8 +338,10 @@ class GetRollingStock(View):
"title": rolling_stock, "title": rolling_stock,
"rolling_stock": rolling_stock, "rolling_stock": rolling_stock,
"class_properties": class_properties, "class_properties": class_properties,
"rolling_stock_properties": rolling_stock_properties, "properties": properties,
"rolling_stock_journal": rolling_stock_journal, "decoder_documents": decoder_documents,
"documents": documents,
"journal": journal,
}, },
) )
@@ -437,12 +446,13 @@ class GetBook(View):
class GetFlatpage(View): class GetFlatpage(View):
def get(self, request, flatpage): def get(self, request, flatpage):
try: try:
flatpage = Flatpage.objects.get( flatpage = Flatpage.objects.get(path=flatpage)
Q(Q(path=flatpage) & Q(published=True))
)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404 raise Http404
if not request.user.is_authenticated:
flatpage = flatpage.filter(published=False)
return render( return render(
request, request,
"flatpages/flatpage.html", "flatpages/flatpage.html",

View File

@@ -1,4 +1,4 @@
from ram.utils import git_suffix from ram.utils import git_suffix
__version__ = "0.6.2" __version__ = "0.6.3"
__version__ += git_suffix(__file__) __version__ += git_suffix(__file__)

View File

@@ -14,6 +14,7 @@ class Document(models.Model):
null=True, null=True,
blank=True, blank=True,
) )
private = models.BooleanField(default=False)
class Meta: class Meta:
abstract = True abstract = True

View File

@@ -64,6 +64,7 @@ class RollingStockDocumentAdmin(admin.ModelAdmin):
"__str__", "__str__",
"rolling_stock", "rolling_stock",
"description", "description",
"private",
"download", "download",
) )
search_fields = ( search_fields = (

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2023-10-06 19:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("roster", "0018_rename_sku_rollingstock_item_number"),
]
operations = [
migrations.AddField(
model_name="rollingstockdocument",
name="private",
field=models.BooleanField(default=False),
),
]