|
|
@@ -17,44 +17,254 @@
|
|
|
<%!
|
|
|
from desktop.views import commonheader, commonfooter
|
|
|
from django.utils.translation import ugettext as _
|
|
|
+ import time as py_time
|
|
|
%>
|
|
|
<%namespace name="actionbar" file="../actionbar.mako" />
|
|
|
<%namespace name="layout" file="../navigation-bar.mako" />
|
|
|
<%namespace name="utils" file="../utils.inc.mako" />
|
|
|
|
|
|
${ commonheader(_("Workflows"), "oozie", user) | n,unicode }
|
|
|
-${ layout.menubar(section='workflows') }
|
|
|
+${ layout.menubar(section='workflows', is_editor=True) }
|
|
|
|
|
|
|
|
|
<div class="container-fluid">
|
|
|
<div class="card card-small">
|
|
|
<h1 class="card-heading simple">${ _('Workflow Manager') }</h1>
|
|
|
|
|
|
- <div class="btn-toolbar" style="display: inline; vertical-align: middle">
|
|
|
- <button class="btn toolbarBtn" id="submit-btn" disabled="disabled"><i class="fa fa-play"></i> ${ _('Submit') }</button>
|
|
|
+ <%actionbar:render>
|
|
|
+ <%def name="search()">
|
|
|
+ <input id="filterInput" type="text" class="input-xlarge search-query" placeholder="${_('Search for name, description, etc...')}">
|
|
|
+ </%def>
|
|
|
|
|
|
- <button class="btn toolbarBtn" id="clone-btn" disabled="disabled"><i class="fa fa-files-o"></i> ${ _('Copy') }</button>
|
|
|
-
|
|
|
- <button class="btn toolbarBtn" id="clone-btn" disabled="disabled"><i class="fa fa-times"></i> ${ _('Delete') }</button>
|
|
|
+ <%def name="actions()">
|
|
|
+ <div class="btn-toolbar" style="display: inline; vertical-align: middle">
|
|
|
+ <button class="btn toolbarBtn" id="submit-btn" disabled="disabled"><i class="fa fa-play"></i> ${ _('Submit') }</button>
|
|
|
+ <button class="btn toolbarBtn" id="schedule-btn" disabled="disabled"><i class="fa fa-calendar"></i> ${ _('Schedule') }</button>
|
|
|
+ <button class="btn toolbarBtn" id="clone-btn" disabled="disabled"><i class="fa fa-files-o"></i> ${ _('Copy') }</button>
|
|
|
+ <button class="btn toolbarBtn" id="delete-btn" disabled="disabled"><i class="fa fa-times"></i> ${ _('Delete') }</button>
|
|
|
+ </div>
|
|
|
+ </%def>
|
|
|
|
|
|
- <a href="${ url('oozie:new_workflow') }" class="btn"><i class="fa fa-plus-circle"></i> ${ _('Create') }</a>
|
|
|
- </div>
|
|
|
+ <%def name="creation()">
|
|
|
+ <a href="${ url('oozie:new_workflow') }" class="btn"><i class="fa fa-plus-circle"></i> ${ _('Create') }</a>
|
|
|
+ </%def>
|
|
|
+ </%actionbar:render>
|
|
|
|
|
|
+ <table id="workflowTable" class="table datatables">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th width="1%"><div class="hueCheckbox selectAll fa" data-selectables="workflowCheck"></div></th>
|
|
|
+ <th>${ _('Name') }</th>
|
|
|
+ <th>${ _('Description') }</th>
|
|
|
+ <th>${ _('Owner') }</th>
|
|
|
+ <th>${ _('Last Modified') }</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
% for workflow in workflows:
|
|
|
- <div>
|
|
|
- <a href="${ url('oozie:edit_workflow') }?workflow=${ workflow.id }">
|
|
|
- ${ workflow.name }
|
|
|
-
|
|
|
- ${ workflow.description }
|
|
|
-
|
|
|
- ${ workflow.owner }
|
|
|
-
|
|
|
- ${ workflow.last_modified }
|
|
|
- </a>
|
|
|
- </div>
|
|
|
+ <tr>
|
|
|
+ <td data-row-selector-exclude="true">
|
|
|
+ <div class="hueCheckbox workflowCheck fa" data-row-selector-exclude="true"
|
|
|
+ ##% if workflow.can_read(user):
|
|
|
+ data-submit-url="${ url('oozie:submit_workflow', workflow=workflow.id) }"
|
|
|
+ data-schedule-url="${ url('oozie:schedule_workflow', workflow=workflow.id) }"
|
|
|
+ data-clone-url="${ url('oozie:clone_workflow', workflow=workflow.id) }"
|
|
|
+ ##% endif
|
|
|
+ ##% if workflow.is_editable(user):
|
|
|
+ data-delete-id="${ workflow.id }"
|
|
|
+ ##% endif
|
|
|
+ ></div>
|
|
|
+ ##% if workflow.can_read(user):
|
|
|
+ <a href="${ url('oozie:edit_workflow') }?workflow=${ workflow.id }" data-row-selector="true"></a>
|
|
|
+ ##% endif
|
|
|
+ </td>
|
|
|
+ <td>${ workflow.name }</td>
|
|
|
+ <td>${ workflow.description }</td>
|
|
|
+ <td>${ workflow.owner }</td>
|
|
|
+ <td nowrap="nowrap" data-sort-value="${py_time.mktime(workflow.last_modified.timetuple())}">${ utils.format_date(workflow.last_modified) }</td>
|
|
|
+ </tr>
|
|
|
% endfor
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+<div class="hueOverlay" data-bind="visible: isLoading">
|
|
|
+ <!--[if lte IE 9]>
|
|
|
+ <img src="/static/art/spinner-big.gif" />
|
|
|
+ <![endif]-->
|
|
|
+ <!--[if !IE]> -->
|
|
|
+ <i class="fa fa-spinner fa-spin"></i>
|
|
|
+ <!-- <![endif]-->
|
|
|
+</div>
|
|
|
+
|
|
|
+<div id="submit-wf-modal" class="modal hide"></div>
|
|
|
+
|
|
|
+<div id="deleteWf" class="modal hide fade">
|
|
|
+ <form id="deleteWfForm" action="${ url('oozie:delete_workflow') }?skip_trash=true" method="POST">
|
|
|
+ ${ csrf_token(request) | n,unicode }
|
|
|
+ <div class="modal-header">
|
|
|
+ <a href="#" class="close" data-dismiss="modal">×</a>
|
|
|
+ <h3 id="deleteWfMessage">${ _('Delete the selected workflow(s)?') }</h3>
|
|
|
+ </div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <a href="#" class="btn" data-dismiss="modal">${ _('No') }</a>
|
|
|
+ <input type="submit" class="btn btn-danger" value="${ _('Yes') }"/>
|
|
|
+ </div>
|
|
|
+ <div class="hide">
|
|
|
+ ##<select name="job_selection" data-bind="options: availableJobs, selectedOptions: chosenJobs" size="5" multiple="true"></select>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+</div>
|
|
|
+
|
|
|
+
|
|
|
+<script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
|
|
|
+<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
|
|
|
+
|
|
|
+
|
|
|
+<script type="text/javascript" charset="utf-8">
|
|
|
+ $(document).ready(function () {
|
|
|
+ var viewModel = {
|
|
|
+ ##availableJobs : ko.observableArray(${ json_jobs | n }),
|
|
|
+ chosenJobs : ko.observableArray([]),
|
|
|
+ isLoading: ko.observable(false)
|
|
|
+ };
|
|
|
+
|
|
|
+ ko.applyBindings(viewModel);
|
|
|
+
|
|
|
+ $(".selectAll").click(function () {
|
|
|
+ if ($(this).attr("checked")) {
|
|
|
+ $(this).removeAttr("checked").removeClass("fa-check");
|
|
|
+ $("." + $(this).data("selectables")).removeClass("fa-check").removeAttr("checked");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $(this).attr("checked", "checked").addClass("fa-check");
|
|
|
+ $("." + $(this).data("selectables")).addClass("fa-check").attr("checked", "checked");
|
|
|
+ }
|
|
|
+ toggleActions();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(".workflowCheck").click(function () {
|
|
|
+ if ($(this).attr("checked")) {
|
|
|
+ $(this).removeClass("fa-check").removeAttr("checked");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $(this).addClass("fa-check").attr("checked", "checked");
|
|
|
+ }
|
|
|
+ $(".selectAll").removeAttr("checked").removeClass("fa-check");
|
|
|
+ toggleActions();
|
|
|
+ });
|
|
|
+
|
|
|
+ function toggleActions() {
|
|
|
+ $(".toolbarBtn").attr("disabled", "disabled");
|
|
|
+ var selector = $(".hueCheckbox[checked='checked']:not(.selectAll)");
|
|
|
+ if (selector.length == 1) {
|
|
|
+ var action_buttons = [
|
|
|
+ ['#submit-btn', 'data-submit-url'],
|
|
|
+ ['#schedule-btn', 'data-schedule-url'],
|
|
|
+ ['#clone-btn', 'data-clone-url'],
|
|
|
+ ['#export-btn', 'data-export-url']
|
|
|
+ ];
|
|
|
+ $.each(action_buttons, function (index) {
|
|
|
+ if (selector.attr(this[1])) {
|
|
|
+ $(this[0]).removeAttr("disabled");
|
|
|
+ } else {
|
|
|
+ $(this[0]).attr("disabled", "disabled");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ var can_delete = $(".hueCheckbox[checked='checked'][data-delete-id]");
|
|
|
+ if (can_delete.length > 0 && can_delete.length == selector.length) {
|
|
|
+ $("#trash-btn").removeAttr("disabled");
|
|
|
+ $("#trash-btn-caret").removeAttr("disabled");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $("#delete-btn").click(function (e) {
|
|
|
+ viewModel.chosenJobs.removeAll();
|
|
|
+ $(".hueCheckbox[checked='checked']").each(function( index ) {
|
|
|
+ viewModel.chosenJobs.push($(this).data("delete-id"));
|
|
|
+ });
|
|
|
+ $("#deleteWf").modal("show");
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#submit-btn").click(function () {
|
|
|
+ var _this = $(".hueCheckbox[checked='checked']");
|
|
|
+ var _action = _this.attr("data-submit-url");
|
|
|
+ $.get(_action, function (response) {
|
|
|
+ $("#submit-wf-modal").html(response);
|
|
|
+ $("#submit-wf-modal").modal("show");
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#clone-btn").click(function (e) {
|
|
|
+ viewModel.isLoading(true);
|
|
|
+ var _this = $(".hueCheckbox[checked='checked']");
|
|
|
+ var _url = _this.attr("data-clone-url");
|
|
|
+ $.post(_url, function (data) {
|
|
|
+ window.location = data.url;
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#schedule-btn").click(function (e) {
|
|
|
+ viewModel.isLoading(true);
|
|
|
+ var _this = $(".hueCheckbox[checked='checked']");
|
|
|
+ var _url = _this.attr("data-schedule-url");
|
|
|
+ window.location.replace(_url);
|
|
|
+ });
|
|
|
+
|
|
|
+ var oTable = $("#workflowTable").dataTable({
|
|
|
+ "sPaginationType":"bootstrap",
|
|
|
+ 'iDisplayLength':50,
|
|
|
+ "bLengthChange":false,
|
|
|
+ "sDom": "<'row'r>t<'row-fluid'<'dt-pages'p><'dt-records'i>>",
|
|
|
+ "aoColumns":[
|
|
|
+ { "bSortable":false },
|
|
|
+ null,
|
|
|
+ null,
|
|
|
+ null,
|
|
|
+ { "sSortDataType":"dom-sort-value", "sType":"numeric" }
|
|
|
+ ],
|
|
|
+ "aaSorting":[
|
|
|
+ [4, 'desc'],
|
|
|
+ [1, 'asc' ]
|
|
|
+ ],
|
|
|
+ "oLanguage":{
|
|
|
+ "sEmptyTable":"${_('No data available')}",
|
|
|
+ "sInfo":"${_('Showing _START_ to _END_ of _TOTAL_ entries')}",
|
|
|
+ "sInfoEmpty":"${_('Showing 0 to 0 of 0 entries')}",
|
|
|
+ "sInfoFiltered":"${_('(filtered from _MAX_ total entries)')}",
|
|
|
+ "sZeroRecords":"${_('No matching records')}",
|
|
|
+ "oPaginate":{
|
|
|
+ "sFirst":"${_('First')}",
|
|
|
+ "sLast":"${_('Last')}",
|
|
|
+ "sNext":"${_('Next')}",
|
|
|
+ "sPrevious":"${_('Previous')}"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "fnDrawCallback":function (oSettings) {
|
|
|
+ $("a[data-row-selector='true']").jHueRowSelector();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#filterInput").keydown(function (e) {
|
|
|
+ if (e.which == 13) {
|
|
|
+ e.preventDefault();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#filterInput").keyup(function () {
|
|
|
+ oTable.fnFilter($(this).val());
|
|
|
+ });
|
|
|
+
|
|
|
+ $("a[data-row-selector='true']").jHueRowSelector();
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+
|
|
|
${commonfooter(messages) | n,unicode}
|