diff --git a/admin.css b/admin.css index 047a8d4..5b2cf86 100644 --- a/admin.css +++ b/admin.css @@ -433,6 +433,18 @@ grid-template-columns: 2fr 1fr; } + /* The tabs bar */ + #botmon__tabs ul.tabs li { + a[aria-selected="true"] { + background-color: #DDD; + color: #111; + } + a[aria-selected="false"] { + background-color: #EEE; + color: #111; + } + } + /* the "today" tab: */ #botmon__latest { @@ -754,7 +766,8 @@ & { border: #999 solid 1px; background-color: #F0F0F0; - margin: 0; padding: .5em; + margin: .5rem 0 0 0; + padding: .5em; border-radius: .5em 1pt 1pt .5em; list-style: none inside; display: block; @@ -763,6 +776,9 @@ overflow: hidden auto } li { + & { + margin: 0; padding: 0; + } &:nth-child(even) { background-color: #DFDFDF; } @@ -771,7 +787,6 @@ &.error { color: #bb2929; } } } - } } @@ -779,6 +794,18 @@ @media (prefers-color-scheme: dark) { body.darkmode.mode_admin #botmon__admin { + #botmon__tabs ul.tabs li { + a[aria-selected="true"] { + background-color: #0c0c0d; + color: #adadb3; + } + a[aria-selected="false"] { + background-color: #39393D; + color: #ADADB3; + } + } + + #botmon__latest { header { @@ -866,6 +893,22 @@ } } } + + #botmon__log { + #botmon__loglist { + & { + border-color: #CCC; + background-color: #232327; + } + li { + &:nth-child(even) { background-color: #39393D; } + &.info { color: #a2a2a2;} + &.success { color: #50b750; } + &.error { color: #f87d7d; } + } + } + } + } } /* layout overrides for narrow screens: */ diff --git a/admin.js b/admin.js index 776f5d6..e101c6b 100644 --- a/admin.js +++ b/admin.js @@ -1732,11 +1732,76 @@ BotMon.live = { gui: { init: function() { - console.log('BotMon.live.gui.init()'); + //console.log('BotMon.live.gui.init()'); + // init sub-objects: BotMon.t._callInit(this); }, + tabs: { + init: function() { + //console.log('BotMon.live.gui.tabs.init()'); + + /* find and add all existing tabs */ + document.querySelectorAll('#botmon__admin *[role=tablist]') + .forEach((tablist) => { + tablist.querySelectorAll('*[role=tab]') + .forEach( t => t.addEventListener('click', this._onTabClick) ) + }); + }, + + /* callback for tab click */ + _onTabClick: function(e) { + //console.log('BotMon.live.gui.tabs._onTabClick()'); + + /* reusable constants: */ + const kAriaSelected = 'aria-selected'; + const kAriaControls = 'aria-controls'; + const kTrue = 'true'; + const kFalse = 'false'; + const kHidden = 'hidden'; + + /* cancel default action */ + e.preventDefault(); + + /* if the active tab is clicked, do nothing: */ + let selState = this.getAttribute(kAriaSelected); + if ( selState && selState == kTrue ) { + return; + } + + /* find the active tab element: */ + var aItem = null; + let tablist = this.parentNode; + while (tablist.getAttribute('role') !== 'tablist') { + tablist = tablist.parentNode; + } + + if (tablist.getAttribute('role') == 'tablist') { + let lis = tablist.querySelectorAll('*[role=tab]'); + lis.forEach( (it) => { + let selected = it.getAttribute(kAriaSelected); + if ( selected && selected == kTrue ) { + aItem = it; + } + }); + } + + /* swap the active states: */ + this.setAttribute(kAriaSelected, kTrue); + if (aItem) { + aItem.setAttribute(kAriaSelected, kFalse); + let aId = aItem.getAttribute(kAriaControls); + let aObj = document.getElementById(aId); + if (aObj) aObj.hidden = true; + } + + /* show the new panel: */ + let nId = this.getAttribute(kAriaControls); + let nObj = document.getElementById(nId); + if (nObj) nObj.hidden = false; + } + }, /* The Overview / web metrics section of the live tab */ overview: { diff --git a/admin.php b/admin.php index 54ddf0a..a9ca24b 100644 --- a/admin.php +++ b/admin.php @@ -47,8 +47,8 @@ class admin_plugin_botmon extends AdminPlugin {

Bot Monitoring Plugin

@@ -90,8 +90,8 @@ class admin_plugin_botmon extends AdminPlugin { Initialising …
-
-

Process log

+