|
@@ -162,6 +162,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
<tr>
|
|
<tr>
|
|
|
<th width="1%"><div class="select-all hueCheckbox fa"></div></th>
|
|
<th width="1%"><div class="select-all hueCheckbox fa"></div></th>
|
|
|
<th>${_('Duration')}</th>
|
|
<th>${_('Duration')}</th>
|
|
|
|
|
+ <th>${_('Started')}</th>
|
|
|
<th>${_('Type')}</th>
|
|
<th>${_('Type')}</th>
|
|
|
<th>${_('Status')}</th>
|
|
<th>${_('Status')}</th>
|
|
|
<th>${_('Progress')}</th>
|
|
<th>${_('Progress')}</th>
|
|
@@ -174,6 +175,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
<tr data-bind="click: fetchJob">
|
|
<tr data-bind="click: fetchJob">
|
|
|
<td><div class="hueCheckbox fa"></div></td>
|
|
<td><div class="hueCheckbox fa"></div></td>
|
|
|
<td data-bind="text: duration"></td>
|
|
<td data-bind="text: duration"></td>
|
|
|
|
|
+ <td data-bind="text: duration"></td>
|
|
|
<td data-bind="text: type"></td>
|
|
<td data-bind="text: type"></td>
|
|
|
<td data-bind="text: status"></td>
|
|
<td data-bind="text: status"></td>
|
|
|
<td data-bind="text: progress"></td>
|
|
<td data-bind="text: progress"></td>
|
|
@@ -191,6 +193,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
<thead>
|
|
<thead>
|
|
|
<tr>
|
|
<tr>
|
|
|
<th>${_('Duration')}</th>
|
|
<th>${_('Duration')}</th>
|
|
|
|
|
+ <th>${_('Started')}</th>
|
|
|
<th>${_('Type')}</th>
|
|
<th>${_('Type')}</th>
|
|
|
<th>${_('Status')}</th>
|
|
<th>${_('Status')}</th>
|
|
|
<th>${_('Progress')}</th>
|
|
<th>${_('Progress')}</th>
|
|
@@ -201,6 +204,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
</thead>
|
|
</thead>
|
|
|
<tbody data-bind="foreach: jobs.finishedApps">
|
|
<tbody data-bind="foreach: jobs.finishedApps">
|
|
|
<tr data-bind="click: fetchJob">
|
|
<tr data-bind="click: fetchJob">
|
|
|
|
|
+ <td data-bind="text: duration"></td>
|
|
|
<td data-bind="text: duration"></td>
|
|
<td data-bind="text: duration"></td>
|
|
|
<td data-bind="text: type"></td>
|
|
<td data-bind="text: type"></td>
|
|
|
<td data-bind="text: status"></td>
|
|
<td data-bind="text: status"></td>
|
|
@@ -1046,6 +1050,10 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
|
|
|
|
|
self.loadingJob = ko.observable(false);
|
|
self.loadingJob = ko.observable(false);
|
|
|
|
|
|
|
|
|
|
+// _fetchJob(callback)
|
|
|
|
|
+
|
|
|
|
|
+// fetchJob
|
|
|
|
|
+// updateJob
|
|
|
|
|
|
|
|
self.fetchJob = function () {
|
|
self.fetchJob = function () {
|
|
|
self.loadingJob(true);
|
|
self.loadingJob(true);
|
|
@@ -1194,7 +1202,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
var Jobs = function (vm) {
|
|
var Jobs = function (vm) {
|
|
|
var self = this;
|
|
var self = this;
|
|
|
|
|
|
|
|
- self.apps = ko.observableArray();
|
|
|
|
|
|
|
+ self.apps = ko.observableArray().extend({ rateLimit: 50 });
|
|
|
self.totalApps = ko.observable(null);
|
|
self.totalApps = ko.observable(null);
|
|
|
self.runningApps = ko.computed(function(job) {
|
|
self.runningApps = ko.computed(function(job) {
|
|
|
return $.grep(self.apps(), function(job) { return job.apiStatus() == 'RUNNING'; });
|
|
return $.grep(self.apps(), function(job) { return job.apiStatus() == 'RUNNING'; });
|
|
@@ -1262,29 +1270,81 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
- self.fetchJobs = function () {
|
|
|
|
|
- self.loadingJobs(true);
|
|
|
|
|
- vm.job(null);
|
|
|
|
|
-
|
|
|
|
|
- $.post("/jobbrowser/api/jobs", {
|
|
|
|
|
|
|
+ self._fetchJobs = function (callback) {
|
|
|
|
|
+ return $.post("/jobbrowser/api/jobs", {
|
|
|
interface: ko.mapping.toJSON(vm.interface),
|
|
interface: ko.mapping.toJSON(vm.interface),
|
|
|
filters: ko.mapping.toJSON(self.filters),
|
|
filters: ko.mapping.toJSON(self.filters),
|
|
|
}, function (data) {
|
|
}, function (data) {
|
|
|
if (data.status == 0) {
|
|
if (data.status == 0) {
|
|
|
- var apps = [];
|
|
|
|
|
- if (data && data.apps) {
|
|
|
|
|
- data.apps.forEach(function (job) { // TODO: update and merge with status and progress
|
|
|
|
|
- apps.push(new Job(vm, job));
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- self.apps(apps);
|
|
|
|
|
- self.totalApps(data.total);
|
|
|
|
|
|
|
+ if (callback) {
|
|
|
|
|
+ callback(data);
|
|
|
|
|
+ };
|
|
|
} else {
|
|
} else {
|
|
|
$(document).trigger("error", data.message);
|
|
$(document).trigger("error", data.message);
|
|
|
}
|
|
}
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var lastFetchJobsRequest = null;
|
|
|
|
|
+
|
|
|
|
|
+ self.fetchJobs = function () {
|
|
|
|
|
+ vm.apiHelper.cancelActiveRequest(lastFetchJobsRequest);
|
|
|
|
|
+
|
|
|
|
|
+ self.loadingJobs(true);
|
|
|
|
|
+ vm.job(null);
|
|
|
|
|
+ lastFetchJobsRequest = self._fetchJobs(function(data) {
|
|
|
|
|
+ var apps = [];
|
|
|
|
|
+ if (data && data.apps) {
|
|
|
|
|
+ data.apps.forEach(function (job) {
|
|
|
|
|
+ apps.push(new Job(vm, job));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ self.apps(apps);
|
|
|
|
|
+ self.totalApps(data.total);
|
|
|
}).always(function () {
|
|
}).always(function () {
|
|
|
self.loadingJobs(false);
|
|
self.loadingJobs(false);
|
|
|
});
|
|
});
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ var lastUpdateJobsRequest = null;
|
|
|
|
|
+
|
|
|
|
|
+ self.updateJobs = function () {
|
|
|
|
|
+ vm.apiHelper.cancelActiveRequest(lastUpdateJobsRequest);
|
|
|
|
|
+
|
|
|
|
|
+ lastFetchJobsRequest = self._fetchJobs(function(data) {
|
|
|
|
|
+ var apps = [];
|
|
|
|
|
+ if (data && data.apps) {
|
|
|
|
|
+ var i = 0, j = 0;
|
|
|
|
|
+ var newJobs = [];
|
|
|
|
|
+
|
|
|
|
|
+ while (i < self.apps().length && j < data.apps.length) {
|
|
|
|
|
+ if (self.apps()[i].id() != data.apps[j].id) {
|
|
|
|
|
+ // New Job
|
|
|
|
|
+ newJobs.push(new Job(vm, data.apps[j]));
|
|
|
|
|
+ j++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Updated jobs
|
|
|
|
|
+ if (self.apps()[i].status() != data.apps[j].status) {
|
|
|
|
|
+ self.apps()[i].status(data.apps[j].status);
|
|
|
|
|
+ self.apps()[i].apiStatus(data.apps[j].apiStatus);
|
|
|
|
|
+ }
|
|
|
|
|
+ i++;
|
|
|
|
|
+ j++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (i < self.apps().length) {
|
|
|
|
|
+ self.apps().splice(i, self.apps().length - i);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ newJobs.forEach(function (job) {
|
|
|
|
|
+ self.apps.push(job);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ self.totalApps(data.total);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
self.control = function (action) {
|
|
self.control = function (action) {
|
|
@@ -1322,6 +1382,17 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
|
|
|
|
|
self.jobs = new Jobs(self);
|
|
self.jobs = new Jobs(self);
|
|
|
self.job = ko.observable();
|
|
self.job = ko.observable();
|
|
|
|
|
+ var clock;
|
|
|
|
|
+ self.job.subscribe(function(val) {
|
|
|
|
|
+ if (! val) {
|
|
|
|
|
+ clock = setInterval(self.jobs.updateJobs, 5000);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (clock) {
|
|
|
|
|
+ clearInterval(clock);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
|
|
|
self.breadcrumbs = ko.observableArray([]);
|
|
self.breadcrumbs = ko.observableArray([]);
|
|
|
self.resetBreadcrumbs = function(extraCrumbs) {
|
|
self.resetBreadcrumbs = function(extraCrumbs) {
|
|
@@ -1331,6 +1402,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
}
|
|
}
|
|
|
self.breadcrumbs(crumbs);
|
|
self.breadcrumbs(crumbs);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
self.resetBreadcrumbs();
|
|
self.resetBreadcrumbs();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -1377,7 +1449,9 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
|
|
|
window.onhashchange = function () {
|
|
window.onhashchange = function () {
|
|
|
loadHash();
|
|
loadHash();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
loadHash();
|
|
loadHash();
|
|
|
|
|
+ console.log('JB2 ready Triggered');
|
|
|
});
|
|
});
|
|
|
})();
|
|
})();
|
|
|
</script>
|
|
</script>
|