From 2ac78ba54d92b8a84ad1b2b85068b3f1a5b01f48 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Wed, 6 Mar 2019 07:40:47 +0100
Subject: [PATCH] Work on forums: presentation, etc

---
 forums/managers.py                            | 11 +++++++
 forums/models.py                              | 26 +++++++++++++++
 forums/templates/forums/forum_as_li.html      | 10 ++++++
 forums/templates/forums/forum_detail.html     |  6 ++++
 forums/templates/forums/forum_form.html       |  1 -
 forums/templates/forums/forum_list.html       | 33 +++++++++++++++++--
 forums/urls.py                                |  5 +++
 forums/views.py                               | 13 +++++++-
 .../static/scipost/assets/css/_forums.scss    |  4 +++
 9 files changed, 105 insertions(+), 4 deletions(-)
 create mode 100644 forums/managers.py
 create mode 100644 forums/templates/forums/forum_as_li.html

diff --git a/forums/managers.py b/forums/managers.py
new file mode 100644
index 000000000..9faa94c41
--- /dev/null
+++ b/forums/managers.py
@@ -0,0 +1,11 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+
+class ForumQuerySet(models.QuerySet):
+    def anchors(self):
+        """Return only the Forums which do not have a parent."""
+        return self.filter(parent_object_id__isnull=True)
diff --git a/forums/models.py b/forums/models.py
index 2507319ed..e2d05d4a5 100644
--- a/forums/models.py
+++ b/forums/models.py
@@ -8,6 +8,8 @@ from django.core.urlresolvers import reverse
 from django.db import models
 from django.utils import timezone
 
+from .managers import ForumQuerySet
+
 
 class Forum(models.Model):
     """
@@ -42,6 +44,8 @@ class Forum(models.Model):
                             object_id_field='parent_object_id',
                             related_query_name='parent_forums')
 
+    objects = ForumQuerySet.as_manager()
+
     class Meta:
         ordering = ['name',]
 
@@ -61,6 +65,21 @@ class Forum(models.Model):
             nr += self.posts.all().count()
         return nr
 
+    def posts_hierarchy_id_list(self):
+        id_list = []
+        for post in self.posts.all():
+            id_list += post.posts_hierarchy_id_list()
+        return id_list
+
+    @property
+    def latest_post(self):
+        id_list = self.posts_hierarchy_id_list()
+        print ('forum post id_list: %s' % id_list)
+        try:
+            return Post.objects.filter(id__in=id_list).order_by('-posted_on').first()
+        except:
+            return None
+
 
 class Post(models.Model):
     """
@@ -109,3 +128,10 @@ class Post(models.Model):
         if self.followup_posts:
             nr += self.followup_posts.all().count()
         return nr
+
+    def posts_hierarchy_id_list(self):
+        id_list = [self.id]
+        for post in self.followup_posts.all():
+            id_list += post.posts_hierarchy_id_list()
+        print ('post %s id_list: %s' % (self.id, id_list))
+        return id_list
diff --git a/forums/templates/forums/forum_as_li.html b/forums/templates/forums/forum_as_li.html
new file mode 100644
index 000000000..8248b2fc2
--- /dev/null
+++ b/forums/templates/forums/forum_as_li.html
@@ -0,0 +1,10 @@
+<li>
+  <a href="{{ forum.get_absolute_url }}">{{ forum }}</a>
+  {% if forum.child_forums.all|length > 0 %}
+  <ul class="list-unstyled forumList">
+    {% for child in forum.child_forums.all %}
+    {% include 'forums/forum_as_li.html' with forum=child %}
+    {% endfor %}
+  </ul>
+  {% endif %}
+</li>
diff --git a/forums/templates/forums/forum_detail.html b/forums/templates/forums/forum_detail.html
index 464fbac1a..0acdea979 100644
--- a/forums/templates/forums/forum_detail.html
+++ b/forums/templates/forums/forum_detail.html
@@ -16,6 +16,12 @@
   <div class="col-12">
     <h3 class="highlight">{{ forum.name }}</h3>
 
+    {% if perms.forums.can_add_forum %}
+    <p>
+      <a href="{% url 'forums:forum_create' parent_model='forum' parent_id=forum.id %}">Create a (sub)Forum within this one</a>
+    </p>
+    {% endif %}
+
     {% for post in forum.posts.all %}
     {% include 'forums/post_card.html' with post=post %}
     {% endfor %}
diff --git a/forums/templates/forums/forum_form.html b/forums/templates/forums/forum_form.html
index ef1ecbe7b..75e06ae88 100644
--- a/forums/templates/forums/forum_form.html
+++ b/forums/templates/forums/forum_form.html
@@ -34,5 +34,4 @@ $("#id_name").keyup(function() {
   </div>
 </div>
 
-
 {% endblock content %}
diff --git a/forums/templates/forums/forum_list.html b/forums/templates/forums/forum_list.html
index 243d2a52a..9abf98a2f 100644
--- a/forums/templates/forums/forum_list.html
+++ b/forums/templates/forums/forum_list.html
@@ -15,10 +15,39 @@
 
 <div class="row">
   <div class="col-12">
+
     <h3 class="highlight">Forums</h3>
     <ul>
       <li><a href="{% url 'forums:forum_create' %}">Create a new Forum</a></li>
     </ul>
+
+    <div class="card-columns">
+      {% for forum in object_list %}
+      <div class="card">
+	<div class="card-header">
+	  <a href="{{ forum.get_absolute_url }}">{{ forum }}</a>
+	</div>
+	<div class="card-body">
+	  Forum description
+	  {% if forum.child_forums.all|length > 0 %}
+	  <hr/>
+	  <p>Descendants:</p>
+	  <ul class="list-unstyled forumList">
+	    {% for child in forum.child_forums.all %}
+	    {% include 'forums/forum_as_li.html' with forum=child %}
+	    {% endfor %}
+	  </ul>
+	  {% endif %}
+	</div>
+      </div>
+      {% endfor %}
+    </div>
+  </div>
+</div>
+
+<div class="row">
+  <div class="col-12">
+    <h3 class="highlight">Latest postings</h3>
     <table class="table">
       <thead class="thead-default">
 	<tr>
@@ -32,8 +61,8 @@
 	{% for forum in object_list %}
 	<tr>
 	  <td><a href="{{ forum.get_absolute_url }}">{{ forum }}</a></td>
-	  <td>{% if forum.posts.all|length > 0 %}{{ forum.posts.first }}{% else %}No posts yet{% endif %}</td>
-	  <td>{% if forum.posts.all|length > 0 %}{{ forum.posts.first.posted_on|date:"Y-m-d" }}{% else %}-{% endif %}</td>
+	  <td>{{ forum.latest_post }}</td>
+	  <td>{{ forum.latest_post.posted_on|date:"Y-m-d" }}</td>
 	  <td>{{ forum.nr_posts }}</td>
 	</tr>
 	{% empty %}
diff --git a/forums/urls.py b/forums/urls.py
index 18621db79..e02b42f3b 100644
--- a/forums/urls.py
+++ b/forums/urls.py
@@ -7,6 +7,11 @@ from django.conf.urls import url
 from . import views
 
 urlpatterns = [
+    url(
+        r'^forum/(?P<parent_model>[a-z]+)/(?P<parent_id>[0-9]+)/add/$',
+        views.ForumCreateView.as_view(),
+        name='forum_create'
+    ),
     url(
         r'^add/$',
         views.ForumCreateView.as_view(),
diff --git a/forums/views.py b/forums/views.py
index c48e4e24b..d97b6df11 100644
--- a/forums/views.py
+++ b/forums/views.py
@@ -24,8 +24,14 @@ class ForumCreateView(PermissionsMixin, CreateView):
 
     def get_initial(self):
         initial = super().get_initial()
+        parent_model = self.kwargs.get('parent_model')
+        parent_object_id = self.kwargs.get('parent_id')
+        if parent_model == 'forum':
+            parent_content_type = ContentType.objects.get(app_label='forums', model='forum')
         initial.update({
-            'moderators': self.request.user
+            'moderators': self.request.user,
+            'parent_content_type': parent_content_type,
+            'parent_object_id': parent_object_id,
         })
         return initial
 
@@ -39,6 +45,11 @@ class ForumListView(ListView):
     model = Forum
     template_name = 'forum_list.html'
 
+    def get_context_data(self, *args, **kwargs):
+        context = super().get_context_data(*args, **kwargs)
+        context['latest_'] = Forum.objects.order_by
+        return context
+
 
 class PostCreateView(CreateView):
     model = Post
diff --git a/scipost/static/scipost/assets/css/_forums.scss b/scipost/static/scipost/assets/css/_forums.scss
index e7a9af689..f816aad56 100644
--- a/scipost/static/scipost/assets/css/_forums.scss
+++ b/scipost/static/scipost/assets/css/_forums.scss
@@ -12,3 +12,7 @@
     margin: 1rem;
     padding-left: 0.4rem;
 }
+
+.forumList {
+    padding-left: 0.4rem;
+}
-- 
GitLab