From 7cb8ccafdf0be3e5f167fd0914a90f05277b86ee Mon Sep 17 00:00:00 2001
From: Fredrik Jonsson <frjo@xdeb.org>
Date: Thu, 25 Apr 2024 21:11:18 +0200
Subject: [PATCH] Use less jQuery, alipinejs or vanillajs instead (#3880)

- [x] Convert toggle-related.js to vanillajs.
- [x] On submission detail convert toggle-actions-panel.js to alpinejs.
- [x] Convert submission-text-cleanup.js to vanillajs.
- [x] Replace dropdown.js with alpinejs.
- [x] Convert all-submissions-table.js to vanillajs.
- [x] Convert application-form-links-new-window.js to vanillajs.
- [x] Made PAF and SOW views and download buttons to look the same.
---
 .../applicationsubmission_admin_detail.html   |  9 +--
 .../project_approval_detail.html              | 17 ++---
 .../project_sow_detail.html                   | 72 +++++++++++--------
 .../javascript/all-submissions-table.js       | 31 +++++---
 .../application-form-links-new-window.js      | 11 +--
 hypha/static_src/javascript/dropdown.js       | 19 -----
 .../javascript/submission-text-cleanup.js     | 32 +++++----
 hypha/static_src/javascript/toggle-related.js | 46 ++++++------
 hypha/static_src/sass/components/_button.scss | 16 -----
 .../static_src/sass/components/_dropdown.scss | 52 +++++---------
 10 files changed, 137 insertions(+), 168 deletions(-)
 delete mode 100644 hypha/static_src/javascript/dropdown.js

diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_admin_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_admin_detail.html
index 31d684878..5a0454873 100644
--- a/hypha/apply/funds/templates/funds/applicationsubmission_admin_detail.html
+++ b/hypha/apply/funds/templates/funds/applicationsubmission_admin_detail.html
@@ -7,9 +7,11 @@
 {% endblock %}
 
 {% block mobile_actions %}
-    <a class="js-actions-toggle button button--white button--full-width button--actions">{% trans "Actions to take" %}</a>
-    <div class="js-actions-sidebar sidebar__inner sidebar__inner--light-blue sidebar__inner--actions sidebar__inner--mobile">
-        {% include "funds/includes/admin_primary_actions.html"  %}
+    <div x-data="{ show: false }">
+        <button x-on:click="show = ! show" class="button button--white button--full-width button--actions">{% trans "Actions to take" %}</button>
+        <div x-show="show" x-transition class="js-actions-sidebar sidebar__inner sidebar__inner--light-blue">
+            {% include "funds/includes/admin_primary_actions.html"  %}
+        </div>
     </div>
 {% endblock %}
 
@@ -87,6 +89,5 @@
     {{ block.super }}
     <script src="{% static 'js/jquery.fancybox.min.js' %}"></script>
     <script src="{% static 'js/fancybox-global.js' %}"></script>
-    <script src="{% static 'js/toggle-actions-panel.js' %}"></script>
     <script src="{% static 'js/toggle-related.js' %}"></script>
 {% endblock %}
diff --git a/hypha/apply/projects/templates/application_projects/project_approval_detail.html b/hypha/apply/projects/templates/application_projects/project_approval_detail.html
index 044e76530..48e563c0d 100644
--- a/hypha/apply/projects/templates/application_projects/project_approval_detail.html
+++ b/hypha/apply/projects/templates/application_projects/project_approval_detail.html
@@ -35,7 +35,6 @@
                 <article class="wrapper--sidebar--inner">
                     <h4 class="mb-2">{% trans "Project Information" %}</h4>
                     <div class="card card--solid">
-
                         {% if object.output_answers %}
                             <div class="simplified__paf_answers">
                                 {{ object.output_answers }}
@@ -100,24 +99,20 @@
                 {% user_can_take_actions object user as can_take_actions %}
                 {% if can_take_actions %}
                     <aside class="sidebar sidebar__project">
-                        {% if mobile %}
-                            <a class="js-actions-toggle button button--white button--full-width button--actions">{% trans "Actions to take" %}</a>
-                        {% endif %}
-
                         <div class="js-actions-sidebar sidebar__inner sidebar__inner--light-blue sidebar__inner--actions {% if mobile %}sidebar__inner--mobile{% endif %}">
                             <h5>{% trans "Actions to take" %}</h5>
                             {% user_can_edit_project object user as can_edit_project %}
                             {% if can_edit_project %}
                                 <a class="button button--bottom-space button--primary button--full-width {% if user_can_approve %} is-disabled {% endif %}" href="{% url 'apply:projects:edit' pk=object.pk %}">{% trans "Edit PAF" %}</a>
                             {% endif %}
-                            <div class="dropdown">
-                                <button class="button button--project-action--paf-download dropbtn button--bottom-space button--full-width" type="button" data-dropdown-target="#dropdown-content-download">
+                            <div x-data="{ show: false }" class="dropdown">
+                                <button x-on:click="show = ! show" class="button button--primary" type="button">
                                     {% trans 'Download Approval Form' %}
                                 </button>
-                                <div id="dropdown-content-download" class="dropdown-content">
-                                    <a class="dropdown-item" href="{% url 'apply:projects:download' pk=object.pk export_type='pdf' %}">
+                                <div x-show="show" x-transition class="dropdown__content">
+                                    <a href="{% url 'apply:projects:download' pk=object.pk export_type='pdf' %}">
                                         {% trans 'Download as PDF' %}</a>
-                                    <a class="dropdown-item" href="{% url 'apply:projects:download' pk=object.pk export_type='docx' %}">
+                                    <a href="{% url 'apply:projects:download' pk=object.pk export_type='docx' %}">
                                         {% trans 'Download as DOCX' %}</a>
                                 </div>
                             </div>
@@ -160,7 +155,6 @@
                                 </div>
                             {% endif %}
                         </div>
-
                     </aside>
                 {% endif %}
             </div>
@@ -173,5 +167,4 @@
     {{ block.super }}
     <script src="{% static 'js/jquery.fancybox.min.js' %}"></script>
     <script src="{% static 'js/fancybox-global.js' %}"></script>
-    <script src="{% static 'js/dropdown.js' %}"></script>
 {% endblock %}
diff --git a/hypha/apply/projects/templates/application_projects/project_sow_detail.html b/hypha/apply/projects/templates/application_projects/project_sow_detail.html
index dd77ece6b..fb14518ac 100644
--- a/hypha/apply/projects/templates/application_projects/project_sow_detail.html
+++ b/hypha/apply/projects/templates/application_projects/project_sow_detail.html
@@ -1,41 +1,31 @@
 {% extends "application_projects/project_approval_detail.html" %}
-{% load i18n static approval_tools %}
-
-{% block title %}{{ object.title }}{% endblock %}
+{% load i18n static approval_tools project_tags apply_tags %}
 
 {% block content %}
-    <div class="simplified">
-        <div class="simplified__admin-bar">
-            <div class="simplified__admin-bar-inner-project">
-                <div>
-                    <a class="simplified__projects-link" href="{{ object.get_absolute_url }}">
-                        {% trans "View project page" %}
-                    </a>
-                    <h1 class="simplified__heading">{{ object.title }}</h1>
-                    <h5 class="simplified__subheading">
-                        <span>{{ object.submission.page }}</span>
-                        <span>{{ object.submission.round }}</span>
-                        <span>{% trans "Lead" %}: {{ object.lead }}</span>
-                    </h5>
-                </div>
+    {% adminbar %}
+        {% slot back_link %}
+            <a class="simplified__projects-link" href="{{ object.get_absolute_url }}" rel="noopener">
+                {% trans "Back to Project" %}
+            </a>
+        {% endslot %}
 
-                <div class="dropdown">
-                    <button class="button button--primary dropbtn" type="button" data-dropdown-target="#dropdown-content-download">
-                        {% trans 'Download SOW' %}
-                    </button>
-                    <div id="dropdown-content-download" class="dropdown-content">
-                        <a class="dropdown-item" href="{% url 'apply:projects:download-sow' pk=object.pk export_type='pdf' %}">
-                            {% trans 'Download as PDF' %}</a>
-                        <a class="dropdown-item" href="{% url 'apply:projects:download-sow' pk=object.pk export_type='docx' %}">
-                            {% trans 'Download as DOCX' %}</a>
-                    </div>
-                </div>
+        {% slot header %}
+            {{ object.title }}
+        {% endslot %}
+        {% slot sub_heading %}
+            <div class="heading heading--meta text-sm mt-1">
+                <span>{{ object.submission.page }}</span>
+                <span>{{ object.submission.round }}</span>
+                <span>{% trans "Lead" %}: {{ object.lead }}</span>
             </div>
-        </div>
+        {% endslot %}
+    {% endadminbar %}
+
+    <div class="simplified">
         <div class="wrapper wrapper--large wrapper--tabs">
             <div class="wrapper wrapper--sidebar">
-                <article class="wrapper--sidebar--inner simplified__wrapper">
-                    <h4>{% trans "Project scope of work(SOW)" %}</h4>
+                <article class="wrapper--sidebar--inner">
+                    <h4 class="mb-2">{% trans "Project scope of work(SOW)" %}</h4>
                     <div class="card card--solid">
                         {% if object.sow.output_answers %}
                             <div class="simplified__paf_answers">
@@ -44,6 +34,26 @@
                         {% endif %}
                     </div>
                 </article>
+                {% user_can_take_actions object user as can_take_actions %}
+                {% if can_take_actions %}
+                    <aside class="sidebar sidebar__project">
+                        <div class="js-actions-sidebar sidebar__inner sidebar__inner--light-blue sidebar__inner--actions {% if mobile %}sidebar__inner--mobile{% endif %}">
+                            <h5>{% trans "Actions to take" %}</h5>
+                            <div x-data="{ show: false }" class="dropdown">
+                                <button x-on:click="show = ! show" class="button button--primary" type="button">
+                                    {% trans 'Download SOW' %}
+                                </button>
+                                <div x-show="show" x-transition class="dropdown__content">
+                                    <a href="{% url 'apply:projects:download-sow' pk=object.pk export_type='pdf' %}">
+                                        {% trans 'Download as PDF' %}</a>
+                                    <a href="{% url 'apply:projects:download-sow' pk=object.pk export_type='docx' %}">
+                                        {% trans 'Download as DOCX' %}</a>
+                                </div>
+                            </div>
+                        </div>
+
+                    </aside>
+                {% endif %}
             </div>
         </div>
     </div>
diff --git a/hypha/static_src/javascript/all-submissions-table.js b/hypha/static_src/javascript/all-submissions-table.js
index e01d2b0e0..11934db6f 100644
--- a/hypha/static_src/javascript/all-submissions-table.js
+++ b/hypha/static_src/javascript/all-submissions-table.js
@@ -1,22 +1,31 @@
-(function ($) {
+(function () {
     "use strict";
 
-    // add the toggle arrow before the submission titles
-    $(".all-submissions-table__parent td.title").prepend(
-        '<span class="all-submissions-table__toggle js-toggle-submission"><span class="arrow"></span></span>'
+    let submission_arrow = document.createElement("span");
+    submission_arrow.classList.add("arrow");
+
+    let submission_toggle = document.createElement("span");
+    submission_toggle.classList.add(
+        "all-submissions-table__toggle",
+        "js-toggle-submission"
     );
+    submission_toggle.appendChild(submission_arrow);
 
-    // grab all the toggles
-    const children = Array.prototype.slice.call(
-        document.querySelectorAll(".js-toggle-submission")
+    // Add the toggle arrow before the submission titles.
+    const submission_titles = document.querySelectorAll(
+        ".all-submissions-table__parent > td.title"
     );
+    submission_titles.forEach(function (title) {
+        title.prepend(submission_toggle.cloneNode(true));
+    });
 
-    // show/hide the submission child rows
+    // Show/hide the submission child rows.
+    const children = document.querySelectorAll(".js-toggle-submission");
     children.forEach(function (child) {
         child.addEventListener("click", (e) => {
-            $(e.target)
+            e.target
                 .closest(".all-submissions-table__parent")
-                .toggleClass("is-expanded");
+                .classList.toggle("is-expanded");
         });
     });
-})(jQuery);
+})();
diff --git a/hypha/static_src/javascript/application-form-links-new-window.js b/hypha/static_src/javascript/application-form-links-new-window.js
index 55c153f35..e2a2160e0 100644
--- a/hypha/static_src/javascript/application-form-links-new-window.js
+++ b/hypha/static_src/javascript/application-form-links-new-window.js
@@ -1,9 +1,10 @@
-(function ($) {
+(function () {
     "use strict";
 
     // Make links on application forms open in a new window/tab.
-    $(".application-form").find("a").not(".section-head a").attr({
-        target: "_blank",
-        rel: "noopener noreferrer",
+    const links = document.querySelectorAll(".application-form a");
+    links.forEach(function (link) {
+        link.setAttribute("target", "_blank");
+        link.setAttribute("rel", "noopener noreferrer");
     });
-})(jQuery);
+})();
diff --git a/hypha/static_src/javascript/dropdown.js b/hypha/static_src/javascript/dropdown.js
deleted file mode 100644
index 8b127c8ac..000000000
--- a/hypha/static_src/javascript/dropdown.js
+++ /dev/null
@@ -1,19 +0,0 @@
-(function ($) {
-    // Add 'data-dropdown-target' attr to dropdown button in html and set its value as id of the dropdown content.
-    // For example look at its usage in project_simplified_detail.html
-
-    "use strict";
-
-    var dropdownButton = $("[data-dropdown-target]");
-    dropdownButton.on("click", function () {
-        // toggle 'show' class whenever dropdown button is getting clicked
-        $($(this).attr("data-dropdown-target")).toggleClass("show");
-    });
-
-    // Close the dropdown menu if the user clicks outside of it
-    window.addEventListener("click", function (event) {
-        if (!event.target.matches("[data-dropdown-target]")) {
-            $(dropdownButton.attr("data-dropdown-target")).removeClass("show");
-        }
-    });
-})(jQuery);
diff --git a/hypha/static_src/javascript/submission-text-cleanup.js b/hypha/static_src/javascript/submission-text-cleanup.js
index 85675c7a1..409e46b5c 100644
--- a/hypha/static_src/javascript/submission-text-cleanup.js
+++ b/hypha/static_src/javascript/submission-text-cleanup.js
@@ -1,17 +1,23 @@
-(function ($) {
+(function () {
     "use strict";
 
-    $(".rich-text--answers")
-        .find("p")
-        .each(function () {
-            // Detach (remove) p tag with only whitespace inside.
-            if ($.trim($(this).text()) === "") {
-                $(this).detach();
-            }
-        });
+    const richtextanswers = document.querySelector(".rich-text--answers");
+
+    // Remove p tags with only whitespace inside.
+    const richtextanswers_paras = richtextanswers.querySelectorAll("p");
+    richtextanswers_paras.forEach(function (para) {
+        if (para.textContent.trim() === "") {
+            para.remove();
+        }
+    });
+
+    let table_wrapper = document.createElement("div");
+    table_wrapper.classList.add("rich-text__table");
 
     // Wrap all tables in a div so overflow auto works.
-    $(".rich-text--answers")
-        .find("table")
-        .wrap('<div class="rich-text__table"></div>');
-})(jQuery);
+    const richtextanswers_tables = richtextanswers.querySelectorAll("table");
+    richtextanswers_tables.forEach(function (table) {
+        table.parentNode.insertBefore(table_wrapper, table);
+        table_wrapper.appendChild(table);
+    });
+})();
diff --git a/hypha/static_src/javascript/toggle-related.js b/hypha/static_src/javascript/toggle-related.js
index abcd959fa..0743f53c7 100644
--- a/hypha/static_src/javascript/toggle-related.js
+++ b/hypha/static_src/javascript/toggle-related.js
@@ -1,26 +1,26 @@
-(function ($) {
+(function () {
     "use strict";
 
-    // Collaps long comments in activity feed.
-    $(".related-sidebar").each(function () {
-        var $content = $(this).find("ul");
-        var content_height = $content.outerHeight();
-        if (content_height > 300) {
-            $(this).addClass("related-sidebar--collaps");
-            $(this).append(
-                '<p class="related-sidebar__show-button"><a class="link link--button link--button--narrow" href="#">Show</a></p>'
-            );
-        }
-    });
+    const related_sidebar = document.querySelector(".related-sidebar");
+    const content_height = related_sidebar
+        .querySelector("ul")
+        .getBoundingClientRect().height;
+
+    let button_show = document.createElement("button");
+    button_show.classList.add("link", "link--button", "link--button--narrow");
+    button_show.textContent = "Show";
+
+    let button_wrapper = document.createElement("p");
+    button_wrapper.classList.add("related-sidebar__show-button");
+    button_wrapper.appendChild(button_show);
 
-    // Allow users to show full comment.
-    $(".related-sidebar__show-button")
-        .find(".link")
-        .click(function (e) {
-            e.preventDefault();
-            $(this)
-                .parents(".related-sidebar")
-                .removeClass("related-sidebar--collaps");
-            $(this).parent().detach();
-        });
-})(jQuery);
+    if (content_height > 300) {
+        related_sidebar.classList.add("related-sidebar--collaps");
+        related_sidebar.append(button_wrapper);
+    }
+
+    button_show.addEventListener("click", function (e) {
+        related_sidebar.classList.remove("related-sidebar--collaps");
+        button_wrapper.remove();
+    });
+})();
diff --git a/hypha/static_src/sass/components/_button.scss b/hypha/static_src/sass/components/_button.scss
index 45eeecb34..b78d275b3 100644
--- a/hypha/static_src/sass/components/_button.scss
+++ b/hypha/static_src/sass/components/_button.scss
@@ -50,22 +50,6 @@
                 color: $color--white;
             }
         }
-
-        &--paf-download {
-            @include button($color--white, $color--light-blue);
-            display: inline-block;
-            color: $color--light-blue;
-            border: 1px solid $color--mid-grey;
-            padding: 0.5rem 3.3rem;
-
-            &:focus {
-                color: $color--light-blue;
-            }
-
-            &:hover {
-                color: $color--white;
-            }
-        }
     }
 
     &--left-space {
diff --git a/hypha/static_src/sass/components/_dropdown.scss b/hypha/static_src/sass/components/_dropdown.scss
index 3ec2d37f4..5abf9451b 100644
--- a/hypha/static_src/sass/components/_dropdown.scss
+++ b/hypha/static_src/sass/components/_dropdown.scss
@@ -1,41 +1,25 @@
 .dropdown {
     position: relative;
     display: inline-block;
-}
 
-.dropbtn {
-    font-size: 16px;
-    cursor: pointer;
-}
+    &__content {
+        position: absolute;
+        background-color: $color--light-grey;
+        min-width: 160px;
+        box-shadow: 1px 8px 16px 1px $color--mid-dark-grey;
+        z-index: 1;
 
-.dropbtn:hover,
-.dropbtn:focus {
-    background-color: $color--dark-blue;
-}
-
-.dropdown-content {
-    display: none;
-    position: absolute;
-    background-color: $color--light-grey;
-    min-width: 160px;
-    box-shadow: 1px 8px 16px 1px $color--mid-dark-grey;
-    z-index: 1;
-}
-
-/* Links inside the dropdown */
-.dropdown-content a {
-    color: $color--black;
-    padding: 12px 16px;
-    text-decoration: none;
-    display: block;
-}
-
-/* Change color of dropdown links on hover */
-.dropdown-content a:hover {
-    background-color: $color--mid-grey;
-}
+        /* Links inside the dropdown */
+        a {
+            color: $color--black;
+            padding: 12px 16px;
+            text-decoration: none;
+            display: block;
 
-/* Show the dropdown menu */
-.show {
-    display: block;
+            /* Change color of dropdown links on hover */
+            &:hover {
+                background-color: $color--mid-grey;
+            }
+        }
+    }
 }
-- 
GitLab