5 Commits

Author SHA1 Message Date
c1a45ad4c9 Bump version 2022-08-27 14:58:13 +02:00
29180572c1 Add a journal for rolling stock 2022-08-27 14:57:26 +02:00
d30d9fc9ed Various improvements for flatpages 2022-08-25 12:44:04 +02:00
4ed95d0edf Fix migrations 2022-08-25 00:49:10 +02:00
24bd2aa53c Add migrations md to html 2022-08-24 17:56:59 +02:00
16 changed files with 290 additions and 9 deletions

View File

@@ -0,0 +1,34 @@
# Generated by Django 4.1 on 2022-08-24 15:30
import markdown
from django.db import migrations
def md_to_html(apps, schema_editor):
fields = {
"Consist": ["notes"],
}
for m in fields.items():
model = apps.get_model("consist", m[0])
for row in model.objects.all():
for field in m[1]:
html = markdown.markdown(getattr(row, field))
row.__dict__[field] = html
row.save(update_fields=m[1])
class Migration(migrations.Migration):
dependencies = [
("consist", "0005_alter_consist_notes"),
]
operations = [
migrations.RunPython(
md_to_html,
reverse_code=migrations.RunPython.noop
),
]

View File

@@ -9,7 +9,8 @@ admin.site.register(SiteConfiguration, SingletonModelAdmin)
@admin.register(Flatpage)
class FlatpageAdmin(admin.ModelAdmin):
readonly_fields = ("path", "creation_time", "updated_time")
list_display = ("name", "path")
list_display = ("name", "path", "published", "get_link")
list_filter = ("published",)
search_fields = ("name",)
fieldsets = (
@@ -20,7 +21,7 @@ class FlatpageAdmin(admin.ModelAdmin):
"name",
"path",
"content",
"draft",
"published",
)
},
),

View File

@@ -0,0 +1,38 @@
# Generated by Django 4.1 on 2022-08-24 15:00
import markdown
from django.db import migrations
def md_to_html(apps, schema_editor):
fields = {
"SiteConfiguration": ["about", "footer", "footer_extended"],
"Flatpage": ["content"]
}
for m in fields.items():
model = apps.get_model("portal", m[0])
for row in model.objects.all():
for field in m[1]:
html = markdown.markdown(getattr(row, field))
row.__dict__[field] = html
row.save(update_fields=m[1])
class Migration(migrations.Migration):
dependencies = [
(
"portal",
"0011_alter_flatpage_content_alter_siteconfiguration_about_and_more",
),
]
operations = [
migrations.RunPython(
md_to_html,
reverse_code=migrations.RunPython.noop
),
]

View File

@@ -0,0 +1,42 @@
# Generated by Django 4.1 on 2022-08-25 10:18
from django.db import migrations, models
def reverse_bool(apps, schema_editor):
model = apps.get_model("portal", "Flatpage")
for row in model.objects.all():
row.published = not row.draft
row.save(update_fields=["published"])
def reverse_bool_back(apps, schema_editor):
model = apps.get_model("portal", "Flatpage")
for row in model.objects.all():
row.draft = not row.published
row.save(update_fields=["draft"])
class Migration(migrations.Migration):
dependencies = [
("portal", "0012_md_to_html"),
]
operations = [
migrations.AddField(
model_name="flatpage",
name="published",
field=models.BooleanField(default=False),
),
migrations.RunPython(
reverse_bool,
reverse_code=reverse_bool_back
),
migrations.RemoveField(
model_name="flatpage",
name="draft",
),
]

View File

@@ -2,6 +2,7 @@ import django
from django.db import models
from django.urls import reverse
from django.dispatch.dispatcher import receiver
from django.utils.safestring import mark_safe
from solo.models import SingletonModel
from ckeditor.fields import RichTextField
@@ -51,7 +52,7 @@ class SiteConfiguration(SingletonModel):
class Flatpage(models.Model):
name = models.CharField(max_length=256, unique=True)
path = models.CharField(max_length=256, unique=True)
draft = models.BooleanField(default=True)
published = models.BooleanField(default=False)
content = RichTextUploadingField()
creation_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
@@ -62,6 +63,14 @@ class Flatpage(models.Model):
def get_absolute_url(self):
return reverse("flatpage", kwargs={"flatpage": self.path})
def get_link(self):
if self.published:
return mark_safe(
'<a href="{0}" target="_blank">Link</a>'.format(
self.get_absolute_url()
)
)
@receiver(models.signals.pre_save, sender=Flatpage)
def tag_pre_save(sender, instance, **kwargs):

View File

@@ -73,7 +73,7 @@
</li>
{% show_menu %}
</ul>
{% include 'includes/search.html' %}
{% include 'includes/search.html' %}
</div>
</div>
</nav>

View File

@@ -3,10 +3,10 @@
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
More ...
</a>
{% for m in menu %}
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
{% for m in menu %}
<li><a class="dropdown-item" href="{{ m.get_absolute_url }}">{{ m.name }}</a></li>
</ul>
{% endfor %}
</ul>
</li>
{% endif %}

View File

@@ -7,6 +7,7 @@
<li><a class="dropdown-item" href="{% url 'admin:roster_rollingstock_changelist' %}">Rolling stock</a></li>
<li><a class="dropdown-item" href="{% url 'admin:consist_consist_changelist' %}">Consists</a></li>
<li><a class="dropdown-item" href="{% url 'admin:app_list' 'metadata' %}">Metadata</a></li>
<li><a class="dropdown-item" href="{% url 'admin:portal_flatpage_changelist' %}">Pages</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'admin:index' %}">Admin</a></li>
<li><a class="dropdown-item" href="{% url 'admin:portal_siteconfiguration_changelist' %}">Site configuration</a></li>

View File

@@ -47,6 +47,7 @@
{% 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.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.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 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 %}
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
@@ -277,6 +278,23 @@
</tbody>
</table>
</div>
<div class="tab-pane fade" id="nav-journal" role="tabpanel" aria-labelledby="nav-journal-tab">
<table class="table table-striped">
<thead>
<tr>
<th colspan="3" scope="row">Journal</th>
</tr>
</thead>
<tbody>
{% for j in rolling_stock_journal %}
<tr>
<th width="35%" scope="row">{{ j.date }}</th>
<td>{{ j.log | safe }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:roster_rollingstock_change' rolling_stock.pk %}">Edit</a>{% endif %}

View File

@@ -6,5 +6,5 @@ register = template.Library()
@register.inclusion_tag('flatpage_menu.html')
def show_menu():
menu = Flatpage.objects.all()
menu = Flatpage.objects.filter(published=True).order_by("name")
return {"menu": menu}

View File

@@ -154,6 +154,12 @@ class GetRollingStock(View):
else rolling_stock.property.filter(property__private=False)
)
rolling_stock_journal = (
rolling_stock.journal.all()
if request.user.is_authenticated
else rolling_stock.journal.filter(private=False)
)
return render(
request,
"page.html",
@@ -161,6 +167,7 @@ class GetRollingStock(View):
"rolling_stock": rolling_stock,
"class_properties": class_properties,
"rolling_stock_properties": rolling_stock_properties,
"rolling_stock_journal": rolling_stock_journal,
},
)
@@ -249,7 +256,7 @@ class GetFlatpage(View):
def get(self, request, flatpage):
try:
flatpage = Flatpage.objects.get(
Q(Q(path=flatpage) & Q(draft=False))
Q(Q(path=flatpage) & Q(published=True))
)
except ObjectDoesNotExist:
raise Http404

View File

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

View File

@@ -6,6 +6,7 @@ from roster.models import (
RollingStockImage,
RollingStockDocument,
RollingStockProperty,
RollingStockJournal,
)
@@ -31,6 +32,7 @@ class RollingStockDocInline(admin.TabularInline):
model = RollingStockDocument
min_num = 0
extra = 0
classes = ["collapse"]
class RollingStockImageInline(admin.TabularInline):
@@ -38,6 +40,7 @@ class RollingStockImageInline(admin.TabularInline):
min_num = 0
extra = 0
readonly_fields = ("image_thumbnail",)
classes = ["collapse"]
class RollingStockPropertyInline(admin.TabularInline):
@@ -46,6 +49,13 @@ class RollingStockPropertyInline(admin.TabularInline):
extra = 0
class RollingStockJournalInline(admin.TabularInline):
model = RollingStockJournal
min_num = 0
extra = 0
classes = ["collapse"]
@admin.register(RollingStockDocument)
class RollingStockDocumentAdmin(admin.ModelAdmin):
list_display = (
@@ -62,12 +72,33 @@ class RollingStockDocumentAdmin(admin.ModelAdmin):
)
@admin.register(RollingStockJournal)
class RollingJournalDocumentAdmin(admin.ModelAdmin):
list_display = (
"__str__",
"date",
"rolling_stock",
"private",
)
list_filter = (
"date",
"private",
)
search_fields = (
"rolling_stock__rolling_class__identifier",
"rolling_stock__road_number",
"rolling_stock__sku",
"log",
)
@admin.register(RollingStock)
class RollingStockAdmin(admin.ModelAdmin):
inlines = (
RollingStockPropertyInline,
RollingStockImageInline,
RollingStockDocInline,
RollingStockJournalInline,
)
readonly_fields = ("creation_time", "updated_time")
list_display = (

View File

@@ -0,0 +1,34 @@
# Generated by Django 4.1 on 2022-08-24 15:30
import markdown
from django.db import migrations
def md_to_html(apps, schema_editor):
fields = {
"RollingStock": ["notes"],
}
for m in fields.items():
model = apps.get_model("roster", m[0])
for row in model.objects.all():
for field in m[1]:
html = markdown.markdown(getattr(row, field))
row.__dict__[field] = html
row.save(update_fields=m[1])
class Migration(migrations.Migration):
dependencies = [
("roster", "0010_alter_rollingstock_notes"),
]
operations = [
migrations.RunPython(
md_to_html,
reverse_code=migrations.RunPython.noop
),
]

View File

@@ -0,0 +1,45 @@
# Generated by Django 4.1 on 2022-08-27 12:43
import ckeditor_uploader.fields
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("roster", "0011_md_to_html"),
]
operations = [
migrations.CreateModel(
name="RollingStockJournal",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("date", models.DateField()),
("log", ckeditor_uploader.fields.RichTextUploadingField()),
("private", models.BooleanField(default=False)),
("creation_time", models.DateTimeField(auto_now_add=True)),
("updated_time", models.DateTimeField(auto_now=True)),
(
"rolling_stock",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="journal",
to="roster.rollingstock",
),
),
],
options={
"ordering": ["date", "rolling_stock"],
},
),
]

View File

@@ -191,6 +191,27 @@ class RollingStockProperty(models.Model):
verbose_name_plural = "Properties"
class RollingStockJournal(models.Model):
rolling_stock = models.ForeignKey(
RollingStock,
on_delete=models.CASCADE,
related_name="journal",
null=False,
blank=False,
)
date = models.DateField()
log = RichTextUploadingField()
private = models.BooleanField(default=False)
creation_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
def __str__(self):
return "{0} - {1}".format(self.rolling_stock, self.date)
class Meta:
ordering = ["date", "rolling_stock"]
# @receiver(models.signals.post_delete, sender=Cab)
# def post_save_image(sender, instance, *args, **kwargs):
# try: