decentralized-internet
Version:
An NPM library of programs to create decentralized web and distributed computing projects
2 lines • 34.8 kB
JavaScript
"use strict";angular.module("jsonFormatter",["RecursionHelper"]).provider("JSONFormatterConfig",function(){var a=!1,b=100,c=5;return{get hoverPreviewEnabled(){return a},set hoverPreviewEnabled(b){a=!!b},get hoverPreviewArrayCount(){return b},set hoverPreviewArrayCount(a){b=parseInt(a,10)},get hoverPreviewFieldCount(){return c},set hoverPreviewFieldCount(a){c=parseInt(a,10)},$get:function(){return{hoverPreviewEnabled:a,hoverPreviewArrayCount:b,hoverPreviewFieldCount:c}}}}).directive("jsonFormatter",["RecursionHelper","JSONFormatterConfig",function(a,b){function c(a){return a.replace('"','"')}function d(a){if(void 0===a)return"";if(null===a)return"Object";if("object"==typeof a&&!a.constructor)return"Object";var b=/function (.{1,})\(/,c=b.exec(a.constructor.toString());return c&&c.length>1?c[1]:""}function e(a){return null===a?"null":typeof a}function f(a,b){var d=e(a);return"null"===d||"undefined"===d?d:("string"===d&&(b='"'+c(b)+'"'),"function"===d?a.toString().replace(/[\r\n]/g,"").replace(/\{.*\}/,"")+"{…}":b)}function g(a){var b="";return angular.isObject(a)?(b=d(a),angular.isArray(a)&&(b+="["+a.length+"]")):b=f(a,a),b}function h(a){a.isArray=function(){return angular.isArray(a.json)},a.isObject=function(){return angular.isObject(a.json)},a.getKeys=function(){return a.isObject()?Object.keys(a.json).map(function(a){return""===a?'""':a}):void 0},a.type=e(a.json),a.hasKey=void 0!==a.key,a.getConstructorName=function(){return d(a.json)},"string"===a.type&&("Invalid Date"!==new Date(a.json).toString()&&(a.isDate=!0),0===a.json.indexOf("http")&&(a.isUrl=!0)),a.isEmptyObject=function(){return a.getKeys()&&!a.getKeys().length&&a.isOpen&&!a.isArray()},a.isOpen=!!a.open,a.toggleOpen=function(){a.isOpen=!a.isOpen},a.childrenOpen=function(){return a.open>1?a.open-1:0},a.openLink=function(b){b&&(window.location.href=a.json)},a.parseValue=function(b){return f(a.json,b)},a.showThumbnail=function(){return!!b.hoverPreviewEnabled&&a.isObject()&&!a.isOpen},a.getThumbnail=function(){if(a.isArray())return a.json.length>b.hoverPreviewArrayCount?"Array["+a.json.length+"]":"["+a.json.map(g).join(", ")+"]";var c=a.getKeys(),d=c.slice(0,b.hoverPreviewFieldCount),e=d.map(function(b){return b+":"+g(a.json[b])}),f=c.length>=5?"…":"";return"{"+e.join(", ")+f+"}"}}return{templateUrl:"json-formatter.html",restrict:"E",replace:!0,scope:{json:"=",key:"=",open:"="},compile:function(b){return a.compile(b,h)}}}]),"object"==typeof module&&(module.exports="jsonFormatter"),angular.module("RecursionHelper",[]).factory("RecursionHelper",["$compile",function(a){return{compile:function(b,c){angular.isFunction(c)&&(c={post:c});var d,e=b.contents().remove();return{pre:c&&c.pre?c.pre:null,post:function(b,f){d||(d=a(e)),d(b,function(a){f.append(a)}),c&&c.post&&c.post.apply(null,arguments)}}}}}]),angular.module("jsonFormatter").run(["$templateCache",function(a){a.put("json-formatter.html",'<div ng-init="isOpen = open && open > 0" class="json-formatter-row"><a ng-click="toggleOpen()"><span class="toggler {{isOpen ? \'open\' : \'\'}}" ng-if="isObject()"></span> <span class="key" ng-if="hasKey"><span class="key-text">{{key}}</span><span class="colon">:</span></span> <span class="value"><span ng-if="isObject()"><span class="constructor-name">{{getConstructorName(json)}}</span> <span ng-if="isArray()"><span class="bracket">[</span><span class="number">{{json.length}}</span><span class="bracket">]</span></span></span> <span ng-if="!isObject()" ng-click="openLink(isUrl)" class="{{type}}" ng-class="{date: isDate, url: isUrl}">{{parseValue(json)}}</span></span> <span ng-if="showThumbnail()" class="thumbnail-text">{{getThumbnail()}}</span></a><div class="children" ng-if="getKeys().length && isOpen"><json-formatter ng-repeat="key in getKeys() track by $index" json="json[key]" key="key" open="childrenOpen()"></json-formatter></div><div class="children empty object" ng-if="isEmptyObject()"></div><div class="children empty array" ng-if="getKeys() && !getKeys().length && isOpen && isArray()"></div></div>')}]),angular.module("clusterpost-list",["ui.bootstrap","smart-table","jsonFormatter","jwt-user-login"]),angular.module("clusterpost-list").factory("clusterpostService",["$q","$http","$location",function(a,b,c){return{getExecutionServers:function(){return b({method:"GET",url:"/executionserver"})},getJobStatus:function(a){return b({method:"GET",url:"/executionserver/"+a})},submitJob:function(a,c){return b({method:"POST",url:"/executionserver/"+a,data:{force:c}})},killJob:function(a){return b({method:"DELETE",url:"/executionserver/"+a})},createJob:function(a){return b({method:"POST",url:"/dataprovider",data:a})},getAllJobs:function(a){return b({method:"GET",url:"/dataprovider",params:{executable:a}})},updateJob:function(a){return b({method:"PUT",url:"/dataprovider",data:a})},getJob:function(a){return b({method:"GET",url:"/dataprovider/"+a})},getJobDownload:function(a){return b({method:"GET",url:"/dataprovider/download/job/"+a,responseType:"blob"}).then(function(c){return b({method:"DELETE",url:"/dataprovider/download/job/"+a}).then(function(){return c})})},getAttachment:function(a,c,d){return b({method:"GET",url:"/dataprovider/"+a+"/"+encodeURIComponent(c),responseType:d})},getAttachmentDowloadToken:function(a,c,d){return b({method:"GET",url:"/dataprovider/download/"+a+"/"+encodeURIComponent(c),params:{expires:d}})},getDownloadAttachmentURL:function(a,b){return this.getAttachmentDowloadToken(a,b).then(function(a){return"/dataprovider/download/"+a.data.token})},addAttachment:function(a,c,d){return b({method:"PUT",url:"/dataprovider/"+a+"/"+c,data:d})},addAttachments:function(a,b,c){var d=this,e=function(a,b,c,f,g){return d.addAttachment(a,b[f],c[f]).then(function(d){return g.push(d),f++,f<b.length&&f<c.length?e(a,b,c,f,g):g})};return e(a,b,c,0,[])},getJobUser:function(a,c,d){return b({method:"GET",url:"/dataprovider/user",params:{userEmail:a,jobstatus:c,executable:d}})},getUserJobs:function(a){return b({method:"GET",url:"/dataprovider/user",params:a})},deleteJob:function(a){return b({method:"DELETE",url:"/dataprovider/"+a})},createAndSubmitJob:function(a,b,c){var d=this;return d.createJob(a).then(function(a){var e=a.data,f=e.id;return d.addAttachments(f,b,c).then(function(a){return d.submitJob(f)})})},getExecutionServerTokens:function(){return b({method:"GET",url:"/executionserver/tokens"})}}}]),angular.module("clusterpost-list").directive("clusterpostJobs",["$routeParams","$location","clusterpostService","$filter","$q","clusterauth",function(a,b,c,d,e,f){function g(a,b){a.jobs={selectedJob:{job:{}},edit:{show:!1},showScopes:!1},f.getUser().then(function(b){return a.user=b,f.getScopes().then(function(b){b.data&&b.data[0]?a.clusterScopes=_.filter(b.data[0].scopes,function(a){return"default"!=a&&"admin"!=a&&"clusterpost"!=a}):console.error("No scopes found!")})}).then(function(){return a.getDB()}),a.jobs.onFilter=function(b){a.jobs.filteredJobs=b},a.updateStatus=function(a){c.getJobStatus(a._id).then(function(b){a.jobstatus=b.data}).catch(function(a){throw console.error(a),a})},a.removeJobScope=function(b,c){if(b.scope){var d=b.scope.indexOf(c);if(-1!=d)return b.scope.splice(d,1),a.saveJob(b)}},a.addJobScope=function(b){if(a.jobs.selectedScope)return b.scope||(b.scope=[]),b.scope.push(a.jobs.selectedScope),b.scope=_.uniq(b.scope),a.saveJob(b)},a.addJobsScope=function(b){_.each(a.jobs.filteredJobs,a.addJobScope)},a.removeJobsScope=function(b){_.each(a.jobs.filteredJobs,function(b){a.removeJobScope(b,a.jobs.selectedScope)})},a.killJob=function(a){c.killJob(a._id).then(function(b){a.jobstatus=b.data}).catch(function(a){throw console.error(a),a})},a.removeRow=function(b){var c=a.rowCollection.indexOf(b);-1!==c&&a.rowCollection.splice(c,1)},a.deleteJob=function(b){c.deleteJob(b._id).then(function(c){for(var d=0;d<a.jobs.data.length;d++)a.jobs.data[d]._id===b._id&&a.jobs.data.splice(d,1)}).catch(function(a){throw console.error(a),a})},a.runJob=function(b,d){c.submitJob(b._id,d).then(function(b){a.getDB()}).catch(function(a){console.error(a)})},a.saveJob=function(a){return c.updateJob(angular.copy(a)).then(function(b){b&&b.data&&b.data[0]&&b.data[0].rev&&(a._rev=b.data[0].rev)}).catch(function(a){console.error(a)})},a.getDB=function(){var b={};b=-1!==a.user.scope.indexOf("admin")?a.executable?_.isArray(a.executable)?Promise.all(_.map(a.executable,function(a){return c.getAllJobs(a)})).then(function(a){return{data:_.flatten(_.pluck(a,"data"))}}):c.getAllJobs():c.getAllJobs(a.executable):a.executable?_.isArray(a.executable)?Promise.all(_.map(a.executable,function(a){return c.getUserJobs({executable:a})})).then(function(a){return{data:_.flatten(_.pluck(a,"data"))}}):c.getUserJobs({executable:a.executable}):c.getUserJobs(),b.then(function(b){a.jobs.data=b.data,a.jobs.status=_.uniq(_.pluck(_.pluck(b.data,"jobstatus"),"status")),a.jobs.executables=_.uniq(_.pluck(b.data,"executable"))}).then(function(){return c.getExecutionServers()}).then(function(b){a.executionservers=b.data}).catch(function(a){console.error(a)})},a.showJobDetail=function(b){a.jobs.selectedJob.job=b,a.activeTab=1,c.getAttachment(b._id,"stdout.out","text").then(function(b){a.jobs.selectedJob.stdout=b.data}).catch(console.error),c.getAttachment(b._id,"stderr.err","text").then(function(b){a.jobs.selectedJob.stderr=b.data}).catch(console.error)},a.runAllJobs=function(){if(a.jobs.filteredJobs){var b=_.map(a.jobs.filteredJobs,function(a){return c.submitJob(a._id).then(function(a){console.log(a)}).catch(console.error)});Promise.all(b).catch(console.error)}},a.updateAllJobs=function(){if(a.jobs.filteredJobs){var b=_.map(a.jobs.filteredJobs,function(a){return c.getJobStatus(a._id).then(function(b){a.jobstatus=b.data}).catch(console.error)});Promise.all(b).catch(console.error)}},a.deleteAllJobs=function(){if(a.jobs.filteredJobs){var b=_.map(a.jobs.filteredJobs,a.deleteJob);Promise.all(b).catch(console.error)}},a.killAllJobs=function(){if(a.jobs.filteredJobs){var b=_.map(a.jobs.filteredJobs,a.killJob);Promise.all(b).catch(console.error)}},a.saveJobEdit=function(){a.jobs.edit.showerror=!1;try{var b=JSON.parse(a.jobs.edit.jobtext);c.updateJob(b).then(function(c){a.jobs.edit.show=!1,a.jobs.selectedJob.job=b;for(var d=0;d<a.jobs.data.length;d++)b._id===a.jobs.data[d]._id&&(a.jobs.data[d]=b)}).catch(function(b){a.jobs.edit.error=b.message,a.jobs.edit.showerror=!0})}catch(b){a.jobs.edit.error=b.message,a.jobs.edit.showerror=!0}},a.downloadJob=function(b){return a.downloadCallback?a.downloadCallback(b):c.getJobDownload(b._id).then(function(a){var c=b._id+".tar.gz";b.name&&(c=b.name+".tar.gz"),pom.setAttribute("href",window.URL.createObjectURL(a)),pom.setAttribute("download",c),pom.dataset.downloadurl=["application/octet-stream",pom.download,pom.href].join(":"),pom.click()})},a.downloadAll=function(){if(a.jobs.filteredJobs){var b=_.map(a.jobs.filteredJobs,a.downloadJob);Promise.all(b).catch(console.error)}},a.numJobsInPage=[{id:"0",value:"10"},{id:"1",value:"50"},{id:"2",value:"100"}],a.rowCollection=[],a.forceRunJob=!1,a.activeTab=0,a.$watch("jobs.edit.show",function(){a.jobs.edit.show&&(a.jobs.edit.jobtext=JSON.stringify(a.jobs.selectedJob.job,null,4))})}return{restrict:"E",link:g,templateUrl:"./src/clusterpost-jobs.directive.html",scope:{executable:"=",jobCallback:"=",downloadCallback:"="}}}]),angular.module("clusterpost-list").directive("onFilter",function(){return{require:"^stTable",scope:{onFilter:"="},link:function(a,b,c,d){a.$watch(d.getFilteredCollection,function(b){a.onFilter&&a.onFilter(b)})}}}),angular.module("clusterpost-list").directive("clusterpostApp",["$routeParams","$location","clusterpostService","$filter","$q","clusterauth",function(a,b,c,d,e,f){function g(d,e){d.jobs={selectedJob:{}},d.jobs.onFilter=function(a){d.jobs.filteredJobs=a},d.updateStatus=function(a){c.getJobStatus(a._id).then(function(b){a.jobstatus=b.data}).catch(function(a){throw console.error(a),a})},d.killJob=function(a){c.killJob(a._id).then(function(b){a.jobstatus=b.data}).catch(function(a){throw console.error(a),a})},d.removeRow=function(a){var b=d.rowCollection.indexOf(a);-1!==b&&d.rowCollection.splice(b,1)},d.deleteJob=function(a){c.deleteJob(a._id).then(function(b){for(var c=0;c<d.jobs.data.length;c++)d.jobs.data[c]._id===a._id&&d.jobs.data.splice(c,1)}).catch(function(a){throw console.error(a),a})},d.saveJob=function(a){return c.updateJob(angular.copy(a)).then(function(b){b&&b.data&&b.data[0]&&b.data[0].rev&&(a._rev=b.data[0].rev)}).catch(function(a){console.error(a)})},d.runJob=function(a,b){c.submitJob(a._id,b).then(function(a){d.getDB()}).catch(function(a){console.error(a)})},d.getDB=function(){c.getUserJobs({userEmail:d.appUser.selectedUser.email,executable:d.appName}).then(function(a){d.jobs.data=a.data,d.jobs.status=_.uniq(_.pluck(_.pluck(a.data,"jobstatus"),"status")),d.jobs.executables=_.uniq(_.pluck(a.data,"executable"))}).catch(function(a){console.error(a)})},d.showJobDetail=function(a){d.jobs.selectedJob.job=a,d.activeTab=1,c.getAttachment(a._id,"stdout.out","text").then(function(a){d.jobs.selectedJob.stdout=a.data.replace(/\n/g,"<br>")}).catch(console.error),c.getAttachment(a._id,"stderr.err","text").then(function(a){d.jobs.selectedJob.stderr=a.data.replace(/\n/g,"<br>")}).catch(console.error)},d.runAllJobs=function(){if(d.jobs.filteredJobs){var a=_.map(d.jobs.filteredJobs,function(a){return c.submitJob(a._id).then(function(a){console.log(a)}).catch(console.error)});Promise.all(a).catch(console.error)}},d.updateAllJobs=function(){if(d.jobs.filteredJobs){var a=_.map(d.jobs.filteredJobs,function(a){return c.getJobStatus(a._id).then(function(b){a.jobstatus=b.data}).catch(console.error)});Promise.all(a).catch(console.error)}},d.deleteAllJobs=function(){if(d.jobs.filteredJobs){var a=_.map(d.jobs.filteredJobs,d.deleteJob);Promise.all(a).catch(console.error)}},d.killAllJobs=function(){if(d.jobs.filteredJobs){var a=_.map(d.jobs.filteredJobs,d.killJob);Promise.all(a).catch(console.error)}},d.jobAppCallback=function(a){d.jobCallback&&d.jobCallback(a)},d.numJobsInPage=[{id:"0",value:"10"},{id:"1",value:"50"},{id:"2",value:"100"}],d.rowCollection=[],d.forceRunJob=!1,d.activeTab=0,d.appUser={},f.getUser().then(function(b){return d.appUser.selectedUser=b,d.appUser.user=b,d.appUser.user.scope.indexOf("admin")?f.getUsers().then(function(b){return d.appUser.allUsers=b.data,a.adminCpUid&&(d.appUser.selectedUser=_.find(d.appUser.allUsers,function(b){return b._id===a.adminCpUid})),d.getDB()}):d.getDB()}).catch(console.error),d.appUser.userChange=function(){d.getDB(),b.search("adminCpUid",d.appUser.selectedUser._id)},d.getJobName=function(a){return a.name?a.name:a._id},d.downloadAllJobs=function(){if(d.jobs.filteredJobs){var a=_.map(d.jobs.filteredJobs,d.downloadJob);Promise.all(a).catch(console.error)}},d.downloadJob=function(a){if(d.downloadCallback)return d.downloadCallback(a);console.log("TODO")}}return{restrict:"E",link:g,scope:{jobCallback:"=",appName:"=",downloadCallback:"="},templateUrl:"./src/clusterpost-app.directive.html"}}]),angular.module("clusterpost-list").directive("clusterpostEsAdmin",["$routeParams","$location","clusterpostService",function(a,b,c){function d(a,b,d){c.getExecutionServerTokens().then(function(b){a.tokens=b.data}),a.downloadToken=function(a){var c=new Blob([angular.toJson(a)],{type:"text/plain"}),d=document.createElement("a");b.append(d),d.setAttribute("href",window.URL.createObjectURL(c)),d.setAttribute("download","token.json"),d.dataset.downloadurl=["text/plain",d.download,d.href].join(":"),d.draggable=!0,d.classList.add("dragout"),d.click()}}return{restrict:"E",link:d,scope:{jobCallback:"=",appName:"=",downloadCallback:"="},templateUrl:"./src/clusterpost-es-admin.directive.html"}}]),angular.module("clusterpost-list").run(["$templateCache",function(a){a.put("./src/clusterpost-app.directive.html",'<uib-tabset active="activeTab">\n\t<uib-tab heading="List" index="0">\n\t\t<div class="panel panel-default">\n\t\t\t<div class="panel-body" style="overflow:scroll">\n\n\t\t\t\t<div class="input-group" ng-if="appUser.user.scope.indexOf(\'admin\') != -1">\n\t\t\t\t\t<select class="form-control" ng-options="user.email for user in appUser.allUsers" ng-model="appUser.selectedUser" ng-change="appUser.userChange()"></select>\n\t\t\t\t</div>\n\t\t\t\t<br>\n\t\t\t\t<table st-table="jobs.displayedJobs" st-safe-src="jobs.data" class="table table-striped" on-filter="jobs.onFilter">\n\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th colspan="6"><input st-search="" class="form-control" placeholder="Global search ..." type="text"/></th>\n\t\t\t\t\t\t\t<th colspan="5">Number of jobs per page \n\t\t\t\t\t\t\t\t<select class="form-control" ng-model="itemsByPage" ng-options="option.value for option in numJobsInPage track by option.id"></select>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th st-sort="name">Detail</th>\n\t\t\t\t\t\t\t<th st-sort="name">Job name</th>\n\t\t\t\t\t\t\t<th st-sort="userEmail">User email</th>\n\t\t\t\t\t\t\t<th st-sort="timestamp">Timestamp</th>\n\t\t\t\t\t\t\t<th st-sort="jobsstatus.status">Job status</th>\n\t\t\t\t\t\t\t<th st-sort="executable"> Executable </th>\n\t\t\t\t\t\t\t<th st-sort="jobstatus.jobid">Job Id</th>\n\t\t\t\t\t\t\t<th st-sort="executionserver">Execution server</th>\n\t\t\t\t\t\t\t<th>Download</th>\n\t\t\t\t\t\t\t<th>Update</th>\n\t\t\t\t\t\t\t<th>Run</th>\n\t\t\t\t\t\t\t<th>Force run</th>\n\t\t\t\t\t\t\t<th>Kill</th>\n\t\t\t\t\t\t\t<th>Delete</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th colspan="2">\n\t\t\t\t\t\t\t\t<input st-search="name" placeholder="search for name" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="userEmail" placeholder="search for userEmail" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="timestamp" placeholder="search for timestamp" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th> \n\t\t\t\t\t\t\t\t<select class="form-control" st-search="jobstatus.status">\n\t\t\t \t<option value="">All</option>\n\t\t\t \t<option ng-repeat="st in jobs.status">{{st}}</option>\n\t\t\t \t</select>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th colspan="2">\n\t\t\t\t\t\t\t\t<select class="form-control" st-search="executable">\n\t\t\t \t<option value="">All</option>\n\t\t\t \t<option ng-repeat="ex in jobs.executables">{{ex}}</option>\n\t\t\t \t</select>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="executionserver" placeholder="search for execution server" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="downloadAllJobs()" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-download"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="updateAllJobs()" class="btn btn-sm btn-info">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-refresh">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="runAllJobs()" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-play">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="killAllJobs()" class="btn btn-sm btn-warning">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-remove-circle">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="deleteAllJobs()" class="btn btn-sm btn-danger">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-trash">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr ng-repeat="row in jobs.displayedJobs">\n\t\t\t\t\t\t\t<td><button class="btn btn-info" ng-click="showJobDetail(row)"><span class="glyphicon glyphicon-eye-open"></span></button></td>\n\t\t\t\t\t\t\t<td><button class="btn btn-default" ng-click="jobAppCallback(row)">{{getJobName(row)}}</button></td>\n\t\t\t\t\t\t\t<td>{{row.userEmail}}</td>\n\t\t\t\t\t\t\t<td>{{row.timestamp}}</td>\n\t\t\t\t\t\t\t<td>{{row.jobstatus.status}}</td>\n\t\t\t\t\t\t\t<td>{{row.executable}}</td>\n\t\t\t\t\t\t\t<td>{{row.jobstatus.jobid}}</td>\n\t\t\t\t\t\t\t<td><select class="form-control" ng-model="row.executionserver" ng-options="es.name as es.name for es in executionservers" ng-change="saveJob(row)"></select></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="downloadJob(row)" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-download"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="updateStatus(row)" class="btn btn-sm btn-info">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-refresh">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="runJob(row,forceRunJob)" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-play">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<input type="checkbox" ng-model="forceRunJob"/>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="killJob(row)" class="btn btn-sm btn-warning">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-remove-circle">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="deleteJob(row)" class="btn btn-sm btn-danger">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-trash">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t<tfoot>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan="10" class="text-center">\n\t\t\t\t\t\t\t\t<div st-pagination="" st-items-by-page="itemsByPage.value" st-displayed-pages="7"></div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tfoot>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t</div>\n \t</uib-tab>\n\t<uib-tab heading="Job detail" index="1">\n\t\t<div class="panel panel-default">\n\t\t\t\x3c!-- <div class="panel-heading">\n\t\t\t\t<h3 class="panel-title">Probabilistic tractography with FSL tools</h3>\n\t\t\t</div> --\x3e\n\t\t\t<div class="panel-body">\n\t\t\t\t<div class="col-md-12">\n\t\t\t\t\t<div class="col-md-6 alert alert-info" role="alert" ng-bind-html="jobs.selectedJob.stdout"></div>\n\t\t\t\t\t<div class="col-md-6 alert alert-warning" role="alert" ng-bind-html="jobs.selectedJob.stderr"></div>\n\t\t\t\t</div>\n\t\t\t\t<div class="col-md-12">\n\t\t \t\t\t<json-formatter json="jobs.selectedJob.job" open="4"></json-formatter>\n\t\t \t\t</div>\n\t\t \t</div>\n\t\t</div>\n\t</uib-tab>\n</uib-tabset>'),a.put("./src/clusterpost-es-admin.directive.html",'<uib-tabset active="activeTab">\n\t<uib-tab heading="Execution server tokens" index="0">\n\t\t<div class="panel panel-default">\n\t\t\t<div class="panel-body" style="overflow:scroll">\n\t\t\t\t<table st-table="displayedTokens" st-safe-src="tokens" class="table table-striped">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th colspan="2"><input st-search="name" class="form-control" placeholder="Global search ..." type="text"/></th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th st-sort="name">Execution server name</th>\n\t\t\t\t\t\t\t<th>Download</th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr ng-repeat="row in displayedTokens">\n\t\t\t\t\t\t\t<td>{{row.executionserver}}</td>\n\t\t\t\t\t\t\t<td><button type="button" class="btn btn-info" ng-click="downloadToken(row)"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></button></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody>\n\t\t\t\t\t<tfoot>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan="10" class="text-center">\n\t\t\t\t\t\t\t\t<div st-pagination="" st-items-by-page="itemsByPage.value" st-displayed-pages="7"></div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tfoot>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t</div>\n \t</uib-tab>\n \t<uib-tab heading="Users" index="1">\n \t\t<div class="panel panel-default">\n\t\t\t<div class="panel-body" style="overflow:scroll">\n'+" \t\t\t\t<users user-scopes=\"['admin', 'clusterpost', 'default']\"></users>\n \t\t\t</div>\n \t\t</div>\n \t</uib-tab>\n</uib-tabset>"),
a.put("./src/clusterpost-jobs.directive.html",'<uib-tabset active="activeTab">\n\t<uib-tab heading="Jobs" index="0">\n\t\t<div class="panel panel-default" style="overflow:scroll">\n\t\t\t<div class="panel-body">\n\t\t\t\t<table st-table="jobs.displayedJobs" st-safe-src="jobs.data" class="table table-striped" on-filter="jobs.onFilter">\n\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th colspan="6"><input st-search="" class="form-control" placeholder="Global search ..." type="text"/></th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<th colspan="4">Number of jobs per page \n\t\t\t\t\t\t\t\t<select class="form-control" ng-model="itemsByPage" ng-options="option.value for option in numJobsInPage track by option.id"></select>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="jobs.showScopes=!jobs.showScopes" class="btn btn-info" title="Show scopes controls">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-user"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th st-sort="_id"> Detail </th>\n\t\t\t\t\t\t\t<th st-sort="name"> Name </th>\n\t\t\t\t\t\t\t<th st-sort="userEmail">User email</th>\n\t\t\t\t\t\t\t<th st-sort="timestamp" st-sort-default="reverse">Timestamp</th>\n\t\t\t\t\t\t\t<th st-sort="jobsstatus.status">Job status</th>\n\t\t\t\t\t\t\t<th st-sort="row.executable"> Executable </th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<th st-sort="scope" ng-if="jobs.showScopes">Scope</th>\n\t\t\t\t\t\t\t<th st-sort="executionserver">Execution server</th>\n\t\t\t\t\t\t\t<th st-sort="jobstatus.jobid">Job Id</th>\n\t\t\t\t\t\t\t<th ng-if="downloadCallback">Download</th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<th>Update</th>\n\t\t\t\t\t\t\t<th>Run</th>\n\t\t\t\t\t\t\t<th>Force run</th>\n\t\t\t\t\t\t\t<th>Kill</th>\n\t\t\t\t\t\t\t<th>Delete</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="_id" placeholder="search for id" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="name" placeholder="search for name" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="userEmail" placeholder="search for userEmail" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<input st-search="timestamp" placeholder="search for timestamp" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th> \n\t\t\t\t\t\t\t\t<select class="form-control" st-search="jobstatus.status">\n\t\t\t \t<option value="">All</option>\n\t\t\t \t<option ng-repeat="st in jobs.status">{{st}}</option>\n\t\t\t \t</select>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th >\n\t\t\t\t\t\t\t\t<select class="form-control" st-search="executable">\n\t\t\t \t<option value="">All</option>\n\t\t\t \t<option ng-repeat="ex in jobs.executables">{{ex}}</option>\n\t\t\t \t</select>\n\t\t\t\t\t\t\t</th>\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<th ng-if="jobs.showScopes">\n\t\t\t\t\t\t\t\t<select class="form-control" ng-options="sc as sc for sc in clusterScopes" ng-model="jobs.selectedScope"></select>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="addJobsScope()" class="btn btn-xs btn-success">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-plus"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="removeJobsScope()" class="btn btn-xs btn-danger">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-remove"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th colspan="2">\n\t\t\t\t\t\t\t\t<input st-search="executionserver" placeholder="search for execution server" class="input-sm form-control" type="search"/>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<th ng-if="downloadCallback">\n\t\t\t\t\t\t\t\t<button type="button" ng-click="downloadAll()" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-download">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="updateAllJobs()" class="btn btn-sm btn-info">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-refresh">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="runAllJobs()" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-play">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="killAllJobs()" class="btn btn-sm btn-warning">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-remove-circle">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="deleteAllJobs()" class="btn btn-sm btn-danger">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-trash">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr ng-repeat="row in jobs.displayedJobs">\n\n\t\t\t\t\t\t\t<td><button class="btn btn-info" ng-click="showJobDetail(row)" title="{{row._id}}"><span class="glyphicon glyphicon-eye-open"></span></td>\n\t\t\t\t\t\t\t<td><button class="btn btn-success" ng-if="jobCallback" ng-click="jobCallback(row)"><span class="glyphicon glyphicon-eye-open"> {{row.name}}</span></button><div ng-if="!jobCallback">{{row.name}}</div></td>\n\t\t\t\t\t\t\t<td>{{row.userEmail}}</td>\n\t\t\t\t\t\t\t<td>{{row.timestamp}}</td>\n\t\t\t\t\t\t\t<td>{{row.jobstatus.status}}</td>\n\t\t\t\t\t\t\t<td>{{row.executable}}</td>\n\t\t\t\t\t\t\t<td ng-if="jobs.showScopes">\n\t\t\t\t\t\t\t\t<button ng-repeat="sc in row.scope" type="button" ng-click="removeJobScope(row, sc)" class="btn btn-xs btn-danger">\n\t\t\t\t\t\t\t\t\t{{sc}}\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-remove"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="addJobScope(row)" class="btn btn-xs btn-success">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-plus"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><select class="form-control" ng-model="row.executionserver" ng-options="es.name as es.name for es in executionservers" ng-change="saveJob(row)"></select></td>\n\t\t\t\t\t\t\t<td>{{row.jobstatus.jobid}}</td>\n\n\t\t\t\t\t\t\t<td ng-if="downloadCallback">\n\t\t\t\t\t\t\t\t<button type="button" ng-click="downloadJob(row)" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t\t<span class="glyphicon glyphicon-download"></span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="updateStatus(row)" class="btn btn-sm btn-info">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-refresh">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="runJob(row,forceRunJob)" class="btn btn-sm btn-success">\n\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-play">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<input type="checkbox" ng-model="forceRunJob"/>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="killJob(row)" class="btn btn-sm btn-warning">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-remove-circle">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<button type="button" ng-click="deleteJob(row)" class="btn btn-sm btn-danger">\n\t\t\t\t\t\t\t\t\t<i class="glyphicon glyphicon-trash">\n\t\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t<tfoot>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan="10" class="text-center">\n\t\t\t\t\t\t\t\t<div st-pagination="" st-items-by-page="itemsByPage.value" st-displayed-pages="7"></div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tfoot>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t</div>\n\t</uib-tab>\n\t<uib-tab heading="Job detail" index="1">\n\t\t<div class="panel panel-default">\n\n\t\t\t<div class="panel-body">\n\n\t\t\t\t<div class="col-md-12">\n\t\t \t\t\t<div class="button-group">\n\t\t\t\t \t\t<button type="button" ng-click="jobs.edit.show=!jobs.edit.show" class="btn btn-default">\n\t\t\t\t\t\t\t<span class="glyphicon glyphicon-pencil"></span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type="button" ng-click="saveJobEdit()" class="btn btn-default">\n\t\t\t\t\t\t\t<span class="glyphicon glyphicon-floppy-save"></span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t\n\t\t\t\t<div class="col-md-12">\n\t\t\t\t\t<div class="col-md-6 alert alert-info" role="alert">\n\t\t\t\t\t\t<p style="white-space: pre; overflow: auto;">\n\t\t\t\t\t\t\t{{jobs.selectedJob.stdout}}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="col-md-6 alert alert-warning" role="alert">\n\t\t\t\t\t\t<p style="white-space: pre; overflow: auto;">\n\t\t\t\t\t \t\t{{jobs.selectedJob.stderr}}\n\t\t\t\t\t \t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class="col-md-12 alert alert-danger" role="alert" ng-if="jobs.edit.showerror">\n\t\t\t\t\t{{jobs.edit.error}}\n\t\t\t\t</div>\n\n\t\t \t\t<div class="col-md-12">\t\t \t\t\t\n\t \t\t\t\t<textarea class="form-control" rows="100" ng-model="jobs.edit.jobtext" ng-if="jobs.edit.show"></textarea>\t\t\t\t\t\n\t\t \t\t\t<json-formatter json="jobs.selectedJob.job" open="4" ng-if="!jobs.edit.show"></json-formatter>\n\t\t \t\t</div>\n\t\t\t \t\n\t\t \t</div>\n\t\t</div>\n\t</uib-tab>\n</uib-tabset>\n ')}]);