Просмотр исходного кода

Implement celery status checking

Peter Justin 3 лет назад
Родитель
Сommit
d5bdf6b747

+ 19 - 32
flaskbb/templates/management/overview.html

@@ -19,7 +19,7 @@
             <div class="settings-content">
                 <div class="stats">
                     <div class="row stats-row">
-                        <div class="overview-notifications col-md-12 col-sm-12 col-xs-12">
+                        <div class="overview-notifications col-12">
                             {% if unread_reports > 0 %}
                             <div class="alert-message alert-message-warning">
                                 <h4>{% trans %}There is something that wants your attention.{% endtrans %}</h4>
@@ -34,7 +34,7 @@
                         </div>
                     </div>
                     <div class="row stats-row">
-                        <div class="col-md-4 col-sm-4 col-xs-4">
+                        <div class="col-4">
                             <div class="stats-widget">
                                 <div class="icon">
                                      <i class="fa fa-users text-success"></i>
@@ -46,7 +46,7 @@
                             </div>
                         </div>
 
-                        <div class="col-md-4 col-sm-4 col-xs-4">
+                        <div class="col-4">
                             <div class="stats-widget">
                                 <div class="icon">
                                      <i class="fa fa-comment text-primary"></i>
@@ -58,7 +58,7 @@
                             </div>
                         </div>
 
-                        <div class="col-md-4 col-sm-4 col-xs-4">
+                        <div class="col-4">
                             <div class="stats-widget">
                                 <div class="icon">
                                      <i class="fa fa-comments text-info"></i>
@@ -98,7 +98,7 @@
                             </div>
                         </div>
 
-                        <div class="col-md-4 col-sm-4 col-xs-4">
+                        <div class="col-4">
                             <div class="row stats-heading">{% trans %}Components{% endtrans %}</div>
 
                             <div class="row">
@@ -119,7 +119,7 @@
                             </div>
                         </div>
 
-                        <div class="col-md-4 col-sm-4 col-xs-4">
+                        <div class="col-4">
                             <div class="row stats-heading">{% trans %}Plugins{% endtrans %}</div>
 
                             {% for plugin in plugins %}
@@ -159,33 +159,20 @@
 {% block scripts %}
 <script>
 
-function celery_not_running_notification() {
-    content = "<div class='alert-message alert-message-danger'>" +
-        "<h4>{% trans %}There is a problem.{% endtrans %}</h4>" +
-        "<p>{% trans %}Celery is <strong>not</strong> running.{% endtrans %}</p>" +
-        "<p>{% trans %}You can start celery with this command:{% endtrans %}</p>" +
-        "<pre>flaskbb --config {{ current_app.config["CONFIG_PATH"] }} celery worker</pre>" +
-        "</div>";
-
-    // replace the no notifications notice with ours
-    if(document.getElementById("#overview-no-notifications") == null) {
-        $("#overview-no-notifications").replaceWith(content);
-    } else {
-        $(".overview-notifications").append(content);
-    }
-}
+// TOOD: Put this into management.celery_status
+const running = "<span id='celery-status' class='text-success'><strong>{% trans %}running{% endtrans %}</strong></span>";
+const not_running = "<span id='celery-status' class='text-danger'><strong>{% trans %}not running{% endtrans %}</strong></span>";
 
-$(document).ready(function () {
-    var $celerystatus = $('#celery-status');
+const notification = `
+    <div class='alert-message alert-message-danger'>
+        <h4>{% trans %}There is a problem.{% endtrans %}</h4>
+        <p class="mb-0">{% trans %}Celery is <strong>not</strong> running.{% endtrans %}</p>
+        <p class="mb-0">{% trans %}You can start celery with this command:{% endtrans %}</p>
+        <pre>flaskbb --config {{ current_app.config["CONFIG_PATH"] }} celery worker</pre>
+    </div>
+`;
+const endpoint = "{{ url_for('management.celery_status') }}";
 
-    $.getJSON('/admin/celerystatus', function(data) {
-        if(data.celery_running) {
-            $celerystatus.replaceWith("<span id='celery-status' class='text-success'><strong>{% trans %}running{% endtrans %}</strong></span>");
-        } else {
-            $celerystatus.replaceWith("<span id='celery-status' class='text-danger'><strong>{% trans %}not running{% endtrans %}</strong></span>");
-            celery_not_running_notification()
-        }
-    });
-});
+window.app.check_overview_status(endpoint, notification, running, not_running);
 </script>
 {% endblock %}

+ 1 - 1
flaskbb/themes/aurora/src/app.js

@@ -7,7 +7,7 @@ import "./app/confirm_modal.js";
 
 
 import "./scss/styles.scss";
-export { BulkActions, show_management_search } from "./app/flaskbb.js";
+export { BulkActions, show_management_search, check_overview_status } from "./app/flaskbb.js";
 
 var tooltips = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
 var tooltipList = tooltips.map(function (el) {

+ 163 - 104
flaskbb/themes/aurora/src/app/flaskbb.js

@@ -3,41 +3,48 @@
  * Copyright: (C) 2015 - FlaskBB Team
  * License: BSD - See LICENSE for more details.
  */
+import { Modal } from "bootstrap";
 
 // get the csrf token from the header
-let csrf_token = document.querySelector('meta[name=csrf-token]').content
+let csrf_token = document.querySelector("meta[name=csrf-token]").content;
 
 export function show_management_search() {
-    let form = document.querySelector('.search-form');
+    let form = document.querySelector(".search-form");
 
     if (window.getComputedStyle(form).display === "none") {
         form.style.display = "block";
-        form.querySelector('input').focus();
+        form.querySelector("input").focus();
     } else {
         form.style.display = "none";
     }
-};
+}
 
 function flash_message(message) {
     let container = document.getElementById("flashed-messages");
 
-    let flashed_message = '<div class="alert alert-' + message.category + '">';
+    let flashed_message = `<div class="alert alert-${message.category} alert-dismissible fade show">`;
 
-    if (message.category == 'success') {
-        flashed_message += '<span class="fas fa-ok-sign"></span>&nbsp;';
-    } else if (message.category == 'error') {
-        flashed_message += '<span class="fas fa-exclamation-sign"></span>&nbsp;';
+    if (message.category == "success") {
+        flashed_message += '<span class="fas fa-ok-sign me-2"></span>';
+    } else if (message.category == "error") {
+        flashed_message += '<span class="fas fa-exclamation-sign me-2"></span>';
     } else {
-        flashed_message += '<span class="fas fa-info-sign"></span>&nbsp;';
+        flashed_message += '<span class="fas fa-info-sign me-2"></span>';
     }
-    flashed_message += '<button type="button" class="close" data-dismiss="alert">&times;</button>' + message.message + '</div>';
-    container.insertAdjacentHTML('beforeend', flashed_message);
-};
+    flashed_message += `
+        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
+
+        ${message.message}
+    </div>`;
+    container.insertAdjacentHTML("beforeend", flashed_message);
+}
 
 export class BulkActions {
     execute(endpoint) {
-        let selected = document.querySelectorAll('input.action-checkbox:checked');
-        let data = { "ids": [] };
+        let selected = document.querySelectorAll(
+            "input.action-checkbox:checked"
+        );
+        let data = { ids: [] };
 
         // don't do anything if nothing is selected
         if (selected.length === 0) {
@@ -47,140 +54,192 @@ export class BulkActions {
         for (let selection of selected) {
             data.ids.push(selection.value);
         }
-        send_data(endpoint, data);
-        //this.confirm(endpoint, data);
+        //send_data(endpoint, data);
+        this.confirm(endpoint, data);
         return false;
-    };
+    }
 
     confirm(endpoint, data) {
         const confirmModalElement = document.getElementById("confirmModal");
-        // Get the instance of this modal
-        //let confirmModal = Modal.getInstance(confirmModalElement);
+        let confirmModal = Modal.getOrCreateInstance(confirmModalElement);
+        confirmModal.show();
 
         // the confirm button of the modal
         let confirmButton = confirmModalElement.querySelector(".confirmBtn");
-        confirmButton.addEventListener("click", function(e) {
-            e.preventDefault();
-            confirmModal.hide();
-            send_data(endpoint, data);
-        }, {
-            once: true,
-        });
-    };
-};
+        confirmButton.addEventListener(
+            "click",
+            function (e) {
+                e.preventDefault();
+                confirmModal.hide();
+                send_data(endpoint, data);
+            },
+            {
+                once: true,
+            }
+        );
+    }
+}
 
 export function send_data(endpoint_url, data) {
     fetch(endpoint_url, {
-        method: 'POST',
+        method: "POST",
         headers: {
-            'X-CSRFToken': csrf_token,
-            'Content-Type': 'application/json',
+            "X-CSRFToken": csrf_token,
+            "Content-Type": "application/json",
         },
-        body: JSON.stringify(data)
+        body: JSON.stringify(data),
     })
-        .then(response => response.json())
-        .then(data => {
+        .then((response) => response.json())
+        .then((data) => {
             flash_message(data);
             for (let obj of data.data) {
                 // get the form
-                const form_id = `#${obj.type}-${obj.id}`
+                const form_id = `#${obj.type}-${obj.id}`;
                 let form = document.querySelector(form_id);
 
                 // check if there is something to reverse it, otherwise remove the DOM.
                 if (obj.reverse) {
-                    form.setAttribute('action', obj.reverse_url)
-
-                    let reverse_html = '';
-                    if (obj.reverse == 'ban') {
-                        reverse_html = '<span class="fa fa-flag text-success" data-toggle="tooltip" data-placement="top" title="' + obj.reverse_name + '"></span>';
-                    } else if (obj.reverse == 'unban') {
-                        reverse_html = '<span class="fa fa-flag text-warning" data-toggle="tooltip" data-placement="top" title="' + obj.reverse_name + '"></span>';
+                    form.setAttribute("action", obj.reverse_url);
+
+                    let reverse_html = "";
+                    if (obj.reverse == "ban") {
+                        reverse_html =
+                            '<span class="fas fa-flag text-success" data-bs-toggle="tooltip" title="' +
+                            obj.reverse_name +
+                            '"></span>';
+                    } else if (obj.reverse == "unban") {
+                        reverse_html =
+                            '<span class="fas fa-flag text-warning" data-bs-toggle="tooltip" title="' +
+                            obj.reverse_name +
+                            '"></span>';
                     }
-                    form.querySelector('button').innerHTML = reverse_html;
-
+                    form.querySelector("button").innerHTML = reverse_html;
                 } else if (obj.type == "delete") {
                     form.parentNode.parentNode.remove();
                 }
             }
         })
-        .catch(error => {
-            flash_message(error)
-        })
-
-};
+        .catch((error) => {
+            flash_message(error);
+        });
+}
 
 export function parse_emoji(value) {
     // use this instead of twemoji.parse
-    return twemoji.parse(
-        value,
-        {
-            callback: function(icon, options, variant) {
-                // exclude some characters
-                switch (icon) {
-                    case 'a9':      // © copyright
-                    case 'ae':      // ® registered trademark
-                    case '2122':    // ™ trademark
-                        return false;
-                }
-                return ''.concat(options.base, options.size, '/', icon, options.ext);
-            },
-            // use svg instead of the default png
-            folder: 'svg',
-            ext: '.svg'
-        }
-    )
-};
+    return twemoji.parse(value, {
+        callback: function (icon, options, variant) {
+            // exclude some characters
+            switch (icon) {
+                case "a9": // © copyright
+                case "ae": // ® registered trademark
+                case "2122": // ™ trademark
+                    return false;
+            }
+            return "".concat(
+                options.base,
+                options.size,
+                "/",
+                icon,
+                options.ext
+            );
+        },
+        // use svg instead of the default png
+        folder: "svg",
+        ext: ".svg",
+    });
+}
+
+function celery_not_running_notification(notification) {
+    let no_notifications = document.getElementById("overview-no-notifications");
+    let notifications = document.querySelector(".overview-notifications");
+
+    // replace the no notifications notice with ours
+    if (no_notifications == null) {
+        no_notifications.outerHTML = notification;
+    } else {
+        notifications.innerHTML = notification;
+    }
+}
 
-document.addEventListener("DOMContentLoaded", function(event) {
+export function check_overview_status(endpoint, notification, running, not_running) {
+    let celerystatus = document.getElementById("celery-status");
+    fetch(endpoint, {
+        method: "GET",
+        headers: {
+            "Content-Type": "application/json",
+        }
+    })
+        .then((response) => response.json())
+        .then((data) => {
+            if (data.celery_running) {
+                celerystatus.outerHTML = running;
+            } else {
+                celerystatus.outerHTML = not_running;
+                celery_not_running_notification(notification);
+            }
+        })
+        .catch((error) => {
+            flash_message(error);
+        });
+}
 
+document.addEventListener("DOMContentLoaded", function (event) {
     // Reply to post
-    document.querySelectorAll(".quote-btn").forEach(el => el.addEventListener('click', event => {
-        event.preventDefault();
-        const post_id = event.target.dataset.postId;
-        const urlprefix = typeof FORUM_URL_PREFIX !== typeof undefined ? FORUM_URL_PREFIX : "";
-        const url = `${urlprefix}post/${post_id}/raw`;
-
-        const editor = document.querySelector(".flaskbb-editor");
-        fetch(url)
-            .then(response => response.text())
-            .then(data => {
-                editor.value = data;
-                editor.selectionStart = editor.selectionEnd = editor.value.length;
-                editor.scrollTop = editor.scrollHeight;
-                window.location.href = '#content';
-            })
-            .catch(error => {
-                console.error("something bad happened", error)
-            })
-    }));
+    document.querySelectorAll(".quote-btn").forEach((el) =>
+        el.addEventListener("click", (event) => {
+            event.preventDefault();
+            const post_id = event.target.dataset.postId;
+            const urlprefix =
+                typeof FORUM_URL_PREFIX !== typeof undefined
+                    ? FORUM_URL_PREFIX
+                    : "";
+            const url = `${urlprefix}post/${post_id}/raw`;
+
+            const editor = document.querySelector(".flaskbb-editor");
+            fetch(url)
+                .then((response) => response.text())
+                .then((data) => {
+                    editor.value = data;
+                    editor.selectionStart = editor.selectionEnd =
+                        editor.value.length;
+                    editor.scrollTop = editor.scrollHeight;
+                    window.location.href = "#content";
+                })
+                .catch((error) => {
+                    console.error("something bad happened", error);
+                });
+        })
+    );
 
     // listen on the action-checkall checkbox to un/check all
-    document.querySelectorAll(".action-checkall").forEach(el => el.addEventListener('change', event => {
-        const cbs = document.querySelectorAll('input.action-checkbox')
-        for (var i = 0; i < cbs.length; i++) {
-            cbs[i].checked = event.target.checked;
-        }
-    }));
+    document.querySelectorAll(".action-checkall").forEach((el) =>
+        el.addEventListener("change", (event) => {
+            const cbs = document.querySelectorAll("input.action-checkbox");
+            for (var i = 0; i < cbs.length; i++) {
+                cbs[i].checked = event.target.checked;
+            }
+        })
+    );
 
-    document.querySelectorAll("time").forEach(el => {
-        let date = new Date(el.getAttribute('datetime'));
+    document.querySelectorAll("time").forEach((el) => {
+        let date = new Date(el.getAttribute("datetime"));
         const options = {
             weekday: undefined,
             era: undefined,
-            year: 'numeric',
-            month: 'short',
-            day: 'numeric',
+            year: "numeric",
+            month: "short",
+            day: "numeric",
             second: undefined,
         };
-        if (el.dataset.what_to_display == 'date-only') {
+        if (el.dataset.what_to_display == "date-only") {
             options.hour = undefined;
             options.minute = undefined;
         } else {
-            options.hour = '2-digit';
-            options.minute = '2-digit';
+            options.hour = "2-digit";
+            options.minute = "2-digit";
         }
         el.textContent = date.toLocaleString(undefined, options);
-    })
+    });
 
     parse_emoji(document.body);
 });