Major frontend reavmp to properly use ui-router.

The core of the work here involved two things:
 * Making the default view / home page 'monitor' instead of 'console'
 * Replacing monitor tab functionality with ui-router's nested views

There are now a few bugs which need to be worked out:
 * Haven't tested saving a monitor
 * Loading an existing monitor's data doesn't work (edit)
 * active tab isn't set
 * who knows what else?
This commit is contained in:
Kyle Johnson 2015-02-17 14:35:08 -05:00
parent 99aac2a372
commit 62d445a61d
12 changed files with 192 additions and 30 deletions

View File

@ -12,17 +12,77 @@ ZoneMinder.config(['$locationProvider', function($locationProvider) {
}]);
ZoneMinder.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$urlRouterProvider
.when ('/', '/monitor')
.otherwise('/');
$stateProvider
.state('/', {
url: '/',
templateUrl: '/views/console.html'
})
///////////////////////////////////////////////////
// Monitor Grid and List View (main monitor page //
///////////////////////////////////////////////////
// This page lets you view the monitors as either a grid, or a list.
// The grid or list is chosen by clicking on the button on the top-right of the page
.state('monitor', {
// State can not be explicitly activated - only implicitly by one of its children
abstract: true,
// This abstract will prepend '/monitor' onto the urls of all its children
url: '/monitor',
// As a top level state, this template will be loaded into index.html's ui-view
templateUrl: '/views/monitor.html'
})
.state('monitor.list', {
url: '',
templateUrl: '/views/monitor.list.html'
})
//////////////////////
// Monitor > Detail //
//////////////////////
// 'detail' is a child of 'monitor' and as such will be loaded into monitor.html's ui-view
// The 'detail' state will be the first 'tab' in the 'detail' view, which is 'General'
.state('monitor.detail', {
// monitor.detail can not be loaded directly
abstract: true,
// This state is a child of 'monitor'. The URL will end up being like:
// '/monitor/{mid:[0-9]{1,4}}'. When the URL becomes something like '/monitor/7',
// this state will become active.
url: '/{mid:[0-9]{1,4}}',
templateUrl: '/views/monitor.detail.html'
})
////////////////////////////
// Monitor > Detail > Tab //
////////////////////////////
// Each 'tab' gets its own state. As these are all children of 'detail', they are lodaed
// into detail's ui-view
.state('monitor.detail.general', {
url: '',
templateUrl: '/views/monitor.detail.general.html'
})
.state('monitor.detail.source', {
url: '',
templateUrl: '/views/monitor.detail.source.html'
})
.state('monitor.detail.timestamps', {
url: '',
templateUrl: '/views/monitor.detail.timestamps.html'
})
.state('monitor.detail.buffers', {
url: '',
templateUrl: '/views/monitor.detail.buffers.html'
})
.state('monitor.detail.misc', {
url: '',
templateUrl: '/views/monitor.detail.misc.html'
})
.state('events', {
url: '/events',
templateUrl: '/views/events.html'
@ -39,6 +99,9 @@ ZoneMinder.config(function(paginationTemplateProvider) {
ZoneMinder.factory('Monitor', function($http) {
return {
getMonitors: function() {
return $http.get('/api/monitors.json');
},
getMonitor: function(mid) {
return $http.get('/api/monitors/'+mid+'.json');
},

View File

@ -203,7 +203,7 @@ ZoneMinder.controller('EventController', function($scope, Event, $modalInstance,
};
});
ZoneMinder.controller('MonitorController', function($scope, $http, $location, Monitor) {
ZoneMinder.controller('MonitorController', function($scope, $http, $location, Monitor, Console) {
// If mid is set, we're editing a monitor. Else, we're adding one.
var mid = $location.search().mid;
if (mid) {
@ -259,9 +259,7 @@ ZoneMinder.controller('MonitorController', function($scope, $http, $location, Mo
// Redirect to the dashboard on success
.success(function(data) { window.location = "/"; });
};
});
ZoneMinder.controller('ConsoleController', function($scope, Console, Monitor) {
$scope.grid = true;
$scope.gridButton = 'glyphicon-th';
$scope.consoleLayout = 4;

View File

@ -1,12 +1,13 @@
<nav class="navbar navbar-default" role="navigation" ng-controller="HeaderController">
<div class="container-fluid">
<a ui-sref="/"><span class="navbar-brand">ZoneMinder</span></a>
<a ui-sref="home"><span class="navbar-brand">ZoneMinder</span></a>
<button type="button" class="btn btn-md navbar-btn pull-right" ng-class="isRunning ? 'btn-success' : 'btn-danger'" data-toggle="modal" data-target="#myModal">
<span class="glyphicon glyphicon-off"></span>
</button>
<ul class="nav navbar-nav pull-right">
<li><a ui-sref="monitor.list">Monitors</a></li>
<li><a ui-sref="events">Events</a></li>
<li><a href="?view=timeline">Timeline</a></li>
<li><a ui-sref="options">Options</a></li>

View File

@ -0,0 +1,25 @@
<div>
<h2>Monitor Detail</h2>
<div class="row">
<form ng-submit="submitMonitor(formMonitor.$valid)" name="formMonitor" novalidate>
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li><a ui-sref="monitor.detail.general">General</a></li>
<li><a ui-sref="monitor.detail.source">Source</a></li>
<li><a ui-sref="monitor.detail.timestamps">Timestamps</a></li>
<li><a ui-sref="monitor.detail.buffers">Buffers</a></li>
<li><a ui-sref="monitor.detail.misc">Misc</a></li>
</ul>
<button type="submit" class="btn btn-success btn-block" ng-disabled="formMonitor.$invalid">Save</button>
</div>
<div class="col-md-10">
<div ui-view class="tab-pane"> </div>
</div>
</form>
</div>
</div>

View File

@ -1,21 +1,3 @@
<div class="container-fluid" ng-controller="MonitorController">
<form ng-submit="submitMonitor(formMonitor.$valid)" name="formMonitor" novalidate>
<ul class="nav nav-tabs" role="tablist" id="tabMonitorAdd">
<li class="active" role="presentation"><a href="#general" aria-expanded="true" aria-controls="general" role="tab" data-toggle="tab">General</a></li>
<li role="presentation"><a href="#source" aria-controls="source" role="tab" data-toggle="tab">Source</a></li>
<li role="presentation"><a href="#timestamp" aria-controls="timestamp" role="tab" data-toggle="tab">Timestamps</a></li>
<li role="presentation"><a href="#buffers" aria-controls="buffers" role="tab" data-toggle="tab">Buffers</a></li>
<li role="presentation"><a href="#misc" aria-controls="misc" role="tab" data-toggle="tab">Misc</a></li>
</ul> <!-- End tabs -->
<div class="tab-content">
<section ng-include="'/views/tab-monitor-general.html'"></section>
<section ng-include="'/views/tab-monitor-source.html'"></section>
<section ng-include="'/views/tab-monitor-timestamp.html'"></section>
<section ng-include="'/views/tab-monitor-buffers.html'"></section>
<section ng-include="'/views/tab-monitor-misc.html'"></section>
</div> <!-- End .tab-content -->
<button type="submit" class="btn btn-success btn-block" ng-disabled="formMonitor.$invalid">Save</button>
</form>
</div> <!-- End .container-fluid -->
<div class="container-fluid" ng-controller="MonitorController">
<div ui-view></div>
</div> <!-- End .container-fluid -->

View File

@ -0,0 +1,93 @@
<h2>Monitor List</h2>
<div ng-show="fresh" class="alert alert-warning">
<p><strong>Uh-oh!</strong> You have no monitors! Why not <a class="alert-link" href="/?view=monitor">add</a> one?</p>
</div>
<div class="row" ng-hide="fresh">
<div class="col-md-1 col-md-offset-10">
<select ng-model="consoleLayout" ng-show="grid" ng-change="updateLayout()">
<option value="1">1 per row</option>
<option value="2">2 per row</option>
<option value="3">3 per row</option>
<option value="4">4 per row</option>
<option value="5">5 per row</option>
<option value="6">6 per row</option>
<option value="7">7 per row</option>
<option value="8">8 per row</option>
<option value="9">9 per row</option>
<option value="10">10 per row</option>
<option value="11">11 per row</option>
<option value="12">12 per row</option>
</select>
</div>
<div class="col-md-1 text-right">
<button ng-click="consoleView()" class="btn btn-default btn-lg" type="button">
<span class="glyphicon" ng-class="gridButton"></span>
</button>
</div>
</div>
<div ng-show="grid" ng-hide="fresh">
<div class="row" ng-repeat="monitors in rows">
<div ng-repeat="monitor in monitors" class="col-md-{{columnSize}}">
<div class="monitor panel" ng-class="(monitor.alerts.zmc || monitor.alerts.zma) ? 'panel-default' : 'panel-danger'">
<div class="panel-heading">
<a ng-hide="(monitor.alerts.zmc || monitor.alerts.zma)" class="pull-right" href="#" tooltip="{{ monitor.alert }}">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
</a>
<h2 class="text-left panel-title">{{ monitor.Name }}</h2>
</div> <!-- End .panel-heading -->
<div class="panel-body center-block">
<img class="img-responsive img-rounded" ng-src="/cgi-bin/nph-zms?mode=single&monitor={{monitor.Id}}" />
</div> <!-- End .panel-body -->
</div> <!-- End .monitor -->
</div>
</div>
</div>
<div class="row" ng-hide="grid">
<div class="col-md-12">
<table class="table table-striped">
<tr>
<th>Id</th>
<th>Name</th>
<th class="col-md-1">Function</th>
<th>Source</th>
<th>Enabled</th>
<th>Zones</th>
<th>Delete</th>
</tr>
<tr ng-repeat="monitor in monitors">
<td ng-bind="monitor.Id"></td>
<td><a ui-sref="monitor.detail.general({mid:monitor.Id})">{{monitor.Name}}</a></td>
<td class="col-md-1">
<label class="sr-only">Function</label>
<select id="function{{monitor.Id}}" ng-model="monitor.Function" class="form-control" ng-change="saveMonitor(monitor)">
<option value="None">None</option>
<option value="Monitor">Monitor</option>
<option value="Modect">Modect</option>
<option value="Record">Record</option>
<option value="Mocord">Mocord</option>
<option value="Nodect">Nodect</option>
</select>
</td>
<td ng-bind="monitor.Type"></td>
<td ng-bind="monitor.Enabled"></td>
<td ng-bind="monitor.Zones"></td>
<td><button type="button" class="btn btn-danger btn-sm" ng-click="delete($index)">{{ monitor.deleteText }}</button></td>
</tr>
<tfoot>
<tr>
<td colspan="7"><a ui-sref="monitor.detail.general">Add New Monitor</a></td>
</tr>
</tfoot>
</table>
</div>
</div>