Merge branch 'master' into 3296-user-profile
[arvados.git] / apps / workbench / app / controllers / pipeline_instances_controller.rb
index 500927bdb62ba240301382cc0239a50f308d34ab..b5c9815ed5c51b8fce88e6f347e4d4de883bd5ff 100644 (file)
@@ -2,6 +2,43 @@ class PipelineInstancesController < ApplicationController
   skip_before_filter :find_object_by_uuid, only: :compare
   before_filter :find_objects_by_uuid, only: :compare
   include PipelineInstancesHelper
+  include PipelineComponentsHelper
+
+  def copy
+    @object = @object.dup
+    @object.components.each do |cname, component|
+      component.delete :job
+    end
+    @object.state = 'New'
+    super
+  end
+
+  def update
+    @updates ||= params[@object.class.to_s.underscore.singularize.to_sym]
+    if (components = @updates[:components])
+      components.each do |cname, component|
+        if component[:script_parameters]
+          component[:script_parameters].each do |param, value_info|
+            if value_info.is_a? Hash
+              if resource_class_for_uuid(value_info[:value]) == Link
+                # Use the link target, not the link itself, as script
+                # parameter; but keep the link info around as well.
+                link = Link.find value_info[:value]
+                value_info[:value] = link.head_uuid
+                value_info[:link_uuid] = link.uuid
+                value_info[:link_name] = link.name
+              else
+                # Delete stale link_uuid and link_name data.
+                value_info[:link_uuid] = nil
+                value_info[:link_name] = nil
+              end
+            end
+          end
+        end
+      end
+    end
+    super
+  end
 
   def graph(pipelines)
     return nil, nil if params['tab_pane'] != "Graph"
@@ -79,77 +116,90 @@ class PipelineInstancesController < ApplicationController
 
     @rows = []          # each is {name: S, components: [...]}
 
-    # Build a table: x=pipeline y=component
-    @objects.each_with_index do |pi, pi_index|
-      pipeline_jobs(pi).each do |component|
-        # Find a cell with the same name as this component but no
-        # entry for this pipeline
-        target_row = nil
-        @rows.each_with_index do |row, row_index|
-          if row[:name] == component[:name] and !row[:components][pi_index]
-            target_row = row
+    if params['tab_pane'] == "Compare" or params['tab_pane'].nil?
+      # Build a table: x=pipeline y=component
+      @objects.each_with_index do |pi, pi_index|
+        pipeline_jobs(pi).each do |component|
+          # Find a cell with the same name as this component but no
+          # entry for this pipeline
+          target_row = nil
+          @rows.each_with_index do |row, row_index|
+            if row[:name] == component[:name] and !row[:components][pi_index]
+              target_row = row
+            end
           end
+          if !target_row
+            target_row = {name: component[:name], components: []}
+            @rows << target_row
+          end
+          target_row[:components][pi_index] = component
         end
-        if !target_row
-          target_row = {name: component[:name], components: []}
-          @rows << target_row
-        end
-        target_row[:components][pi_index] = component
       end
-    end
 
-    @rows.each do |row|
-      # Build a "normal" pseudo-component for this row by picking the
-      # most common value for each attribute. If all values are
-      # equally common, there is no "normal".
-      normal = {}              # attr => most common value
-      highscore = {}           # attr => how common "normal" is
-      score = {}               # attr => { value => how common }
-      row[:components].each do |pj|
-        next if pj.nil?
-        pj.each do |k,v|
-          vstr = for_comparison v
-          score[k] ||= {}
-          score[k][vstr] = (score[k][vstr] || 0) + 1
-          highscore[k] ||= 0
-          if score[k][vstr] == highscore[k]
-            # tie for first place = no "normal"
-            normal.delete k
-          elsif score[k][vstr] == highscore[k] + 1
-            # more pipelines have v than anything else
-            highscore[k] = score[k][vstr]
-            normal[k] = vstr
+      @rows.each do |row|
+        # Build a "normal" pseudo-component for this row by picking the
+        # most common value for each attribute. If all values are
+        # equally common, there is no "normal".
+        normal = {}              # attr => most common value
+        highscore = {}           # attr => how common "normal" is
+        score = {}               # attr => { value => how common }
+        row[:components].each do |pj|
+          next if pj.nil?
+          pj.each do |k,v|
+            vstr = for_comparison v
+            score[k] ||= {}
+            score[k][vstr] = (score[k][vstr] || 0) + 1
+            highscore[k] ||= 0
+            if score[k][vstr] == highscore[k]
+              # tie for first place = no "normal"
+              normal.delete k
+            elsif score[k][vstr] == highscore[k] + 1
+              # more pipelines have v than anything else
+              highscore[k] = score[k][vstr]
+              normal[k] = vstr
+            end
           end
         end
-      end
 
-      # Add a hash in component[:is_normal]: { attr => is_the_value_normal? }
-      row[:components].each do |pj|
-        next if pj.nil?
-        pj[:is_normal] = {}
-        pj.each do |k,v|
-          pj[:is_normal][k] = (normal.has_key?(k) && normal[k] == for_comparison(v))
+        # Add a hash in component[:is_normal]: { attr => is_the_value_normal? }
+        row[:components].each do |pj|
+          next if pj.nil?
+          pj[:is_normal] = {}
+          pj.each do |k,v|
+            pj[:is_normal][k] = (normal.has_key?(k) && normal[k] == for_comparison(v))
+          end
         end
       end
     end
 
-    provenance, pips = graph(@objects)
+    if params['tab_pane'] == "Graph"
+      provenance, pips = graph(@objects)
 
-    @pipelines = @objects
+      @pipelines = @objects
 
-    @prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
-      :request => request,
-      :all_script_parameters => true,
-      :combine_jobs => :script_and_version,
-      :script_version_nodes => true,
-      :pips => pips }
+      if provenance
+        @prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
+          :request => request,
+          :all_script_parameters => true,
+          :combine_jobs => :script_and_version,
+          :script_version_nodes => true,
+          :pips => pips }
+      end
+    end
+
+    @object = @objects.first
+
+    show
   end
 
   def show_pane_list
-    panes = %w(Components Graph Attributes Metadata JSON API)
+    panes = %w(Components Graph Advanced)
     if @object and @object.state.in? ['New', 'Ready']
       panes = %w(Inputs) + panes
     end
+    if not @object.components.values.any? { |x| x[:job] rescue false }
+      panes -= ['Graph']
+    end
     panes
   end