[ARVADOS] created: e9fc9e309865dcabc472ffd889347f753be4ccb0

Git user git at public.curoverse.com
Thu Aug 25 11:32:09 EDT 2016


        at  e9fc9e309865dcabc472ffd889347f753be4ccb0 (commit)


commit e9fc9e309865dcabc472ffd889347f753be4ccb0
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Aug 25 11:25:03 2016 -0400

    9043: Remove non-existent "Graph" tab.  Fix "false" selection dropdown.  Use
    helper function instead of duplicating regex.

diff --git a/apps/workbench/app/controllers/container_requests_controller.rb b/apps/workbench/app/controllers/container_requests_controller.rb
index 34f892a..54e5914 100644
--- a/apps/workbench/app/controllers/container_requests_controller.rb
+++ b/apps/workbench/app/controllers/container_requests_controller.rb
@@ -5,8 +5,8 @@ class ContainerRequestsController < ApplicationController
   }
 
   def show_pane_list
-    panes = %w(Status Log Graph Advanced)
-    if @object and @object.state == 'Uncommitted'
+    panes = %w(Status Log Advanced)
+    if @object.andand.state == 'Uncommitted'
       panes = %w(Inputs) + panes - %w(Log)
     end
     panes
@@ -27,23 +27,25 @@ class ContainerRequestsController < ApplicationController
     if input_obj
       workflow = @object.mounts[:"/var/lib/cwl/workflow.json"][:content]
       workflow[:inputs].each do |input_schema|
-        if input_obj.include? input_schema[:id]
-          required, primary_type, param_id = cwl_input_info(input_schema)
-          if input_obj[param_id] == ""
-            input_obj[param_id] = nil
-          elsif primary_type == "boolean"
-            input_obj[param_id] = input_obj[param_id] == "true"
-          elsif ["int", "long"].include? primary_type
-            input_obj[param_id] = input_obj[param_id].to_i
-          elsif ["float", "double"].include? primary_type
-            input_obj[param_id] = input_obj[param_id].to_f
-          elsif ["File", "Directory"].include? primary_type
-            input_obj[param_id].match /^([0-9a-z]{5}-([0-9a-z]{5})-[0-9a-z]{15})(\/.*)?$/ do |re|
-              c = display_value = Collection.find(re[1])
-              input_obj[param_id] = {"class" => primary_type,
-                                     "location" => "keep:#{c.portable_data_hash}#{re[3]}",
-                                     "arv:collection" => input_obj[param_id]}
-            end
+        if not input_obj.include? input_schema[:id]
+          next
+        end
+        required, primary_type, param_id = cwl_input_info(input_schema)
+        if input_obj[param_id] == ""
+          input_obj[param_id] = nil
+        elsif primary_type == "boolean"
+          input_obj[param_id] = input_obj[param_id] == "true"
+        elsif ["int", "long"].include? primary_type
+          input_obj[param_id] = input_obj[param_id].to_i
+        elsif ["float", "double"].include? primary_type
+          input_obj[param_id] = input_obj[param_id].to_f
+        elsif ["File", "Directory"].include? primary_type
+          re = CollectionsHelper.match_uuid_with_optional_filepath(input_obj[param_id])
+          if re
+            c = Collection.find(re[1])
+            input_obj[param_id] = {"class" => primary_type,
+                                   "location" => "keep:#{c.portable_data_hash}#{re[4]}",
+                                   "arv:collection" => input_obj[param_id]}
           end
         end
       end
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index 27c7504..ec2e93f 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -503,7 +503,7 @@ module ApplicationHelper
         end
       end
     elsif "boolean" == primary_type
-      return link_to attrvalue, '#', {
+      return link_to attrvalue.to_s, '#', {
                      "data-emptytext" => "none",
                      "data-placement" => "bottom",
                      "data-type" => "select",
@@ -512,7 +512,7 @@ module ApplicationHelper
                      "data-title" => "Set value for #{input_schema[:id]}",
                      "data-name" => dn,
                      "data-pk" => "{id: \"#{object.uuid}\", key: \"#{object.class.to_s.underscore}\"}",
-                     "data-value" => attrvalue,
+                     "data-value" => attrvalue.to_s,
                      # "clear" button interferes with form-control's up/down arrows
                      "data-clear" => false,
                      :class => "editable #{'required' if required} form-control",

commit e3849d724f92123d61b4219a8c22d810795ad428
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Aug 23 14:57:52 2016 -0400

    9043: Initial commit testing for container request editing

diff --git a/apps/workbench/test/integration/container_requests_test.rb b/apps/workbench/test/integration/container_requests_test.rb
new file mode 100644
index 0000000..232f33c
--- /dev/null
+++ b/apps/workbench/test/integration/container_requests_test.rb
@@ -0,0 +1,26 @@
+require 'integration_helper'
+
+class ContainerRequestsTest < ActionDispatch::IntegrationTest
+  setup do
+    need_javascript
+  end
+
+  test "enter a float for a number workflow input" do
+    # Poltergeist either does not support the HTML 5 <input
+    # type="number">, or interferes with the associated X-Editable
+    # validation code.  If the input field has type=number (forcing an
+    # integer), this test will yield a false positive under
+    # Poltergeist.  --Brett, 2015-02-05
+    need_selenium "for strict X-Editable input validation"
+    request_uuid = api_fixture("container_requests", "uncommitted", "uuid")
+    visit page_with_token("active", "/container_requests/#{request_uuid}")
+    INPUT_SELECTOR =
+      ".editable[data-name='[mounts][/var/lib/cwl/cwl.input.json][content][ex_double]']"
+    find(INPUT_SELECTOR).click
+    find(".editable-input input").set("12.34")
+    find("#editable-submit").click
+    assert_no_selector(".editable-popup")
+    assert_selector(INPUT_SELECTOR, text: "12.34")
+  end
+
+end

commit 35a067690a188e2448da298f51ef24258a4ba2e3
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Mon Aug 22 16:21:59 2016 -0400

    9043: Complete support for editing basic parameter types.
    
    Supported parameter types: boolean, string, int, long, float, double, enum,
    File, Directory.  May be specified required or optional.
    
    Not supported: arrays, unions (other than with "null"), records.

diff --git a/apps/workbench/app/controllers/container_requests_controller.rb b/apps/workbench/app/controllers/container_requests_controller.rb
index ff6105f..34f892a 100644
--- a/apps/workbench/app/controllers/container_requests_controller.rb
+++ b/apps/workbench/app/controllers/container_requests_controller.rb
@@ -23,22 +23,32 @@ class ContainerRequestsController < ApplicationController
 
   def update
     @updates ||= params[@object.class.to_s.underscore.singularize.to_sym]
-    input_obj = @updates[:mounts][:"/var/lib/cwl/cwl.input.json"][:content]
-    workflow = @object.mounts[:"/var/lib/cwl/workflow.json"][:content]
-    workflow[:inputs].each do |input_schema|
-      if input_obj.include? input_schema[:id]
-        required, primary_type, param_id = cwl_input_info(input_schema)
-        if primary_type == "boolean"
-          input_obj[param_id] = input_obj[param_id] == "true"
-        elsif ["int", "long"].include? primary_type
-          input_obj[param_id] = input_obj[param_id].to_i
-        elsif ["float", "double"].include? primary_type
-          input_obj[param_id] = input_obj[param_id].to_f
-        elsif ["File", "Directory"].include? primary_type
-          input_obj[param_id] = {"class" => "File", "location" => "keep:" + input_obj[param_id]}
+    input_obj = @updates[:mounts].andand[:"/var/lib/cwl/cwl.input.json"].andand[:content]
+    if input_obj
+      workflow = @object.mounts[:"/var/lib/cwl/workflow.json"][:content]
+      workflow[:inputs].each do |input_schema|
+        if input_obj.include? input_schema[:id]
+          required, primary_type, param_id = cwl_input_info(input_schema)
+          if input_obj[param_id] == ""
+            input_obj[param_id] = nil
+          elsif primary_type == "boolean"
+            input_obj[param_id] = input_obj[param_id] == "true"
+          elsif ["int", "long"].include? primary_type
+            input_obj[param_id] = input_obj[param_id].to_i
+          elsif ["float", "double"].include? primary_type
+            input_obj[param_id] = input_obj[param_id].to_f
+          elsif ["File", "Directory"].include? primary_type
+            input_obj[param_id].match /^([0-9a-z]{5}-([0-9a-z]{5})-[0-9a-z]{15})(\/.*)?$/ do |re|
+              c = display_value = Collection.find(re[1])
+              input_obj[param_id] = {"class" => primary_type,
+                                     "location" => "keep:#{c.portable_data_hash}#{re[3]}",
+                                     "arv:collection" => input_obj[param_id]}
+            end
+          end
         end
       end
     end
+    params[:merge] = true
     super
   end
 
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index a82c795..27c7504 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -424,6 +424,8 @@ module ApplicationHelper
       primary_type = input_schema[:type].select { |n| n != "null" }[0]
     elsif input_schema[:type].is_a? String
       primary_type = input_schema[:type]
+    elsif input_schema[:type].is_a? Hash
+      primary_type = input_schema[:type]
     end
     param_id = input_schema[:id]
     return required, primary_type, param_id
@@ -453,14 +455,25 @@ module ApplicationHelper
     required, primary_type, param_id = cwl_input_info(input_schema)
 
     dn, attrvalue = cwl_input_value(object, input_schema, set_attr_path + [param_id])
-    attrvalue ||= ""
+    attrvalue = if attrvalue.nil? then "" else attrvalue end
 
     id = "#{object.uuid}-#{param_id}"
 
+    opt_empty_selection = if required then [] else [{value: "", text: ""}] end
+
     if ["Directory", "File"].include? primary_type
       chooser_title = "Choose a #{primary_type == 'Directory' ? 'dataset' : 'file'}:"
       selection_param = object.class.to_s.underscore + dn
-      display_value = attrvalue
+      if attrvalue.is_a? Hash
+        display_value = attrvalue[:"arv:collection"] || attrvalue[:location]
+        display_value.match /^([0-9a-z]{5}-([0-9a-z]{5})-[0-9a-z]{15})(\/.*)?$/ do |re|
+          if re[3]
+            display_value = "#{Collection.find(re[1]).name} / #{re[3][1..-1]}"
+          else
+            display_value = Collection.find(re[1]).name
+          end
+        end
+      end
       modal_path = choose_collections_path \
       ({ title: chooser_title,
          filters: [['owner_uuid', '=', object.owner_uuid]].to_json,
@@ -494,7 +507,7 @@ module ApplicationHelper
                      "data-emptytext" => "none",
                      "data-placement" => "bottom",
                      "data-type" => "select",
-                     "data-source" => "[{value: true, text: \"true\"}, {value: false, text: \"false\"}]",
+                     "data-source" => (opt_empty_selection + [{value: "true", text: "true"}, {value: "false", text: "false"}]).to_json,
                      "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore, merge: true),
                      "data-title" => "Set value for #{input_schema[:id]}",
                      "data-name" => dn,
@@ -505,9 +518,23 @@ module ApplicationHelper
                      :class => "editable #{'required' if required} form-control",
                      :id => id
                    }.merge(htmloptions)
-    elsif "enum" == primary_type
-
-    else
+    elsif primary_type.is_a? Hash and primary_type[:type] == "enum"
+      return link_to attrvalue, '#', {
+                     "data-emptytext" => "none",
+                     "data-placement" => "bottom",
+                     "data-type" => "select",
+                     "data-source" => (opt_empty_selection + primary_type[:symbols].map {|i| {:value => i, :text => i} }).to_json,
+                     "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore, merge: true),
+                     "data-title" => "Set value for #{input_schema[:id]}",
+                     "data-name" => dn,
+                     "data-pk" => "{id: \"#{object.uuid}\", key: \"#{object.class.to_s.underscore}\"}",
+                     "data-value" => attrvalue,
+                     # "clear" button interferes with form-control's up/down arrows
+                     "data-clear" => false,
+                     :class => "editable #{'required' if required} form-control",
+                     :id => id
+                   }.merge(htmloptions)
+    elsif primary_type.is_a? String
       if ["float", "double", "int", "long"].include? primary_type
         datatype = "number"
       else
@@ -527,7 +554,9 @@ module ApplicationHelper
                      "data-clear" => false,
                      :class => "editable #{'required' if required} form-control",
                      :id => id
-                   }.merge(htmloptions)
+                     }.merge(htmloptions)
+    else
+      return "Unable to render editing control for parameter type #{primary_type}"
     end
   end
 
diff --git a/apps/workbench/app/views/container_requests/_show_inputs.html.erb b/apps/workbench/app/views/container_requests/_show_inputs.html.erb
index 87b36c1..b365dc5 100644
--- a/apps/workbench/app/views/container_requests/_show_inputs.html.erb
+++ b/apps/workbench/app/views/container_requests/_show_inputs.html.erb
@@ -22,19 +22,19 @@
 <% end %>
 
 <% if n_inputs == 0 %>
-  <p>This workflow does not need any further inputs specified. You can start it by clicking the "Run" button whenever you're ready. (It's not too late to change the settings, though.)</p>
+  <p><i>This workflow does not need any further inputs specified.  Click the "Run" button at the bottom of the page to start the workflow.</i></p>
 <% else %>
-  <%= render_unreadable_inputs_present %>
-
   <p><i>Provide <%= n_inputs > 1 ? 'values' : 'a value' %> for the following <%= n_inputs > 1 ? 'parameters' : 'parameter' %>, then click the "Run" button to start the workflow.</i></p>
-  <% if @object.editable? %>
-    <%= content_for :pi_input_form %>
-      <%= link_to(url_for('container_request[state]' => 'Committed'),
-          class: 'btn btn-primary run-pipeline-button',
-          method: :patch
-          ) do %>
-        Run <i class="fa fa-fw fa-play"></i>
-    <% end %>
-  <% end %>
+<% end %>
 
+<% if @object.editable? %>
+  <%= content_for :pi_input_form %>
+  <%= link_to(url_for('container_request[state]' => 'Committed'),
+        class: 'btn btn-primary run-pipeline-button',
+        method: :patch
+        ) do %>
+    Run <i class="fa fa-fw fa-play"></i>
+  <% end %>
 <% end %>
+
+<%= render_unreadable_inputs_present %>

commit 5d0bdcce49ffc587e2e3058a6e8e45ecfcff53c3
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Fri Aug 19 17:33:18 2016 -0400

    9043: Fixup incoming values from x-editable to have correct types.  Work in progress.

diff --git a/apps/workbench/app/controllers/container_requests_controller.rb b/apps/workbench/app/controllers/container_requests_controller.rb
index b82dbbc..ff6105f 100644
--- a/apps/workbench/app/controllers/container_requests_controller.rb
+++ b/apps/workbench/app/controllers/container_requests_controller.rb
@@ -20,4 +20,26 @@ class ContainerRequestsController < ApplicationController
       redirect_to @object
     end
   end
+
+  def update
+    @updates ||= params[@object.class.to_s.underscore.singularize.to_sym]
+    input_obj = @updates[:mounts][:"/var/lib/cwl/cwl.input.json"][:content]
+    workflow = @object.mounts[:"/var/lib/cwl/workflow.json"][:content]
+    workflow[:inputs].each do |input_schema|
+      if input_obj.include? input_schema[:id]
+        required, primary_type, param_id = cwl_input_info(input_schema)
+        if primary_type == "boolean"
+          input_obj[param_id] = input_obj[param_id] == "true"
+        elsif ["int", "long"].include? primary_type
+          input_obj[param_id] = input_obj[param_id].to_i
+        elsif ["float", "double"].include? primary_type
+          input_obj[param_id] = input_obj[param_id].to_f
+        elsif ["File", "Directory"].include? primary_type
+          input_obj[param_id] = {"class" => "File", "location" => "keep:" + input_obj[param_id]}
+        end
+      end
+    end
+    super
+  end
+
 end
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index e364cd9..a82c795 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -425,41 +425,34 @@ module ApplicationHelper
     elsif input_schema[:type].is_a? String
       primary_type = input_schema[:type]
     end
-    return required, primary_type
+    param_id = input_schema[:id]
+    return required, primary_type, param_id
   end
 
   def cwl_input_value(object, input_schema, set_attr_path)
-    param_id = input_schema[:id]
     dn = ""
     attrvalue = object
     set_attr_path.each do |a|
       dn += "[#{a}]"
-      attrvalue = attrvalue[a]
+      attrvalue = attrvalue[a.to_sym]
     end
-    dn += "[#{param_id}]"
-    attrvalue = attrvalue[param_id.to_sym]
-    return dn, attrvalue, param_id
+    return dn, attrvalue
   end
 
   def cwl_inputs_required(object, inputs_schema, set_attr_path)
     r = 0
     inputs_schema.each do |input|
-      required, primary_type = cwl_input_info(input)
-      dn, attrvalue = cwl_input_value(object, input, set_attr_path)
+      required, primary_type, param_id = cwl_input_info(input)
+      dn, attrvalue = cwl_input_value(object, input, set_attr_path + [param_id])
       r += 1 if required and attrvalue.nil?
     end
     r
   end
 
   def render_cwl_input(object, input_schema, set_attr_path, htmloptions={})
-    required, primary_type = cwl_input_info(input_schema)
-    if ["float", "double", "int", "long"].include? primary_type
-      datatype = "number"
-    else
-      datatype = "text"
-    end
+    required, primary_type, param_id = cwl_input_info(input_schema)
 
-    dn, attrvalue, param_id = cwl_input_value(object, input_schema, set_attr_path)
+    dn, attrvalue = cwl_input_value(object, input_schema, set_attr_path + [param_id])
     attrvalue ||= ""
 
     id = "#{object.uuid}-#{param_id}"
@@ -496,7 +489,31 @@ module ApplicationHelper
                   })
         end
       end
+    elsif "boolean" == primary_type
+      return link_to attrvalue, '#', {
+                     "data-emptytext" => "none",
+                     "data-placement" => "bottom",
+                     "data-type" => "select",
+                     "data-source" => "[{value: true, text: \"true\"}, {value: false, text: \"false\"}]",
+                     "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore, merge: true),
+                     "data-title" => "Set value for #{input_schema[:id]}",
+                     "data-name" => dn,
+                     "data-pk" => "{id: \"#{object.uuid}\", key: \"#{object.class.to_s.underscore}\"}",
+                     "data-value" => attrvalue,
+                     # "clear" button interferes with form-control's up/down arrows
+                     "data-clear" => false,
+                     :class => "editable #{'required' if required} form-control",
+                     :id => id
+                   }.merge(htmloptions)
+    elsif "enum" == primary_type
+
     else
+      if ["float", "double", "int", "long"].include? primary_type
+        datatype = "number"
+      else
+        datatype = "text"
+      end
+
       return link_to attrvalue, '#', {
                      "data-emptytext" => "none",
                      "data-placement" => "bottom",

commit 70e445970a75b84354c975a72490051c9bd0129d
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Fri Aug 19 16:36:46 2016 -0400

    9043: Initial work on rendering input forms for CWL workflows.  Works for
    simple parameters.  Successfully writes back to container request object.

diff --git a/apps/workbench/app/controllers/container_requests_controller.rb b/apps/workbench/app/controllers/container_requests_controller.rb
index f5a68fe..b82dbbc 100644
--- a/apps/workbench/app/controllers/container_requests_controller.rb
+++ b/apps/workbench/app/controllers/container_requests_controller.rb
@@ -5,7 +5,11 @@ class ContainerRequestsController < ApplicationController
   }
 
   def show_pane_list
-    %w(Status Log Advanced)
+    panes = %w(Status Log Graph Advanced)
+    if @object and @object.state == 'Uncommitted'
+      panes = %w(Inputs) + panes - %w(Log)
+    end
+    panes
   end
 
   def cancel
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index a37ecda..e364cd9 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -418,6 +418,102 @@ module ApplicationHelper
     lt
   end
 
+  def cwl_input_info(input_schema)
+    required = !(input_schema[:type].include? "null")
+    if input_schema[:type].is_a? Array
+      primary_type = input_schema[:type].select { |n| n != "null" }[0]
+    elsif input_schema[:type].is_a? String
+      primary_type = input_schema[:type]
+    end
+    return required, primary_type
+  end
+
+  def cwl_input_value(object, input_schema, set_attr_path)
+    param_id = input_schema[:id]
+    dn = ""
+    attrvalue = object
+    set_attr_path.each do |a|
+      dn += "[#{a}]"
+      attrvalue = attrvalue[a]
+    end
+    dn += "[#{param_id}]"
+    attrvalue = attrvalue[param_id.to_sym]
+    return dn, attrvalue, param_id
+  end
+
+  def cwl_inputs_required(object, inputs_schema, set_attr_path)
+    r = 0
+    inputs_schema.each do |input|
+      required, primary_type = cwl_input_info(input)
+      dn, attrvalue = cwl_input_value(object, input, set_attr_path)
+      r += 1 if required and attrvalue.nil?
+    end
+    r
+  end
+
+  def render_cwl_input(object, input_schema, set_attr_path, htmloptions={})
+    required, primary_type = cwl_input_info(input_schema)
+    if ["float", "double", "int", "long"].include? primary_type
+      datatype = "number"
+    else
+      datatype = "text"
+    end
+
+    dn, attrvalue, param_id = cwl_input_value(object, input_schema, set_attr_path)
+    attrvalue ||= ""
+
+    id = "#{object.uuid}-#{param_id}"
+
+    if ["Directory", "File"].include? primary_type
+      chooser_title = "Choose a #{primary_type == 'Directory' ? 'dataset' : 'file'}:"
+      selection_param = object.class.to_s.underscore + dn
+      display_value = attrvalue
+      modal_path = choose_collections_path \
+      ({ title: chooser_title,
+         filters: [['owner_uuid', '=', object.owner_uuid]].to_json,
+         action_name: 'OK',
+         action_href: container_request_path(id: object.uuid),
+         action_method: 'patch',
+         preconfigured_search_str: "",
+         action_data: {
+           merge: true,
+           use_preview_selection: primary_type == 'File' ? true : nil,
+           selection_param: selection_param,
+           success: 'page-refresh'
+         }.to_json,
+        })
+
+      return content_tag('div', :class => 'input-group') do
+        html = text_field_tag(dn, display_value,
+                              :class =>
+                              "form-control #{'required' if required}")
+        html + content_tag('span', :class => 'input-group-btn') do
+          link_to('Choose',
+                  modal_path,
+                  { :class => "btn btn-primary",
+                    :remote => true,
+                    :method => 'get',
+                  })
+        end
+      end
+    else
+      return link_to attrvalue, '#', {
+                     "data-emptytext" => "none",
+                     "data-placement" => "bottom",
+                     "data-type" => datatype,
+                     "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore, merge: true),
+                     "data-title" => "Set value for #{input_schema[:id]}",
+                     "data-name" => dn,
+                     "data-pk" => "{id: \"#{object.uuid}\", key: \"#{object.class.to_s.underscore}\"}",
+                     "data-value" => attrvalue,
+                     # "clear" button interferes with form-control's up/down arrows
+                     "data-clear" => false,
+                     :class => "editable #{'required' if required} form-control",
+                     :id => id
+                   }.merge(htmloptions)
+    end
+  end
+
   def render_arvados_object_list_start(list, button_text, button_href,
                                        params={}, *rest, &block)
     show_max = params.delete(:show_max) || 3
diff --git a/apps/workbench/app/views/container_requests/_show_inputs.html.erb b/apps/workbench/app/views/container_requests/_show_inputs.html.erb
new file mode 100644
index 0000000..87b36c1
--- /dev/null
+++ b/apps/workbench/app/views/container_requests/_show_inputs.html.erb
@@ -0,0 +1,40 @@
+<% n_inputs = cwl_inputs_required(@object, @object.mounts[:"/var/lib/cwl/workflow.json"][:content][:inputs], [:mounts, :"/var/lib/cwl/cwl.input.json", :content]) %>
+
+<% content_for :pi_input_form do %>
+<form role="form" style="width:60%">
+  <div class="form-group">
+    <% workflow = @object.mounts[:"/var/lib/cwl/workflow.json"][:content] %>
+    <% workflow[:inputs].each do |input| %>
+      <label for="#input-<%= input[:id] %>">
+        <%= input[:label] || input[:id] %>
+      </label>
+      <div>
+        <p class="form-control-static">
+          <%= render_cwl_input @object, input, [:mounts, :"/var/lib/cwl/cwl.input.json", :content] %>
+        </p>
+      </div>
+      <p class="help-block">
+        <%= input[:doc] %>
+      </p>
+    <% end %>
+  </div>
+</form>
+<% end %>
+
+<% if n_inputs == 0 %>
+  <p>This workflow does not need any further inputs specified. You can start it by clicking the "Run" button whenever you're ready. (It's not too late to change the settings, though.)</p>
+<% else %>
+  <%= render_unreadable_inputs_present %>
+
+  <p><i>Provide <%= n_inputs > 1 ? 'values' : 'a value' %> for the following <%= n_inputs > 1 ? 'parameters' : 'parameter' %>, then click the "Run" button to start the workflow.</i></p>
+  <% if @object.editable? %>
+    <%= content_for :pi_input_form %>
+      <%= link_to(url_for('container_request[state]' => 'Committed'),
+          class: 'btn btn-primary run-pipeline-button',
+          method: :patch
+          ) do %>
+        Run <i class="fa fa-fw fa-play"></i>
+    <% end %>
+  <% end %>
+
+<% end %>

commit db380bae85dfd8fe68e24a3cbc070abe078ea35d
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Mon Aug 22 16:33:32 2016 -0400

    9043: Expand "uncommitted" test fixture to include more optional parameter types.  Add uncommitted_ready_to_run to test the "Run" button.

diff --git a/services/api/test/fixtures/container_requests.yml b/services/api/test/fixtures/container_requests.yml
index 22d7451..1e5bb7b 100644
--- a/services/api/test/fixtures/container_requests.yml
+++ b/services/api/test/fixtures/container_requests.yml
@@ -167,92 +167,288 @@ uncommitted:
   state: "Uncommitted"
   container_image: arvados/jobs
   mounts: {
-    "/var/lib/cwl/workflow.json": {
-      "kind": "json",
-      "content": {
-        "cwlVersion": "v1.0",
-        "class": "CommandLineTool",
-        "inputs": [
-        {
-          "doc": "a longer documentation string for this parameter (optional)",
-          "type": "boolean",
-          "id": "ex_boolean",
-          "label": "a short label for this parameter (optional)"
-        },
-        {
-          "doc": "directory selection should present the workbench collection picker",
-          "type": "Directory",
-          "id": "ex_dir"
-        },
-        {
-          "type": "double",
-          "id": "ex_double"
-        },
-        {
-          "doc": "file selection should present the workbench file picker",
-          "type": "File",
-          "id": "ex_file"
-        },
-        {
-          "doc": "any parameter can be turned into an array with {\"type\": \"array\", \"items\": \"the_type\"}\n",
-          "type": {
-            "items": "File",
-            "type": "array"
-          },
-          "id": "ex_file_array"
+        "/var/lib/cwl/workflow.json": {
+            "kind": "json",
+            "content": {
+                "cwlVersion": "v1.0",
+                "class": "CommandLineTool",
+                "baseCommand": ["echo"],
+                "inputs": [
+                    {
+                        "doc": "a longer documentation string for this parameter (optional)",
+                        "type": "boolean",
+                        "id": "ex_boolean",
+                        "label": "a short label for this parameter (optional)",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "boolean"],
+                        "id": "ex_boolean_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "directory selection should present the workbench collection picker",
+                        "type": "Directory",
+                        "id": "ex_dir",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "double",
+                        "id": "ex_double",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "file selection should present the workbench file picker",
+                        "type": "File",
+                        "id": "ex_file",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "float",
+                        "id": "ex_float",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "int",
+                        "id": "ex_int",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "int"],
+                        "id": "ex_int_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "long",
+                        "id": "ex_long",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "any parameter can be turned into an optional array with [\"null\", {\"type\": \"array\", \"items\": \"the_type\"}\n",
+                        "type": [
+                            "null",
+                            {
+                                "items": "File",
+                                "type": "array"
+                            }
+                        ],
+                        "id": "ex_opt_file_array",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "any parameter can be made optional by providing a union of [\"null\", \"the_type\"]\n",
+                        "type": [
+                            "null",
+                            "string"
+                        ],
+                        "id": "ex_opt_string",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "string",
+                        "id": "ex_string",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "string"],
+                        "id": "ex_string_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": {
+                            "type": "enum",
+                            "symbols": ["a", "b", "c"]
+                        },
+                        "id": "ex_enum",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", {
+                            "type": "enum",
+                            "symbols": ["a", "b", "c"]
+                        }],
+                        "id": "ex_enum_opt",
+                        "inputBinding": {"position": 1}
+                    }
+                ],
+                "outputs": []
+            }
         },
-        {
-          "type": "float",
-          "id": "ex_float"
+        "/var/lib/cwl/cwl.input.json": {
+            "kind": "json",
+            "content": {}
         },
-        {
-          "type": "int",
-          "id": "ex_int"
+        "stdout": {
+            "kind": "file",
+            "path": "/var/spool/cwl/cwl.output.json"
         },
-        {
-          "type": "long",
-          "id": "ex_long"
+        "/var/spool/cwl": {
+            "kind": "collection",
+            "writable": true
+        }
+    }
+  runtime_constraints:
+    vcpus: 1
+    ram: 256000000
+    API: true
+
+uncommitted_ready_to_run:
+  uuid: zzzzz-xvhdp-cr4uncommittedd
+  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  name: uncommitted_ready_to_run
+  created_at: 2016-01-11 11:11:11.111111111 Z
+  updated_at: 2016-01-11 11:11:11.111111111 Z
+  modified_at: 2016-01-11 11:11:11.111111111 Z
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  command: ["arvados-cwl-runner", "--local", "--api=containers",
+            "/var/lib/cwl/workflow.json", "/var/lib/cwl/cwl.input.json"]
+  output_path: "/var/spool/cwl"
+  cwd: "/var/spool/cwl"
+  priority: 1
+  state: "Uncommitted"
+  container_image: arvados/jobs
+  mounts: {
+        "/var/lib/cwl/workflow.json": {
+            "kind": "json",
+            "content": {
+                "cwlVersion": "v1.0",
+                "class": "CommandLineTool",
+                "baseCommand": ["echo"],
+                "inputs": [
+                    {
+                        "doc": "a longer documentation string for this parameter (optional)",
+                        "type": "boolean",
+                        "id": "ex_boolean",
+                        "label": "a short label for this parameter (optional)",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "boolean"],
+                        "id": "ex_boolean_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "directory selection should present the workbench collection picker",
+                        "type": "Directory",
+                        "id": "ex_dir",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "double",
+                        "id": "ex_double",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "file selection should present the workbench file picker",
+                        "type": "File",
+                        "id": "ex_file",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "float",
+                        "id": "ex_float",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "int",
+                        "id": "ex_int",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "int"],
+                        "id": "ex_int_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "long",
+                        "id": "ex_long",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "any parameter can be turned into an optional array with [\"null\", {\"type\": \"array\", \"items\": \"the_type\"}\n",
+                        "type": [
+                            "null",
+                            {
+                                "items": "File",
+                                "type": "array"
+                            }
+                        ],
+                        "id": "ex_opt_file_array",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "doc": "any parameter can be made optional by providing a union of [\"null\", \"the_type\"]\n",
+                        "type": [
+                            "null",
+                            "string"
+                        ],
+                        "id": "ex_opt_string",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": "string",
+                        "id": "ex_string",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", "string"],
+                        "id": "ex_string_opt",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": {
+                            "type": "enum",
+                            "symbols": ["a", "b", "c"]
+                        },
+                        "id": "ex_enum",
+                        "inputBinding": {"position": 1}
+                    },
+                    {
+                        "type": ["null", {
+                            "type": "enum",
+                            "symbols": ["a", "b", "c"]
+                        }],
+                        "id": "ex_enum_opt",
+                        "inputBinding": {"position": 1}
+                    }
+                ],
+                "outputs": []
+            }
         },
-        {
-          "doc": "any parameter can be turned into an optional array with [\"null\", {\"type\": \"array\", \"items\": \"the_type\"}\n",
-          "type": [
-            "null",
-            {
-              "items": "File",
-              "type": "array"
+        "/var/lib/cwl/cwl.input.json": {
+            "kind": "json",
+            "content": {
+              "ex_string_opt": null,
+              "ex_int_opt": null,
+              "ex_boolean": false,
+              "ex_boolean_opt": true,
+              "ex_dir": {
+                "class": "Directory",
+                "location": "keep:1f4b0bc7583c2a7f9102c395f4ffc5e3+45",
+                "arv:collection": "zzzzz-4zz18-znfnqtbbv4spc3w"
+              },
+              "ex_double": 66.0,
+              "ex_file": {
+                "class": "File",
+                "location": "keep:1f4b0bc7583c2a7f9102c395f4ffc5e3+45/foo",
+                "arv:collection": "zzzzz-4zz18-znfnqtbbv4spc3w/foo"
+              },
+              "ex_float": 55.0,
+              "ex_int": 55,
+              "ex_long": 22,
+              "ex_string": "qq",
+              "ex_enum": "a"
             }
-          ],
-          "id": "ex_opt_file_array"
         },
-        {
-          "doc": "any parameter can be made optional by providing a union of [\"null\", \"the_type\"]\n",
-          "type": [
-            "null",
-            "string"
-          ],
-          "id": "ex_opt_string"
+        "stdout": {
+            "kind": "file",
+            "path": "/var/spool/cwl/cwl.output.json"
         },
-        {
-          "type": "string",
-          "id": "ex_string"
+        "/var/spool/cwl": {
+            "kind": "collection",
+            "writable": true
         }
-        ],
-        "outputs": []
-      },
-    },
-    "/var/lib/cwl/cwl.input.json": {
-      "kind": "json",
-      "content": {}
-    },
-    "stdout": {
-      "kind": "file",
-      "path": "/var/spool/cwl/cwl.output.json"
-    },
-    "/var/spool/cwl": {
-      "kind": "collection",
-      "writable": True
     }
-  }
   runtime_constraints:
     vcpus: 1
     ram: 256000000

commit 7953a07f804e43af6d7f4ec45acbacf13fa4a68f
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Aug 18 15:16:07 2016 -0400

    Test fixture for uncommitted container request.

diff --git a/services/api/test/fixtures/container_requests.yml b/services/api/test/fixtures/container_requests.yml
index de41ff0..22d7451 100644
--- a/services/api/test/fixtures/container_requests.yml
+++ b/services/api/test/fixtures/container_requests.yml
@@ -151,6 +151,114 @@ running_anonymous_accessible:
     vcpus: 1
     ram: 123
 
+uncommitted:
+  uuid: zzzzz-xvhdp-cr4uncommittedc
+  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  name: uncommitted
+  created_at: 2016-01-11 11:11:11.111111111 Z
+  updated_at: 2016-01-11 11:11:11.111111111 Z
+  modified_at: 2016-01-11 11:11:11.111111111 Z
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  command: ["arvados-cwl-runner", "--local", "--api=containers",
+            "/var/lib/cwl/workflow.json", "/var/lib/cwl/cwl.input.json"]
+  output_path: "/var/spool/cwl"
+  cwd: "/var/spool/cwl"
+  priority: 1
+  state: "Uncommitted"
+  container_image: arvados/jobs
+  mounts: {
+    "/var/lib/cwl/workflow.json": {
+      "kind": "json",
+      "content": {
+        "cwlVersion": "v1.0",
+        "class": "CommandLineTool",
+        "inputs": [
+        {
+          "doc": "a longer documentation string for this parameter (optional)",
+          "type": "boolean",
+          "id": "ex_boolean",
+          "label": "a short label for this parameter (optional)"
+        },
+        {
+          "doc": "directory selection should present the workbench collection picker",
+          "type": "Directory",
+          "id": "ex_dir"
+        },
+        {
+          "type": "double",
+          "id": "ex_double"
+        },
+        {
+          "doc": "file selection should present the workbench file picker",
+          "type": "File",
+          "id": "ex_file"
+        },
+        {
+          "doc": "any parameter can be turned into an array with {\"type\": \"array\", \"items\": \"the_type\"}\n",
+          "type": {
+            "items": "File",
+            "type": "array"
+          },
+          "id": "ex_file_array"
+        },
+        {
+          "type": "float",
+          "id": "ex_float"
+        },
+        {
+          "type": "int",
+          "id": "ex_int"
+        },
+        {
+          "type": "long",
+          "id": "ex_long"
+        },
+        {
+          "doc": "any parameter can be turned into an optional array with [\"null\", {\"type\": \"array\", \"items\": \"the_type\"}\n",
+          "type": [
+            "null",
+            {
+              "items": "File",
+              "type": "array"
+            }
+          ],
+          "id": "ex_opt_file_array"
+        },
+        {
+          "doc": "any parameter can be made optional by providing a union of [\"null\", \"the_type\"]\n",
+          "type": [
+            "null",
+            "string"
+          ],
+          "id": "ex_opt_string"
+        },
+        {
+          "type": "string",
+          "id": "ex_string"
+        }
+        ],
+        "outputs": []
+      },
+    },
+    "/var/lib/cwl/cwl.input.json": {
+      "kind": "json",
+      "content": {}
+    },
+    "stdout": {
+      "kind": "file",
+      "path": "/var/spool/cwl/cwl.output.json"
+    },
+    "/var/spool/cwl": {
+      "kind": "collection",
+      "writable": True
+    }
+  }
+  runtime_constraints:
+    vcpus: 1
+    ram: 256000000
+    API: true
+
+
 # Test Helper trims the rest of the file
 
 # Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list