From acd1fd1d38e9aeaa4ff4620bba48627e180c81a9 Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Thu, 8 Jun 2023 16:48:56 +0200
Subject: [PATCH] add auto explansion of accordion submenu change load for
 intersect

---
 ...ctionstream_actions_change_properties.html | 40 --------------
 ..._productionstream_actions_proofs_item.html |  3 +-
 ..._hx_productionstream_details_contents.html | 55 +++++++++----------
 ...uctionstream_details_summary_contents.html | 26 ++++-----
 .../templates/production/upload_proofs.html   |  4 +-
 scipost_django/production/views.py            | 29 ++++++++--
 6 files changed, 69 insertions(+), 88 deletions(-)

diff --git a/scipost_django/production/templates/production/_hx_productionstream_actions_change_properties.html b/scipost_django/production/templates/production/_hx_productionstream_actions_change_properties.html
index 2062f3fdf..7afb65a41 100644
--- a/scipost_django/production/templates/production/_hx_productionstream_actions_change_properties.html
+++ b/scipost_django/production/templates/production/_hx_productionstream_actions_change_properties.html
@@ -1,46 +1,6 @@
 {% load bootstrap %}
 {% load scipost_extras %}
 
-{% comment %} {% if status_form|all_fields_have_choices %}
-    <form id="productionstream-{{ productionstream.id }}-update-status" hx-post="{% url 'production:update_status' productionstream.id %}" hx-target="this" hx-swap="outerHTML" hx-trigger="submit">
-        {% csrf_token %}
-        <div class="row">
-            <div class="col">{{ status_form|bootstrap_purely_inline }}</div>
-            <div class="col-12 col-sm-auto col-md-12 col-lg-auto h-100 d-none-empty" hx-post="{% url 'production:render_action_buttons' productionstream.id 'status' %}" hx-swap="innerHTML" hx-trigger="load, change from:select#productionstream_{{ productionstream.id }}_id_status" hx-target="this"></div>
-        </div>
-    </form>
-{% endif %}
-
-{% if supervisor_form|all_fields_have_choices %}
-    <form id="productionstream-{{ productionstream.id }}-update-supervisor" hx-post="{% url 'production:update_supervisor' productionstream.id %}" hx-target="this" hx-swap="outerHTML" hx-trigger="submit">
-        {% csrf_token %}
-        <div class="row">
-            <div class="col">{{ supervisor_form|bootstrap_purely_inline }}</div>
-            <div class="col-12 col-sm-auto col-md-12 col-lg-auto h-100 d-none-empty" hx-post="{% url 'production:render_action_buttons' productionstream.id 'supervisor' %}" hx-swap="innerHTML" hx-trigger="load, change from:select#productionstream_{{ productionstream.id }}_id_supervisor" hx-target="this"></div>
-        </div>
-    </form>
-{% endif %}
-
-{% if officer_form|all_fields_have_choices %}
-    <form id="productionstream-{{ productionstream.id }}-update-officer" hx-post="{% url 'production:update_officer' productionstream.id %}" hx-target="this" hx-swap="outerHTML" hx-trigger="submit">
-        {% csrf_token %}
-        <div class="row">
-            <div class="col">{{ officer_form|bootstrap_purely_inline }}</div>
-            <div class="col-12 col-sm-auto col-md-12 col-lg-auto h-100 d-none-empty" hx-post="{% url 'production:render_action_buttons' productionstream.id 'officer' %}" hx-swap="innerHTML" hx-trigger="load, change from:select#productionstream_{{ productionstream.id }}_id_officer" hx-target="this"></div>
-        </div>
-    </form>
-{% endif %}
-
-{% if invitations_officer_form|all_fields_have_choices %}
-    <form id="productionstream-{{ productionstream.id }}-update-invitations_officer" hx-post="{% url 'production:update_invitations_officer' productionstream.id %}" hx-target="this" hx-swap="outerHTML" hx-trigger="submit">
-        {% csrf_token %}
-        <div class="row">
-            <div class="col">{{ invitations_officer_form|bootstrap_purely_inline }}</div>
-            <div class="col-12 col-sm-auto col-md-12 col-lg-auto h-100 d-none-empty" hx-post="{% url 'production:render_action_buttons' productionstream.id 'invitations_officer' %}" hx-swap="innerHTML" hx-trigger="load, change from:select#productionstream_{{ productionstream.id }}_id_invitations_officer" hx-target="this"></div>
-        </div>
-    </form>
-{% endif %} {% endcomment %}
-
 {% include "production/_hx_productionstream_change_status.html" with form=status_form stream=productionstream %}
 {% include "production/_hx_productionstream_change_supervisor.html" with form=supervisor_form stream=productionstream %}
 {% include "production/_hx_productionstream_change_officer.html" with form=officer_form stream=productionstream %}
diff --git a/scipost_django/production/templates/production/_hx_productionstream_actions_proofs_item.html b/scipost_django/production/templates/production/_hx_productionstream_actions_proofs_item.html
index af0f23f13..6848c94ea 100644
--- a/scipost_django/production/templates/production/_hx_productionstream_actions_proofs_item.html
+++ b/scipost_django/production/templates/production/_hx_productionstream_actions_proofs_item.html
@@ -33,7 +33,8 @@
             <div id="productionstream-{{ stream.id }}-proofs-list-accordion-proofs-{{ proofs.version }}-action-row"
                  class="row g-2">
                 <div class="col-12 col-sm-6 col-md-12 col-lg-6 h-100 d-none-empty">
-                    <a class="row m-0 d-none-empty"
+                    <a download
+                       class="row m-0 d-none-empty"
                        href="{% url 'production:proofs_pdf' proofs.slug %}">
                         <button class="btn btn-sm btn-secondary">Download Proofs</button>
                     </a>
diff --git a/scipost_django/production/templates/production/_hx_productionstream_details_contents.html b/scipost_django/production/templates/production/_hx_productionstream_details_contents.html
index 97f801c2e..4d58bc797 100644
--- a/scipost_django/production/templates/production/_hx_productionstream_details_contents.html
+++ b/scipost_django/production/templates/production/_hx_productionstream_details_contents.html
@@ -18,25 +18,25 @@
       {% if perms.scipost.can_take_decisions_related_to_proofs %}
         <div class="accordion-item">
           <h2 class="accordion-header"
-              id="productionstream-{{ productionstream.id }}-change-stream-properties-header">
-            <button class="accordion-button fs-6 collapsed"
+              id="productionstream-{{ productionstream.id }}-change-properties-header">
+            <button class="accordion-button fs-6 {% if accordion_default_open == '' or accordion_default_open != 'change-properties' %}collapsed{% endif %}"
                     type="button"
                     data-bs-toggle="collapse"
-                    data-bs-target="#productionstream-{{ productionstream.id }}-change-stream-properties"
+                    data-bs-target="#productionstream-{{ productionstream.id }}-change-properties"
                     aria-expanded="true"
-                    aria-controls="productionstream-{{ productionstream.id }}-change-stream-properties"
-                    hx-get="{% url 'production:_hx_productionstream_actions_change_properties' productionstream_id=productionstream.id %}"
-                    hx-trigger="click once, submit from:#productionstream-{{ productionstream.id }}-details-contents target:form delay:1000"
-                    hx-target="#productionstream-{{ productionstream.id }}-change-stream-properties-body">
-              Change stream properties
+                    aria-controls="productionstream-{{ productionstream.id }}-change-properties">
+              Change Properties
             </button>
           </h2>
-          <div id="productionstream-{{ productionstream.id }}-change-stream-properties"
-               class="accordion-collapse collapse"
-               aria-labelledby="productionstream-{{ productionstream.id }}-change-stream-properties-header"
+          <div id="productionstream-{{ productionstream.id }}-change-properties"
+               class="accordion-collapse collapse {% if accordion_default_open == 'change-properties' %}show{% endif %}"
+               aria-labelledby="productionstream-{{ productionstream.id }}-change-properties-header"
                data-bs-parent="#productionstream-{{ productionstream.id }}-actions-accordion">
             <div class="accordion-body">
-              <div id="productionstream-{{ productionstream.id }}-change-stream-properties-body">
+              <div id="productionstream-{{ productionstream.id }}-change-properties-body"
+                   class="accordion-body"
+                   hx-get="{% url 'production:_hx_productionstream_actions_change_properties' productionstream_id=productionstream.id %}"
+                   hx-trigger="intersect once, submit from:#productionstream-{{ productionstream.id }}-details-contents target:form delay:1000">
  
                 {% comment %} Placeholder before HTMX content loads {% endcomment %}
                 <div class="placeholder-glow">
@@ -67,22 +67,21 @@
         <div class="accordion-item">
           <h2 class="accordion-header"
               id="productionstream-{{ productionstream.id }}-upload-proofs-header">
-            <button class="accordion-button fs-6 collapsed"
+            <button class="accordion-button fs-6 {% if accordion_default_open == '' or  accordion_default_open != 'upload_proofs' %}collapsed{% endif %}"
                     type="button"
                     data-bs-toggle="collapse"
                     data-bs-target="#productionstream-{{ productionstream.id }}-upload-proofs"
                     aria-expanded="false"
-                    aria-controls="productionstream-{{ productionstream.id }}-upload-proofs"
-                    hx-get="{% url 'production:upload_proofs' stream_id=productionstream.id %}"
-                    hx-trigger="click once"
-                    hx-target="#productionstream-{{ productionstream.id }}-upload-proofs-body">Upload Proofs</button>
+                    aria-controls="productionstream-{{ productionstream.id }}-upload-proofs">Upload Proofs</button>
           </h2>
           <div id="productionstream-{{ productionstream.id }}-upload-proofs"
-               class="accordion-collapse collapse"
+               class="accordion-collapse collapse {% if accordion_default_open == 'upload-proofs' %}show{% endif %}"
                aria-labelledby="productionstream-{{ productionstream.id }}-upload-proofs-header"
                data-bs-parent="#productionstream-{{ productionstream.id }}-actions-accordion">
             <div id="productionstream-{{ productionstream.id }}-upload-proofs-body"
-                 class="accordion-body">
+                 class="accordion-body"
+                 hx-get="{% url 'production:upload_proofs' stream_id=productionstream.id %}"
+                 hx-trigger="intersect once">
  
               {% comment %} Placeholder before HTMX content loads {% endcomment %}
               <div class="placeholder-glow">
@@ -111,23 +110,21 @@
       <div class="accordion-item">
         <h2 class="accordion-header"
             id="productionstream-{{ productionstream.id }}-work-log-header">
-          <button class="accordion-button fs-6 collapsed"
+          <button class="accordion-button fs-6 {% if accordion_default_open == '' or  accordion_default_open != 'work-log' %}collapsed{% endif %}"
                   type="button"
                   data-bs-toggle="collapse"
                   data-bs-target="#productionstream-{{ productionstream.id }}-work-log"
                   aria-expanded="false"
-                  aria-controls="productionstream-{{ productionstream.id }}-work-log"
-                  hx-get="{% url 'production:_hx_productionstream_actions_work_log' productionstream_id=productionstream.id %}"
-                  hx-trigger="click once, htmx:trigger from:#productionstream-{{ productionstream.id }}-work-log-body target:a.work_log_delete_btn delay:1000"
-                  hx-target="#productionstream-{{ productionstream.id }}-work-log-body"
-                  hx-swap="innerHTML">Work Log</button>
+                  aria-controls="productionstream-{{ productionstream.id }}-work-log">Work Log</button>
         </h2>
         <div id="productionstream-{{ productionstream.id }}-work-log"
-             class="accordion-collapse collapse"
+             class="accordion-collapse collapse {% if accordion_default_open == 'work-log' %}show{% endif %}"
              aria-labelledby="productionstream-{{ productionstream.id }}-work-log-header"
              data-bs-parent="#productionstream-{{ productionstream.id }}-actions-accordion">
           <div id="productionstream-{{ productionstream.id }}-work-log-body"
-               class="accordion-body">
+               class="accordion-body"
+               hx-get="{% url 'production:_hx_productionstream_actions_work_log' productionstream_id=productionstream.id %}"
+               hx-trigger="intersect once, htmx:trigger from:this target:a.work_log_delete_btn delay:1000">
  
             {% comment %} Placeholder before HTMX content loads {% endcomment %}
             <div class="placeholder-glow">
@@ -184,7 +181,7 @@
               <div class="row m-0 d-none-empty">
                 <button class="btn btn-warning text-white"
                         hx-get="{% url 'production:mark_as_completed' stream_id=productionstream.id %}"
-                        hx-confim="Are you sure you want to mark this stream as completed?"
+                        {% if stream.status != 'published' %}hx-confirm="Are you sure you want to mark this unpublished stream as completed?"{% endif %}
                         hx-target="#productionstream-{{ productionstream.id }}-details">
                   Mark this stream as completed
                 </button>
@@ -217,7 +214,7 @@
          class="overflow-scroll mb-4"
          style="max-height: max(50vh, 40em)"
          hx-get="{% url 'production:render_stream_events' productionstream.id %}"
-         hx-trigger="load, submit from:#productionstream-{{ productionstream.id }}-details target:form delay:500,  click from:#productionstream-{{ productionstream.id }}-details target:.proof-action-button delay:500">
+         hx-trigger="intersect once, submit from:#productionstream-{{ productionstream.id }}-details target:form delay:500,  click from:#productionstream-{{ productionstream.id }}-details target:.proof-action-button delay:500">
 
       {% comment %} Placeholder before HTMX content loads {% endcomment %}
       <table class="table table-bordered table-striped overflow-scroll mb-0"
diff --git a/scipost_django/production/templates/production/_productionstream_details_summary_contents.html b/scipost_django/production/templates/production/_productionstream_details_summary_contents.html
index 20d76cf19..a6ee8f1f9 100644
--- a/scipost_django/production/templates/production/_productionstream_details_summary_contents.html
+++ b/scipost_django/production/templates/production/_productionstream_details_summary_contents.html
@@ -53,48 +53,48 @@
     <div id="productionstream-{{ productionstream.id }}-summary-assignees"
          class="col-md-6"
          hx-get="{% url 'production:render_stream_assignees_status' productionstream.id %}"
-         hx-trigger="intersect, submit from:#productionstream-{{ productionstream.id }}-details target:form delay:500, click from:#productionstream-{{ productionstream.id }}-details target:.proof-action-button delay:500">
+         hx-trigger="intersect once, submit from:#productionstream-{{ productionstream.id }}-details target:form delay:500, click from:#productionstream-{{ productionstream.id }}-details target:.proof-action-button delay:500">
 
         {% comment %} Placeholder while HTMX is loading {% endcomment %}
         <div class="row mb-0 placeholder-glow">
             <div class="order-3 order-sm-1 order-md-3 order-xl-1 col-sm-6 col-md-12 col-xl-6">
                 <div class="row justify-content-between">
-                    <small class="col-4 text-muted text-nowrap placeholder">Stream opened</small>
+                    <small class="col-4 text-muted text-nowrap">Stream opened</small>
                     <div class="col-8">
-                        <div class="w-100 placeholder"></div>
+                        <div class="ms-2 w-100 placeholder"></div>
                     </div>
                 </div>
             </div>
             <div class="order-2 order-sm-4 order-md-2 order-xl-4 col-sm-6 col-md-12 col-xl-6">
                 <div class="row justify-content-between">
-                    <small class="col-4 text-muted text-nowrap placeholder">Officer</small>
+                    <small class="col-4 text-muted text-nowrap">Officer</small>
                     <div class="col-8 text-nowrap text-truncate">
-                        <div class="w-100 placeholder"></div>
+                        <div class="ms-2 w-100 placeholder"></div>
                     </div>
                 </div>
             </div>
             <div class="order-4 order-sm-3 order-md-4 order-xl-3 col-sm-6 col-md-12 col-xl-6">
                 <div class="row justify-content-between">
-                    <small class="col-4 text-muted text-nowrap placeholder">Latest activity</small>
+                    <small class="col-4 text-muted text-nowrap">Latest activity</small>
                     <div class="col-8">
-                        <div class="w-100 placeholder"></div>
+                        <div class="ms-2 w-100 placeholder"></div>
                     </div>
                 </div>
             </div>
             <div class="order-1 order-sm-2 order-md-1 order-xl-2 col-sm-6 col-md-12 col-xl-6">
                 <div class="row justify-content-between">
-                    <small class="col-4 text-muted text-nowrap placeholder">Supervisor</small>
+                    <small class="col-4 text-muted text-nowrap">Supervisor</small>
                     <div class="col-8 text-nowrap text-truncate">
-                        <div class="w-100 placeholder"></div>
+                        <div class="ms-2 w-100 placeholder"></div>
                     </div>
                 </div>
             </div>
             <div class="order-5 order-sm-5 order-md-5 order-xl-5 col-sm-6 col-md-12 col-xl-6">
                 <div class="row mb-0 justify-content-between align-items-center">
-                    <small class="col-4 text-muted text-nowrap placeholder">Stream Status</small>
-                    <div class="col-8">
-                        <div class="badge bg-secondary w-50">
-                            <div class="w-100 placeholder"></div>
+                    <small class="col-4 text-muted text-nowrap">Stream Status</small>
+                    <div class="offset-5 col-3">
+                        <div class="badge bg-primary w-100">
+                            <div class="placeholder py-2"></div>
                         </div>
                     </div>
                 </div>
diff --git a/scipost_django/production/templates/production/upload_proofs.html b/scipost_django/production/templates/production/upload_proofs.html
index a1ba1307b..afa710d9b 100644
--- a/scipost_django/production/templates/production/upload_proofs.html
+++ b/scipost_django/production/templates/production/upload_proofs.html
@@ -13,7 +13,9 @@
 
 <div class="row mt-3">
   <div class="col-12">
-    <form method="post" enctype="multipart/form-data">
+    <form enctype="multipart/form-data"
+          hx-post="{% url 'production:upload_proofs' stream_id=stream.id %}"
+          hx-target="#productionstream-{{ stream.id }}-upload-proofs-body">
       {% csrf_token %}
       {{ form|bootstrap_purely_inline }}
       <input type="submit"
diff --git a/scipost_django/production/views.py b/scipost_django/production/views.py
index ae47ae093..7f7c7631a 100644
--- a/scipost_django/production/views.py
+++ b/scipost_django/production/views.py
@@ -106,6 +106,25 @@ def _hx_productionstream_details_contents(request, productionstream_id):
 
     upload_proofs_form = ProofsUploadForm()
 
+    # Determine which accordion tab to open by default
+    accordion_default_open = ""
+    if request.user.production_user == productionstream.supervisor:
+        if productionstream.status in [
+            constants.PROOFS_ACCEPTED,
+        ]:
+            accordion_default_open = "upload-proofs"
+        else:
+            accordion_default_open = "change-properties"
+
+    if request.user.production_user == productionstream.officer:
+        if not productionstream.work_logs.all():
+            accordion_default_open = "work-log"
+        elif not productionstream.proofs.all():
+            accordion_default_open = "upload-proofs"
+
+    if productionstream.status == constants.PRODUCTION_STREAM_INITIATED:
+        accordion_default_open = "change-properties"
+
     context = {
         "productionstream": productionstream,
         "status_form": status_form,
@@ -113,6 +132,7 @@ def _hx_productionstream_details_contents(request, productionstream_id):
         "inv_officer_form": inv_officer_form,
         "prod_officer_form": prod_officer_form,
         "upload_proofs_form": upload_proofs_form,
+        "accordion_default_open": accordion_default_open,
     }
     return render(
         request,
@@ -405,7 +425,6 @@ def _hx_productionstream_actions_work_log(request, productionstream_id):
         log.content = productionstream
         log.user = request.user
         log.save()
-        messages.success(request, "Work Log added to Stream.")
     else:
         # messages.warning(request, "The form was invalidly filled.")
         pass
@@ -979,7 +998,11 @@ def upload_proofs(request, stream_id):
     stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id)
     checker = ObjectPermissionChecker(request.user)
     if not checker.has_perm("can_work_for_stream", stream):
-        return redirect(reverse("production:production"))
+        return HttpResponse(
+            r"""<div class="text-danger border border-danger p-3">
+                You are forbidden from working in this stream.
+            </div>"""
+        )
 
     form = ProofsUploadForm(request.POST or None, request.FILES or None)
     if form.is_valid():
@@ -990,7 +1013,6 @@ def upload_proofs(request, stream_id):
         Proofs.objects.filter(stream=stream).exclude(version=proofs.version).exclude(
             status=constants.PROOFS_ACCEPTED
         ).update(status=constants.PROOFS_RENEWED)
-        messages.success(request, "Proof uploaded.")
 
         # Update Stream status
         if stream.status == constants.PROOFS_TASKED:
@@ -1007,7 +1029,6 @@ def upload_proofs(request, stream_id):
             noted_by=request.user.production_user,
         )
         prodevent.save()
-        return redirect(stream.get_absolute_url())
 
     context = {"stream": stream, "form": form, "total_proofs": stream.proofs.count()}
     return render(request, "production/upload_proofs.html", context)
-- 
GitLab