diff options
author | Simon Rettberg | 2016-06-22 17:56:04 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-06-22 17:56:04 +0200 |
commit | a6a484ea37aeb91f848c11cb818e2d7d4351d391 (patch) | |
tree | 03cc7b9df8dabf61bdb1bc84137601ce187339ef /modules-available/sysconfig | |
parent | [location] Support passing array of selected locs to getLocations() (diff) | |
download | slx-admin-a6a484ea37aeb91f848c11cb818e2d7d4351d391.tar.gz slx-admin-a6a484ea37aeb91f848c11cb818e2d7d4351d391.tar.xz slx-admin-a6a484ea37aeb91f848c11cb818e2d7d4351d391.zip |
[locations/sysconfig] Implement location specific sysconfig
Diffstat (limited to 'modules-available/sysconfig')
-rw-r--r-- | modules-available/sysconfig/api.inc.php | 78 | ||||
-rw-r--r-- | modules-available/sysconfig/clientscript.js | 62 | ||||
-rw-r--r-- | modules-available/sysconfig/inc/sysconfig.inc.php | 17 | ||||
-rw-r--r-- | modules-available/sysconfig/install.inc.php | 6 | ||||
-rw-r--r-- | modules-available/sysconfig/page.inc.php | 160 | ||||
-rw-r--r-- | modules-available/sysconfig/templates/_page.html | 227 | ||||
-rw-r--r-- | modules-available/sysconfig/templates/list-configs.html | 115 | ||||
-rw-r--r-- | modules-available/sysconfig/templates/list-legend.html | 44 | ||||
-rw-r--r-- | modules-available/sysconfig/templates/list-modules.html | 59 |
9 files changed, 500 insertions, 268 deletions
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 @@ +<?php + +$ip = $_SERVER['REMOTE_ADDR']; +if (substr($ip, 0, 7) === '::ffff:') { + $ip = substr($ip, 7); +} + +$uuid = Request::any('uuid', false, 'string'); +if ($uuid !== false && strlen($uuid) !== 36) { + $uuid = false; +} +$locationId = false; +if (Module::isAvailable('locations')) { + $locationId = Location::getFromIpAndUuid($ip, $uuid); + if ($locationId !== false) { + $locationChain = Location::getLocationRootChain($locationId); + $locationChain[] = 0; + } +} +if ($locationId === false) { + $locationId = 0; + $locationChain = array(0); +} + +// What we do if we can't supply the requested config +function deliverEmpty($message) +{ + EventLog::failure($message); + Header('HTTP/1.1 404 Not found'); + die('Config file could not be found or read!'); +} + +// Get config module path + +// We get all the configs for the whole location chain up to root +$res = Database::simpleQuery("SELECT c.title, c.filepath, c.status, cl.locationid FROM configtgz c" + . " INNER JOIN configtgz_location cl USING (configid)" + . " WHERE cl.locationid IN (" . implode(',', $locationChain) . ")"); +$best = 1000; +$row = false; +while ($r = $res->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 @@ +<?php + +class SysConfig +{ + + public static function getAll() + { + $res = Database::simpleQuery("SELECT c.configid, c.title, c.filepath, c.status, Group_Concat(cl.locationid) AS locs FROM configtgz c" + . " LEFT JOIN configtgz_location cl USING (configid) GROUP BY c.configid"); + $ret = array(); + while ($row = $res->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 @@ -10,6 +10,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('<script> $(window).load(function (e) { - forceTable($("#modtable")); - forceTable($("#conftable")); - }); // </script>'); } 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 @@ -<div class="row"> - <div class="col-md-6"> - <div class="panel panel-default"> - <div class="panel-heading"> - {{lang_availableSystem}} - <a class="btn btn-default" data-toggle="modal" data-target="#help-config"><span class="glyphicon glyphicon-question-sign"></span></a> - </div> - <div class="panel-body"> - <form method="post" action="?do=SysConfig"> - <input type="hidden" name="token" value="{{token}}"> - <input type="hidden" name="action" value="config"> - <table id="conftable" class="slx-table" style="max-width:100px !important"> - {{#configs}} - <tr> - <td data-modlist="{{modlist}}" class="slx-pointer slx-width-ignore slx-nowrap"onclick="showmod(this, 'bold')" onmouseover="showmod(this, 'fade')" onmouseout="showmod(this, 'reset')"> - <div class="slx-dyn-ellipsis">{{config}}</div> - </td> - <td> - {{^current}} - <button class="btn btn-primary btn-xs" name="activate" value="{{configid}}"> - <span class="glyphicon glyphicon-flag"></span> - {{lang_activate}} - </button> - {{/current}} - {{#current}} - <span class="btn btn-success btn-xs slx-nopointer"> - <span class="glyphicon glyphicon-ok"></span> - {{lang_active}} - </span> - {{/current}} - </td> - <td class="slx-nowrap"> - <button - {{#needrebuild}} - class="refconf btn btn-primary btn-xs" - {{/needrebuild}} - {{^needrebuild}} - class="refconf btn btn-default btn-xs" - {{/needrebuild}} - name="rebuild" value="{{configid}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button> - </td> - <td class="slx-nowrap"> - <a class="btn btn-success btn-xs" href="?do=SysConfig&action=addconfig&edit={{configid}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a> - <button class="btn btn-danger btn-xs" name="del" value="{{configid}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button> - </td> - </tr> - {{/configs}} - </table> - {{^configs}} - <div class="alert alert-warning"> - {{lang_systemConfigurationNotFound}} - </div> - {{^modules}} - <div class="alert alert-danger"> - {{lang_systemConfigurationAlert}} - </div> - {{/modules}} - {{/configs}} - </form> - </div> - {{#havemodules}} - <div class="panel-footer"> - <a class="btn btn-primary" href="?do=SysConfig&action=addconfig">{{lang_newConfiguration}}</a> - </div> - {{/havemodules}} - </div> - </div> - - <div class="col-md-6"> - <div class="panel panel-default"> - <div class="panel-heading"> - {{lang_availableModules}} - <a class="btn btn-default" data-toggle="modal" data-target="#help-module"><span class="glyphicon glyphicon-question-sign"></span></a> - </div> - <div class="panel-body"> - <form method="post" action="?do=SysConfig"> - <input type="hidden" name="token" value="{{token}}"> - <input type="hidden" name="action" value="module"> - <table id="modtable" class="slx-table" style="max-width:100px !important"> - {{#modules}} - <tr> - <td class="badge slx-nowrap">{{moduletype}}</td> - <td data-id="{{moduleid}}" class="modrow slx-width-ignore slx-nowrap"><div class="slx-dyn-ellipsis">{{module}}</div></td> - <td class="slx-nowrap"> - {{#iscustom}} - <button class="btn btn-default btn-xs" name="list" value="{{moduleid}}" title="{{lang_show}}"><span class="glyphicon glyphicon-eye-open"></span></button> - <!-- a class="btn btn-default btn-xs"><span class="glyphicon glyphicon-edit"></span> Bearbeiten</a --> - <button class="btn btn-default btn-xs" name="download" value="{{moduleid}}" title="{{lang_download}}"><span class="glyphicon glyphicon-download-alt"></span></button> - {{/iscustom}} - </td> - <td class="slx-nowrap"> - <button - {{#needrebuild}} - class="refmod btn btn-primary btn-xs" - {{/needrebuild}} - {{^needrebuild}} - class="refmod btn btn-default btn-xs" - {{/needrebuild}} - name="rebuild" value="{{moduleid}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button> - <a class="btn btn-success btn-xs" href="?do=SysConfig&action=addmodule&step={{moduletype}}_Start&edit={{moduleid}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a> - <button class="btn btn-danger btn-xs" name="del" value="{{moduleid}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button> - </td> - </tr> - {{/modules}} - </table> - {{^modules}} - <div class="alert alert-warning">{{lang_configurationModuleNotFound}}</div> - {{/modules}} - </form> - </div> - <div class="panel-footer"> - <a class="btn btn-primary" href="?do=SysConfig&action=addmodule">{{lang_newModule}}</a> - </div> - </div> - </div> -</div> - -<div class="panel panel-default"> - <div class="panel-heading">{{lang_legend}}</div> - <div class="panel-body"> - <p> - <span class="btn btn-default btn-xs" title="{{lang_show}}"><span class="glyphicon glyphicon-eye-open"></span></span> - {{lang_showLong}} - </p> - <p> - <span class="btn btn-default btn-xs" title="{{lang_download}}"><span class="glyphicon glyphicon-download-alt"></span></span> - {{lang_downloadLong}} - </p> - <p> - <span class="btn btn-default btn-xs" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></span> - {{lang_rebuildLong}} - </p> - <p> - <span class="btn btn-primary btn-xs" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></span> - {{lang_rebuildOutdatedLong}} - </p> - <p> - <span class="btn btn-success btn-xs" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></span> - {{lang_editLong}} - </p> - <div> - <span class="btn btn-danger btn-xs" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></span> - {{lang_deleteLong}} - </div> - </div> -</div> - -<div class="modal fade" id="help-config" tabindex="-1" role="dialog"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header">{{lang_systemConfiguration}}</div> - <div class="modal-body"> - {{lang_helpSystemConfiguration}} - </div> - <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> - </div> - </div> -</div> - -<div class="modal fade" id="help-module" tabindex="-1" role="dialog"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header">{{lang_moduleConfiguration}}</div> - <div class="modal-body"> - {{lang_helpModuleConfiguration}} - </div> - <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> - </div> - </div> -</div> - -<script type="text/javascript"><!-- - 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"); - } - } - - 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); - console.log("POSTING"); - $.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'); - }); - } - document.addEventListener("DOMContentLoaded", checkBuildStatus, false); -// --></script>
\ 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}} +<div class="col-md-12"> + <h1>{{locationname}}</h1> + <div class="alert alert-info"> + <span class="glyphicon glyphicon-exclamation-sign"></span> + {{lang_editingLocationInfo}} + </div> +</div> +{{/locationid}} +<div class="col-md-6"> + <div class="panel panel-default"> + <div class="panel-heading"> + {{lang_availableSystem}} + <a class="btn btn-default" data-toggle="modal" data-target="#help-config"><span class="glyphicon glyphicon-question-sign"></span></a> + </div> + <div class="panel-body"> + <form method="post" action="?do=SysConfig"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="config"> + <input type="hidden" name="locationid" value="{{locationid}}"> + <table id="conftable" class="slx-table" style="max-width:100px !important"> + {{#configs}} + <tr> + <td data-modlist="{{modlist}}" class="slx-pointer slx-width-ignore slx-nowrap"onclick="showmod(this, 'bold')" onmouseover="showmod(this, 'fade')" onmouseout="showmod(this, 'reset')" width="100%"> + <div class="slx-dyn-ellipsis">{{config}}</div> + </td> + <td> + {{^current}} + <button class="btn btn-primary btn-xs" name="activate" value="{{configid}}"> + <span class="glyphicon glyphicon-flag"></span> + {{lang_activate}} + </button> + {{/current}} + {{#current}} + <span class="btn btn-success btn-xs slx-nopointer"> + <span class="glyphicon glyphicon-ok"></span> + {{lang_active}} + </span> + {{/current}} + </td> + <td> + {{#locationCount}} + <span class="badge" {{#readableLocList}} data-toggle="tooltip" data-placement="top" title="{{readableLocList}}" {{/readableLocList}} > + +{{locationCount}} + </span> + {{/locationCount}} + </td> + <td class="slx-nowrap"> + <button + {{#needrebuild}} + class="refconf btn btn-primary btn-xs" + {{/needrebuild}} + {{^needrebuild}} + class="refconf btn btn-default btn-xs" + {{/needrebuild}} + name="rebuild" value="{{configid}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button> + </td> + <td class="slx-nowrap"> + <a class="btn btn-success btn-xs" href="?do=SysConfig&action=addconfig&edit={{configid}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a> + <button class="btn btn-danger btn-xs" name="del" value="{{configid}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button> + </td> + </tr> + {{/configs}} + {{#locationid}} + <tr> + <td><i>Vererben von übergeordnetem Raum</i></td> + <td> + {{^inheritConfig}} + <button class="btn btn-primary btn-xs" name="activate" value="0"> + <span class="glyphicon glyphicon-flag"></span> + {{lang_activate}} + </button> + {{/inheritConfig}} + {{#inheritConfig}} + <span class="btn btn-success btn-xs slx-nopointer"> + <span class="glyphicon glyphicon-ok"></span> + {{lang_active}} + </span> + {{/inheritConfig}} + </td> + <td></td> + <td></td> + </tr> + {{/locationid}} + </table> + {{^configs}} + <div class="alert alert-warning"> + {{lang_systemConfigurationNotFound}} + </div> + {{^modules}} + <div class="alert alert-danger"> + {{lang_systemConfigurationAlert}} + </div> + {{/modules}} + {{/configs}} + </form> + </div> + <div class="panel-footer"> + <a class="btn btn-primary" href="?do=SysConfig&action=addconfig">{{lang_newConfiguration}}</a> + </div> + </div> + + <div class="modal fade" id="help-config" tabindex="-1" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header">{{lang_systemConfiguration}}</div> + <div class="modal-body"> + {{lang_helpSystemConfiguration}} + </div> + <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> + </div> + </div> + </div> + +</div>
\ 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 @@ +<div class="panel panel-default"> + <div class="panel-heading">{{lang_legend}}</div> + <div class="panel-body"> + <p> + <span class="btn btn-default btn-xs" title="{{lang_show}}"><span class="glyphicon glyphicon-eye-open"></span></span> + {{lang_showLong}} + </p> + <p> + <span class="btn btn-default btn-xs" title="{{lang_download}}"><span class="glyphicon glyphicon-download-alt"></span></span> + {{lang_downloadLong}} + </p> + <p> + <span class="btn btn-default btn-xs" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></span> + {{lang_rebuildLong}} + </p> + <p> + <span class="btn btn-primary btn-xs" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></span> + {{lang_rebuildOutdatedLong}} + </p> + <p> + <span class="btn btn-success btn-xs" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></span> + {{lang_editLong}} + </p> + <p> + <span class="btn btn-danger btn-xs" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></span> + {{lang_deleteLong}} + </p> + {{#showLocationBadge}} + <p> + <span class="badge">+4</span> + {{lang_configLocationLong}} + </p> + {{/showLocationBadge}} + </div> +</div> + +<script type="application/javascript"><!-- +document.addEventListener("DOMContentLoaded", function () { + forceTable($("#modtable")); + forceTable($("#conftable")); + checkBuildStatus(); + $('[data-toggle="tooltip"]').tooltip(); +}, false); +// --></script>
\ 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 @@ +<div class="col-md-6"> + <div class="panel panel-default"> + <div class="panel-heading"> + {{lang_availableModules}} + <a class="btn btn-default" data-toggle="modal" data-target="#help-module"><span class="glyphicon glyphicon-question-sign"></span></a> + </div> + <div class="panel-body"> + <form method="post" action="?do=SysConfig"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="module"> + <table id="modtable" class="slx-table" style="max-width:100px !important"> + {{#modules}} + <tr> + <td class="badge slx-nowrap">{{moduletype}}</td> + <td data-id="{{moduleid}}" class="modrow slx-width-ignore slx-nowrap" width="100%"><div class="slx-dyn-ellipsis">{{module}}</div></td> + <td class="slx-nowrap"> + {{#iscustom}} + <button class="btn btn-default btn-xs" name="list" value="{{moduleid}}" title="{{lang_show}}"><span class="glyphicon glyphicon-eye-open"></span></button> + <button class="btn btn-default btn-xs" name="download" value="{{moduleid}}" title="{{lang_download}}"><span class="glyphicon glyphicon-download-alt"></span></button> + {{/iscustom}} + </td> + <td class="slx-nowrap"> + <button + {{#needrebuild}} + class="refmod btn btn-primary btn-xs" + {{/needrebuild}} + {{^needrebuild}} + class="refmod btn btn-default btn-xs" + {{/needrebuild}} + name="rebuild" value="{{moduleid}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button> + <a class="btn btn-success btn-xs" href="?do=SysConfig&action=addmodule&step={{moduletype}}_Start&edit={{moduleid}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a> + <button class="btn btn-danger btn-xs" name="del" value="{{moduleid}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button> + </td> + </tr> + {{/modules}} + </table> + {{^modules}} + <div class="alert alert-warning">{{lang_configurationModuleNotFound}}</div> + {{/modules}} + </form> + </div> + <div class="panel-footer"> + <a class="btn btn-primary" href="?do=SysConfig&action=addmodule">{{lang_newModule}}</a> + </div> + </div> + + <div class="modal fade" id="help-module" tabindex="-1" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header">{{lang_moduleConfiguration}}</div> + <div class="modal-body"> + {{lang_helpModuleConfiguration}} + </div> + <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> + </div> + </div> + </div> + +</div>
\ No newline at end of file |