Repository: eagle
Updated Branches:
  refs/heads/master 906692058 -> 93f83f4a9


[EAGLE-949] Support job suggestion

JPM:
* Success job display job suggestions
* Failure Job display task attempt & detail

APP:
* UI support dialog window

Author: zombieJ <[email protected]>

Closes #872 from zombieJ/EAGLE-949.


Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/93f83f4a
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/93f83f4a
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/93f83f4a

Branch: refs/heads/master
Commit: 93f83f4a975dd3303f776c4fc9b3da8a53384aa3
Parents: 9066920
Author: zombieJ <[email protected]>
Authored: Wed Mar 15 00:52:54 2017 +0800
Committer: Hao Chen <[email protected]>
Committed: Wed Mar 15 00:52:54 2017 +0800

----------------------------------------------------------------------
 .../main/webapp/app/apps/jpm/ctrl/detailCtrl.js | 73 ++++++++++++++++----
 .../app/apps/jpm/partials/job/detail.html       | 46 +++++++++++-
 .../src/main/webapp/app/dev/public/css/main.css |  4 ++
 .../webapp/app/dev/public/js/services/uiSrv.js  | 33 +++++++++
 eagle-server/src/main/webapp/app/package.json   |  2 +-
 5 files changed, 141 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/eagle/blob/93f83f4a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/detailCtrl.js
----------------------------------------------------------------------
diff --git 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/detailCtrl.js 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/detailCtrl.js
index 905f270..b56335b 100644
--- a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/detailCtrl.js
+++ b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/detailCtrl.js
@@ -21,7 +21,7 @@
         * `register` without params will load the module which using require
         */
        register(function (jpmApp) {
-               jpmApp.controller("detailCtrl", function ($q, $wrapState, 
$element, $scope, PageConfig, Time, Entity, JPM) {
+               jpmApp.controller("detailCtrl", function ($q, $wrapState, 
$element, $rootScope, $scope, $sce, PageConfig, Time, Entity, JPM, UI) {
                        var TASK_BUCKET_TIMES = [0, 30, 60, 120, 300, 600, 
1800, 3600, 7200, 18000];
                        var i;
                        var startTime, endTime;
@@ -125,21 +125,68 @@
 
 
                                // =============================== task attempt 
===============================
-                               if ($scope.job.currentState === 'FAILED') {
-                                       $scope.taskAttemptList = 
JPM.list('TaskAttemptErrorCategoryService', {
-                                               site: $scope.job.tags.site,
-                                               jobId: $scope.job.tags.jobId
-                                       },
+                               (function () {
+                                       if ($scope.job.currentState === 
'FAILED') {
+                                               // Attempt List
+                                               $scope.taskAttemptList = 
JPM.list('TaskAttemptErrorCategoryService', {
+                                                       site: 
$scope.job.tags.site,
+                                                       jobId: 
$scope.job.tags.jobId
+                                               },
+                                                       
Time($scope.startTimestamp).subtract(1, 'day'),
+                                                       
Time($scope.endTimestamp).add(1, 'day'));
+                                               $scope.taskAttemptCategories = 
{};
+                                               
$scope.taskAttemptList._promise.then(function () {
+                                                       
$.each($scope.taskAttemptList, function (i, attempt) {
+                                                               
$scope.taskAttemptCategories[attempt.tags.errorCategory] =
+                                                                       
($scope.taskAttemptCategories[attempt.tags.errorCategory] || 0) + 1;
+                                                       });
+                                               });
+
+                                               // Error Mapping
+                                               $scope.errorMapping = {};
+                                               var errorMappingList = 
JPM.list('JobErrorMappingService', {
+                                                       site: 
$scope.job.tags.site,
+                                                       jobId: 
$scope.job.tags.jobId
+                                               },
+                                                       
Time($scope.startTimestamp).subtract(1, 'day'),
+                                                       
Time($scope.endTimestamp).add(1, 'day'));
+                                               
errorMappingList._promise.then(function () {
+                                                       
$.each(errorMappingList, function (i, entity) {
+                                                               var 
errorTooltip = $sce.trustAsHtml('<div class="text-break">' + entity.error + 
'</div>');
+
+                                                               
$.each(entity.taskAttempts, function (j, attempt) {
+                                                                       
$scope.errorMapping[attempt] = errorTooltip;
+                                                               });
+                                                       });
+                                               });
+                                       }
+                               })();
+
+                               $scope.loadAttemptDetail = function 
(taskAttemptId) {
+                                       var scope = $rootScope.$new(true);
+                                       scope.content = 'Loading...';
+
+                                       var attemptList = 
JPM.list('TaskAttemptExecutionService', {
+                                                       site: 
$scope.job.tags.site,
+                                                       taskAttemptId: 
taskAttemptId
+                                               },
                                                
Time($scope.startTimestamp).subtract(1, 'day'),
                                                
Time($scope.endTimestamp).add(1, 'day'));
-                                       $scope.taskAttemptCategories = {};
-                                       
$scope.taskAttemptList._promise.then(function () {
-                                               $.each($scope.taskAttemptList, 
function (i, attempt) {
-                                                       
$scope.taskAttemptCategories[attempt.tags.errorCategory] =
-                                                               
($scope.taskAttemptCategories[attempt.tags.errorCategory] || 0) + 1;
-                                               });
+                                       attemptList._promise.then(function () {
+                                               scope.content = 
common.getValueByPath(attemptList, [0, 'error'], '(No Data)');
+                                               scope.$apply();
                                        });
-                               }
+
+                                       UI.dialog(taskAttemptId, 
'<pre>{{content}}</pre>', scope);
+                               };
+
+                               // ============================== job 
suggestion ==============================
+                               $scope.jobSuggestionList = 
JPM.list('JobOptimizerSuggestionService', {
+                                               site: $scope.job.tags.site,
+                                               jobId: $scope.job.tags.jobId
+                                       },
+                                       Time($scope.startTimestamp).subtract(1, 
'day'),
+                                       Time($scope.endTimestamp).add(1, 
'day'));
 
                                // ================================ dashboards 
================================
                                // Dashboard 1: Allocated MB

http://git-wip-us.apache.org/repos/asf/eagle/blob/93f83f4a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/job/detail.html
----------------------------------------------------------------------
diff --git 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/job/detail.html 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/job/detail.html
index 359b043..eeb5976 100644
--- 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/job/detail.html
+++ 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/job/detail.html
@@ -193,7 +193,7 @@
        </div>
        <div class="box-body">
                <div sort-table="taskAttemptList" is-sorting="isSorting" 
class="table-responsive" max-size="7" ng-show="taskAttemptList._done">
-                       <table class="table table-bordered">
+                       <table class="table table-bordered table-hover">
                                <thead>
                                <tr>
                                        <th sortpath="startTime">Start Time</th>
@@ -205,13 +205,53 @@
                                </tr>
                                </thead>
                                <tbody>
-                               <tr ng-repeat="item in jobList">
+                               <tr class="row-clickable" 
ng-click="loadAttemptDetail(item.tags.taskAttemptId)">
                                        <td>{{Time.format(item.startTime)}}</td>
                                        <td>{{Time.format(item.endTime)}}</td>
                                        <td>{{item.tags.hostname || "-"}}</td>
                                        <td>{{item.tags.taskType || "-"}}</td>
                                        <td>{{item.tags.taskAttemptId || 
"-"}}</td>
-                                       <td>{{item.tags.errorCategory || 
"-"}}</td>
+                                       <td class="text-no-break">
+                                               {{item.tags.errorCategory || 
"-"}}
+                                               <span
+                                                               
ng-if="errorMapping[item.tags.taskAttemptId]"
+                                                               class="fa 
fa-info-circle" tooltip-placement="left"
+                                                               
uib-tooltip-html="errorMapping[item.tags.taskAttemptId]"
+                                               >
+                                               </span>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </div>
+       </div>
+</div>
+
+<!-- Job Suggestion -->
+<div class="box box-primary collapsed-box" ng-if="jobSuggestionList.length">
+       <div class="box-header with-border">
+               <h3 class="box-title">
+                       Job Suggestion ({{jobSuggestionList.length}})
+               </h3>
+               <div class="box-tools pull-right">
+                       <button type="button" class="btn btn-box-tool" 
data-widget="collapse">
+                               <i class="fa fa-plus"></i>
+                       </button>
+               </div>
+       </div>
+       <div class="box-body">
+               <div sort-table="jobSuggestionList" class="table-responsive" 
max-size="7">
+                       <table class="table table-bordered">
+                               <thead>
+                               <tr>
+                                       <th sortpath="tags.ruleType">Rule 
Type</th>
+                                       <th>Optimizer Suggestion</th>
+                               </tr>
+                               </thead>
+                               <tbody>
+                               <tr>
+                                       <td>{{item.tags.ruleType}}</td>
+                                       <td><pre 
class="inline">{{item.optimizerSuggestion}}</pre></td>
                                </tr>
                                </tbody>
                        </table>

http://git-wip-us.apache.org/repos/asf/eagle/blob/93f83f4a/eagle-server/src/main/webapp/app/dev/public/css/main.css
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/css/main.css 
b/eagle-server/src/main/webapp/app/dev/public/css/main.css
index 30e10d7..a50ffac 100644
--- a/eagle-server/src/main/webapp/app/dev/public/css/main.css
+++ b/eagle-server/src/main/webapp/app/dev/public/css/main.css
@@ -163,6 +163,10 @@ table.table .btn-group .btn.opt {
        width: 22px;
 }
 
+table.table .row-clickable {
+       cursor: pointer;
+}
+
 table.table.table-sm th,
 table.table.table-sm td {
        padding: 3px 5px;

http://git-wip-us.apache.org/repos/asf/eagle/blob/93f83f4a/eagle-server/src/main/webapp/app/dev/public/js/services/uiSrv.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/services/uiSrv.js 
b/eagle-server/src/main/webapp/app/dev/public/js/services/uiSrv.js
index 6ce77b8..81ee9d8 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/services/uiSrv.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/services/uiSrv.js
@@ -252,6 +252,21 @@
                        return wrapPromise(_deferred.promise);
                };
 
+               UI.dialog = function (title, html, $scope) {
+                       var $mdl;
+
+                       $mdl = $(common.template(TMPL_MODAL, {
+                               title: title,
+                               html: html
+                       })).appendTo('body');
+                       $compile($mdl)($scope);
+                       $mdl.modal();
+
+                       $mdl.on("hidden.bs.modal", function() {
+                               $mdl.remove();
+                       });
+               };
+
                return UI;
        });
 
@@ -313,4 +328,22 @@
                '</div>' +
                '</div>' +
                '</div>';
+
+       var TMPL_MODAL =
+               '<div class="modal fade" tabindex="-1" role="dialog" 
aria-hidden="true">' +
+                       '<div class="modal-dialog">' +
+                               '<div class="modal-content">' +
+                                       '<div class="modal-header">' +
+                                               '<button type="button" 
class="close" data-dismiss="modal" aria-hidden="true">&times;</button>' +
+                                               '<h4 
class="modal-title">${title}</h4>' +
+                                       '</div>' +
+                                       '<div class="modal-body">' +
+                                               '${html}' +
+                                       '</div>' +
+                                       '<div class="modal-footer">' +
+                                               '<button type="button" 
class="btn btn-default" data-dismiss="modal">Close</button>' +
+                                       '</div>' +
+                               '</div>' +
+                       '</div>' +
+               '</div>';
 }());

http://git-wip-us.apache.org/repos/asf/eagle/blob/93f83f4a/eagle-server/src/main/webapp/app/package.json
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/package.json 
b/eagle-server/src/main/webapp/app/package.json
index 2c5d272..11d72e3 100644
--- a/eagle-server/src/main/webapp/app/package.json
+++ b/eagle-server/src/main/webapp/app/package.json
@@ -19,7 +19,7 @@
     "angular-cookies": "1.5.0",
     "angular-resource": "1.5.0",
     "angular-route": "1.5.0",
-    "angular-ui-bootstrap": "1.1.2",
+    "angular-ui-bootstrap": "1.3.3",
     "angular-ui-router": "0.3.1",
     "bootstrap": "3.3.6",
     "d3": "3.5.16",

Reply via email to