feat: show component and module version tiles on dashboard
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Universal: Auto Version Bump / Version Bump (push) Has been cancelled
Platform: moko-platform CI / Gate 1: Code Quality (push) Has been cancelled

Add getMokoExtensions() to DashboardModel to fetch installed MokoWaaS
component and modules with versions. Renders version badges below the
info bar for com_mokowaas, mod_mokowaas_cpanel, mod_mokowaas_menu,
mod_mokowaas_cache, and mod_mokowaas_categories.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-06-06 08:17:12 -05:00
parent 5e33f94cce
commit 398fefe2fd
3 changed files with 76 additions and 0 deletions
@@ -212,6 +212,54 @@ class DashboardModel extends BaseDatabaseModel
];
}
/**
* Get installed MokoWaaS component and modules with versions.
*
* @return array Array of extension objects with name, element, type, version.
*/
public function getMokoExtensions(): array
{
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select([
$db->quoteName('element'),
$db->quoteName('name'),
$db->quoteName('type'),
$db->quoteName('enabled'),
$db->quoteName('manifest_cache'),
])
->from($db->quoteName('#__extensions'))
->where('('
// The component
. '(' . $db->quoteName('type') . ' = ' . $db->quote('component')
. ' AND ' . $db->quoteName('element') . ' = ' . $db->quote('com_mokowaas') . ')'
// Admin modules
. ' OR (' . $db->quoteName('type') . ' = ' . $db->quote('module')
. ' AND ' . $db->quoteName('element') . ' LIKE ' . $db->quote('mod_mokowaas%') . ')'
. ')')
->order($db->quoteName('type') . ' ASC, ' . $db->quoteName('element') . ' ASC');
$db->setQuery($query);
$rows = $db->loadObjectList() ?: [];
$extensions = [];
foreach ($rows as $row)
{
$manifest = json_decode($row->manifest_cache ?? '{}');
$extensions[] = (object) [
'element' => $row->element,
'name' => $manifest->name ?? $row->name,
'type' => $row->type,
'version' => $manifest->version ?? '',
'enabled' => (int) $row->enabled,
];
}
return $extensions;
}
/**
* Toggle a plugin's enabled state.
*
@@ -25,6 +25,7 @@ class HtmlView extends BaseHtmlView
protected $wafBlocks = [];
protected $wafChartData = [];
protected $loginChartData = [];
protected $mokoExtensions = [];
public function display($tpl = null)
{
@@ -38,6 +39,7 @@ class HtmlView extends BaseHtmlView
$this->wafBlocks = $model->getRecentWafBlocks(5);
$this->wafChartData = $model->getWafBlocksByDay(14);
$this->loginChartData = $model->getLoginsByDay(14);
$this->mokoExtensions = $model->getMokoExtensions();
// Check for importable Akeeba data
try
@@ -19,6 +19,7 @@ $siteInfo = $this->siteInfo;
$plugins = $this->plugins;
$recentLogins = $this->recentLogins;
$pendingUpdates = $this->pendingUpdates;
$mokoExts = $this->mokoExtensions;
$adminToolsAvail = $this->adminToolsAvailable ?? null;
$atsAvail = $this->atsAvailable ?? null;
$checkedOut = $this->checkedOutItems;
@@ -72,6 +73,31 @@ $categoryOrder = ['core', 'security', 'monitoring', 'content', 'tools', 'api'];
</div>
</div>
<?php if (!empty($mokoExts)): ?>
<!-- Moko Component & Module Versions -->
<div class="d-flex flex-wrap gap-2 mb-4">
<?php
$extIcons = [
'com_mokowaas' => 'icon-cogs',
'mod_mokowaas_cpanel' => 'icon-tachometer-alt',
'mod_mokowaas_menu' => 'icon-bars',
'mod_mokowaas_cache' => 'icon-bolt',
'mod_mokowaas_categories' => 'icon-folder',
];
foreach ($mokoExts as $ext):
$icon = $extIcons[$ext->element] ?? 'icon-puzzle-piece';
$label = str_replace(['mod_mokowaas_', 'com_mokowaas'], ['', 'Component'], $ext->element);
$label = ucfirst($label ?: 'Component');
?>
<div class="d-flex align-items-center gap-2 px-3 py-2 rounded border bg-white" style="font-size:0.85rem;">
<span class="<?php echo $icon; ?>" aria-hidden="true" style="color:#1a2744;"></span>
<span><?php echo $this->escape($label); ?></span>
<span class="badge bg-light text-dark"><?php echo $this->escape($ext->version); ?></span>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($adminToolsAvail || $atsAvail): ?>
<!-- Akeeba Import Banner -->
<div class="alert alert-info d-flex flex-wrap align-items-center gap-3 mb-4">