summaryrefslogtreecommitdiffstats
path: root/modules-available/locations
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/locations')
-rw-r--r--modules-available/locations/inc/location.inc.php3
-rw-r--r--modules-available/locations/lang/de/template-tags.json5
-rw-r--r--modules-available/locations/lang/en/template-tags.json7
-rw-r--r--modules-available/locations/page.inc.php102
-rw-r--r--modules-available/locations/permissions/permissions.json9
-rw-r--r--modules-available/locations/style.css13
-rw-r--r--modules-available/locations/templates/location-subnets.html134
-rw-r--r--modules-available/locations/templates/locations.html83
-rw-r--r--modules-available/locations/templates/subnets.html17
9 files changed, 284 insertions, 89 deletions
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 0576e660..42026f8b 100644
--- a/modules-available/locations/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -385,7 +385,8 @@ class Location
*/
public static function getSubnets()
{
- $res = Database::simpleQuery("SELECT startaddr, endaddr, locationid FROM subnet");
+ $res = Database::simpleQuery("SELECT startaddr, endaddr, locationid FROM subnet WHERE locationid IN (:locations)",
+ array("locations" => User::getAllowedLocations("subnetlist.view")));
$subnets = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
settype($row['locationid'], 'int');
diff --git a/modules-available/locations/lang/de/template-tags.json b/modules-available/locations/lang/de/template-tags.json
index 29a19b85..04d10d06 100644
--- a/modules-available/locations/lang/de/template-tags.json
+++ b/modules-available/locations/lang/de/template-tags.json
@@ -6,6 +6,7 @@
"lang_deleteChildLocations": "Untergeordnete Orte ebenfalls l\u00f6schen",
"lang_deleteLocation": "Ort l\u00f6schen",
"lang_deleteSubnet": "Bereich l\u00f6schen",
+ "lang_deleteSubnetWarning": "Alle zum L\u00f6schen markierten Subnetze werden gelöscht. Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
"lang_editConfigVariables": "Konfig.-Variablen",
"lang_editRoomplan": "Raumplan bearbeiten",
"lang_endAddress": "Endadresse",
@@ -28,7 +29,7 @@
"lang_startAddress": "Startadresse",
"lang_subnet": "IP-Bereich",
"lang_sysConfig": "Lokalisierung",
- "lang_thisListByLocation": "Zur Ortsansicht",
- "lang_thisListBySubnet": "Nach Subnetzen auflisten",
+ "lang_thisListByLocation": "Orte",
+ "lang_thisListBySubnet": "Subnetze",
"lang_unassignedMachines": "Rechner, die in keinen definierten Ort fallen"
} \ No newline at end of file
diff --git a/modules-available/locations/lang/en/template-tags.json b/modules-available/locations/lang/en/template-tags.json
index 7256c958..ddb90f83 100644
--- a/modules-available/locations/lang/en/template-tags.json
+++ b/modules-available/locations/lang/en/template-tags.json
@@ -6,8 +6,9 @@
"lang_deleteChildLocations": "Delete child locations aswell",
"lang_deleteLocation": "Delete location",
"lang_deleteSubnet": "Delete range",
+ "lang_deleteSubnetWarning": "All subnets marked for deletion will be deleted. This cannot be undone!",
"lang_editConfigVariables": "Config vars",
- "lang_editRoomplan": "edit roomplan",
+ "lang_editRoomplan": "Edit roomplan",
"lang_endAddress": "End address",
"lang_listOfSubnets": "List of subnets",
"lang_location": "Location",
@@ -28,7 +29,7 @@
"lang_startAddress": "Start address",
"lang_subnet": "IP range",
"lang_sysConfig": "Localization\/Integration",
- "lang_thisListByLocation": "List by location",
- "lang_thisListBySubnet": "List by subnet",
+ "lang_thisListByLocation": "Locations",
+ "lang_thisListBySubnet": "Subnets",
"lang_unassignedMachines": "Machines not matching any location"
}
diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php
index 20af7b63..d9bc7130 100644
--- a/modules-available/locations/page.inc.php
+++ b/modules-available/locations/page.inc.php
@@ -12,7 +12,7 @@ class Page_Locations extends Page
protected function doPreprocess()
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -47,6 +47,12 @@ class Page_Locations extends Page
Message::addError('main.value-invalid', 'locationid', $loc);
continue;
}
+
+ $oldLoc = Database::queryFirst("SELECT locationid FROM subnet WHERE subnetid = :subnetid", array("subnetid" => $subnetid))["locationid"];
+ if (($loc == $oldLoc && !User::hasPermission("subnet.edit", $loc)) ||
+ ($loc != $oldLoc && (!User::hasPermission("subnet.delete", $oldLoc) || !User::hasPermission("subnet.add", $loc))))
+ continue;
+
$range = $this->rangeToLongVerbose($start, $end);
if ($range === false)
continue;
@@ -57,7 +63,7 @@ class Page_Locations extends Page
}
AutoLocation::rebuildAll();
Message::addSuccess('subnets-updated', $count);
- Util::redirect('?do=Locations');
+ Util::redirect('?do=Locations&action=showsubnets');
}
private function addLocations()
@@ -75,6 +81,8 @@ class Page_Locations extends Page
if (empty($name))
continue;
$parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0;
+ if (!User::hasPermission("location.add", $parent))
+ continue;
if ($parent !== 0) {
$ok = false;
foreach ($locs as $loc) {
@@ -115,15 +123,25 @@ class Page_Locations extends Page
$change = false;
// Delete location?
if ($locationId === $del) {
+ if (!User::hasPermission("location.delete", $locationId)) {
+ Message::addError('main.no-permission', 'locationid', $locationId);
+ Util::redirect('?do=Locations');
+ }
$this->deleteLocation($location);
$change = true;
}
// Update subnets
$change |= $this->updateLocationSubnets();
- // Insert subnets
- $change |= $this->addNewLocationSubnets($location);
- // Update location!
- $change |= $this->updateLocationData($location);
+
+ if (User::hasPermission("subnet.add", $locationId)) {
+ // Insert subnets
+ $change |= $this->addNewLocationSubnets($location);
+ }
+ if (User::hasPermission("location.edit", $locationId)) {
+ // Update location!
+ $change |= $this->updateLocationData($location);
+ }
+
if ($change) {
// In case subnets or tree layout changed, recalc this
AutoLocation::rebuildAll();
@@ -195,9 +213,12 @@ class Page_Locations extends Page
private function updateLocationSubnets()
{
$change = false;
+
+ $locationId = Request::post('locationid', false, 'integer');
+
// Deletion first
$dels = Request::post('deletesubnet', false);
- if (is_array($dels)) {
+ if (is_array($dels) && User::hasPermission("subnet.delete", $locationId)) {
$count = 0;
$stmt = Database::prepare('DELETE FROM subnet WHERE subnetid = :id');
foreach ($dels as $key => $value) {
@@ -212,6 +233,9 @@ class Page_Locations extends Page
$change = true;
}
}
+ if (!User::hasPermission("subnet.edit", $locationId))
+ return $change;
+
// Now actual updates
$starts = Request::post('startaddr', false);
$ends = Request::post('endaddr', false);
@@ -291,15 +315,28 @@ class Page_Locations extends Page
Util::redirect('?do=Locations&action=showlocations');
}
if ($getAction === 'showsubnets') {
- $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet");
+ $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet
+ WHERE locationid IN (:locations) ORDER BY startaddr ASC",
+ array("locations" => User::getAllowedLocations("location.view")));
$rows = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['startaddr'] = long2ip($row['startaddr']);
$row['endaddr'] = long2ip($row['endaddr']);
$row['locations'] = Location::getLocations($row['locationid']);
+
+ $allowedLocs = User::getAllowedLocations("subnet.add");
+ foreach ($row['locations'] as &$loc) {
+ if (!(in_array($loc["locationid"], $allowedLocs) || $loc["locationid"] == $row['locationid'])) {
+ $loc["disabled"] = "disabled";
+ }
+ }
+
+ $row['editThisSubnetAllowed'] = User::hasPermission("subnet.edit", $row['locationid']);
+ $row['deleteThisSubnetAllowed'] = User::hasPermission("subnet.delete", $row['locationid']);
$rows[] = $row;
}
- Render::addTemplate('subnets', array('list' => $rows));
+
+ Render::addTemplate('subnets', array('list' => $rows, 'editSubnetAllowed' => User::hasPermission("subnet.edit")));
} elseif ($getAction === 'showlocations') {
$this->showLocationList();
}
@@ -388,6 +425,32 @@ class Page_Locations extends Page
}
}
}
+
+ $allowedLocs = User::getAllowedLocations("location.view");
+ $withParents = array();
+ foreach ($allowedLocs as $loc) {
+ $withParents = array_merge($withParents, Location::getLocationRootChain($loc));
+ }
+
+ foreach ($locs as $key => $loc) {
+ if (!in_array($loc["locationid"], $withParents)) {
+ unset($locs[$key]);
+ } elseif (!in_array($loc["locationid"], $allowedLocs)) {
+ $id = $locs[$key]["locationid"];
+ $name = $locs[$key]["locationname"];
+ $depth = $locs[$key]["depth"];
+ $locs[$key] = array("locationid" => $id, "locationname" => $name, "depth" => $depth, "linkClass" => "not-allowed");
+ }
+ }
+
+ $addAllowedLocs = User::getAllowedLocations("location.add");
+ $addAllowedList = Location::getLocations(0, 0, True);
+ foreach ($addAllowedList as &$loc) {
+ if (!in_array($loc["locationid"], $addAllowedLocs)) {
+ $loc["disabled"] = "disabled";
+ }
+ }
+
// Output
Render::addTemplate('locations', array(
'list' => array_values($locs),
@@ -400,6 +463,8 @@ class Page_Locations extends Page
'haveOverlapOther' => !empty($overlapOther),
'unassignedCount' => $unassigned,
'defaultConfig' => $defaultConfig,
+ 'addAllowed' => User::hasPermission("location.add"),
+ 'addAllowedList' => array_values($addAllowedList)
));
}
@@ -422,6 +487,11 @@ class Page_Locations extends Page
private function ajaxShowLocation()
{
$locationId = Request::any('locationid', 0, 'integer');
+
+ if (!User::hasPermission("location.view", $locationId)) {
+ die('Permission denied');
+ }
+
$loc = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location WHERE locationid = :lid',
array('lid' => $locationId));
if ($loc === false) {
@@ -442,6 +512,14 @@ class Page_Locations extends Page
'roomplanner' => Module::get('roomplanner') !== false && Location::isLeaf($locationId),
'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true)
);
+
+ $allowedLocs = User::getAllowedLocations("location.edit");
+ foreach ($data['parents'] as &$parent) {
+ if (!(in_array($parent["locationid"], $allowedLocs) || $parent["locationid"] == $loc['parentlocationid'])) {
+ $parent["disabled"] = "disabled";
+ }
+ }
+
if (Module::get('dozmod') !== false) {
$lectures = Database::queryFirst('SELECT Count(*) AS cnt FROM sat.lecture l '
. ' INNER JOIN sat.lecture_x_location ll ON (l.lectureid = ll.lectureid AND ll.locationid = :lid)',
@@ -474,6 +552,12 @@ class Page_Locations extends Page
$data['havebaseconfig'] = Module::get('baseconfig') !== false;
$data['havesysconfig'] = Module::get('sysconfig') !== false;
+ $data['editAllowed'] = User::hasPermission("location.edit", $locationId);
+ $data['deleteAllowed'] = User::hasPermission("location.delete", $locationId);
+ $data['editSubnetAllowed'] = User::hasPermission("subnet.edit", $locationId);
+ $data['deleteSubnetAllowed'] = User::hasPermission("subnet.delete", $locationId);
+ $data['addSubnetAllowed'] = User::hasPermission("subnet.add", $locationId);
+ $data['saveButton'] = $data['editAllowed'] || $data['editSubnetAllowed'] || $data['deleteSubnetAllowed'] || $data['addSubnetAllowed'];
// echo '<pre>';
// var_dump($data);
diff --git a/modules-available/locations/permissions/permissions.json b/modules-available/locations/permissions/permissions.json
new file mode 100644
index 00000000..db0ac5f6
--- /dev/null
+++ b/modules-available/locations/permissions/permissions.json
@@ -0,0 +1,9 @@
+{
+ "location.view": "View locations.",
+ "location.edit": "Edit locations.",
+ "location.add": "Add locations.",
+ "location.delete": "Delete locations.",
+ "subnet.edit": "Edit subnets.",
+ "subnet.add": "Add subnets.",
+ "subnet.delete": "Delete subnets."
+} \ No newline at end of file
diff --git a/modules-available/locations/style.css b/modules-available/locations/style.css
index 86f9dfca..042ac4d1 100644
--- a/modules-available/locations/style.css
+++ b/modules-available/locations/style.css
@@ -1,3 +1,14 @@
table.locations tbody td:nth-of-type(even) {
background-color: rgba(0, 0, 0, 0.025);
-} \ No newline at end of file
+}
+
+.not-allowed {
+ pointer-events: none;
+ cursor: default;
+ color: inherit;
+}
+
+.disabled {
+ pointer-events: none;
+ opacity: 0.6;
+}
diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html
index b8a2b091..2cc8e98b 100644
--- a/modules-available/locations/templates/location-subnets.html
+++ b/modules-available/locations/templates/location-subnets.html
@@ -1,6 +1,6 @@
<div class="slx-well">
<div class="slx-bold">{{lang_locationSettings}}</div>
- <form method="post" action="?do=Locations">
+ <form id="locationForm{{locationid}}" method="post" action="?do=Locations">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="updatelocation">
<input type="hidden" name="locationid" value="{{locationid}}">
@@ -8,30 +8,25 @@
<button type="submit" class="btn btn-primary">Save</button>
</div>
<div class="row">
- <div class="col-sm-6">
- <div class="input-group">
- <span class="input-group-addon slx-ga2">{{lang_name}}</span>
- <input class="form-control" type="text" name="locationname" value="{{locationname}}" pattern=".*\S.*">
+ <div class="{{^editAllowed}}disabled{{/editAllowed}}">
+ <div class="col-sm-6">
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">{{lang_name}}</span>
+ <input class="form-control" type="text" name="locationname" value="{{locationname}}" pattern=".*\S.*">
+ </div>
</div>
- </div>
- <div class="col-sm-6">
- <div class="input-group">
- <span class="input-group-addon slx-ga2">{{lang_parentLocation}}</span>
- <select class="form-control" name="parentlocationid">
- {{#parents}}
- <option value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
- {{/parents}}
- </select>
+ <div class="col-sm-6">
+ <div class="input-group">
+ <span class="input-group-addon slx-ga2">{{lang_parentLocation}}</span>
+ <select class="form-control" name="parentlocationid">
+ {{#parents}}
+ <option {{disabled}} value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
+ {{/parents}}
+ </select>
+ </div>
</div>
</div>
</div>
- <div>
- <div class="pull-right">
- <label><input type="checkbox" name="recursive" value="on"> {{lang_deleteChildLocations}}</label>
- <button type="submit" class="btn btn-sm btn-danger" name="deletelocation" value="{{locationid}}" onclick="return slxConfirm()">{{lang_deleteLocation}}</button>
- </div>
- <div class="clearfix"></div>
- </div>
<br>
<div class="slx-bold">{{lang_assignedSubnets}}</div>
<div><i>{{lang_assignSubnetExplanation}}</i></div>
@@ -40,47 +35,92 @@
<th>#</th>
<th>{{lang_startAddress}}</th>
<th>{{lang_endAddress}}</th>
- <th title="{{lang_deleteSubnet}}"><span class="glyphicon glyphicon-trash"></span></th>
+ <th title="{{lang_deleteSubnet}}" class="text-center"><span class="glyphicon glyphicon-trash"></span></th>
</tr>
{{#list}}
<tr class="cidrmagic">
<td>{{subnetid}}</td>
- <td><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
- <td><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
- <td class="danger" align="center"><input type="checkbox" name="deletesubnet[{{subnetid}}]" value="on"></td>
+ <td class="{{^editSubnetAllowed}}disabled{{/editSubnetAllowed}}"><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
+ <td class="{{^editSubnetAllowed}}disabled{{/editSubnetAllowed}}"><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
+ <td class="danger">
+ <div class="checkbox text-center" style="margin-left: 9px">
+ <input {{^deleteSubnetAllowed}}disabled{{/deleteSubnetAllowed}} type="checkbox" name="deletesubnet[{{subnetid}}]" value="on">
+ <label class="text-left"></label>
+ </div>
+ </td>
</tr>
{{/list}}
<tr id="loc-sub-{{locationid}}">
<td colspan="4">
- <button class="btn btn-success btn-sm" type="button" onclick="slxAddSubnetRow(this, {{locationid}})" title="{{lang_addNewSubnet}}">
- <span class="glyphicon glyphicon-plus-sign"></span> {{lang_subnet}}
+ <button {{^addSubnetAllowed}}disabled{{/addSubnetAllowed}} class="btn btn-success btn-sm pull-right" type="button" onclick="slxAddSubnetRow(this, {{locationid}})" title="{{lang_addNewSubnet}}">
+ <span class="glyphicon glyphicon-plus"></span> {{lang_subnet}}
</button>
</td>
</tr>
</table>
- <br>
- <div class="btn-group">
- {{#roomplanner}}
- <a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
+ <div class="slx-bold">{{lang_locationInfo}}</div>
+
+ <div class="row">
+ <div class="col-md-4">
+ {{#haveDozmod}}
+ <div>
+ <span class="slx-ga2">{{lang_referencingLectures}}:</span> {{lectures}}
+ </div>
+ {{/haveDozmod}}
+ {{#haveStatistics}}
+ <div>
+ <span class="slx-ga2">{{lang_matchingMachines}}:</span> <a href="?do=Statistics&amp;show=list&amp;filters=location={{locationid}}">{{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)</a>
+ </div>
+ {{/haveStatistics}}
+ </div>
+ <div class="col-md-4 text-center">
+ <div class="btn-group">
+ {{#roomplanner}}
+ <a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false">
- <span class="glyphicon glyphicon-move"></span>{{lang_editRoomplan}}
- </a>
- {{/roomplanner}}
+ <span class="glyphicon glyphicon-move"></span> {{lang_editRoomplan}}
+ </a>
+ {{/roomplanner}}
+ </div>
+ </div>
+ <div class="col-md-4 text-right">
+ <button style="margin-right: 10px" {{^deleteAllowed}}disabled{{/deleteAllowed}} type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteLocationModal{{locationid}}"><span class="glyphicon glyphicon-trash"></span> {{lang_deleteLocation}}</button>
+ <button onclick="deleteSubnetWarning('{{locationid}}')" {{^saveButton}}disabled{{/saveButton}} type="button" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ </div>
</div>
- <div class="pull-right">
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
- </div>
- <div class="slx-bold">{{lang_locationInfo}}</div>
- {{#haveDozmod}}
- <div>
- <span class="slx-ga2">{{lang_referencingLectures}}:</span> {{lectures}}
+
+ <div class="modal fade" id="deleteLocationModal{{locationid}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" style="width: 400px" role="document">
+ <div class="modal-content">
+ <div class="modal-body">
+ {{lang_areYouSureNoUndo}}
+ <div class="checkbox">
+ <input type="checkbox" name="recursive" value="on">
+ <label>{{lang_deleteChildLocations}}</label>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-danger" name="deletelocation" value="{{locationid}}"><span class="glyphicon glyphicon-trash"></span> {{lang_deleteLocation}}</button>
+ </div>
+ </div>
+ </div>
</div>
- {{/haveDozmod}}
- {{#haveStatistics}}
- <div>
- <span class="slx-ga2">{{lang_matchingMachines}}:</span> <a href="?do=Statistics&amp;show=list&amp;filters=location={{locationid}}">{{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)</a>
+
+ <div class="modal fade" id="saveWarningModal{{locationid}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" style="width: 400px" role="document">
+ <div class="modal-content">
+ <div class="modal-body">
+ {{lang_deleteSubnetWarning}}
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ </div>
+ </div>
+ </div>
</div>
- {{/haveStatistics}}
+
</form>
-</div>
+</div> \ No newline at end of file
diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html
index c2dc610e..fb09a45e 100644
--- a/modules-available/locations/templates/locations.html
+++ b/modules-available/locations/templates/locations.html
@@ -1,6 +1,7 @@
<div>
- <div class="pull-right">
- <a href="?do=Locations&amp;action=showsubnets">{{lang_thisListBySubnet}}</a>
+ <div class="btn-group pull-right">
+ <a href="?do=Locations&amp;action=showlocations" class="btn btn-default active"><span class="glyphicon glyphicon-home"></span> {{lang_thisListByLocation}}</a>
+ <a href="?do=Locations&amp;action=showsubnets" class="btn btn-default"><span class="glyphicon glyphicon-list-alt"></span> {{lang_thisListBySubnet}}</a>
</div>
<h1>{{lang_locationsMainHeading}}</h1>
<table class="table table-condensed locations" style="margin-bottom:0px">
@@ -23,9 +24,10 @@
<tr>
<td>
<div style="display:inline-block;width:{{depth}}em"></div>
- <a href="#" onclick="slxOpenLocation(this, {{locationid}}); return false">{{locationname}} <b class="caret"></b></a>
+ <a href="#" class="{{linkClass}}" onclick="slxOpenLocation(this, {{locationid}}); return false">{{locationname}}{{^linkClass}} <b class="caret"></b>{{/linkClass}}</a>
</td>
<td class="text-nowrap" align="right">
+ {{^linkClass}}
{{#havestatistics}}
{{clientCount}}
<span class="text-muted">
@@ -34,13 +36,17 @@
</span>
<a class="btn btn-default btn-xs" href="?do=Statistics&amp;show=list&amp;filters=location={{locationid}}"><span class="glyphicon glyphicon-eye-open"></span></a>
{{/havestatistics}}
+ {{/linkClass}}
</td>
<td class="text-nowrap" align="right">
+ {{^linkClass}}
{{#havestatistics}}
{{clientLoad}}
{{/havestatistics}}
+ {{/linkClass}}
</td>
<td class="text-nowrap">
+ {{^linkClass}}
{{#havebaseconfig}}
<div class="pull-right" style="z-index:-1">
<a class="btn btn-default btn-xs" href="?do=baseconfig&amp;module=locations&amp;locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a>
@@ -49,8 +55,10 @@
{{lang_overrideCount}}: {{overriddenVars}}&emsp;&emsp;
{{/overriddenVars}}
{{/havebaseconfig}}
+ {{/linkClass}}
</td>
<td class="text-nowrap">
+ {{^linkClass}}
{{#havesysconfig}}
<div class="pull-right">
<a class="btn btn-default btn-xs" href="?do=sysconfig&amp;locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a>
@@ -59,6 +67,7 @@
{{configName}}&emsp;&emsp;
</span>
{{/havesysconfig}}
+ {{/linkClass}}
</td>
</tr>
{{/list}}
@@ -84,14 +93,14 @@
<input type="hidden" name="action" value="addlocations">
<table class="table table-condensed table-hover">
<tr id="lasttr">
- <td>
- <button class="btn btn-success btn-sm" type="button" onclick="slxAddLocationRow()">
- <span class="glyphicon glyphicon-plus-sign"></span> {{lang_location}}
+ <td width="60%">&emsp;</td>
+ <td class="text-right" colspan="2">
+ <button id="saveLocationRows" type="submit" class="btn btn-primary" style="display: none">
+ <span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}
+ </button>
+ <button {{^addAllowed}}disabled{{/addAllowed}} class="btn btn-success" type="button" onclick="slxAddLocationRow()">
+ <span class="glyphicon glyphicon-plus"></span> {{lang_location}}
</button>
- </td>
- <td width="80%">&emsp;</td>
- <td width="20%" align="right">
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
</td>
</tr>
</table>
@@ -111,17 +120,28 @@
var slxAddCounter = 0;
var slxLastLocation = false;
+var newRowCounter = 0;
+
function slxAddLocationRow() {
+ $("#saveLocationRows").show();
var tr = $('#lasttr');
- tr.before('<tr>\
- <td>#</td>\
+ tr.before('<tr id="row' + slxAddCounter + '">\
<td><input class="form-control" type="text" name="newlocation[' + slxAddCounter + ']" placeholder="{{lang_locationName}}" pattern=".*\\S.*"></td>\
<td><select class="form-control" name="newparent[' + slxAddCounter + ']">\
- <option value="0">{{lang_noParent}}</option>\
- {{#list}}<option value="{{locationid}}">{{locationpad}} {{locationname}}</option>{{/list}}\
+ {{#addAllowedList}}<option {{disabled}} value="{{locationid}}">{{locationpad}} {{locationname}}</option>{{/addAllowedList}}\
</select></td>\
+ <td class="text-center"><button class="btn btn-default btn-sm" type="button" onclick="removeNewLocationRow(' + slxAddCounter + ')"><span class="glyphicon glyphicon-remove"></span></button></td>\
</tr>');
slxAddCounter++;
+ newRowCounter++;
+}
+
+function removeNewLocationRow(r) {
+ $("#row"+r).remove();
+ newRowCounter--;
+ if (newRowCounter === 0) {
+ $("#saveLocationRows").hide();
+ }
}
function slxOpenLocation(e, lid) {
@@ -134,9 +154,10 @@ function slxOpenLocation(e, lid) {
if (existing.is(slxLastLocation)) {
slxLastLocation = false;
} else {
- existing.show()[0].scrollIntoView();
+ existing.show();
$(e).closest('tr').addClass('active slx-bold');
slxLastLocation = existing;
+ scollIntoView(existing);
}
return;
}
@@ -146,25 +167,51 @@ function slxOpenLocation(e, lid) {
$(e).closest('tr').addClass('active slx-bold').after(tr);
td.load('?do=Locations&action=showlocation&locationid=' + lid, function() {
slxAttachCidr();
- $('#location-details-' + lid)[0].scrollIntoView();
+ scollIntoView(tr);
});
slxLastLocation = tr;
}
+function scollIntoView(el) {
+ var offset = $(el).offset();
+ var win = $(window);
+ var h = $(el).height();
+ if (offset.top + h > win.scrollTop() + win.height()) {
+ offset.top -= win.height();
+ offset.top += h;
+ $('html, body').animate({
+ scrollTop: offset.top
+ });
+ }
+}
+
function slxAddSubnetRow(e, lid) {
var tr = $('#loc-sub-' + lid);
- tr.before('<tr class="cidrmagic">\
+ tr.before('<tr id="row' + slxAddCounter + '" class="cidrmagic">\
<td>#</td>\
<td><input class="form-control cidrstart" type="text" name="newstartaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\
<td><input class="form-control cidrend" type="text" name="newendaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\
- <td></td>\
+ <td class="text-center"><button class="btn btn-default btn-sm" type="button" onclick="removeNewSubnetRow(' + slxAddCounter + ')"><span class="glyphicon glyphicon-remove"></span></button></td>\
</tr>');
slxAddCounter++;
slxAttachCidr();
}
+function removeNewSubnetRow(r) {
+ $("#row"+r).remove();
+}
+
function slxConfirm() {
return confirm('{{lang_areYouSureNoUndo}}');
}
+
+function deleteSubnetWarning(locid) {
+ var form = $("#locationForm"+locid);
+ if (form.find("input[type=checkbox]:checked").length > 0) {
+ $("#saveWarningModal"+locid).modal();
+ } else {
+ form.submit();
+ }
+}
// -->
</script>
diff --git a/modules-available/locations/templates/subnets.html b/modules-available/locations/templates/subnets.html
index 15fa28f2..cb7fb758 100644
--- a/modules-available/locations/templates/subnets.html
+++ b/modules-available/locations/templates/subnets.html
@@ -1,6 +1,7 @@
<div>
- <div class="pull-right">
- <a href="?do=Locations&amp;action=showlocations">{{lang_thisListByLocation}}</a>
+ <div class="btn-group pull-right">
+ <a href="?do=Locations&amp;action=showlocations" class="btn btn-default"><span class="glyphicon glyphicon-home"></span> {{lang_thisListByLocation}}</a>
+ <a href="?do=Locations&amp;action=showsubnets" class="btn btn-default active"><span class="glyphicon glyphicon-list-alt"></span> {{lang_thisListBySubnet}}</a>
</div>
<h1>{{lang_listOfSubnets}}</h1>
<form method="post" action="?do=Locations">
@@ -16,20 +17,20 @@
{{#list}}
<tr class="cidrmagic">
<td>{{subnetid}}</td>
- <td><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td>
- <td><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td>
- <td>
+ <td class="{{^editThisSubnetAllowed}}disabled{{/editThisSubnetAllowed}}"><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td>
+ <td class="{{^editThisSubnetAllowed}}disabled{{/editThisSubnetAllowed}}"><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td>
+ <td class="{{^deleteThisSubnetAllowed}}disabled{{/deleteThisSubnetAllowed}}">
<select class="form-control" name="location[{{subnetid}}]">
{{#locations}}
- <option value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
+ <option {{disabled}} value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
{{/locations}}
</select>
</td>
</tr>
{{/list}}
</table>
- <div>
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
+ <div class="text-right" style="margin-bottom: 20px">
+ <button {{^editSubnetAllowed}}disabled{{/editSubnetAllowed}} type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
</form>
</div>