Added notifications to the ngax UI

This commit is contained in:
Kenneth Skovhede
2015-12-03 22:04:47 +01:00
parent 116aed59fc
commit e6ef75bd76
5 changed files with 266 additions and 0 deletions
+4
View File
@@ -42,6 +42,7 @@
<script type="text/javascript" src="scripts/services/SystemInfo.js"></script>
<script type="text/javascript" src="scripts/services/EditUriBackendConfig.js"></script>
<script type="text/javascript" src="scripts/services/EditUriBuiltins.js"></script>
<script type="text/javascript" src="scripts/services/NotificationService.js"></script>
<script type="text/javascript" src="scripts/controllers/AppController.js"></script>
<script type="text/javascript" src="scripts/controllers/AboutController.js"></script>
@@ -71,6 +72,7 @@
<script type="text/javascript" src="scripts/directives/waitArea.js"></script>
<script type="text/javascript" src="scripts/directives/restoreFilePicker.js"></script>
<script type="text/javascript" src="scripts/directives/keyboardHandlers.js"></script>
<script type="text/javascript" src="scripts/directives/notificationArea.js"></script>
<script type="text/javascript" src="scripts/directives/progressBar.js"></script>
<script type="text/javascript" src="scripts/oem.js"></script>
@@ -157,6 +159,8 @@
</div>
</div>
<notification-area></notification-area>
<div ng-show="state.connectionState != 'connected'" class="blocker"></div>
<div ng-show="state.connectionState != 'connected'" class="connection-lost">
@@ -0,0 +1,53 @@
backupApp.directive('notificationArea', function() {
return {
restrict: 'E',
templateUrl: 'templates/notificationarea.html',
controller: function($scope, $location, $timeout, NotificationService, ServerStatus, AppService, AppUtils) {
$scope.Notifications = NotificationService.watch($scope);
$scope.state = ServerStatus.watch($scope);
$scope.doDismiss = function(id) {
AppService.delete('/notification/' + id);
};
$scope.doShowLog = function(backupid) {
AppService.get('/backup/' + backupid + '/isactive').then(
function() {
$location.path('/log/' + backupid);
},
function(resp) {
if (resp.status == 404) {
if ((parseInt(backupid) + '') != backupid)
alert('The backup was temporary and does not exist anymore, so the log data is lost');
else
alert('The backup is missing, has it been delete?');
} else {
AppUtils.connectionError('Failed to find backup: ', resp);
}
}
);
};
$scope.doInstallUpdate = function(id) {
AppService.post('/updates/install');
};
$scope.doActivateUpdate = function() {
AppService.post('/updates/activate').then(function() {}, AppUtils.connectionError('Activate failed: '));
};
$scope.doShowUpdate = function(id) {
$location.path('/updatechangelog');
};
$scope.doDownloadBugreport = function(item) {
var id = item.Action.substr('bug-report:created:'.length);
item.DownloadLink = AppService.get_bugreport_url(id);
document.getElementById('notification-download-iframe').src = item.DownloadLink;
};
}
}
});
@@ -0,0 +1,85 @@
backupApp.service('NotificationService', function($rootScope, $timeout, AppService, ServerStatus) {
// Track repeated refresh requests
var isRefreshing = false;
var needsRefresh = false;
var notifications = [];
this.notifications = notifications;
function refresh_notifications() {
if (isRefreshing) {
needsRefresh = true;
return;
}
needsRefresh = false;
isRefreshing = true;
AppService.get('/notifications').then(
function(resp) {
var idmap = {};
for(var n in resp.data)
idmap[resp.data[n].ID] = resp.data[n];
// Sync map and list
for (var i = notifications.length - 1; i >= 0; i--)
if (!idmap[notifications[i].ID])
notifications.splice(i, 1);
else
delete idmap[notifications[i].ID];
// Then add all new items
for (var n in idmap)
notifications.push(idmap[n]);
notifications.sort(function(a, b) {
if (a.ID < b.ID)
return -1;
else if (a.ID > b.ID)
return 1;
else
return 0;
});
$rootScope.$broadcast('notificationschanged');
isRefreshing = false;
if (needsRefresh)
refresh_notifications();
},
function(resp) {
isRefreshing = false;
}
);
};
this.watch = function(scope, m) {
scope.$on('notificationschanged', function() {
$timeout(function() {
if (m) m();
scope.$digest();
});
});
if (m) $timeout(m);
return notifications;
}
var first = ServerStatus.state.lastNotificationUpdateId == -1;
$rootScope.$on('serverstatechanged.lastNotificationUpdateId', function() {
// We always refresh, so no need to use the initial event
if (first)
first = false;
else
refresh_notifications();
});
this.refresh_notifications = refresh_notifications;
refresh_notifications();
});
@@ -503,3 +503,69 @@ div.blocker {
.themelink {
margin-left: 20px;
}
ul.notification {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
margin: auto;
width: 300px;
}
.notification .title {
border: 1px solid #65b1dd;
background-color: #65b1dd;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
padding: 2px;
padding-left: 5px;
padding-right: 5px;
font-weight: bold;
color: lightgray;
width: 100%;
text-align: center;
clear: both;
}
.notification .content {
background-color: white;
border: 1px solid #65b1dd;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
padding: 2px;
padding-left: 5px;
padding-right: 5px;
padding-bottom: 30px;
width: 100%;
}
.notification .message {
width: 100%;
color: black;
}
.notification .button {
padding: 2px 10px;
}
.notification .error .title, .notification .error .content, .notification .error .button {
border-color: red;
}
.notification .error .title, .notification .error .button {
background-color: red;
}
.notification .warning .title, .notification .warning .button {
background-color: orange;
}
.notification .warning .title, .notification .warning .content, .notification .warning .button {
border-color: orange;
}
@@ -0,0 +1,58 @@
<ul class="notification">
<!-- <li ng-show="state.updaterState != 'Waiting' || state.updatedVersion != null">
<div class="title">Updates</div>
<div class="content">
<div ng-show="state.updaterState == 'Checking'">
<div class="message">Checking for updates ...</div>
</div>
<div xng-show="state.updaterState == 'Downloading'">
<div class="message">
<progress-bar ng-text="Downloading update..." ng-progress="state.updateDownloadProgress"></progress-bar>
</div>
</div>
<div ng-show="state.updaterState == 'Waiting' &amp;&amp; state.updateReady">
<div class="message">Update <a href ng-click="doShowUpdate()">{{state.updatedVersion}}</a> is installed</div>
<div class="buttons">
<a href ng-click="doActivateUpdate()" class="button activateupdate">Activate</a>
</div>
</div>
<div ng-show="state.updaterState == 'Waiting' &amp;&amp; !state.updateReady &amp;&amp; state.updatedVersion != null">
<div class="message">Update <a href ng-click="doShowUpdate()">{{state.updatedVersion}}</a> is available</div>
<div class="buttons">
<a href ng-click="doInstallUpdate()" class="button installupdate">Install</a>
</div>
</div>
</div>
</li> -->
<li ng-repeat="item in Notifications track by item.ID" ng-show="$index < 4" class="{{item.Type.toLowerCase()}}">
<div class="title">{{item.Title}}</div>
<div class="content">
<div class="message">{{item.Message}}</div>
<div ng-show="item.DownloadLink != null">
<div>If the backup file was not downloaded automatically,</div>
<div>
<a href="{{item.DownloadLink}}" target="_blank">right click and choose &quot;Save as ...&quot;</a>
</div>
</div>
<div class="buttons">
<a href ng-click="doDismiss(item.ID)" class="button dismiss">Dismiss</a>
<a href ng-show="item.Action == 'backup:show-log'" ng-click="doShowLog(item.BackupID)" class="button showlog">Show</a>
<a href ng-show="item.Action == 'update:new'" ng-click="doInstallUpdate()" class="button installupdate">Install</a>
<a href ng-show="item.Action == 'update:new'" ng-click="doShowUpdate()" class="button showupdate">Show</a>
<a href ng-show="item.Action.indexOf('bug-report:created:') == 0 &amp;&amp; item.DownloadLink == null" ng-click="doDownloadBugreport(item)" class="button downloadbugreport">Download</a>
</div>
</li>
</ul>
<iframe style="display: none" id="notification-download-iframe"></iframe>