Эх сурвалжийг харах

[oozie] Drag a node onto workflow editor.

When adding a new node, users are now able to drag the node onto the canvas.
In order to save the workflow, the user will likely have to edit the node first.
Catching the 'dragstop' event, which should be called after 'drop'.
Cannot handle the 'drop' event since the workflow editor must use them and stops event bubbling.
abec 13 жил өмнө
parent
commit
89cf843

+ 36 - 13
apps/oozie/src/oozie/templates/editor/edit_workflow.mako

@@ -179,6 +179,7 @@ ${ layout.menubar(section='workflows') }
             </div>
 
             <div id="graph" class="row-fluid" data-bind="template: { name: function(item) { return item.view_template() }, foreach: nodes }"></div>
+            <div id="new-node" class="row-fluid" data-bind="template: { name: 'nodeTemplate', if: new_node, data: new_node }"></div>
           </div>
         </div>
         <div class="form-actions center">
@@ -302,8 +303,6 @@ ${ layout.menubar(section='workflows') }
 <script src="/static/ext/js/jquery/plugins/jquery-ui-draggable-droppable-sortable-1.8.23.min.js" type="text/javascript" charset="utf-8"></script>
 
 
-
-
 % for form_info in action_forms:
   ${ actions.action_form(action_form=form_info[1], node_type=form_info[0], template=True) }
 % endfor
@@ -507,7 +506,6 @@ var modal = new Modal($('#node-modal'));
 workflow.load({ success: workflow_load_success });
 import_node.loadAvailableNodes({ success: import_load_available_nodes_success });
 
-
 /**
  * Modals
  */
@@ -553,14 +551,11 @@ function edit_node_modal(node, save, cancel) {
   });
 }
 
-// Modal for editing a node
-$('#workflow').on('click', '.edit-node-link', function(e) {
-  var node = ko.contextFor(this).$data;
-  edit_node_modal(node);
-});
+// Drag a new node onto the canvas
+$('#workflow').on('mousedown', '.new-node-link', function(e) {
+  e.preventDefault();
 
-// Modal for creating a new node
-$('#workflow').on('click', '.new-node-link', function(e) {
+  // Node starts off graph, then is validated/dropped onto graph, after being dragged onto graph.
   var node_type = $(this).attr('data-node-type');
   var NodeModel = nodeModelChooser(node_type);
   var model = new NodeModel({
@@ -570,24 +565,52 @@ $('#workflow').on('click', '.new-node-link', function(e) {
   var node = new Node(workflow, model, registry);
   workflow.registry.add(model.id, node);
 
+  // Add to new node location, then drag and drop.
+  workflow.new_node( node );
+  workflow.draggables();
+
+  // Reposition node to mouse pointer.
+  var el = $("#new-node .node-action");
+  var old_position = el.offset();
+
+  // Trigger fake mousedown event to start dragging node.
+  el.offset({ top: e.pageY - el.height()/10, left: e.pageX - el.width()/10 });
+  el.trigger($.Event("mousedown", {pageX: e.pageX, pageY: e.pageY, target: el[0], which: 1}));
+
   var cancel_edit = function(e) {
     // Didn't save, erase node.
+    node.detach();
     node.erase();
     modal.hide();
+    workflow.is_dirty( false );
+    $('#workflow').trigger('workflow:rebuild');
   };
 
   var try_save = function(e) {
     if (node.validate()) {
       workflow.is_dirty( true );
       modal.hide();
-      // save, add kill, add node to workflow.
       node.addChild(workflow.kill);
-      workflow.nodes()[workflow.nodes().length - 2].append(node);
       $('#workflow').trigger('workflow:rebuild');
     }
   };
 
-  edit_node_modal(node, try_save, cancel_edit);
+  // Remember to cleanup after.
+  el.one('dragstop', function(e) {
+    workflow.new_node(null);
+    el.offset(old_position);
+    if (node.findChildren().length > 0 || node.findParents().length > 1) {
+      edit_node_modal(node, try_save, cancel_edit);
+    } else {
+      node.erase();
+    }
+  });
+});
+
+// Modal for editing a node
+$('#workflow').on('click', '.edit-node-link', function(e) {
+  var node = ko.contextFor(this).$data;
+  edit_node_modal(node);
 });
 
 // Modal for cloning a node

+ 1 - 1
apps/oozie/static/css/workflow.css

@@ -69,7 +69,7 @@ ul {
   box-shadow: inset 0px 3px 5px 0px #DDD;
 }
 
-#graph {
+#graph, #new-node {
   text-align: center;
 }
 

+ 3 - 1
apps/oozie/static/js/workflow.js

@@ -1773,6 +1773,7 @@ var WorkflowModule = function($, NodeModelChooser, Node, ForkNode, DecisionNode,
     self.kill = null;
     self.is_dirty = ko.observable( false );
     self.read_only = ko.observable( options.read_only || false );
+    self.new_node = ko.observable();
 
     self.url = ko.computed(function() {
       return '/oozie/workflows/' + self.id()
@@ -2136,6 +2137,7 @@ var WorkflowModule = function($, NodeModelChooser, Node, ForkNode, DecisionNode,
             revert: true,
             zIndex: 1000,
             opacity: 0.45,
+            revertDuration: 0,
             cancel: '.node-action-bar'
           });
         }
@@ -2315,7 +2317,7 @@ var WorkflowModule = function($, NodeModelChooser, Node, ForkNode, DecisionNode,
         var newParents = droppable.findParents();
 
         // skip forking beneathe a decision node
-        if (droppable.id() != draggable.id() && newParents.length == 1 && draggable.findParents().length == 1) {
+        if (droppable.id() != draggable.id() && newParents.length == 1 && draggable.findParents().length <= 1) {
           var ForkModel = NodeModelChooser('fork');
           var JoinModel = NodeModelChooser('join');