* Pipeline components are topologically sorted based on :output_of, then sorted lexic...
authorPeter Amstutz <peter.amstutz@curoverse.com>
Fri, 7 Mar 2014 21:55:42 +0000 (16:55 -0500)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Fri, 7 Mar 2014 21:55:42 +0000 (16:55 -0500)
* Refactored code to render pipeline components to be consistent across pipeline instance page and pipeline template page.
* Added "pipelines" tab that shows pipelines that were created from the current template.  Uses the pipeline_instances/show_recent partial.

apps/workbench/app/assets/stylesheets/pipeline_templates.css.scss
apps/workbench/app/assets/stylesheets/selection.css [new file with mode: 0644]
apps/workbench/app/controllers/pipeline_templates_controller.rb
apps/workbench/app/helpers/application_helper.rb
apps/workbench/app/helpers/pipeline_instances_helper.rb
apps/workbench/app/helpers/pipeline_templates_helper.rb
apps/workbench/app/views/pipeline_instances/_show_components.html.erb
apps/workbench/app/views/pipeline_templates/_show_attributes.html.erb
apps/workbench/app/views/pipeline_templates/_show_components.html.erb [new file with mode: 0644]
apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb [new file with mode: 0644]
apps/workbench/app/views/pipeline_templates/_show_pipelines.html.erb [new file with mode: 0644]

index 35d2946bb0e4868dad2694945bc5ab0970158eb2..c70377a6ffc9849775b3a27d2a4ed81cc56647e2 100644 (file)
@@ -1,3 +1,30 @@
 // Place all the styles related to the PipelineTemplates controller here.
 // They will automatically be included in application.css.
 // You can use Sass (SCSS) here: http://sass-lang.com/
+
+.pipeline_color_legend {
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+table.pipeline-components-table {
+  width: 100%;
+  table-layout: fixed;
+  overflow: hidden;
+}
+
+table.pipeline-components-table thead th {
+  text-align: bottom;
+}
+table.pipeline-components-table div.progress {
+  margin-bottom: 0;
+}
+
+table.pipeline-components-table td {
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+td.required {
+  background: #ffdddd;
+}
diff --git a/apps/workbench/app/assets/stylesheets/selection.css b/apps/workbench/app/assets/stylesheets/selection.css
new file mode 100644 (file)
index 0000000..147d6fe
--- /dev/null
@@ -0,0 +1,29 @@
+#persistent-selection-list {
+    width: 500px;
+}
+
+#selection-form-content > li > a, #selection-form-content > li > input {
+    display: block;
+    padding: 3px 20px;
+    clear: both;
+    font-weight: normal;
+    line-height: 1.42857;
+    color: rgb(51, 51, 51);
+    white-space: nowrap;    
+    border: none;
+    background: transparent;
+    width: 100%;
+    text-align: left;
+}
+
+#selection-form-content li table tr {
+    padding: 3px 20px;
+    line-height: 1.42857;
+    border-top: 1px solid rgb(221, 221, 221);
+}
+
+#selection-form-content a:hover, #selection-form-content a:focus, #selection-form-content input:hover, #selection-form-content input:focus, #selection-form-content tr:hover {
+    text-decoration: none;
+    color: rgb(38, 38, 38);
+    background-color: whitesmoke;
+}
\ No newline at end of file
index fdbebcfaed2cb5b2d68192a8d63ff56ceee358c1..98101b5e9b0953b61060a554d54456d8c37b7841 100644 (file)
@@ -1,2 +1,15 @@
 class PipelineTemplatesController < ApplicationController
+  
+  def show
+    @objects = [] 
+    PipelineInstance.where(pipeline_template_uuid: @object.uuid).each do |pipeline|
+      @objects.push(pipeline)
+    end
+    super
+  end
+
+  def show_pane_list
+    %w(Components Pipelines Attributes Metadata JSON API)
+  end
+
 end
index 0b788430efaef33ca97ee50d60444ae0733f8dd2..6aaa70f6892642509ede281d661dcd9f27e894f4 100644 (file)
@@ -106,12 +106,14 @@ module ApplicationHelper
   end
 
   def render_editable_subattribute(object, attr, subattr, template, htmloptions={})
-    attrvalue = object.send(attr)
-    subattr.each do |k|
-      if attrvalue and attrvalue.is_a? Hash
-        attrvalue = attrvalue[k]
-      else
-        break
+    if object
+      attrvalue = object.send(attr)
+      subattr.each do |k|
+        if attrvalue and attrvalue.is_a? Hash
+          attrvalue = attrvalue[k]
+        else
+          break
+        end
       end
     end
 
@@ -135,6 +137,7 @@ module ApplicationHelper
       end
     end
 
+    return template if !object
     return attrvalue if !object.attribute_editable? attr
 
     if dataclass
index d0caf121199fa2a322dce0ce25eb7922f8970e2c..c52d33915822f717d047c9335544e4e3b68de2d8 100644 (file)
@@ -28,7 +28,25 @@ module PipelineInstancesHelper
   def pipeline_jobs_newschool object
     ret = []
     i = -1
-    object.components.each do |cname, c|
+
+    comp = []
+
+    template = PipelineTemplate.find(@object.pipeline_template_uuid) rescue nil
+    if template
+      order = PipelineTemplatesHelper::sort_components(template.components)
+      order.each do |k|
+        if object.components[k]
+          comp.push([k, object.components[k]])
+        end
+      end
+    else
+      object.components.each do |k, v|
+        comp.push([k, v])
+      end
+    end
+
+    comp.each do |cname, c|
+      puts cname, c
       i += 1
       pj = {index: i, name: cname}
       pj[:job] = c[:job].is_a?(Hash) ? c[:job] : {}
index be82878a8e26d0157efb6e19b54b996d3dc04b42..0540047e9ca9d6a4b09f7f7d04806679553c45f0 100644 (file)
@@ -1,2 +1,24 @@
+require 'tsort'
+
+class Hash
+  include TSort
+  def tsort_each_node(&block)
+    keys.sort.each(&block)
+  end
+
+  def tsort_each_child(node)
+    if self[node]
+      self[node][:script_parameters].sort.map do |k, v|
+        if v.is_a? Hash and v[:output_of]
+          yield v[:output_of].to_sym
+        end
+      end
+    end
+  end
+end
+
 module PipelineTemplatesHelper
+  def self.sort_components(components)
+    components.tsort
+  end
 end
index 170e3f54221d851e7718a95d6b24c9a23ce8ad21..638fb8e037910d4f63e55786b29a09ed9270e29a 100644 (file)
@@ -1,38 +1,13 @@
 <% content_for :css do %>
-  .pipeline_color_legend {
-    padding-left: 1em;
-    padding-right: 1em;
-  }
-table.pipeline-components-table {
-  width: 100%;
-  table-layout: fixed;
-  overflow: hidden;
-}
-
-table.pipeline-components-table thead th {
-  text-align: bottom;
-}
-table.pipeline-components-table div.progress {
-  margin-bottom: 0;
-}
-
-table.pipeline-components-table td {
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-td.required {
-  background: #ffdddd;
-}
 
 <% end %>
 
-<% template = PipelineTemplate.find(@object.pipeline_template_uuid) %>
+<% template = PipelineTemplate.find(@object.pipeline_template_uuid) rescue nil %>
+
 <%= content_for :content_top do %>
   <% if template %>
     <h2><%= template.name %></h2>
   <% end %>
-  
 <% end %>
 
 <% if @object.active != nil %>
@@ -108,55 +83,6 @@ setInterval(function(){$('a.refresh').click()}, 15000);
     <% end %>
   <% end %>
 
-<table class="table pipeline-components-table" style="margin-top: -.1em">
-  <colgroup>
-    <col style="width: 15%" />
-    <col style="width: 20%" />
-    <col style="width: 20%" />
-    <col style="width: 45%" />
-  </colgroup>
-
-  <thead>
-    <tr>
-      <th>
-        component
-      </th><th>
-        script
-      </th><th>
-        parameter
-      </th><th>
-        value
-      </th>
-    </tr>
-  </thead>
-  <tbody>
-    <% template.components.each do |k, template_value| %>
-
-    <tr>
-      <td><span class="label label-default"><%= k %></span></td>
-
-      <td><%= render_editable_subattribute @object, :components, [k, :script], template_value[:script] %></td>
-
-      <td>script version</td>
-
-      <td>
-        <%= render_editable_subattribute @object, :components, [k, :script_version], template_value[:script_version] %>
-      </td>
-    </tr>
-
-    <% if template_value[:script_parameters].length > 0 %>
-      <% template_value[:script_parameters].each do |p, tv| %>
-        <tr>
-          <td style="border-top: none"></td>
-          <td style="border-top: none"></td>
-          
-          <td class="property-edit-row"><%= p %></td>
-          <td class="property-edit-row"><%= render_editable_subattribute @object, :components, [k, :script_parameters, p.to_sym], tv %></td>
-      <% end %>
-      </tr>
-    <% end %>
-  <% end %>
-  </tbody>
-  </table>
+  <%= render partial: 'pipeline_templates/show_components_template', locals: {:template => template, :obj => @object} %>
   
 <% end %>
index c16229a19dea24ec3aa4d4f7ee06e2cc5652147e..cc95b9d78141366e215fb4199f196371c3d6bc25 100644 (file)
@@ -1,39 +1,15 @@
+<%= content_for :content_top do %>
+  <h2>Template '<%= @object.name %>'</h2>
+<% end %>
+
 <table class="table topalign">
   <thead>
   </thead>
   <tbody>
     <% @object.attributes_for_display.each do |attr, attrvalue| %>
-    <% if attr == 'components' and attrvalue.is_a? Hash and attrvalue[:steps].is_a? Array %>
-
-    <tr><td>components[steps]</td><td>
-        <table class="table">
-          <% attrvalue[:steps].each_with_index do |s, i| %>
-          <tr>
-            <td><%= i %></td>
-            <% %w(name function min_revision max_steps_per_node params).each do |key| %>
-            <td>
-              <% if key == 'params' %>
-              <% s[key.to_sym].each do |p| %>
-              <%= p[:name] %>
-              <% if p[:data_locator] || p[:value] %>
-              &larr; <%= p[:data_locator] || p[:value] %>
-              <% end %>
-              <%= '(optional)' if p[:optional] %>
-              <br />
-              <% end %>
-              <% else %>
-              <%= s[key.to_sym] %>
-              <% end %>
-            </td>
-            <% end %>
-          </tr>
-          <% end %>
-        </table>
-    </td></tr>
-
-    <% else %>
-    <%= render partial: 'application/arvados_object_attr', locals: { attr: attr, attrvalue: attrvalue } %>
-    <% end %>
+      <% if attr != 'components' %>
+        <%= render partial: 'application/arvados_object_attr', locals: { attr: attr, attrvalue: attrvalue } %>
+      <% end %>
     <% end %>
   </tbody>
 </table>
diff --git a/apps/workbench/app/views/pipeline_templates/_show_components.html.erb b/apps/workbench/app/views/pipeline_templates/_show_components.html.erb
new file mode 100644 (file)
index 0000000..0d34ba0
--- /dev/null
@@ -0,0 +1,8 @@
+<% content_for :tab_line_buttons do %>
+  <%= form_tag '/pipeline_instances' do |f| %>
+  <%= hidden_field :pipeline_instance, :pipeline_template_uuid, :value => @object.uuid %>
+  <%= button_tag "Create pipeline", {class: 'btn btn-primary pull-right', id: "run-pipeline-button"} %>
+<% end %>
+<% end %>
+
+<%= render partial: 'pipeline_templates/show_components_template', locals: {:template => @object, :obj => nil} %>
diff --git a/apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb b/apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb
new file mode 100644 (file)
index 0000000..718c8c8
--- /dev/null
@@ -0,0 +1,54 @@
+<table class="table pipeline-components-table" style="margin-top: -.1em">
+  <colgroup>
+    <col style="width: 15%" />
+    <col style="width: 20%" />
+    <col style="width: 20%" />
+    <col style="width: 45%" />
+  </colgroup>
+
+  <thead>
+    <tr>
+      <th>
+        component
+      </th><th>
+        script
+      </th><th>
+        parameter
+      </th><th>
+        value
+      </th>
+    </tr>
+  </thead>
+  <tbody>
+    <% order = PipelineTemplatesHelper::sort_components(template.components) %>
+    <% puts "order is #{order}" %>
+    <% order.each do |k| %>
+      <% template_value = template.components[k] %>
+      <% puts "#{k} #{template_value}" %>
+      <% if not template_value then next end %>
+    <tr>
+      <td><span class="label label-default"><%= k %></span></td>
+
+      <td><%= render_editable_subattribute obj, :components, [k, :script], template_value[:script] %></td>
+
+      <td>script version</td>
+
+      <td>
+        <%= render_editable_subattribute obj, :components, [k, :script_version], template_value[:script_version] %>
+      </td>
+    </tr>
+
+    <% if template_value[:script_parameters].length > 0 %>
+      <% template_value[:script_parameters].each do |p, tv| %>
+        <tr>
+          <td style="border-top: none"></td>
+          <td style="border-top: none"></td>
+          
+          <td class="property-edit-row"><%= p %></td>
+          <td class="property-edit-row"><%= render_editable_subattribute obj, :components, [k, :script_parameters, p.to_sym], tv %></td>
+      <% end %>
+      </tr>
+    <% end %>
+  <% end %>
+  </tbody>
+</table>
diff --git a/apps/workbench/app/views/pipeline_templates/_show_pipelines.html.erb b/apps/workbench/app/views/pipeline_templates/_show_pipelines.html.erb
new file mode 100644 (file)
index 0000000..8ff42a7
--- /dev/null
@@ -0,0 +1,2 @@
+
+  <%= render partial: 'pipeline_instances/show_recent' %>