mirror of
				https://github.com/ohwgiles/laminar.git
				synced 2025-06-13 12:54:29 +00:00 
			
		
		
		
	spinner+progress
This commit is contained in:
		
							parent
							
								
									1e0a2ebc36
								
							
						
					
					
						commit
						2b6cbc18b1
					
				| @ -58,7 +58,7 @@ add_custom_command(OUTPUT laminar.capnp.c++ laminar.capnp.h | |||||||
| # Zip and compile statically served resources | # Zip and compile statically served resources | ||||||
| generate_compressed_bins(${CMAKE_SOURCE_DIR}/src/resources index.html js/app.js | generate_compressed_bins(${CMAKE_SOURCE_DIR}/src/resources index.html js/app.js | ||||||
|     tpl/home.html tpl/job.html tpl/run.html tpl/browse.html |     tpl/home.html tpl/job.html tpl/run.html tpl/browse.html | ||||||
|     favicon.ico favicon-152.png icon.png) |     favicon.ico favicon-152.png icon.png progress.png) | ||||||
| # Download 3rd-party frontend JS libs... | # Download 3rd-party frontend JS libs... | ||||||
| file(DOWNLOAD https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js | file(DOWNLOAD https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js | ||||||
|         js/angular.min.js EXPECTED_MD5 b1137641dbb512a60e83d673f7e2d98f) |         js/angular.min.js EXPECTED_MD5 b1137641dbb512a60e83d673f7e2d98f) | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ Resources::Resources() | |||||||
|     INIT_RESOURCE("/", index_html); |     INIT_RESOURCE("/", index_html); | ||||||
|     INIT_RESOURCE("/favicon.ico", favicon_ico); |     INIT_RESOURCE("/favicon.ico", favicon_ico); | ||||||
|     INIT_RESOURCE("/favicon-152.png", favicon_152_png); |     INIT_RESOURCE("/favicon-152.png", favicon_152_png); | ||||||
|  |     INIT_RESOURCE("/progress.png", progress_png); | ||||||
|     INIT_RESOURCE("/icon.png", icon_png); |     INIT_RESOURCE("/icon.png", icon_png); | ||||||
|     INIT_RESOURCE("/js/app.js", js_app_js); |     INIT_RESOURCE("/js/app.js", js_app_js); | ||||||
|     INIT_RESOURCE("/js/Chart.HorizontalBar.js", js_Chart_HorizontalBar_js); |     INIT_RESOURCE("/js/Chart.HorizontalBar.js", js_Chart_HorizontalBar_js); | ||||||
|  | |||||||
| @ -32,8 +32,29 @@ | |||||||
|   } |   } | ||||||
|   .progress { |   .progress { | ||||||
|    height: 10px; |    height: 10px; | ||||||
|  |    margin-top: 5px; | ||||||
|    margin-bottom: 0; |    margin-bottom: 0; | ||||||
|   } |   } | ||||||
|  |   .spin { | ||||||
|  | 	  -webkit-animation: rotation 2s infinite linear; | ||||||
|  |   } | ||||||
|  |   @-webkit-keyframes rotation { | ||||||
|  |     from {-webkit-transform: rotate(0deg);} | ||||||
|  |     to   {-webkit-transform: rotate(359deg);} | ||||||
|  |   } | ||||||
|  |   img.spin.small { | ||||||
|  | 	  width: 11px; | ||||||
|  | 	  height: 11px; | ||||||
|  |   } | ||||||
|  |   img.spin { | ||||||
|  |     -webkit-animation:spin 4s linear infinite; | ||||||
|  |     -moz-animation:spin 4s linear infinite; | ||||||
|  |     animation:spin 4s linear infinite; | ||||||
|  | } | ||||||
|  | @-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } } | ||||||
|  | @-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } } | ||||||
|  | @keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } } | ||||||
|  | 
 | ||||||
|  </style> |  </style> | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|  | |||||||
| @ -59,9 +59,9 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 			$rootScope.title = data.title; | 			$rootScope.title = data.title; | ||||||
| 			// populate jobs
 | 			// populate jobs
 | ||||||
| 			$scope.jobsQueued = data.queued; | 			$scope.jobsQueued = data.queued; | ||||||
|  | 			data.running.forEach($rootScope.updateProgress); | ||||||
| 			$scope.jobsRunning = data.running; | 			$scope.jobsRunning = data.running; | ||||||
| 			$scope.jobsRecent = data.recent; | 			$scope.jobsRecent = data.recent; | ||||||
| 
 |  | ||||||
| 			$scope.$apply(); | 			$scope.$apply(); | ||||||
| 			 | 			 | ||||||
| 			// setup charts
 | 			// setup charts
 | ||||||
| @ -145,20 +145,8 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| 	timeUpdater = $interval(function() { | 	var timeUpdater = $interval(function() { | ||||||
| 		$scope.jobsRunning.forEach(function(o){ | 		$scope.jobsRunning.forEach($rootScope.updateProgress); | ||||||
| 			if(o.etc) { |  | ||||||
| 				var d = new Date(); |  | ||||||
| 				var p = (d.getTime()/1000 - o.started) / (o.etc - o.started); |  | ||||||
| 				if(p > 1.2) { |  | ||||||
| 					o.overtime = true; |  | ||||||
| 				} else if(p >= 1) { |  | ||||||
| 					o.progress = 99; |  | ||||||
| 				} else { |  | ||||||
| 					o.progress = 100 * p; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	}, 1000); | 	}, 1000); | ||||||
| 	$scope.$on('$destroy', function() { | 	$scope.$on('$destroy', function() { | ||||||
| 		$interval.cancel(timeUpdater); | 		$interval.cancel(timeUpdater); | ||||||
| @ -259,7 +247,7 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| }) | }) | ||||||
| .controller('RunController', function($rootScope, $scope, $routeParams, $ws) { | .controller('RunController', function($rootScope, $scope, $routeParams, $ws, $interval) { | ||||||
| 	$rootScope.bc = { | 	$rootScope.bc = { | ||||||
| 		nodes: [{ href: '/', label: 'Home' }, | 		nodes: [{ href: '/', label: 'Home' }, | ||||||
| 		{ href: '/jobs', label: 'Jobs' }, | 		{ href: '/jobs', label: 'Jobs' }, | ||||||
| @ -273,6 +261,7 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 	$ws.statusListener({ | 	$ws.statusListener({ | ||||||
| 		status: function(data) { | 		status: function(data) { | ||||||
| 			$rootScope.title = data.title; | 			$rootScope.title = data.title; | ||||||
|  | 			$rootScope.updateProgress(data); | ||||||
| 			$scope.job = data; | 			$scope.job = data; | ||||||
| 			$scope.$apply(); | 			$scope.$apply(); | ||||||
| 		}, | 		}, | ||||||
| @ -299,6 +288,12 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| 	 | 	 | ||||||
|  | 	var timeUpdater = $interval(function() { | ||||||
|  | 		$rootScope.updateProgress($scope.job); | ||||||
|  | 	}, 1000); | ||||||
|  | 	$scope.$on('$destroy', function() { | ||||||
|  | 		$interval.cancel(timeUpdater); | ||||||
|  | 	}); | ||||||
| }) | }) | ||||||
| .run(function($rootScope) { | .run(function($rootScope) { | ||||||
| 	angular.extend($rootScope, { | 	angular.extend($rootScope, { | ||||||
| @ -309,11 +304,26 @@ angular.module('laminar',['ngRoute','ngSanitize']) | |||||||
| 			// TODO reimplement when toLocaleDateString() accepts formatting
 | 			// TODO reimplement when toLocaleDateString() accepts formatting
 | ||||||
| 			// options on most browsers
 | 			// options on most browsers
 | ||||||
| 			var d = new Date(1000 * unix); | 			var d = new Date(1000 * unix); | ||||||
| 			return d.getHours() + ':' + d.getMinutes() + ' on ' +  | 			var m = d.getMinutes(); | ||||||
|  | 			if(m < 10) m = '0' + m; | ||||||
|  | 			return d.getHours() + ':' + m + ' on ' +  | ||||||
| 				['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][d.getDay()] + ' ' | 				['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][d.getDay()] + ' ' | ||||||
| 				+ d.getDate() + '. ' + ['Jan','Feb','Mar','Apr','May','Jun', | 				+ d.getDate() + '. ' + ['Jan','Feb','Mar','Apr','May','Jun', | ||||||
| 				'Jul','Aug','Sep', 'Oct','Nov','Dec'][d.getMonth()] + ' ' | 				'Jul','Aug','Sep', 'Oct','Nov','Dec'][d.getMonth()] + ' ' | ||||||
| 				+ d.getFullYear(); | 				+ d.getFullYear(); | ||||||
|  | 		}, | ||||||
|  | 		updateProgress: function(o){ | ||||||
|  | 			if(o.etc) { | ||||||
|  | 				var d = new Date(); | ||||||
|  | 				var p = (d.getTime()/1000 - o.started) / (o.etc - o.started); | ||||||
|  | 				if(p > 1.2) { | ||||||
|  | 					o.overtime = true; | ||||||
|  | 				} else if(p >= 1) { | ||||||
|  | 					o.progress = 99; | ||||||
|  | 				} else { | ||||||
|  | 					o.progress = 100 * p; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								src/resources/progress.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/resources/progress.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 816 B | 
| @ -6,7 +6,7 @@ | |||||||
|    <td><a href="jobs/{{job.name}}">{{job.name}}</a> <i>queued</i></td> |    <td><a href="jobs/{{job.name}}">{{job.name}}</a> <i>queued</i></td> | ||||||
|   </tr> |   </tr> | ||||||
|   <tr class="animate-repeat" ng-repeat="job in jobsRunning track by $index"> |   <tr class="animate-repeat" ng-repeat="job in jobsRunning track by $index"> | ||||||
|    <td><a href="jobs/{{job.name}}">{{job.name}}</a> <a href="jobs/{{job.name}}/{{job.number}}">#{{job.number}}</a> <div class="progress"> |    <td><img class="spin small" src="/progress.png"> <a href="jobs/{{job.name}}">{{job.name}}</a> <a href="jobs/{{job.name}}/{{job.number}}">#{{job.number}}</a> <div class="progress"> | ||||||
|     <div class="progress-bar progress-bar-{{job.overtime?'warning':'info'}} progress-bar-striped {{job.etc?'':'active'}}" style="width:{{!job.etc?'100':job.progress}}%"></div> |     <div class="progress-bar progress-bar-{{job.overtime?'warning':'info'}} progress-bar-striped {{job.etc?'':'active'}}" style="width:{{!job.etc?'100':job.progress}}%"></div> | ||||||
|     </div> |     </div> | ||||||
|    </td> |    </td> | ||||||
|  | |||||||
| @ -32,7 +32,10 @@ | |||||||
|     <td colspan="4"><i>{{nQueued}} run(s) queued</i></td> |     <td colspan="4"><i>{{nQueued}} run(s) queued</i></td> | ||||||
|    </tr> |    </tr> | ||||||
|    <tr class="animate-repeat" ng-repeat="job in jobsRunning track by $index"> |    <tr class="animate-repeat" ng-repeat="job in jobsRunning track by $index"> | ||||||
|     <td><a href="jobs/{{job.name}}/{{job.number}}">#{{job.number}}</a> progressbar?</td> |     <td><img class="spin small" src="/progress.png"> <a href="jobs/{{name}}/{{job.number}}">#{{job.number}}</a></td> | ||||||
|  |     <td class="text-center">{{formatDate(job.started)}}</td> | ||||||
|  |     <td class="text-center">--</td> | ||||||
|  |     <td class="text-center hidden-xs">{{job.reason}}</td> | ||||||
|    </tr> |    </tr> | ||||||
|    <tr class="animate-repeat" ng-repeat="job in jobsRecent track by $index"> |    <tr class="animate-repeat" ng-repeat="job in jobsRecent track by $index"> | ||||||
|     <td><span ng-bind-html="runIcon(job.result)"></span> <a href="jobs/{{name}}/{{job.number}}">#{{job.number}}</a></td> |     <td><span ng-bind-html="runIcon(job.result)"></span> <a href="jobs/{{name}}/{{job.number}}">#{{job.number}}</a></td> | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| <div class="container-fluid"> | <div class="container-fluid"> | ||||||
| <div class="row"> | <div class="row"> | ||||||
| <div class="col-sm-5 col-md-6 col-lg-7"> | <div class="col-sm-5 col-md-6 col-lg-7"> | ||||||
|  <h3 style="float:left"><span ng-bind-html="runIcon(job.result)"></span> {{name}} #{{num}}</h3> |  <h3 style="float:left"><img class="spin" src="/progress.png" ng-hide="job.result"><span ng-bind-html="runIcon(job.result)"></span> {{name}} #{{num}}</h3> | ||||||
|  <nav class="pull-left"> |  <nav class="pull-left"> | ||||||
|   <ul class="pagination" style="margin:15px 20px"> |   <ul class="pagination" style="margin:15px 20px"> | ||||||
|    <li><a href="jobs/{{name}}/{{num-1}}">«</a></li> |    <li><a href="jobs/{{name}}/{{num-1}}">«</a></li> | ||||||
| @ -18,6 +18,9 @@ | |||||||
|  </dl> |  </dl> | ||||||
| </div> | </div> | ||||||
| <div class="col-sm-7 col-md-6 col-lg-5"> | <div class="col-sm-7 col-md-6 col-lg-5"> | ||||||
|  |  <div class="progress" ng-hide="job.result"> | ||||||
|  |   <div class="progress-bar progress-bar-{{job.overtime?'warning':'info'}} progress-bar-striped {{job.etc?'':'active'}}" style="width:{{!job.etc?'100':job.progress}}%;"></div> | ||||||
|  |  </div> | ||||||
|  <div class="panel panel-default" ng-show="job.artifacts.length"> |  <div class="panel panel-default" ng-show="job.artifacts.length"> | ||||||
|   <div class="panel-heading">Artifacts</div> |   <div class="panel-heading">Artifacts</div> | ||||||
|   <div class="panel-body"> |   <div class="panel-body"> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user