diff --git a/src/ui/app/routes/login.py b/src/ui/app/routes/login.py index 5da6ca7de..8d91ff54b 100644 --- a/src/ui/app/routes/login.py +++ b/src/ui/app/routes/login.py @@ -46,7 +46,7 @@ def login_page(): if not ui_user.totp_secret: flash( f'Please enable two-factor authentication to secure your account here', - "error", + "warning", ) # redirect him to the page he originally wanted or to the home page diff --git a/src/ui/app/routes/profile.py b/src/ui/app/routes/profile.py index 5b4336af5..eb57d343d 100644 --- a/src/ui/app/routes/profile.py +++ b/src/ui/app/routes/profile.py @@ -13,25 +13,6 @@ profile = Blueprint("profile", __name__) -BROWSERS = { - "Chrome": "bxl-chrome", - "Firefox": "bxl-firefox", - "Safari": "bx-compass", - "Edge": "bxl-edge", - "Opera": "bxl-opera", - "Internet Explorer": "bxl-internet-explorer", -} - -OS = { - "Windows": "bxl-windows", - "Mac": "bxl-apple", - "Linux": "bxl-tux", -} - -DEVICES = { - "PC": "bx-desktop", -} - def get_last_sessions(page: int, per_page: int) -> Tuple[Generator[Dict[str, Union[str, bool]], None, None], int]: db_sessions = DB.get_ui_user_sessions(current_user.username, session.get("session_id")) @@ -53,7 +34,7 @@ def session_generator(page: int, per_page: int): for db_session in additional_sessions + db_sessions[(page - 1) * per_page : page * per_page]: # noqa: E203 ua_data = parse(db_session["user_agent"]) - last_session = { + yield { "current": db_session["id"] == session.get("session_id") if "session_id" in session else "id" not in db_session, "browser": ua_data.get_browser(), "os": ua_data.get_os(), @@ -67,20 +48,6 @@ def session_generator(page: int, per_page: int): ), } - for browser, icon in BROWSERS.items(): - if browser in last_session["browser"]: - last_session["browser"] = f" {last_session['browser']}" - break - - for os, icon in OS.items(): - if os in last_session["os"]: - last_session["os"] = f" {last_session['os']}" - break - - last_session["device"] = f" {last_session['device']}" - - yield last_session - return session_generator(page, per_page), total_sessions diff --git a/src/ui/app/static/css/overrides.css b/src/ui/app/static/css/overrides.css index f5ce761f4..1a8bea08a 100644 --- a/src/ui/app/static/css/overrides.css +++ b/src/ui/app/static/css/overrides.css @@ -768,3 +768,8 @@ a.courier-prime:hover { .courier-prime { font-family: var(--font-courier-prime); } + +.warning-tooltip { + --bs-tooltip-bg: var(--bs-warning); + --bs-tooltip-color: var(--bs-white); +} diff --git a/src/ui/app/static/img/diamond-white.svg b/src/ui/app/static/img/diamond-white.svg new file mode 100644 index 000000000..3d47be7ca --- /dev/null +++ b/src/ui/app/static/img/diamond-white.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ui/app/static/js/pages/config_edit.js b/src/ui/app/static/js/pages/config_edit.js index d7a94643f..fa43aac2a 100644 --- a/src/ui/app/static/js/pages/config_edit.js +++ b/src/ui/app/static/js/pages/config_edit.js @@ -111,6 +111,7 @@ $(document).ready(function () { ).first(); $("#select-type") .parent() + .attr("data-bs-custom-class", "warning-tooltip") .attr( "data-bs-original-title", `Switched to ${firstMultisiteType diff --git a/src/ui/app/static/js/pages/home.js b/src/ui/app/static/js/pages/home.js index fe8dce31a..794a6bd6b 100644 --- a/src/ui/app/static/js/pages/home.js +++ b/src/ui/app/static/js/pages/home.js @@ -431,6 +431,7 @@ $(function () { chart: { type: "bar", width: "100%", + height: 400, }, title: { text: "Blocked Requests per Hour", diff --git a/src/ui/app/static/js/pages/setup.js b/src/ui/app/static/js/pages/setup.js index 0e45482f9..e2c909848 100644 --- a/src/ui/app/static/js/pages/setup.js +++ b/src/ui/app/static/js/pages/setup.js @@ -217,7 +217,7 @@ $(document).ready(() => { $currentStepContainer.find(".plugin-setting").each(function () { const $input = $(this); - const value = $input.val().trim(); + const value = $input.val(); const isRequired = $input.prop("required"); const pattern = $input.attr("pattern"); const fieldName = diff --git a/src/ui/app/static/js/plugins-settings.js b/src/ui/app/static/js/plugins-settings.js index 294d58d3a..35c193502 100644 --- a/src/ui/app/static/js/plugins-settings.js +++ b/src/ui/app/static/js/plugins-settings.js @@ -14,7 +14,6 @@ $(document).ready(() => { } let currentTemplate = $("#selected-template").val(); - let currentTemplateMethod = $("#selected-template-method").val(); let currentMode = $("#selected-mode").val(); let currentType = $("#selected-type").val(); @@ -159,7 +158,7 @@ $(document).ready(() => { currentStepContainer.find(".plugin-setting").each(function () { const $input = $(this); - const value = $input.val().trim(); + const value = $input.val(); const isRequired = $input.prop("required"); const pattern = $input.attr("pattern"); const fieldName = diff --git a/src/ui/app/static/js/utils.js b/src/ui/app/static/js/utils.js index d2aa4ea69..c7f5d2ecf 100644 --- a/src/ui/app/static/js/utils.js +++ b/src/ui/app/static/js/utils.js @@ -17,7 +17,7 @@ class News { if (lastNews) { this.render(JSON.parse(lastNews)); } else { - $.getJSON("https://www.bunkerweb.io/api/posts/0/2") + $.getJSON("https://www.bunkerweb.io/api/posts/0/3") .done((res) => { const reverseData = res.data.reverse(); this.render(reverseData); @@ -271,29 +271,40 @@ $(document).ready(() => { const intervalTime = 7000; let interval; const $bannerText = $("#banner-text"); - // Create a hidden element to measure the max height - const $measuringElement = $("
") - .css({ - position: "absolute", - visibility: "hidden", - height: "auto", - width: $bannerText.width(), - whiteSpace: "nowrap", - }) - .appendTo("body"); - - // Calculate the minimum height required for the banner text - let minHeight = 0; - newsItems.forEach((item) => { - $measuringElement.html(item); - minHeight = Math.max(minHeight, $measuringElement.outerHeight()); - }); - // Set the minimum height to avoid layout shifts - $bannerText.css("min-height", minHeight); + function calculateMinHeight() { + // Create a hidden element to measure the max height + const $measuringElement = $("
") + .css({ + position: "absolute", + visibility: "hidden", + height: "auto", + width: $bannerText.width(), // Set width to match the current width of the banner text container + whiteSpace: "normal", // Change to normal for wrapping if needed + }) + .appendTo("body"); + + // Calculate the minimum height required for the banner text + let minHeight = 0; + newsItems.forEach((item) => { + $measuringElement.html(item); + minHeight = Math.max(minHeight, $measuringElement.outerHeight()); + }); + + // Set the minimum height to avoid layout shifts + $bannerText.css("min-height", minHeight); + + // Remove the measuring element from the DOM + $measuringElement.remove(); + } - // Remove the measuring element from the DOM - $measuringElement.remove(); + // Calculate the min-height on page load + calculateMinHeight(); + + // Recalculate the min-height on window resize + $(window).on("resize", function () { + calculateMinHeight(); + }); const news = new News(); news.init(); @@ -380,4 +391,35 @@ $(document).ready(() => { loadData(); $("#next-news").trigger("click"); } + + var notificationsRead = + parseInt(sessionStorage.getItem("notificationsRead")) || 0; + + function updateNotificationsBadge() { + const $notificationsBadge = $("#unread-notifications"); + let unreadNotifications = parseInt($notificationsBadge.text()); + + unreadNotifications = isNaN(unreadNotifications) ? 0 : unreadNotifications; + + if ($notificationsBadge.length) { + const updatedUnread = unreadNotifications - notificationsRead; + if (updatedUnread > 0) { + $notificationsBadge.text(updatedUnread); + $notificationsBadge.removeClass("d-none"); + } else { + $notificationsBadge.addClass("d-none"); + } + } + } + + updateNotificationsBadge(); + + $("#notifications-button").on("click", function () { + const readNotifications = $( + "#notifications-toast-container .bs-toast", + ).length; + notificationsRead = readNotifications; + sessionStorage.setItem("notificationsRead", notificationsRead); + updateNotificationsBadge(); + }); }); diff --git a/src/ui/app/templates/dashboard.html b/src/ui/app/templates/dashboard.html index 9cb882b26..782bab227 100644 --- a/src/ui/app/templates/dashboard.html +++ b/src/ui/app/templates/dashboard.html @@ -141,7 +141,8 @@ Notifications {% if flash_messages %} - + {{ flash_messages|length }} unread notifications @@ -174,7 +175,7 @@ aria-pressed="true" href="{{ url_for('pro') }}"> - Pro plugin diff --git a/src/ui/app/templates/flash.html b/src/ui/app/templates/flash.html index f1af37671..89adddda6 100644 --- a/src/ui/app/templates/flash.html +++ b/src/ui/app/templates/flash.html @@ -8,12 +8,12 @@ {% endif %} {% for category, message in messages %} -