From a6a484ea37aeb91f848c11cb818e2d7d4351d391 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Wed, 22 Jun 2016 17:56:04 +0200
Subject: [locations/sysconfig] Implement location specific sysconfig
---
modules-available/locations/inc/location.inc.php | 8 +-
modules-available/locations/page.inc.php | 54 ++++-
.../locations/templates/locations.html | 35 +++-
modules-available/sysconfig/api.inc.php | 78 +++++++
modules-available/sysconfig/clientscript.js | 62 ++++++
modules-available/sysconfig/inc/sysconfig.inc.php | 17 ++
modules-available/sysconfig/install.inc.php | 6 +
modules-available/sysconfig/page.inc.php | 160 +++++++++++----
modules-available/sysconfig/templates/_page.html | 227 ---------------------
.../sysconfig/templates/list-configs.html | 115 +++++++++++
.../sysconfig/templates/list-legend.html | 44 ++++
.../sysconfig/templates/list-modules.html | 59 ++++++
style/default.css | 4 +
13 files changed, 589 insertions(+), 280 deletions(-)
create mode 100644 modules-available/sysconfig/api.inc.php
create mode 100644 modules-available/sysconfig/inc/sysconfig.inc.php
create mode 100644 modules-available/sysconfig/templates/list-configs.html
create mode 100644 modules-available/sysconfig/templates/list-legend.html
create mode 100644 modules-available/sysconfig/templates/list-modules.html
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 788fc588..b1474279 100644
--- a/modules-available/locations/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -64,7 +64,7 @@ class Location
return $output;
}
- public static function getLocations($selected = 0, $excludeId = 0, $addNoParent = false)
+ public static function getLocations($selected = 0, $excludeId = 0, $addNoParent = false, $keepArrayKeys = false)
{
if (is_string($selected)) {
settype($selected, 'int');
@@ -99,6 +99,8 @@ class Location
'selected' => $selected === 0
));
}
+ if ($keepArrayKeys)
+ return $rows;
return array_values($rows);
}
@@ -129,14 +131,14 @@ class Location
}
$output = array();
foreach ($tree as $node) {
- $output[] = array(
+ $output[(int)$node['locationid']] = array(
'locationid' => $node['locationid'],
'locationname' => $node['locationname'],
'locationpad' => str_repeat('--', $depth),
'depth' => $depth
);
if (!empty($node['children'])) {
- $output = array_merge($output, self::flattenTree($node['children'], $depth + 1));
+ $output += self::flattenTree($node['children'], $depth + 1);
}
}
return $output;
diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php
index 84bc11a9..de724350 100644
--- a/modules-available/locations/page.inc.php
+++ b/modules-available/locations/page.inc.php
@@ -166,7 +166,6 @@ class Page_Locations extends Page
}
}
// Now actual updates
- // TODO: Warn on mismatch/overlap (should lie entirely in parent's subnet, not overlap with others)
$starts = Request::post('startaddr', false);
$ends = Request::post('endaddr', false);
if (!is_array($starts) || !is_array($ends)) {
@@ -263,7 +262,8 @@ class Page_Locations extends Page
{
$overlapSelf = $overlapOther = true;
$subnets = Location::getSubnetsByLocation($overlapSelf, $overlapOther);
- $locs = Location::getLocations();
+ $locs = Location::getLocations(0, 0, false, true);
+ // Statistics: Count machines for each subnet
$unassigned = false;
if (Module::get('statistics') !== false) {
foreach ($locs as &$location) {
@@ -289,15 +289,61 @@ class Page_Locations extends Page
$unassigned = $res['cnt'];
}
unset($loc, $location);
+ // Show currently active sysconfig for each location
+ $defaultConfig = false;
+ if (Module::isAvailable('sysconfig')) {
+ $confs = SysConfig::getAll();
+ foreach ($confs as $conf) {
+ $confLocs = explode(',', $conf['locs']);
+ foreach ($confLocs as $loc) {
+ settype($loc, 'int');
+ if ($loc === 0) {
+ $defaultConfig = $conf['title'];
+ }
+ if (!isset($locs[$loc]))
+ continue;
+ $locs[$loc] += array('configName' => $conf['title'], 'configClass' => 'slx-bold');
+ }
+ }
+ $depth = array();
+ foreach ($locs as &$loc) {
+ $d = $loc['depth'];
+ if (!isset($loc['configName'])) {
+ // Has no explicit config assignment
+ if ($d === 0) {
+ $loc['configName'] = $defaultConfig;
+ } else {
+ $loc['configName'] = $depth[$d - 1];
+ }
+ $loc['configClass'] = 'gray';
+ }
+ $depth[$d] = $loc['configName'];
+ unset($depth[$d + 1]);
+ }
+ unset($loc);
+ }
+ // Count overridden config vars
+ if (Module::get('baseconfig') !== false) {
+ $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM `setting_location` GROUP BY locationid");
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $lid = (int)$row['locationid'];
+ if (isset($locs[$lid])) {
+ $locs[$lid]['overriddenVars'] = $row['cnt'];
+ }
+ }
+ }
+ // Output
Render::addTemplate('locations', array(
- 'list' => $locs,
+ 'list' => array_values($locs),
'havestatistics' => Module::get('statistics') !== false,
'havebaseconfig' => Module::get('baseconfig') !== false,
+ 'havesysconfig' => Module::get('sysconfig') !== false,
'overlapSelf' => $overlapSelf,
'overlapOther' => $overlapOther,
'haveOverlapSelf' => !empty($overlapSelf),
'haveOverlapOther' => !empty($overlapOther),
- 'unassignedCount' => $unassigned
+ 'unassignedCount' => $unassigned,
+ 'defaultConfig' => $defaultConfig,
));
}
diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html
index e8b5d707..11142ef8 100644
--- a/modules-available/locations/templates/locations.html
+++ b/modules-available/locations/templates/locations.html
@@ -6,34 +6,59 @@
{{lang_locationName}} |
- |
+ {{#havestatistics}}{{lang_machineCount}}{{/havestatistics}} |
+ {{lang_editConfigVariables}} |
+ {{#havesysconfig}}
+
+ {{#havebaseconfig}}{{lang_sysConfig}}{{/havebaseconfig}}
+ |
+ {{/havesysconfig}}
{{#list}}
- {{locationname}}
+ {{locationname}}
|
{{#havestatistics}}
{{clientCount}}
{{/havestatistics}}
+ |
+
{{#havebaseconfig}}
- {{lang_editConfigVariables}}
+
+ {{#overriddenVars}}
+ {{lang_overrideCount}}: {{overriddenVars}}
+ {{/overriddenVars}}
{{/havebaseconfig}}
|
+
+
+
+ {{configName}}
+
+ {{#havesysconfig}}
+ {{/havesysconfig}}
+ |
{{/list}}
{{#unassignedCount}}
- |
+ {{lang_unassignedMachines}} |
- {{lang_unassignedMachines}}: {{unassignedCount}}
+ {{unassignedCount}}
|
+ |
+ {{defaultConfig}} |
{{/unassignedCount}}
diff --git a/modules-available/sysconfig/api.inc.php b/modules-available/sysconfig/api.inc.php
new file mode 100644
index 00000000..556e99f3
--- /dev/null
+++ b/modules-available/sysconfig/api.inc.php
@@ -0,0 +1,78 @@
+fetch(PDO::FETCH_ASSOC)) {
+ settype($r['locationid'], 'int');
+ $index = array_search($r['locationid'], $locationChain);
+ if ($index === false || $index > $best)
+ continue;
+ if (!file_exists($r['filepath'])) {
+ if ($r['locationid'] === 0) {
+ EventLog::failure("The global config.tgz '{$r['title']}' was not found at '{$r['filepath']}'. Please regenerate the system configuration");
+ } else {
+ EventLog::warning("config.tgz '{$r['title']}' for location $locationId not found at '{$r['filepath']}', trying fallback....");
+ }
+ continue;
+ }
+ $best = $index;
+ $row = $r;
+}
+
+if ($row === false) {
+ // TODO Not found in DB
+ deliverEmpty("No config.tgz for location $locationId found");
+}
+
+if (!file_exists($row['filepath'])) {
+ // TODO Does not exist
+ deliverEmpty();
+}
+
+Header('Content-Type: application/gzip');
+Header('Content-Disposition: attachment; filename=' . Util::sanitizeFilename($row['title']) . '.tgz');
+$ret = readfile($row['filepath']);
+
+if ($ret === false || $ret === 0) {
+ // TODO didn't send anything/everything
+ // Cannot deliver empty, don't know what has been send already
+ EventLog::warning("Could not deliver config.tgz to client $ip: readfile() returned " . ($ret === false ? 'false' : $ret));
+}
+
+exit;
\ No newline at end of file
diff --git a/modules-available/sysconfig/clientscript.js b/modules-available/sysconfig/clientscript.js
index 2a133353..47761ea5 100644
--- a/modules-available/sysconfig/clientscript.js
+++ b/modules-available/sysconfig/clientscript.js
@@ -1,4 +1,6 @@
+// Ugly hack to get the ellipsisized fields to work
+
function forceTable(t)
{
var pwidth = t.parent().innerWidth();
@@ -19,3 +21,63 @@ function forceTable(t)
w -= 3;
} while (t.width() > pwidth);
}
+
+// Mouseover and clicking
+
+var boldItem = false;
+
+function showmod(e, action) {
+ var list = $(e).attr('data-modlist');
+ list = list.split(',');
+ if (action === 'bold') {
+ $(boldItem).removeClass("slx-bold");
+ if (boldItem === e) {
+ action = 'fade';
+ boldItem = false;
+ }
+ } else if (boldItem !== false) {
+ return;
+ }
+ $('.modrow').each(function () {
+ var elem = $(this);
+ elem.removeClass("slx-fade slx-bold");
+ if (action === 'reset')
+ return;
+ if (action === 'bold' && list.indexOf(elem.attr('data-id')) !== -1)
+ elem.addClass("slx-bold");
+ if (list.indexOf(elem.attr('data-id')) === -1)
+ elem.addClass("slx-fade");
+ });
+ if (action === 'bold') {
+ boldItem = e;
+ $(e).addClass("slx-bold");
+ }
+}
+
+// Polling for updated status (outdated, missing, ok)
+
+var statusChecks = 0;
+
+function checkBuildStatus() {
+ var mods = [];
+ var confs = [];
+ $(".refmod.btn-primary").each(function (index) {
+ mods.push($(this).val());
+ });
+ $(".refconf.btn-primary").each(function (index) {
+ confs.push($(this).val());
+ });
+ if (mods.length === 0 && confs.length === 0) return;
+ if (++statusChecks < 10) setTimeout(checkBuildStatus, 200 + 50 * statusChecks);
+ $.post('?do=SysConfig', { mods: mods.join(), confs: confs.join(), token: TOKEN, action: 'status' }, function (data) {
+ if (typeof data === 'undefined') return;
+ if (typeof data.mods === 'object') updateButtonColor($(".refmod.btn-primary"), data.mods);
+ if (typeof data.confs === 'object') updateButtonColor($(".refconf.btn-primary"), data.confs);
+ }, 'json');
+}
+
+function updateButtonColor(list,ids) {
+ list.each(function() {
+ if (ids.indexOf($(this).val()) >= 0) $(this).removeClass('btn-primary').addClass('btn-default');
+ });
+}
diff --git a/modules-available/sysconfig/inc/sysconfig.inc.php b/modules-available/sysconfig/inc/sysconfig.inc.php
new file mode 100644
index 00000000..15bd4104
--- /dev/null
+++ b/modules-available/sysconfig/inc/sysconfig.inc.php
@@ -0,0 +1,17 @@
+fetch(PDO::FETCH_ASSOC)) {
+ $ret[] = $row;
+ }
+ return $ret;
+ }
+
+}
\ No newline at end of file
diff --git a/modules-available/sysconfig/install.inc.php b/modules-available/sysconfig/install.inc.php
index 35697d1f..0cde39c2 100644
--- a/modules-available/sysconfig/install.inc.php
+++ b/modules-available/sysconfig/install.inc.php
@@ -30,6 +30,12 @@ $res[] = tableCreate('configtgz_x_module', "
KEY `moduleid` (`moduleid`)
");
+$res[] = tableCreate('configtgz_location', "
+ `locationid` int(11) NOT NULL,
+ `configid` int(10) unsigned NOT NULL,
+ PRIMARY KEY (`locationid`),
+ KEY `configid` (`configid`)
+");
// Constraints
if (in_array(UPDATE_DONE, $res)) {
diff --git a/modules-available/sysconfig/page.inc.php b/modules-available/sysconfig/page.inc.php
index 121e4cee..9bf9cacd 100644
--- a/modules-available/sysconfig/page.inc.php
+++ b/modules-available/sysconfig/page.inc.php
@@ -9,6 +9,18 @@ class Page_SysConfig extends Page
*/
protected static $moduleTypes = array();
+ /**
+ * @var int current locationid, 0 if global
+ */
+ private $currentLoc;
+
+ /**
+ * @var array Associative list of known locations
+ */
+ private $locations;
+
+ private $haveOverriddenLocations = false;
+
/**
* Add a known configuration module. Every addmoule_* file should call this
* for its module provided.
@@ -51,6 +63,22 @@ class Page_SysConfig extends Page
Util::redirect('?do=Main');
}
+ // Determine location we're editing
+ if (!Module::isAvailable('locations')) {
+ $this->locations = array();
+ $this->currentLoc = 0;
+ } else {
+ $this->locations = Location::getLocationsAssoc();
+ $this->currentLoc = Request::any('locationid', 0, 'int');
+ }
+ // Location valid?
+ if ($this->currentLoc !== 0 && !isset($this->locations[$this->currentLoc])) {
+ Message::addError('locations.invalid-location-id', $this->currentLoc);
+ Util::redirect('?do=sysconfig');
+ }
+
+ // Action handling
+
$action = Request::any('action', 'list');
// Load all addmodule classes, as they populate the $moduleTypes array
@@ -115,7 +143,13 @@ class Page_SysConfig extends Page
AddConfig_Base::render();
return;
case 'list':
+ Render::openTag('div', array('class' => 'row'));
$this->listConfigs();
+ if ($this->currentLoc === 0) {
+ $this->listModules();
+ }
+ Render::closeTag('div');
+ Render::addTemplate('list-legend', array('showLocationBadge' => $this->haveOverriddenLocations));
return;
case 'module':
$listid = Request::post('list');
@@ -135,27 +169,79 @@ class Page_SysConfig extends Page
Message::addError('invalid-action', $action, 'main');
}
+ private function getLocationNames($locations, $ids)
+ {
+ $ret = array();
+ foreach ($ids as $id) {
+ settype($id, 'int');
+ if (isset($locations[$id])) {
+ $ret[] = $locations[$id]['locationname'];
+ }
+ }
+ return implode(', ', $ret);
+ }
+
/**
* List all configurations and configuration modules.
*/
private function listConfigs()
{
// Configs
- $res = Database::simpleQuery("SELECT configtgz.configid, configtgz.title, configtgz.filepath, configtgz.status, GROUP_CONCAT(configtgz_x_module.moduleid) AS modlist"
- . " FROM configtgz"
- . " INNER JOIN configtgz_x_module USING (configid)"
+ $res = Database::simpleQuery("SELECT c.configid, c.title, c.filepath, c.status,"
+ . " GROUP_CONCAT(DISTINCT cl.locationid) AS loclist, GROUP_CONCAT(cxm.moduleid) AS modlist"
+ . " FROM configtgz c"
+ . " INNER JOIN configtgz_x_module cxm USING (configid)"
+ . " LEFT JOIN configtgz_location cl ON (c.configid = cl.configid)"
. " GROUP BY configid"
. " ORDER BY title ASC");
$configs = array();
+ if ($this->currentLoc !== 0) {
+ $locationName = $this->locations[$this->currentLoc]['locationname'];
+ } else {
+ $locationName = false;
+ }
+ $hasDefault = false;
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (is_null($row['loclist'])) {
+ $locList = array();
+ } else {
+ $locList = explode(',', $row['loclist']);
+ }
+ $isDefault = in_array((string)$this->currentLoc, $locList, true);
+ $hasDefault |= $isDefault;
+ if ($this->currentLoc !== 0) {
+ $locCount = 0;
+ } else {
+ $locCount = count($locList);
+ if ($isDefault) {
+ $locCount--;
+ }
+ }
+ if ($locCount > 0) {
+ $this->haveOverriddenLocations = true;
+ }
$configs[] = array(
'configid' => $row['configid'],
'config' => $row['title'],
'modlist' => $row['modlist'],
- 'current' => readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $row['filepath'],
+ 'current' => $isDefault,
+ 'loclist' => $row['loclist'],
+ 'readableLocList' => $this->getLocationNames($this->locations, $locList),
+ 'locationCount' => $locCount,
'needrebuild' => ($row['status'] !== 'OK')
);
}
+ Render::addTemplate('list-configs', array(
+ 'locationid' => $this->currentLoc,
+ 'locationname' => $locationName,
+ 'havelocations' => Module::isAvailable('locations'),
+ 'configs' => $configs,
+ 'inheritConfig' => !$hasDefault,
+ ));
+ }
+
+ private function listModules()
+ {
// Config modules
$res = Database::simpleQuery("SELECT moduleid, title, moduletype, status FROM configtgz_module ORDER BY moduletype ASC, title ASC");
$modules = array();
@@ -168,15 +254,10 @@ class Page_SysConfig extends Page
'needrebuild' => ($row['status'] !== 'OK')
);
}
- Render::addTemplate('_page', array(
- 'configs' => $configs,
+ Render::addTemplate('list-modules', array(
'modules' => $modules,
'havemodules' => (count($modules) > 0)
));
- Render::addFooter('');
}
private function listModuleContents($moduleid)
@@ -185,7 +266,7 @@ class Page_SysConfig extends Page
$row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
if ($row === false) {
Message::addError('config-invalid', $moduleid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
// find files in that archive
@@ -196,7 +277,7 @@ class Page_SysConfig extends Page
$status = Taskmanager::waitComplete($status, 4000);
if (!Taskmanager::isFinished($status) || Taskmanager::isFailed($status)) {
Taskmanager::addErrorMessage($status);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
// Sort files for better display
@@ -232,7 +313,7 @@ class Page_SysConfig extends Page
$config = Database::queryFirst("SELECT title FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid));
if ($config === false) {
Message::addError('config-invalid', $configid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
// fetch the data
$res = Database::simpleQuery("SELECT module.moduleid, module.title AS moduletitle"
@@ -257,25 +338,22 @@ class Page_SysConfig extends Page
private function activateConfig()
{
- $configid = Request::post('activate', 'MISSING');
- $row = Database::queryFirst("SELECT title, filepath FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid));
- if ($row === false) {
- Message::addError('config-invalid', $configid);
- Util::redirect('?do=SysConfig');
+ $configid = Request::post('activate', false, 'int');
+ if ($configid === false) {
+ Message::addError('main.empty-field');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
- $task = Taskmanager::submit('LinkConfigTgz', array(
- 'destination' => $row['filepath']
- ));
- if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) {
- $task = Taskmanager::waitComplete($task['id']);
- }
- if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) {
- Message::addError('main.task-error', $task['data']['error']);
- } elseif ($task['statusCode'] === TASK_FINISHED) {
- Message::addSuccess('config-activated', $row['title']);
- Event::activeConfigChanged();
+ if ($this->currentLoc === 0 || $configid !== 0) {
+ $row = Database::queryFirst("SELECT title, filepath FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid));
+ if ($row === false) {
+ Message::addError('config-invalid', $configid);
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
+ }
}
- Util::redirect('?do=SysConfig');
+ $locationid = $this->currentLoc;
+ Database::exec("INSERT INTO configtgz_location (locationid, configid) VALUES (:locationid, :configid)"
+ . " ON DUPLICATE KEY UPDATE configid = :configid", compact('locationid', 'configid'));
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
private function rebuildConfig()
@@ -284,7 +362,7 @@ class Page_SysConfig extends Page
$config = ConfigTgz::get($configid);
if ($config === false) {
Message::addError('config-invalid', $configid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
$ret = $config->generate(false, 350); // TODO
if ($ret === true)
@@ -293,7 +371,7 @@ class Page_SysConfig extends Page
Message::addError('module-rebuild-failed', $config->title());
else
Message::addInfo('module-rebuilding', $config->title());
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
private function delModule()
@@ -302,14 +380,14 @@ class Page_SysConfig extends Page
$row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
if ($row === false) {
Message::addError('config-invalid', $moduleid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
$existing = Database::queryFirst("SELECT title FROM configtgz_x_module"
. " INNER JOIN configtgz USING (configid)"
. " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
if ($existing !== false) {
Message::addError('module-in-use', $row['title'], $existing['title']);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
$task = Taskmanager::submit('DeleteFile', array(
'file' => $row['filepath']
@@ -323,7 +401,7 @@ class Page_SysConfig extends Page
Message::addSuccess('module-deleted', $row['title']);
}
Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
private function downloadModule()
@@ -332,10 +410,10 @@ class Page_SysConfig extends Page
$row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
if ($row === false) {
Message::addError('config-invalid', $moduleid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
if (!Util::sendFile($row['filepath'], $row['title'] . '.tgz'))
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
exit(0);
}
@@ -345,7 +423,7 @@ class Page_SysConfig extends Page
$module = ConfigModule::get($moduleid);
if ($module === false) {
Message::addError('config-invalid', $moduleid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
$ret = $module->generate(false, 250);
if ($ret === true)
@@ -354,7 +432,7 @@ class Page_SysConfig extends Page
Message::addError('module-rebuild-failed', $module->title());
else
Message::addInfo('module-rebuilding', $module->title());
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig');
}
private function delConfig()
@@ -363,10 +441,10 @@ class Page_SysConfig extends Page
$config = ConfigTgz::get($configid);
if ($config === false) {
Message::addError('config-invalid', $configid);
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
$config->delete();
- Util::redirect('?do=SysConfig');
+ Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc);
}
private function initAddModule()
diff --git a/modules-available/sysconfig/templates/_page.html b/modules-available/sysconfig/templates/_page.html
index 1a2f64d6..e69de29b 100644
--- a/modules-available/sysconfig/templates/_page.html
+++ b/modules-available/sysconfig/templates/_page.html
@@ -1,227 +0,0 @@
-
-
-
-
- {{lang_availableSystem}}
-
-
-
- {{#havemodules}}
-
- {{/havemodules}}
-
-
-
-
-
-
- {{lang_availableModules}}
-
-
-
-
-
-
-
-
-
-
{{lang_legend}}
-
-
-
- {{lang_showLong}}
-
-
-
- {{lang_downloadLong}}
-
-
-
- {{lang_rebuildLong}}
-
-
-
- {{lang_rebuildOutdatedLong}}
-
-
-
- {{lang_editLong}}
-
-
-
- {{lang_deleteLong}}
-
-
-
-
-
-
-
-
-
- {{lang_helpSystemConfiguration}}
-
-
-
-
-
-
-
-
-
-
-
- {{lang_helpModuleConfiguration}}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/modules-available/sysconfig/templates/list-configs.html b/modules-available/sysconfig/templates/list-configs.html
new file mode 100644
index 00000000..ed027385
--- /dev/null
+++ b/modules-available/sysconfig/templates/list-configs.html
@@ -0,0 +1,115 @@
+{{#locationid}}
+
+
{{locationname}}
+
+
+ {{lang_editingLocationInfo}}
+
+
+{{/locationid}}
+
+
+
+ {{lang_availableSystem}}
+
+
+
+
+
+
+
+
+
+
+
+ {{lang_helpSystemConfiguration}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules-available/sysconfig/templates/list-legend.html b/modules-available/sysconfig/templates/list-legend.html
new file mode 100644
index 00000000..090ef526
--- /dev/null
+++ b/modules-available/sysconfig/templates/list-legend.html
@@ -0,0 +1,44 @@
+
+
{{lang_legend}}
+
+
+
+ {{lang_showLong}}
+
+
+
+ {{lang_downloadLong}}
+
+
+
+ {{lang_rebuildLong}}
+
+
+
+ {{lang_rebuildOutdatedLong}}
+
+
+
+ {{lang_editLong}}
+
+
+
+ {{lang_deleteLong}}
+
+ {{#showLocationBadge}}
+
+ +4
+ {{lang_configLocationLong}}
+
+ {{/showLocationBadge}}
+
+
+
+
\ No newline at end of file
diff --git a/modules-available/sysconfig/templates/list-modules.html b/modules-available/sysconfig/templates/list-modules.html
new file mode 100644
index 00000000..c3e2d736
--- /dev/null
+++ b/modules-available/sysconfig/templates/list-modules.html
@@ -0,0 +1,59 @@
+
+
+
+ {{lang_availableModules}}
+
+
+
+
+
+
+
+
+
+
+
+ {{lang_helpModuleConfiguration}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/style/default.css b/style/default.css
index 9b93bfda..0fa8fe26 100644
--- a/style/default.css
+++ b/style/default.css
@@ -107,6 +107,10 @@ body {
color: #0b0;
}
+.gray {
+ color: gray;
+}
+
.slx-label {
font-weight: bold;
margin: auto;
--
cgit v1.2.3-55-g7522