From 41612c4481111969367d1a228ad4875d781558a2 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 30 Nov 2021 15:27:59 +0100 Subject: [locations] Modularize additional column handling Additional columns are now added through a hook, moving specialized code where it belongs. --- .../locations/inc/abstractlocationcolumn.inc.php | 24 +++ .../locations/pages/locations.inc.php | 170 +++++---------------- modules-available/locations/style.css | 12 +- .../locations/templates/locations.html | 107 +++---------- 4 files changed, 95 insertions(+), 218 deletions(-) create mode 100644 modules-available/locations/inc/abstractlocationcolumn.inc.php (limited to 'modules-available/locations') diff --git a/modules-available/locations/inc/abstractlocationcolumn.inc.php b/modules-available/locations/inc/abstractlocationcolumn.inc.php new file mode 100644 index 00000000..9583429e --- /dev/null +++ b/modules-available/locations/inc/abstractlocationcolumn.inc.php @@ -0,0 +1,24 @@ +getColumnHtml(0); + } + +} \ No newline at end of file diff --git a/modules-available/locations/pages/locations.inc.php b/modules-available/locations/pages/locations.inc.php index ce08e597..0eb035c8 100644 --- a/modules-available/locations/pages/locations.inc.php +++ b/modules-available/locations/pages/locations.inc.php @@ -93,126 +93,43 @@ class SubPage $unassignedIdle = $unassignedLoad = $unassignedOverrides = 0; $allowedLocationIds = User::getAllowedLocations("location.view"); - foreach (array_keys($locationList) as $lid) { - if (!User::hasPermission('.baseconfig.view', $lid)) { - $locationList[$lid]['havebaseconfig'] = false; - } - if (!User::hasPermission('.sysconfig.config.view-list', $lid)) { - $locationList[$lid]['havesysconfig'] = false; - } - if (!User::hasPermission('.statistics.view.list', $lid)) { - $locationList[$lid]['havestatistics'] = false; - } - if (!User::hasPermission('.serversetup.ipxe.menu.assign', $lid)) { - $locationList[$lid]['haveipxe'] = false; - } - if (!in_array($lid, $allowedLocationIds)) { - $locationList[$lid]['show-only'] = true; - } - } - // Client statistics - if (Module::get('statistics') !== false) { - $unassigned = 0; - $extra = ''; - if (in_array(0, $allowedLocationIds)) { - $extra = ' OR locationid IS NULL'; - } - $res = Database::simpleQuery("SELECT m.locationid, Count(*) AS cnt, - Sum(If(m.state = 'OCCUPIED', 1, 0)) AS used, Sum(If(m.state = 'IDLE', 1, 0)) AS idle - FROM machine m WHERE (locationid IN (:allowedLocationIds) $extra) GROUP BY locationid", compact('allowedLocationIds')); - foreach ($res as $row) { - $locId = (int)$row['locationid']; - if (isset($locationList[$locId])) { - $locationList[$locId]['clientCount'] = $row['cnt']; - $locationList[$locId]['clientLoad'] = round(100 * $row['used'] / $row['cnt']); - $locationList[$locId]['clientIdle'] = round(100 * ($row['used'] + $row['idle']) / $row['cnt']); - } else { - $unassigned += $row['cnt']; - $unassignedLoad += $row['used']; - $unassignedIdle += $row['idle']; - } - } - $res = Database::simpleQuery("SELECT m.locationid, Count(DISTINCT sm.machineuuid) AS cnt FROM setting_machine sm - INNER JOIN machine m USING (machineuuid) GROUP BY m.locationid"); - foreach ($res as $row) { - $locId = (int)$row['locationid']; - if (isset($locationList[$locId])) { - $locationList[$locId]['machineVarsOverrideCount'] = $row['cnt']; - } else { - $unassignedOverrides += $row['cnt']; - } - } - unset($loc); - foreach ($locationList as &$loc) { - if (!in_array($loc['locationid'], $allowedLocationIds)) - continue; - if (!isset($loc['clientCountSum'])) { - $loc['clientCountSum'] = 0; - } - if (!isset($loc['clientCount'])) { - $loc['clientCount'] = $loc['clientIdle'] = $loc['clientLoad'] = 0; - } - $loc['clientCountSum'] += $loc['clientCount']; - foreach ($loc['parents'] as $pid) { - if (!in_array($pid, $allowedLocationIds)) - continue; - $locationList[(int)$pid]['hasChild'] = true; - $locationList[(int)$pid]['clientCountSum'] += $loc['clientCount']; - } - } - unset($loc); - - } - // Show currently active sysconfig for each location - $defaultConfig = false; - if (Module::isAvailable('sysconfig')) { - $confs = SysConfig::getAll(); - foreach ($confs as $conf) { - if (strlen($conf['locs']) === 0) - continue; - $confLocs = explode(',', $conf['locs']); - foreach ($confLocs as $locId) { - settype($locId, 'int'); - if ($locId === 0) { - $defaultConfig = $conf['title']; + $plugins = []; + foreach (Hook::load('locations-column') as $hook) { + $c = @include($hook->file); + if ($c instanceof AbstractLocationColumn) { + $plugins[sprintf('%04d.%s', $c->priority(), $hook->moduleId)] = $c; + } elseif (is_array($c)) { + foreach ($c as $i => $cc) { + if ($cc instanceof AbstractLocationColumn) { + $plugins[sprintf('%04d.%d.%s', $cc->priority(), $i, $hook->moduleId)] = $cc; } - if (!isset($locationList[$locId])) - continue; - $locationList[$locId] += array('configName' => $conf['title'], 'configClass' => 'slx-bold'); } } - self::propagateFields($locationList, $defaultConfig, 'configName', 'configClass'); } - // Count overridden config vars - if (Module::get('baseconfig') !== false) { - $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM `setting_location` - WHERE locationid IN (:allowedLocationIds) GROUP BY locationid", compact('allowedLocationIds')); - foreach ($res as $row) { - $lid = (int)$row['locationid']; - if (isset($locationList[$lid])) { - $locationList[$lid]['overriddenVars'] = $row['cnt']; - } + ksort($plugins); + foreach ($locationList as $lid => &$loc) { + $loc['plugins'] = []; + foreach ($plugins as $pk => $plugin) { + $loc['plugins'][$pk] = [ + 'url' => $plugin->getEditUrl($lid), + 'html' => $plugin->getColumnHtml($lid), + ]; + } + if (!in_array($lid, $allowedLocationIds)) { + $locationList[$lid]['show-only'] = true; } - // Confusing because the count might be inaccurate within a branch - //$this->propagateFields($locationList, '', 'overriddenVars', 'overriddenClass'); } - // Show ipxe menu - if (Module::isAvailable('serversetup') && class_exists('IPxe')) { - $res = Database::simpleQuery("SELECT ml.locationid, m.title, ml.defaultentryid FROM serversetup_menu m - INNER JOIN serversetup_menu_location ml USING (menuid) - WHERE locationid IN (:allowedLocationIds) GROUP BY locationid", compact('allowedLocationIds')); - foreach ($res as $row) { - $lid = (int)$row['locationid']; - if (isset($locationList[$lid])) { - if ($row['defaultentryid'] !== null) { - $row['title'] .= '(*)'; - } - $locationList[$lid]['customMenu'] = $row['title']; - } + unset($loc); + foreach ($plugins as $pk => $plugin) { + if ($plugin->propagateColumn()) { + self::propagateFields($locationList, $plugin->propagateDefaultHtml(), $pk); } - self::propagateFields($locationList, '', 'customMenu', 'customMenuClass'); } + foreach ($locationList as &$loc) { + $loc['plugins'] = array_values($loc['plugins']); + } + unset($loc); $addAllowedLocs = User::getAllowedLocations("location.add"); $addAllowedList = Location::getLocations(0, 0, true); @@ -224,44 +141,37 @@ class SubPage unset($loc); // Output - $data = array( + $data = [ + 'colspan' => (2 + count($plugins)), + 'plugins' => array_values($plugins), 'list' => array_values($locationList), - 'havestatistics' => Module::get('statistics') !== false, - 'havebaseconfig' => Module::get('baseconfig') !== false, - 'havesysconfig' => Module::get('sysconfig') !== false, - 'haveipxe' => Module::isAvailable('serversetup') && class_exists('IPxe'), 'overlapSelf' => $overlapSelf, 'overlapOther' => $overlapOther, 'mismatchMachines' => $mismatchMachines, - 'unassignedCount' => $unassigned, - 'unassignedLoad' => ($unassigned ? (round(($unassignedLoad / $unassigned) * 100)) : ''), - 'unassignedIdle' => ($unassigned ? (round((($unassignedLoad + $unassignedIdle) / $unassigned) * 100)) : ''), - 'unassignedOverrides' => $unassignedOverrides, - 'defaultConfig' => $defaultConfig, 'addAllowedList' => array_values($addAllowedList), - ); - // TODO: Buttons for config vars and sysconfig are currently always shown, as their availability - // depends on permissions in the according modules, not this one + ]; Permission::addGlobalTags($data['perms'], NULL, ['subnets.edit', 'location.add']); Render::addTemplate('locations', $data); Module::isAvailable('js_ip'); // For CIDR magic } - private static function propagateFields(&$locationList, $defaultValue, $name, $class) + private static function propagateFields(array &$locationList, string $defaultValue, string $plugin) { $depth = array(); foreach ($locationList as &$loc) { $d = $loc['depth']; - if (!isset($loc[$name])) { + if (empty($loc['plugins'][$plugin]['html'])) { // Has no explicit config assignment if ($d === 0) { - $loc[$name] = $defaultValue; + $loc['plugins'][$plugin]['html'] = $defaultValue; } else { - $loc[$name] = $depth[$d - 1]; + $loc['plugins'][$plugin]['html'] = $depth[$d - 1]; } - $loc[$class] = 'gray'; + $loc['plugins'][$plugin]['class'] = 'gray'; + } elseif (empty($loc['plugins'][$plugin]['class'])) { + $loc['plugins'][$plugin]['class'] = 'slx-bold'; } - $depth[$d] = $loc[$name]; + $depth[$d] = $loc['plugins'][$plugin]['html']; unset($depth[$d + 1]); } } diff --git a/modules-available/locations/style.css b/modules-available/locations/style.css index 19950a38..0de0a801 100644 --- a/modules-available/locations/style.css +++ b/modules-available/locations/style.css @@ -1,4 +1,4 @@ -table.locations tbody td:nth-of-type(even) { +table.locations > tbody > tr > td:nth-of-type(even) { background-color: rgba(0, 0, 0, 0.025); } @@ -16,4 +16,12 @@ table.locations tbody td:nth-of-type(even) { .load-col { text-align: right; text-shadow: 1px 1px #fff; -} \ No newline at end of file + margin:0 -5px; + min-width: 80px; +} + +.edit-btn { + background: inherit; + padding:0 2px; + text-align: right; +} diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html index 125c101a..efd48216 100644 --- a/modules-available/locations/templates/locations.html +++ b/modules-available/locations/templates/locations.html @@ -31,21 +31,11 @@ - - - + {{#plugins}} - + {{/plugins}} {{#list}} @@ -61,85 +51,30 @@ {{/show-only}} - - - - - + {{/plugins}} {{/list}} - {{#unassignedCount}} - - - - + {{/plugins}} - {{/unassignedCount}}
{{lang_locationName}} - {{#havestatistics}}{{lang_machineCount}}{{/havestatistics}} - - {{#havestatistics}}{{lang_machineLoad}}{{/havestatistics}} - - {{#havebaseconfig}}{{lang_editConfigVariables}}{{/havebaseconfig}} - - {{#havesysconfig}}{{lang_sysConfig}}{{/havesysconfig}} - - {{#haveipxe}}{{lang_bootMenu}}{{/haveipxe}} + {{header}}
- {{#havestatistics}} -  {{clientCount}}  - - {{#hasChild}} - (↓{{clientCountSum}}) - {{/hasChild}} - - {{/havestatistics}} - - {{#clientCount}} - {{clientLoad}} % - {{/clientCount}} - - {{#havebaseconfig}} -
- -
- {{#overriddenVars}} - - {{.}} - - {{/overriddenVars}} - {{#machineVarsOverrideCount}} - - {{.}} - - {{/machineVarsOverrideCount}} -    - {{/havebaseconfig}} -
- {{#havesysconfig}} -
- -
- - {{configName}}   - - {{/havesysconfig}} -
- {{#haveipxe}} -
- -
- - {{customMenu}}   - - {{/haveipxe}} + {{#plugins}} +
+ + + {{#url}} + + {{/url}} +
{{{html}}} + + + +
{{lang_unassignedMachines}} - -  {{unassignedCount}}  - - - - {{#unassignedCount}} - {{unassignedLoad}} % - {{/unassignedCount}} - - {{#unassignedOverrides}} - - {{.}} - - {{/unassignedOverrides}} + {{#plugins}} + + {{{propagateDefaultHtml}}} {{defaultConfig}}
@@ -214,7 +149,7 @@ function slxOpenLocation(e, lid) { } return; } - var td = $('').attr('colspan', '6').css('padding', '0px 0px 12px'); + var td = $('').attr('colspan', '{{colspan}}').css('padding', '0px 0px 12px'); var tr = $('').attr('id', 'location-details-' + lid); tr.append(td); $(e).closest('tr').addClass('active slx-bold').after(tr); -- cgit v1.2.3-55-g7522