Explorar o código

HUE-4149 [editor] Integrated progress report of MR jobs

Enrico Berti %!s(int64=9) %!d(string=hai) anos
pai
achega
e56922995d

+ 2 - 0
desktop/core/src/desktop/templates/common_header.mako

@@ -302,6 +302,7 @@ if USE_NEW_EDITOR.get():
           },
           function(data) {
             if (data != null && data.jobs != null) {
+              huePubSub.publish('jobbrowser.data', data.jobs);
               if (data.jobs.length > 0){
                 $("#jobBrowserCount").removeClass("hide").text(data.jobs.length);
               }
@@ -314,6 +315,7 @@ if USE_NEW_EDITOR.get():
           window.clearTimeout(checkJobBrowserStatusIdx);
         });
       }
+      huePubSub.subscribe('check.job.browser', checkJobBrowserStatus);
       % endif
 
       function openDropdown(which, timeout){

+ 18 - 0
desktop/libs/notebook/src/notebook/static/notebook/css/notebook.css

@@ -617,6 +617,24 @@ h1.empty {
   background-color: #fdae6b;
 }
 
+.progress-job {
+  height: 2px;
+}
+
+.jobs-overlay {
+  background-color: transparent;
+}
+
+.jobs-overlay li {
+  background-color: #FFF;
+  margin-bottom: 5px;
+  padding: 0;
+}
+
+.jobs-overlay li a {
+  margin: 6px;
+}
+
 @-webkit-keyframes pulsate {
   0% {
     margin-left: 0;

+ 28 - 2
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -1052,7 +1052,7 @@
         notebook: ko.mapping.toJSON(notebook.getContext()),
         snippet: ko.mapping.toJSON(self.getContext()),
         from: self.result.logLines,
-        jobs: ko.mapping.toJSON(self.jobs),
+        jobs: ko.mapping.toJSON(self.jobs, { ignore: ['percentJob'] }),
         full_log: self.result.logs
       }, function (data) {
         if (data.status == 1) { // Append errors to the logs
@@ -1070,8 +1070,33 @@
               self.result.logs(oldLogs + "\n" + data.logs);
             }
           }
+
+          self.jobs().forEach(function(job){
+            if (typeof job.percentJob === 'undefined'){
+              job.percentJob = ko.observable(-1);
+            }
+          });
+
           if (data.jobs.length > 0) {
-            self.jobs(data.jobs);
+            data.jobs.forEach(function (job) {
+              var _found = ko.utils.arrayFilter(self.jobs(), function (item) {
+                return item.name === job.name;
+              });
+              if (_found.length === 0) {
+                if (typeof job.percentJob === 'undefined') {
+                  job.percentJob = ko.observable(-1);
+                }
+                self.jobs.push(job);
+              }
+            });
+            self.jobs().forEach(function (job) {
+              var _found = ko.utils.arrayFilter(self.jobs(), function (item) {
+                return item.name === job.name;
+              });
+              if (_found.length === 0) {
+                self.jobs.remove(job);
+              }
+            });
           }
           if (self.status() == 'running') { // Maybe the query finished or failed in the meantime
             self.progress(data.progress)
@@ -1947,6 +1972,7 @@
       }
 
       self.selectedNotebook(notebook);
+      huePubSub.publish('check.job.browser');
     };
 
     self.openNotebook = function (uuid, queryTab) {

+ 34 - 5
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -1103,7 +1103,14 @@ ${ hueIcons.symbols() }
   <div class="snippet-log-container margin-bottom-10" data-bind="visible: showLogs() && status() != 'ready' && status() != 'loading'" style="display: none;">
     <div data-bind="delayedOverflow, css: resultsKlass" style="margin-top: 5px; position: relative;">
       <ul data-bind="visible: jobs().length > 0, foreach: jobs" class="unstyled jobs-overlay">
-        <li><a data-bind="text: $.trim($data.name), attr: { href: $data.url }" target="_blank"></a></li>
+        <li data-bind="attr: {'id': $data.name.substr(4)}"><a data-bind="text: $.trim($data.name), attr: { href: $data.url }" target="_blank"></a>
+          <!-- ko if: typeof percentJob !== 'undefined' && percentJob() > -1 -->
+          <div class="progress-job progress active pull-left" style="background-color: #FFF; width: 100%" data-bind="css: {'progress-warning': percentJob() < 100, 'progress-success': percentJob() === 100}">
+            <div class="bar" data-bind="style: {'width': percentJob() + '%'}"></div>
+          </div>
+          <!-- /ko -->
+          <div class="clearfix"></div>
+        </li>
       </ul>
       <pre data-bind="visible: result.logs().length == 0" class="logs logs-bigger">${ _('No logs available at this moment.') }</pre>
       <pre data-bind="visible: result.logs().length > 0, text: result.logs, logScroller: result.logs, logScrollerVisibilityEvent: showLogs" class="logs logs-bigger logs-populated"></pre>
@@ -1722,7 +1729,7 @@ ${ hueIcons.symbols() }
 <script type="text/html" id="snippet-execution-status">
   <div class="snippet-execution-status" data-bind="clickForAceFocus: ace">
     <div class="snippet-progress-container">
-      <div class="progress active" data-bind="css: {
+      <div class="progress-snippet progress active" data-bind="css: {
         'progress-starting': progress() == 0 && status() == 'running',
         'progress-warning': progress() > 0 && progress() < 100,
         'progress-success': progress() == 100,
@@ -3134,7 +3141,7 @@ ${ hueIcons.symbols() }
 
       $(document).on("executeStarted", function (e, snippet) {
         var _el = $("#snippet_" + snippet.id()).find(".resultTable");
-        $("#snippet_" + snippet.id()).find(".progress").animate({
+        $("#snippet_" + snippet.id()).find(".progress-snippet").animate({
           height: "3px"
         }, 100);
         if (_el.hasClass("dt")) {
@@ -3214,7 +3221,7 @@ ${ hueIcons.symbols() }
       $(document).on("progress", function (e, options) {
         if (options.data == 100) {
           window.setTimeout(function () {
-            $("#snippet_" + options.snippet.id()).find(".progress").animate({
+            $("#snippet_" + options.snippet.id()).find(".progress-snippet").animate({
               height: "0"
             }, 100, function () {
               options.snippet.progress(0);
@@ -3234,12 +3241,34 @@ ${ hueIcons.symbols() }
         }
       });
 
-      huePubSub.subscribe('submit.popup.return', function(data){
+      huePubSub.subscribe('submit.popup.return', function (data) {
         console.log('Job id', data.job_id);
         $.jHueNotify.info('${_('Coordinator submitted.')}');
         $('.submit-modal').modal('hide');
       });
 
+      huePubSub.subscribe('jobbrowser.data', function (jobs) {
+        if (jobs.length > 0) {
+          jobs.forEach(function (job) {
+            if ($("#" + job.shortId).length > 0) {
+              var _job = ko.dataFor($("#" + job.shortId)[0]);
+              if (!isNaN(parseInt(job.mapsPercentComplete))) {
+                _job.percentJob(parseInt(job.mapsPercentComplete));
+              }
+            }
+          });
+        }
+        else {
+          if (viewModel.selectedNotebook()) {
+            viewModel.selectedNotebook().snippets().forEach(function (snippet) {
+              snippet.jobs().forEach(function (job) {
+                job.percentJob(100);
+              });
+            });
+          }
+        }
+      });
+
       $(document).on("gridShown", function (e, snippet) {
         window.setTimeout(function () {
           resizeToggleResultSettings(snippet);