diff options
Diffstat (limited to 'modules-available/locations')
-rw-r--r-- | modules-available/locations/inc/location.inc.php | 3 | ||||
-rw-r--r-- | modules-available/locations/lang/de/template-tags.json | 5 | ||||
-rw-r--r-- | modules-available/locations/lang/en/template-tags.json | 9 | ||||
-rw-r--r-- | modules-available/locations/page.inc.php | 102 | ||||
-rw-r--r-- | modules-available/locations/permissions/permissions.json | 9 | ||||
-rw-r--r-- | modules-available/locations/style.css | 13 | ||||
-rw-r--r-- | modules-available/locations/templates/location-subnets.html | 134 | ||||
-rw-r--r-- | modules-available/locations/templates/locations.html | 83 | ||||
-rw-r--r-- | modules-available/locations/templates/subnets.html | 17 |
9 files changed, 285 insertions, 90 deletions
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php index 476f4c68..1581f744 100644 --- a/modules-available/locations/inc/location.inc.php +++ b/modules-available/locations/inc/location.inc.php @@ -360,7 +360,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 6094ebce..e3c0b056 100644 --- a/modules-available/locations/lang/en/template-tags.json +++ b/modules-available/locations/lang/en/template-tags.json @@ -6,11 +6,12 @@ "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": "Ort", + "lang_location": "Location", "lang_locationInfo": "Location details", "lang_locationName": "Name", "lang_locationOtherOverlap": "Warning! These locations have overlapping address ranges", @@ -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" }
\ No newline at end of file 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&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&show=list&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&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&show=list&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&action=showsubnets">{{lang_thisListBySubnet}}</a> + <div class="btn-group pull-right"> + <a href="?do=Locations&action=showlocations" class="btn btn-default active"><span class="glyphicon glyphicon-home"></span> {{lang_thisListByLocation}}</a> + <a href="?do=Locations&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&show=list&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&module=locations&locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a> @@ -49,8 +55,10 @@ {{lang_overrideCount}}: {{overriddenVars}}   {{/overriddenVars}} {{/havebaseconfig}} + {{/linkClass}} </td> <td class="text-nowrap"> + {{^linkClass}} {{#havesysconfig}} <div class="pull-right"> <a class="btn btn-default btn-xs" href="?do=sysconfig&locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a> @@ -59,6 +67,7 @@ {{configName}}   </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%"> </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%"> </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&action=showlocations">{{lang_thisListByLocation}}</a> + <div class="btn-group pull-right"> + <a href="?do=Locations&action=showlocations" class="btn btn-default"><span class="glyphicon glyphicon-home"></span> {{lang_thisListByLocation}}</a> + <a href="?do=Locations&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> |