azkaban-uncached
Changes
src/java/azkaban/webapp/servlet/velocity/flowpage.vm 228(+132 -96)
src/web/js/azkaban.flow.view.js 172(+97 -75)
Details
src/java/azkaban/webapp/servlet/velocity/flowpage.vm 228(+132 -96)
diff --git a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
index cde432c..3abe09d 100644
--- a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
@@ -16,16 +16,12 @@
<!DOCTYPE html>
<html>
- <head>
-#parse( "azkaban/webapp/servlet/velocity/style.vm" )
- <script type="text/javascript" src="${context}/js/jquery/jquery-1.9.1.js"></script>
+ <head lang="en">
+
+#parse("azkaban/webapp/servlet/velocity/style2.vm")
+#parse("azkaban/webapp/servlet/velocity/javascript.vm")
+
<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui-1.10.1.custom.js"></script>
-
- <script type="text/javascript" src="${context}/js/underscore-1.4.4-min.js"></script>
- <script type="text/javascript" src="${context}/js/namespace.js"></script>
- <script type="text/javascript" src="${context}/js/backbone-0.9.10-min.js"></script>
- <script type="text/javascript" src="${context}/js/jquery.simplemodal-1.4.4.js"></script>
-
<script type="text/javascript" src="${context}/js/azkaban.date.utils.js"></script>
<script type="text/javascript" src="${context}/js/azkaban.ajax.utils.js"></script>
<script type="text/javascript" src="${context}/js/azkaban.common.utils.js"></script>
@@ -47,107 +43,147 @@
var flowId = "${flowid}";
var execId = null;
</script>
+ <link rel="stylesheet" type="text/css" href="${context}/css/azkaban-svg.css" />
<link rel="stylesheet" type="text/css" href="${context}/css/jquery-ui-1.10.1.custom.css" />
</head>
<body>
-#set($current_page="all")
-#parse( "azkaban/webapp/servlet/velocity/nav.vm" )
- <div class="messaging"><p id="messageClose">X</p><p id="message"></p></div>
- <div class="content">
-#if($errorMsg)
- <div class="box-error-message">$errorMsg</div>
+
+#set ($current_page="all")
+#parse ("azkaban/webapp/servlet/velocity/nav2.vm")
+
+ <div class="container">
+
+## Page error or success message.
+
+#if ($errorMsg)
+ <div class="panel panel-danger">
+ <div class="panel-heading">Error</div>
+ <div class="panel-body">
+ $errorMsg
+ </div>
+ </div>
#else
-#if($error_message != "null")
- <div class="box-error-message">$error_message</div>
-#elseif($success_message != "null")
- <div class="box-success-message">$success_message</div>
-#end
+ #if ($error_message != "null")
+ <div class="alert alert-danger">$error_message</div>
+ #elseif ($success_message != "null")
+ <div class="alert alert-success">$success_message</div>
+ #end
- <div id="all-jobs-content">
- <div class="section-hd flow-header">
- <h2><a href="${context}/manager?project=${project.name}&flow=${flowid}">Flow <span>$flowid</span></a></h2>
- <div class="section-sub-hd">
- <h4><a href="${context}/manager?project=${project.name}">Project <span>$project.name</span></a></h4>
- <h4 class="separator">></h4>
- <h4><a href="${context}/manager?project=${project.name}&flow=${flowid}">Flow <span>$flowid</span></a></h4>
- </div>
-
- <div id="executebtn" class="btn1">Schedule / Execute Flow</div>
- </div>
-
- <div id="headertabs" class="headertabs">
- <ul>
- <li><a id="graphViewLink" href="#graph">Graph</a></li>
- <li class="lidivider">|</li>
- <li><a id="executionsViewLink" href="#executions">Executions</a></li>
- </ul>
- </div>
- <div id="graphView">
- <div class="relative">
- <div id="jobList" class="jobList">
- <div id="filterList" class="filterList">
- <input id="filter" class="filter" placeholder=" Job Filter" />
- </div>
- <div id="list" class="list">
- </div>
- <div id="resetPanZoomBtn" class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
- </div>
- <div id="svgDiv" class="svgDiv">
- <svg id="svgGraph" class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
- </svg>
+ ## Alert message
+
+ <div class="alert alert-dismissable alert-messaging" id="messaging">
+ <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+ <p id="messaging-message"></p>
+ </div>
+
+ ## Page header.
+
+ <div class="row">
+ <div class="col-lg-8">
+ <h1><a href="${context}/manager?project=${project.name}">Project <small>$project.name</small></a></h1>
+ <p>$project.description</p>
+ </div>
+ <div class="col-lg-4">
+ <button type="button" class="btn btn-success" id="executebtn">Schedule / Execute Flow</button>
+ </div>
+ </div>
+ <hr>
+
+ ## Breadcrumbs
+
+ <div class="row">
+ <div class="col-lg-12">
+ <ol class="breadcrumb">
+ <li><a href="${context}/manager?project=${project.name}"><strong>Project</strong> $project.name</a></li>
+ <li><a href="${context}/manager?project=${project.name}&flow=${flowid}"><strong>Flow</strong> $flowid</a></li>
+ </ol>
+
+ <ul class="nav nav-tabs" id="headertabs">
+ <li class="active"><a href="#" id="graphViewLink">Graph</a></li>
+ <li><a href="#" id="executionsViewLink">Executions</a></li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="row" id="graphView">
+ <div class="col-lg-4">
+ <div class="panel panel-default" id="jobList">
+ <div class="panel-heading">
+ <div class="pull-right">
+ <button type="button" class="btn btn-xs btn-default" id="resetPanZoomBtn">Reset Pan Zoom</button>
</div>
+ Jobs
</div>
- </div>
- <div id="executionsView">
- <div id="executionDiv" class="all-jobs executionInfo">
- <table id="execTable">
- <thead>
- <tr>
- <th>Execution Id</th>
- <th>User</th>
- <th class="date">Start Time</th>
- <th class="date">End Time</th>
- <th class="elapse">Elapsed</th>
- <th class="status">Status</th>
- <th class="action">Action</th>
- </tr>
- </thead>
- <tbody id="execTableBody">
- </tbody>
- </table>
- </div>
-
- <div id="pageSelection">
- <ul>
- <li id="previous" class="first"><a><span class="arrow">←</span>Previous</a></li>
- <li id="page1"><a href="#page1">1</a></li>
- <li id="page2"><a href="#page2">2</a></li>
- <li id="page3"><a href="#page3">3</a></li>
- <li id="page4"><a href="#page4">4</a></li>
- <li id="page5"><a href="#page5">5</a></li>
- <li id="next"><a>Next<span class="arrow">→</span></a></li>
- </ul>
+ <div class="panel-body">
+ <input id="filter" type="text" placeholder="Job Filter">
+ <div id="list"></div>
</div>
</div>
</div>
- <!-- modal content -->
+ <div class="col-lg-8">
+ <div id="svgDiv" class="well">
+ <svg id="svgGraph" class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
+ </svg>
+ </div>
+ </div>
+ </div>
- <div id="invalid-session" class="modal">
- <h3>Invalid Session</h3>
- <p>Session has expired. Please re-login.</p>
- <div class="actions">
- <a class="yes btn3" id="login-btn" href="#">Re-login</a>
- </div>
+ <div class="row" id="executionsView">
+ <div class="col-lg-12">
+ <table class="table table-striped table-bordered" id="execTable">
+ <thead>
+ <tr>
+ <th>Execution Id</th>
+ <th>User</th>
+ <th class="date">Start Time</th>
+ <th class="date">End Time</th>
+ <th class="elapse">Elapsed</th>
+ <th class="status">Status</th>
+ <th class="action">Action</th>
+ </tr>
+ </thead>
+ <tbody id="execTableBody">
+ </tbody>
+ </table>
+ <ul id="pageSelection" class="pagination">
+ <li id="previous" class="first"><a><span class="arrow">←</span>Previous</a></li>
+ <li id="page1"><a href="#page1">1</a></li>
+ <li id="page2"><a href="#page2">2</a></li>
+ <li id="page3"><a href="#page3">3</a></li>
+ <li id="page4"><a href="#page4">4</a></li>
+ <li id="page5"><a href="#page5">5</a></li>
+ <li id="next"><a>Next<span class="arrow">→</span></a></li>
+ </ul>
</div>
+ </div>
+
+ <div id="contextMenu">
+ </div>
-#parse( "azkaban/webapp/servlet/velocity/flowexecutionpanel.vm" )
+ ## Modal dialog to be displayed when the user sesion is invalid.
+
+ <div class="modal fade" id="invalid-session-modal">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h4 class="modal-title">Invalid Session</h4>
+ </div>
+ <div class="modal-body">
+ <p>Session has expired. Please re-login.</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary" id="login-btn">Re-login</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ #parse ("azkaban/webapp/servlet/velocity/flowexecutionpanel.vm")
+ #parse ("azkaban/webapp/servlet/velocity/messagedialog.vm")
#end
- </div>
- <div id="contextMenu">
- </div>
- #parse( "azkaban/webapp/servlet/velocity/messagedialog.vm" )
+#parse("azkaban/webapp/servlet/velocity/footer.vm")
+ </div><!-- /.container -->
</body>
-</html>
-
+</body>
src/web/js/azkaban.flow.view.js 172(+97 -75)
diff --git a/src/web/js/azkaban.flow.view.js b/src/web/js/azkaban.flow.view.js
index ce01dbc..abcfd77 100644
--- a/src/web/js/azkaban.flow.view.js
+++ b/src/web/js/azkaban.flow.view.js
@@ -41,12 +41,13 @@ var handleJobMenuClick = function(action, el, pos) {
}
var flowTabView;
-azkaban.FlowTabView= Backbone.View.extend({
- events : {
- "click #graphViewLink" : "handleGraphLinkClick",
- "click #executionsViewLink" : "handleExecutionLinkClick"
+azkaban.FlowTabView = Backbone.View.extend({
+ events: {
+ "click #graphViewLink": "handleGraphLinkClick",
+ "click #executionsViewLink": "handleExecutionLinkClick"
},
- initialize : function(settings) {
+
+ initialize: function(settings) {
var selectedView = settings.selectedView;
if (selectedView == "executions") {
this.handleExecutionLinkClick();
@@ -54,11 +55,12 @@ azkaban.FlowTabView= Backbone.View.extend({
else {
this.handleGraphLinkClick();
}
-
},
+
render: function() {
console.log("render graph");
},
+
handleGraphLinkClick: function(){
$("#executionsViewLink").removeClass("selected");
$("#graphViewLink").addClass("selected");
@@ -66,13 +68,14 @@ azkaban.FlowTabView= Backbone.View.extend({
$("#executionsView").hide();
$("#graphView").show();
},
+
handleExecutionLinkClick: function() {
$("#graphViewLink").removeClass("selected");
$("#executionsViewLink").addClass("selected");
- $("#graphView").hide();
- $("#executionsView").show();
- executionModel.trigger("change:view");
+ $("#graphView").hide();
+ $("#executionsView").show();
+ executionModel.trigger("change:view");
}
});
@@ -84,12 +87,14 @@ azkaban.ExecutionsView = Backbone.View.extend({
events: {
"click #pageSelection li": "handleChangePageSelection"
},
+
initialize: function(settings) {
this.model.bind('change:view', this.handleChangeView, this);
this.model.bind('render', this.render, this);
this.model.set({page: 1, pageSize: 16});
this.model.bind('change:page', this.handlePageChange, this);
},
+
render: function(evt) {
console.log("render");
// Render page selections
@@ -155,6 +160,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
this.renderPagination(evt);
},
+
renderPagination: function(evt) {
var total = this.model.get("total");
total = total? total : 1;
@@ -228,14 +234,15 @@ azkaban.ExecutionsView = Backbone.View.extend({
a.attr("href", "#page" + tpage);
}
},
+
handleChangePageSelection: function(evt) {
if ($(evt.currentTarget).hasClass("disabled")) {
return;
}
var page = evt.currentTarget.page;
-
this.model.set({"page": page});
},
+
handleChangeView: function(evt) {
if (this.init) {
return;
@@ -245,21 +252,28 @@ azkaban.ExecutionsView = Backbone.View.extend({
this.handlePageChange(evt);
this.init = true;
},
+
handlePageChange: function(evt) {
var page = this.model.get("page") - 1;
var pageSize = this.model.get("pageSize");
var requestURL = contextURL + "/manager";
var model = this.model;
- $.get(
- requestURL,
- {"project": projectName, "flow":flowId, "ajax": "fetchFlowExecutions", "start":page * pageSize, "length": pageSize},
- function(data) {
- model.set({"executions": data.executions, "total": data.total});
- model.trigger("render");
- },
- "json"
- );
+ var requestData = {
+ "project": projectName,
+ "flow": flowId,
+ "ajax": "fetchFlowExecutions",
+ "start": page * pageSize,
+ "length": pageSize
+ };
+ var successHandler = function(data) {
+ model.set({
+ "executions": data.executions,
+ "total": data.total
+ });
+ model.trigger("render");
+ };
+ $.get(requestURL, requestData, successHandler, "json");
}
});
@@ -269,8 +283,8 @@ var exNodeClickCallback = function(event) {
var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" + flowId + "&job=" + jobId;
var menu = [
- {title: "Open Job...", callback: function() {window.location.href=requestURL;}},
- {title: "Open Job in New Window...", callback: function() {window.open(requestURL);}}
+ {title: "Open Job...", callback: function() {window.location.href=requestURL;}},
+ {title: "Open Job in New Window...", callback: function() {window.open(requestURL);}}
];
contextMenuView.show(event, menu);
@@ -282,8 +296,8 @@ var exJobClickCallback = function(event) {
var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" + flowId + "&job=" + jobId;
var menu = [
- {title: "Open Job...", callback: function() {window.location.href=requestURL;}},
- {title: "Open Job in New Window...", callback: function() {window.open(requestURL);}}
+ {title: "Open Job...", callback: function() {window.location.href=requestURL;}},
+ {title: "Open Job in New Window...", callback: function() {window.open(requestURL);}}
];
contextMenuView.show(event, menu);
@@ -318,14 +332,20 @@ $(function() {
var selected;
// Execution model has to be created before the window switches the tabs.
executionModel = new azkaban.ExecutionModel();
- executionsView = new azkaban.ExecutionsView({el:$('#executionsView'), model: executionModel});
- flowTabView = new azkaban.FlowTabView({el:$( '#headertabs'), selectedView: selected });
+ executionsView = new azkaban.ExecutionsView({
+ el: $('#executionsView'),
+ model: executionModel
+ });
+ flowTabView = new azkaban.FlowTabView({
+ el: $('#headertabs'),
+ selectedView: selected
+ });
graphModel = new azkaban.GraphModel();
mainSvgGraphView = new azkaban.SvgGraphView({
el: $('#svgDiv'),
model: graphModel,
- rightClick: {
+ rightClick: {
"node": exNodeClickCallback,
"edge": exEdgeClickCallback,
"graph": exGraphClickCallback
@@ -352,61 +372,63 @@ $(function() {
flowExecuteDialogView.show(executingData);
});
- $.get(
- requestURL,
- {"project": projectName, "ajax":"fetchflowgraph", "flow":flowId},
- function(data) {
- // Create the nodes
- var nodes = {};
- for (var i=0; i < data.nodes.length; ++i) {
- var node = data.nodes[i];
- nodes[node.id] = node;
+ var requestData = {
+ "project": projectName,
+ "ajax":"fetchflowgraph",
+ "flow": flowId
+ };
+ var successHandler = function(data) {
+ // Create the nodes
+ var nodes = {};
+ for (var i = 0; i < data.nodes.length; ++i) {
+ var node = data.nodes[i];
+ nodes[node.id] = node;
+ }
+ for (var i = 0; i < data.edges.length; ++i) {
+ var edge = data.edges[i];
+ var fromNode = nodes[edge.from];
+ var toNode = nodes[edge.target];
+
+ if (!fromNode.outNodes) {
+ fromNode.outNodes = {};
}
- for (var i=0; i < data.edges.length; ++i) {
- var edge = data.edges[i];
- var fromNode = nodes[edge.from];
- var toNode = nodes[edge.target];
-
- if (!fromNode.outNodes) {
- fromNode.outNodes = {};
- }
- fromNode.outNodes[toNode.id] = toNode;
-
- if (!toNode.inNodes) {
- toNode.inNodes = {};
- }
- toNode.inNodes[fromNode.id] = fromNode;
+ fromNode.outNodes[toNode.id] = toNode;
+
+ if (!toNode.inNodes) {
+ toNode.inNodes = {};
}
+ toNode.inNodes[fromNode.id] = fromNode;
+ }
+
+ console.log("data fetched");
+ graphModel.set({data: data});
+ graphModel.set({nodes: nodes});
+ graphModel.set({disabled: {}});
+ graphModel.trigger("change:graph");
- console.log("data fetched");
- graphModel.set({data: data});
- graphModel.set({nodes: nodes});
- graphModel.set({disabled: {}});
- graphModel.trigger("change:graph");
-
- // Handle the hash changes here so the graph finishes rendering first.
- if (window.location.hash) {
- var hash = window.location.hash;
- if (hash == "#executions") {
+ // Handle the hash changes here so the graph finishes rendering first.
+ if (window.location.hash) {
+ var hash = window.location.hash;
+ if (hash == "#executions") {
+ flowTabView.handleExecutionLinkClick();
+ }
+ else if (hash == "#graph") {
+ // Redundant, but we may want to change the default.
+ selected = "graph";
+ }
+ else {
+ if ("#page" == hash.substring(0, "#page".length)) {
+ var page = hash.substring("#page".length, hash.length);
+ console.log("page " + page);
flowTabView.handleExecutionLinkClick();
- }
- else if (hash == "#graph") {
- // Redundant, but we may want to change the default.
- selected = "graph";
+ executionModel.set({"page": parseInt(page)});
}
else {
- if ("#page" == hash.substring(0, "#page".length)) {
- var page = hash.substring("#page".length, hash.length);
- console.log("page " + page);
- flowTabView.handleExecutionLinkClick();
- executionModel.set({"page": parseInt(page)});
- }
- else {
- selected = "graph";
- }
+ selected = "graph";
}
}
- },
- "json"
- );
+ }
+ };
+
+ $.get(requestURL, requestData, successHandler, "json");
});