浏览代码

HUE-1176 [jb] Workflow action button logic

Romain Rigaux 8 年之前
父节点
当前提交
a6cbb4a

+ 3 - 1
apps/jobbrowser/src/jobbrowser/apis/workflow_api.py

@@ -155,8 +155,10 @@ class WorkflowApi(Api):
       return 'RUNNING'
     elif status == 'SUSPENDED':
       return 'PAUSED'
+    elif status == 'SUCCEEDED':
+      return 'SUCCEEDED'    
     else:
-      return 'FINISHED' # SUCCEEDED , KILLED and FAILED
+      return 'FAILED' # KILLED and FAILED
 
 
 class WorkflowActionApi(Api):

+ 70 - 19
apps/jobbrowser/src/jobbrowser/templates/job_browser.mako

@@ -673,23 +673,44 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
   ${ _('Submitted') } <span data-bind="text: submitted"></span>
 
   <br><br>
-  Variables, Workspace<br>
+  Variables? Workspace<br>
   Duration 8s<br>
   <br><br>
 
-  <div class="progress-job progress active pull-left" style="background-color: #FFF; width: 100%" data-bind="css: {'progress-warning': progress() < 100, 'progress-success': progress() === 100}">
+  <div class="progress-job progress pull-left" style="background-color: #FFF; width: 100%" data-bind="css: {'progress-warning': isRunning(), 'progress-success': apiStatus() === 'SUCCEEDED', 'progress-danger': apiStatus() === 'FAILED'}">
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
   </div>
 
-  <a href="javascript:void(0)" data-bind="click: function() { control('kill'); }">${ _('Stop') }</a> |
-  <a href="javascript:void(0)" data-bind="click: function() { control('resume'); }">${ _('Resume')}</a> |
-  <a href="javascript:void(0)" data-bind="click: function() { control('rerun'); }">${ _('Rerun') }</a>
+  <div class="btn-group">
+    <!-- ko if: $root.job().hasKill -->
+    <button class="btn btn-danger" title="${_('Stop selected')}" data-bind="click: function() { control('kill'); }, enable: killEnabled">
+      ## TODO confirmation
+      <i class="fa fa-times"></i> ${_('Kill')}
+    </button>
+    <!-- /ko -->
+    <!-- ko if: $root.job().hasResume -->
+    <button class="btn" title="${ _('Resume selected') }" data-bind="click: function() { control('resume'); }, enable: resumeEnabled">
+      <i class="fa fa-play"></i> ${ _('Resume') }
+    </button>
+    <!-- /ko -->
+    <!-- ko if: $root.job().hasSuspend -->
+    <button class="btn" title="${ _('Suspend selected') }" data-bind="click: function() { control('resume'); }, enable: suspendEnabled">
+      <i class="fa fa-pause"></i> ${ _('Suspend') }
+    </button>
+    <!-- /ko -->
+    <!-- ko if: $root.job().hasRerun -->
+    <button class="btn" title="${ _('Rerun selected') }" data-bind="click: function() { control('rerun'); }, enable: rerunEnabled">
+      <i class="fa fa-repeat"></i> ${ _('Rerun') }
+    </button>
+    <!-- /ko -->
+  </div>
+
 
   <ul class="nav nav-tabs margin-top-20">
     <li class="active"><a href="#workflow-page-graph" data-toggle="tab">${ _('Graph') }</a></li>
+    <li><a href="#workflow-page-metadata" data-bind="click: function(){ fetchProfile('properties'); $('a[href=\'#workflow-page-metadata\']').tab('show'); }">${ _('Properties') }</a></li>
     <li><a href="#workflow-page-logs" data-toggle="tab">${ _('Logs') }</a></li>
     <li><a href="#workflow-page-tasks" data-toggle="tab">${ _('Tasks') }</a></li>
-    <li><a href="#workflow-page-metadata" data-bind="click: function(){ fetchProfile('properties'); $('a[href=\'#workflow-page-metadata\']').tab('show'); }">${ _('Properties') }</a></li>
     <li><a href="#workflow-page-xml" data-bind="click: function(){ fetchProfile('xml'); $('a[href=\'#workflow-page-xml\']').tab('show'); }">${ _('XML') }</a></li>
   </ul>
 
@@ -978,7 +999,8 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
 
   (function () {
 
-/**
+/**  cf. updateWorkflowGraph()
+
     var Workflow = function(vm, job) {
 
             var lastPosition = {
@@ -1036,6 +1058,9 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       self.status = ko.observableDefault(job.status);
       self.apiStatus = ko.observableDefault(job.apiStatus);
       self.progress = ko.observableDefault(job.progress);
+      self.isRunning = ko.computed(function() {
+        return self.apiStatus() != 'SUCCEEDED' && self.apiStatus() != 'FAILED';
+      });
 
       self.user = ko.observableDefault(job.user);
       self.cluster = ko.observableDefault(job.cluster);
@@ -1049,7 +1074,37 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       self.properties = ko.mapping.fromJS(job.properties || {});
       self.mainType = ko.observable(vm.interface());
 
+      self.isKill = ko.computed(function() {
+        return ['workflow'].indexOf(self.type()) != -1;
+      });
+      self.hasKill = ko.computed(function() {
+        return ['workflow'].indexOf(self.type()) != -1;
+      });
+      self.killEnabled = ko.computed(function() {
+        return self.hasKill() && self.apiStatus() == 'RUNNING';
+      });
+      self.hasResume = ko.computed(function() {
+        return ['workflow'].indexOf(self.type()) != -1;
+      });
+      self.resumeEnabled = ko.computed(function() {
+        return self.hasResume() && self.apiStatus() == 'PAUSED';
+      });
+      self.hasRerun = ko.computed(function() {
+        return ['workflow'].indexOf(self.type()) != -1;
+      });
+      self.rerunEnabled = ko.computed(function() {
+        return self.hasRerun() && ! self.isRunning();
+      });
+      self.hasPause = ko.computed(function() {
+        return ['workflow'].indexOf(self.type()) != -1;
+      });
+      self.pauseEnabled = ko.computed(function() {
+        return self.hasPause() && self.apiStatus() == 'RUNNING';
+      });
+
       self.loadingJob = ko.observable(false);
+      var lastFetchJobRequest = null;
+      var lastUpdateJobRequest = null;
 
       self._fetchJob = function (callback) {
         return $.post("/jobbrowser/api/job", {
@@ -1066,9 +1121,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
         });
       };
 
-      var lastFetchJobRequest = null;
-      var lastUpdateJobRequest = null;
-
       self.fetchJob = function () {
         vm.apiHelper.cancelActiveRequest(lastFetchJobRequest);
         vm.apiHelper.cancelActiveRequest(lastUpdateJobRequest);
@@ -1123,7 +1175,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
             crumbs.push({'id': vm.job().id(), 'name': vm.job().name(), 'type': vm.job().type()});
             vm.resetBreadcrumbs(crumbs);
 
-            self.fetchLogs();
+            vm.job().fetchLogs();
           } else {
             $(document).trigger("error", data.message);
           }
@@ -1137,8 +1189,11 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
 
         if (vm.job() == self && self.apiStatus() == 'RUNNING') {
           lastFetchJobRequest = self._fetchJob(function (data) {
-            vm.job(new Job(vm, data.app)); // vm.job().fetchStatus() would only update progress and status
+            // vm.job(new Job(vm, data.app)); // Updates everything but redraw the page
+            vm.job().fetchStatus();
             vm.job().fetchLogs();
+            // vm.job().fetchProfile(); // Get name of active tab?
+            // updateWorkflowGraph() // If workflow
           });
         }
       };
@@ -1174,10 +1229,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       };
 
       self.fetchStatus = function () {
-        if (self.apiStatus() != 'RUNNING') {
-          return;
-        }
-
         $.post("/jobbrowser/api/job", {
           app_id: ko.mapping.toJSON(self.id),
           interface: ko.mapping.toJSON(self.mainType)
@@ -1201,10 +1252,10 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
         }, function (data) {
           if (data.status == 0) {
              $(document).trigger("info", data.message);
+             self.fetchStatus();
           } else {
             $(document).trigger("error", data.message);
           }
-        }).always(function () {
         });
       };
     };
@@ -1215,10 +1266,10 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       self.apps = ko.observableArray().extend({ rateLimit: 50 });
       self.totalApps = ko.observable(null);
       self.runningApps = ko.computed(function(job) {
-        return $.grep(self.apps(), function(job) { return job.apiStatus() == 'RUNNING'; });
+        return $.grep(self.apps(), function(job) { return job.isRunning(); });
       });
       self.finishedApps = ko.computed(function(job) {
-        return $.grep(self.apps(), function(job) { return job.apiStatus() == 'FINISHED'; });
+        return $.grep(self.apps(), function(job) { return ! job.isRunning(); });
       });
       self.loadingJobs = ko.observable(false);
       self.selectedJobs = ko.observableArray();