myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [2881] branches/datasets: Added ability to upload


From: noreply
Subject: [myexperiment-hackers] [2881] branches/datasets: Added ability to upload a file as data.
Date: Wed, 14 Dec 2011 09:13:09 -0500 (EST)

Revision
2881
Author
fbacall
Date
2011-12-14 09:13:09 -0500 (Wed, 14 Dec 2011)

Log Message

Added ability to upload a file as data. Added non-AJAX support

Modified Paths

Added Paths

Removed Paths

Diff

Modified: branches/datasets/app/controllers/data_items_controller.rb (2880 => 2881)


--- branches/datasets/app/controllers/data_items_controller.rb	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/controllers/data_items_controller.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -8,37 +8,52 @@
   before_filter :fetch_data_item, :except => [:create, :new]
   before_filter :fetch_data_set_and_workflow
   before_filter :auth
-  before_filter :fetch_port_names, : [:new, :edit]
+  before_filter :fetch_port_names, : [:new, :edit, :create, :update]
   before_filter :fetch_blobs, : [:new, :edit]
 
   def create
     @data_item = DataItem.new
 
     if (data = "" &&
-       @data_item.update_attributes(:data ="" data, :port_name => params[:workflow_port], :port_type => params[:workflow_port_type],
+       @data_item.update_attributes(:data ="" data, :port_name => params[:workflow_port], :port_type => params[:port_type],
                                     :data_set => @data_set)
       respond_to do |format|
-        format.html {render :partial => "data_sets/data_set", :object => @data_set}
+        if request.xhr?
+          format.html { render :partial => "data_sets/data_set", :object => @data_set }
+        else
+          format.html { redirect_to data_set_url(@data_set) }
+        end
       end
     else
       respond_to do |format|
-        format.html {render :partial => "data_sets/errors", :status => :unprocessable_entity,
-                            :locals => {:errors => @data_item.errors.full_messages}}
+        if request.xhr?
+          format.html { render :partial => "data_sets/errors", :status => :unprocessable_entity,
+                               :locals => {:errors => @data_item.errors.full_messages} }
+        else
+          format.html { render :action ="" "new", :status => :unprocessable_entity }
+        end
       end
     end
   end
 
   def update
-    if @data_item.update_attributes(:data ="" get_data, :port_name => params[:workflow_port], :port_type => params[:workflow_port_type],
+    if @data_item.update_attributes(:data ="" get_data, :port_name => params[:workflow_port], :port_type => params[:port_type],
                                     :data_set => @data_set)
       respond_to do |format|
-        format.html {render :partial => "data_sets/data_item", :object => @data_item,
-                            :locals => {:port_type => params[:workflow_port_type]}}
+        if request.xhr?
+          format.html { render :partial => "data_items/data_item", :object => @data_item }
+        else
+          format.html { redirect_to data_set_url(@data_set) }
+        end
       end
     else
       respond_to do |format|
-        format.html {render :partial => "data_sets/errors", :status => :unprocessable_entity,
-                            :locals => {:errors => @data_item.errors.full_messages}}
+        if request.xhr?
+          format.html { render :partial => "data_sets/errors", :status => :unprocessable_entity,
+                               :locals => {:errors => @data_item.errors.full_messages} }
+        else
+          format.html { render :action ="" "edit", :status => :unprocessable_entity }
+        end
       end
     end
   end
@@ -46,36 +61,55 @@
   def destroy
     if @data_item.destroy
       respond_to do |format|
-        format.html {render :partial => "data_sets/data_set", :object => @data_set}
+        if request.xhr?
+          format.html { render :partial => "data_sets/data_set", :object => @data_set }
+        else
+          format.html { redirect_to data_set_url(@data_set) }
+        end
       end
     end
   end
 
   def edit
     respond_to do |format|
-      format.html {render :partial => "data_sets/data_item_form",
-                          :locals => {:port_type => @data_item.port_type}}
+      if request.xhr?
+        format.html { render :partial => "data_items/data_item_form" }
+      else
+        format.html
+      end
     end
   end
 
   def new
-    @data_item = DataItem.new
+    @data_item ||= DataItem.new(:port_type => params[:port_type])
 
     if @port_names.empty?
       respond_to do |format|
-        format.html {render :nothing => true, :status => :unprocessable_entity}
+        if request.xhr?
+          format.html { render :nothing => true, :status => :unprocessable_entity }
+        else
+          flash[:error] = "No more #{params[:port_type]}s left to specify."
+          format.html { redirect_to data_set_url(@data_set) }
+        end
       end
     else
       respond_to do |format|
-        format.html {render :partial => "data_sets/data_item_form",
-                          :locals => {:port_type => params[:port_type]}}
+        if request.xhr?
+          format.html { render :partial => "data_items/data_item_form" }
+        else
+          format.html
+        end
       end
     end
   end
 
   def show
     respond_to do |format|
-      format.html {render :partial => "data_sets/data_item", :object => @data_item}
+      if request.xhr?
+        format.html { render :partial => "data_items/data_item", :object => @data_item }
+      else
+        format.html
+      end
     end
   end
 
@@ -89,14 +123,29 @@
     @workflow = @data_set.workflow
   end
 
+  # Either: Find associated data, or create new data (which is not saved to the DB until the data item validates and saves)
+  #  and return it.
   def get_data
     if params[:data_type] == "TextData"
       if @data_item.data.kind_of?(TextData) && params[:data] == @data_item.data.data
-          return @data_item.data
+        return @data_item.data
       else
         # Create new data to be autosaved when data item is saved
         return TextData.new(:data ="" params[:data])
       end
+    elsif params[:data_type] == "FileData"
+      if @data_item.data.kind_of?(FileData) && (params[:file_data].blank? || params[:file_data].size == 0)
+        return @data_item.data
+      else
+        # Create new data to be autosaved when data item is saved
+        content_type = ContentType.find_by_mime_type(params[:file_data].content_type) ||
+                       ContentType.new(:user_id => current_user.id,
+                                       :mime_type => params[:file_data].content_type,
+                                       :title => params[:file_data].content_type)
+        return FileData.new(:file_name => params[:file_data].original_filename,
+                            :content_blob => ContentBlob.new(:data ="" params[:file_data].read),
+                            :content_type => content_type)
+      end
     elsif params[:data_type] == "Blob"
       return Blob.find(params[:data_id])
     else
@@ -106,13 +155,11 @@
 
   def fetch_port_names
     port_type = params[:port_type] || @data_item.port_type
+    version = @data_set.workflow_version
 
     existing_ports = @data_set.data_items.select {|i| port_type == i.port_type}.map {|r| r.port_name}
-
     existing_ports.delete(@data_item.port_name) if @data_item
 
-    version = @data_set.workflow_version
-
     @port_names = (port_type == "input" ? @workflow.get_workflow_model_object(version).sources :
                                           @workflow.get_workflow_model_object(version).sinks).map {|s| s.name}
 

Modified: branches/datasets/app/controllers/data_sets_controller.rb (2880 => 2881)


--- branches/datasets/app/controllers/data_sets_controller.rb	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/controllers/data_sets_controller.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -8,7 +8,7 @@
   before_filter :fetch_data_set, :except => [:create, :new, :index]
   before_filter :fetch_workflow
   before_filter :auth
-  before_filter :fetch_and_auth_data_sets, : [:index, :show]
+  before_filter :fetch_and_auth_data_sets, : [:index]
   before_filter :set_sharing_mode_variables, : [:new, :create, :edit, :update]
 
   def create

Modified: branches/datasets/app/models/data_item.rb (2880 => 2881)


--- branches/datasets/app/models/data_item.rb	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/models/data_item.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -5,17 +5,32 @@
 
 class DataItem < ActiveRecord::Base
 
+  # Things that can be attached as data to a workflow port:
+
+  # - These types of data are independent from the DataItem:
+  INDEPENDENT_DATA_TYPES = ["Blob"]
+
+  # - These types of data are strongly linked to the DataItem and will be destroyed if disassociated from it:
+  DEPENDENT_DATA_TYPES = ["FileData", "TextData"]
+
+  PERMITTED_DATA_TYPES = INDEPENDENT_DATA_TYPES + DEPENDENT_DATA_TYPES
+
+  DATA_TYPE_EXPLANATIONS = {"Blob"     => "A file on #{Conf.sitename}",
+                            "FileData" => "A file uploaded from your computer",
+                            "TextData" => "Text"
+  }
+
   belongs_to :data_set
   belongs_to :data, :polymorphic => true, :autosave => true
 
   validates_presence_of :port_name, :port_type, :data, :data_set
   validates_inclusion_of :port_type, :in => ["input", "output"]
-  validates_inclusion_of :data_type, :in => ["TextData", "Blob"]
+  validates_inclusion_of :data_type, :in => PERMITTED_DATA_TYPES
   validates_uniqueness_of :port_name, :scope => [:port_type, :data_set_id]
 
   # To avoid leaving useless orphaned text data
-  after_destroy :destroy_text_data
-  before_save :destroy_old_text_data
+  after_destroy :destroy_data
+  before_save :destroy_old_data
 
   def input?
     port_type == "input"
@@ -25,18 +40,26 @@
     port_type == "output"
   end
 
+  def dependent_data?
+    DEPENDENT_DATA_TYPES.include?(self.data_type)
+  end
+
+  def independent_data?
+    INDEPENDENT_DATA_TYPES.include?(self.data_type)
+  end
+
   private
 
-  def destroy_text_data
-    if data.kind_of?(TextData)
+  def destroy_data
+    if dependent_data? && data
       data.destroy
     end
   end
 
-  def destroy_old_text_data
+  def destroy_old_data
     # Cool new Rails 2 methods to get the former attribute values
-    if (data_type_changed? || data_id_changed?) && data_type_was == "TextData"
-      TextData.find(data_id_was).destroy
+    if (data_type_changed? || data_id_changed?) && DEPENDENT_DATA_TYPES.include?(data_type_was)
+      eval(data_type_was).find_by_id(data_id_was).try(:destroy)
     end
   end
 end

Modified: branches/datasets/app/models/data_set.rb (2880 => 2881)


--- branches/datasets/app/models/data_set.rb	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/models/data_set.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -47,6 +47,9 @@
           else
             stats[data_item.port_type][:hidden] += 1
           end
+        elsif data.kind_of?(FileData)
+          zipfile.add_data("#{data_item.port_type}s/#{data_item.port_name} - #{data.file_name}", data.content_blob.data)
+          stats[data_item.port_type][:files] += 1
         elsif data.kind_of?(TextData)
           zipfile.add_data("#{data_item.port_type}s/#{data_item.port_name} - text.txt", data.data)
           stats[data_item.port_type][:text] += 1

Added: branches/datasets/app/models/file_data.rb (0 => 2881)


--- branches/datasets/app/models/file_data.rb	                        (rev 0)
+++ branches/datasets/app/models/file_data.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,20 @@
+# myExperiment: app/models/file_data.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class FileData < ActiveRecord::Base
+
+  set_table_name "file_data"
+
+  has_one :data_item, :as => :data
+  belongs_to :content_blob, :dependent => :destroy, :autosave => true
+  belongs_to :content_type, :autosave => true
+
+  validates_presence_of :file_name
+  validates_each :content_blob do |record, attr, value|
+    if value.data.size > Conf.max_upload_size
+      record.errors.add(:file, "is too big.  Maximum size is #{Conf.max_upload_size} bytes.")
+    end
+  end
+end

Added: branches/datasets/app/views/data_items/_breadcrumbs.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/_breadcrumbs.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/_breadcrumbs.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,20 @@
+<li><%= link_to 'Workflows', workflows_path -%></li>
+
+<li><b>&#187;</b></li>
+<li><%= link_to h(@workflow.title), workflow_path(@workflow) -%></li>
+
+<li><b>&#187;</b></li>
+<li><%= link_to h(@data_set.title), data_set_path(@data_set) %></li>
+
+<% case controller.action_name.to_s; when "show" %>
+  <li><b>&#187;</b></li>
+  <li>Viewing data item</li>
+<% when "new" %>
+  <li><b>&#187;</b></li>
+  <li>Create new data item</li>
+<% when "edit" %>
+  <li><b>&#187;</b></li>
+  <li>Editing data item</li>
+<% else %>
+  <!-- no breadcrumb -->
+<% end %>

Copied: branches/datasets/app/views/data_items/_data_item.rhtml (from rev 2869, branches/datasets/app/views/data_sets/_data_item.rhtml) (0 => 2881)


--- branches/datasets/app/views/data_items/_data_item.rhtml	                        (rev 0)
+++ branches/datasets/app/views/data_items/_data_item.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,41 @@
+<% port_td = capture do %>
+  <td class="port <%= data_item.port_type -%>">
+    <h5><img src="" <%= data_item.port_type.capitalize %> Name</h5>
+    <div>
+      <input title="<%= data_item.port_name -%>" type="text" readonly="readonly" value="<%= data_item.port_name -%>" size="24" class="readonly"/>
+    </div>
+  </td>
+<% end  %>
+
+<% data_td = capture do %>
+  <td class="data">
+    <h5><img src="" Data</h5>
+    <%= render :partial => "data_items/data_types/#{data_item.data_type.underscore}/data", :object => data_item.data %>
+  </td>
+<% end  %>
+
+<%= data_item.port_type == "input" ? data_td : port_td %>
+<td class="arrow"><img src=""
+<%= data_item.port_type == "input" ? port_td : data_td %>
+
+<% if Authorization.is_authorized?("destroy", nil, @data_set, current_user) %>
+<td class="controls">
+  <% if Authorization.is_authorized?("edit", nil, @data_set, current_user) %>
+    <%= icon('destroy', {:url ="" data_item_path(data_item), :method => :delete,
+                        :update => {:success => "data_set_container"},
+                        :loading => "$('data_item_#{data_item.id}_spinner').show();",
+                        :complete => "$('data_item_#{data_item.id}_spinner').hide();"},
+             nil, {:method => :delete,
+                   :confirm => "Are you sure?",
+                   :title => "Delete this #{data_item.dependent_data? ? "data" : "association"}"}, "", true) %>
+    <br/>
+  <% end %>
+  <%= icon('edit', {:url ="" edit_data_item_path(data_item), :method => :get,
+                    :update => {:success => "item_#{data_item.id}"},
+                    :loading => "$('data_item_#{data_item.id}_spinner').show();",
+                    :complete => "$('data_item_#{data_item.id}_spinner').hide();"},
+           nil, {:title => "Edit this #{data_item.dependent_data? ? "data" : "association"}"}, "", true) %>
+  <br/>
+  <img id="data_item_<%=data_item.id-%>_spinner" src="" style="display:none; vertical-align: middle;"/>
+</td>
+<% end %>

Copied: branches/datasets/app/views/data_items/_data_item_form.rhtml (from rev 2869, branches/datasets/app/views/data_sets/_data_item_form.rhtml) (0 => 2881)


--- branches/datasets/app/views/data_items/_data_item_form.rhtml	                        (rev 0)
+++ branches/datasets/app/views/data_items/_data_item_form.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,118 @@
+<%
+  data = ""
+  port_name = @data_item.port_name
+  port_type = @data_item.port_type
+
+  port_names_for_select = @port_names.map do |p|
+    %(<option #{"selected=\"selected\"" if (port_name == p)}
+        value="#{p}" title="#{h p}">#{h truncate(p, :length => 20)}</option>)
+  end.join.html_safe
+
+
+  container_element = @data_item.id.nil? ? "data_item_#{port_type}_form" : "address@hidden"
+  unique_id = (@data_item.id || port_type).to_s
+
+
+  # We have to revert using a normal, non-AJAX HTTP request when uploading a file, because files cannot be uploaded using
+  # _javascript_, as it is forbidden from accessing the file system for security reasons.
+  #
+  # This function decides whether or not to do that when the form is submitted.
+
+  form_submit_function = nil
+
+  unless (no_ajax ||= false)
+    form_submit_function = %(
+      if($F('data_type_select_#{unique_id}') == "FileData"){
+        //Normal HTTP request
+        $('data_item_form_spinner_#{unique_id}').show();
+        $('data_item_submit_#{unique_id}').disable().value = "Saving...";;
+        return true;
+      }
+      else{
+        //AJAX
+        #{remote_function(:url ="" (@data_item.id.nil? ? data_set_data_items_path(@data_set) : data_item_path(@data_item)),
+                          :method => (@data_item.id.nil? ? :post : :put),
+                          :update => {:success => (@data_item.id.nil? ? "data_set_container" : container_element),
+                                      :failure => "data_item_form_errors"},
+                          :failure => "$('data_item_form_errors').show();",
+                          :loading => "$('data_item_form_spinner_#{unique_id}').show();",
+                          :complete => "$('data_item_form_spinner_#{unique_id}').hide();",
+                          :form => true)};
+        return false;
+      }
+    )
+  else
+    form_submit_function = %(
+      $('data_item_form_spinner_#{unique_id}').show();
+      $('data_item_submit_#{unique_id}').disable().value = "Saving...";
+      return true;
+    )
+  end
+%>
+
+<td colspan="4" style="padding: 0">
+  <% port_td = capture do %>
+    <td class="port <%= port_type -%>" style="vertical-align: top">
+      <h5>Select <%= port_type %></h5>
+      <div>
+        <%= select_tag(:workflow_port, port_names_for_select) %>
+      </div>
+    </td>
+  <% end  %>
+
+  <% data_td = capture do %>
+    <td class="data">
+      <h5>Select data type</h5>
+      <select id="data_type_select_<%=unique_id-%>" name="data_type"  "$$('##{container_element} .data_form').each(function (f){ f.hide()});"+
+                                                                                   "$(this.options[this.selectedIndex].value + '_form_#{unique_id}').show();"-%>">
+      <% DataItem::PERMITTED_DATA_TYPES.each do |type| %>
+        <option value="<%= type -%>" <%= 'selected="selected"' if type == @data_item.data_type -%>>
+          <%= DataItem::DATA_TYPE_EXPLANATIONS[type] || type -%>
+        </option>
+      <% end %>
+      </select>
+
+      <% DataItem::PERMITTED_DATA_TYPES.each do |type| %>
+      <div class="data_form" id="<%=type-%>_form_<%=unique_id-%>" <%= 'style="display: none"' if !((@data_item.data_type == type) ||
+                                                                                                     @data_item.data_type.nil? && (type == DataItem::PERMITTED_DATA_TYPES.first)) -%>>
+        <%= render :partial => "data_items/data_types/#{type.underscore}/form", :locals => {:unique_id => unique_id} %>
+      </div>
+      <% end %>
+    </td>
+  <% end  %>
+  <% form_tag((@data_item.id.nil? ? data_set_data_items_path(@data_set) : data_item_path(@data_item)),
+              {: form_submit_function,
+               :multipart => true,
+               :method => (@data_item.id.nil? ? :post : :put),
+               :id => "data_item_form_#{unique_id}" }) do %>
+    <div id="data_item_form_errors" <%= 'style="display:none"' if @data_item.errors.empty?-%>>
+      <%= error_messages_for 'data_item' -%>
+    </div>
+
+    <table>
+      <tr>
+        <%= port_type == "input" ? data_td : port_td %>
+        <td class="arrow"><img src=""
+        <%= port_type == "input" ? port_td : data_td %>
+
+        <td class="controls">
+          <%= hidden_field_tag(:port_type, port_type) %>
+          <%= submit_tag "Save", :id => "data_item_submit_#{unique_id}" %><br/>
+          or<br/>
+          <% if @data_item.id.nil? %>
+            <%= link_to "Cancel", "#", : "$$('##{container_element} td').each(function (e){ e.remove()});return false;" %>
+          <% else %>
+            <%= link_to "Cancel", "#", : remote_function(:url ="" data_item_path(@data_item),
+                                                     :method => :get,
+                                                     :update => {:success => container_element},
+                                                     :loading => "$('data_item_form_spinner_#{unique_id}').show();",
+                                                     :complete => "$('data_item_form_spinner_#{unique_id}').hide();")+
+                                                     ";return false" %>
+          <% end %>
+          <br/>
+          <img id="data_item_form_spinner_<%=unique_id-%>" src="" style="display:none; vertical-align: middle;"/>
+        </td>
+      </tr>
+    </table>
+  <% end %>
+</td>

Added: branches/datasets/app/views/data_items/data_types/blob/_data.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/blob/_data.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/blob/_data.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,23 @@
+<div class="file_data">
+  <% can_download = Authorization.is_authorized?("download", nil, data, current_user) %>
+  <% can_view = can_download || Authorization.is_authorized?("view", nil, data, current_user) %>
+  <% if can_view -%>
+    <div style="float:left">
+      <b>Title:</b> <%= link_to "#{h truncate(data.label, :length => 70)}", file_path(data), :class => "file_link" %><br/>
+      <b>Type: </b> <%= h data.content_type.title %><br/>
+      <b>Size: </b> <%= number_to_human_size(data.content_blob.data.size) %><br/>
+    </div>
+    <div class="actions">
+      <%= icon('show', file_path(data), nil, nil, 'View') %><br/>
+
+      <% if can_download %>
+        <%= icon('download', download_file_path(data), nil, nil, 'Download') %><br/>
+      <% end %>
+
+    </div>
+  <% else %>
+    <p class="denied_text" style="text-align: center;">
+      You are not authorised to view this data file.
+    </p>
+  <% end %>
+</div>
\ No newline at end of file

Added: branches/datasets/app/views/data_items/data_types/blob/_form.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/blob/_form.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/blob/_form.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,12 @@
+<%
+  blobs = current_user.blobs +
+        (current_user.bookmarks.find(:all, :conditions => ["bookmarkable_type = 'Blob'"]).map {|b| b.bookmarkable})
+
+  blob_names_for_select = blobs.map do |b|
+    %(<option #{"selected=\"selected\"" if (@data_item.data == b)}
+        value="#{b.id}" title="#{h b.title}">#{h truncate(b.title, :length => 30)}</option>)
+  end.join.html_safe
+%>
+
+<h5>Select data file</h5>
+<%= select_tag :data_id, blob_names_for_select %><br/>

Added: branches/datasets/app/views/data_items/data_types/file_data/_data.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/file_data/_data.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/file_data/_data.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,10 @@
+<div class="file_data">
+  <div style="float:left">
+    <b>Title:</b> <%= h truncate(data.file_name, :length => 70) %><br/>
+    <b>Type: </b> <%= h data.content_type.title %><br/>
+    <b>Size: </b> <%= number_to_human_size(data.content_blob.data.size) %><br/>
+  </div>
+  <div class="actions">
+    <%= icon('download', "", nil, nil, 'Download') %><br/>
+  </div>
+</div>
\ No newline at end of file

Added: branches/datasets/app/views/data_items/data_types/file_data/_form.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/file_data/_form.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/file_data/_form.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,7 @@
+<h5>Choose a file</h5>
+<%= file_field_tag :file_data %>
+<% if @data_item.data_type == "FileData" %>
+<p style="font-size: 77%">
+  If left blank, the current file <b>(<%= @data_item.data.file_name -%>)</b> will be used.
+</p>
+<% end %>

Added: branches/datasets/app/views/data_items/data_types/text_data/_data.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/text_data/_data.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/text_data/_data.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,3 @@
+<div>
+  <%= text_area_tag :data, data.data, :readonly =>"readonly", :rows => 1, :cols => 50, :class => "readonly" %>
+</div>

Added: branches/datasets/app/views/data_items/data_types/text_data/_form.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/data_types/text_data/_form.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/data_types/text_data/_form.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,2 @@
+<h5>Input your data</h5>
+<%= text_area_tag(:data, (@data_item.data.data if @data_item.data_type == "TextData"), :rows => 4, :cols => 50) %>

Added: branches/datasets/app/views/data_items/edit.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/edit.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/edit.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,10 @@
+<h1>Editing Data Item</h1>
+<div class="data_set">
+  <table>
+  <tbody>
+    <tr class="data_item" id="item_<%= @data_item.id -%>">
+      <%= render :partial => "data_items/data_item_form", :object => @data_item, :locals => {:no_ajax => true} %>
+    </tr>
+  </tbody>
+  </table>
+</div>

Added: branches/datasets/app/views/data_items/new.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/new.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/new.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,10 @@
+<h1>New Data Item</h1>
+<div class="data_set">
+  <table>
+  <tbody>
+    <tr class="data_item" id="data_item_<%= @data_item.port_type -%>_form">
+      <%= render :partial => "data_items/data_item_form", :object => @data_item, :locals => {:no_ajax => true} %>
+    </tr>
+  </tbody>
+  </table>
+</div>

Added: branches/datasets/app/views/data_items/show.html.erb (0 => 2881)


--- branches/datasets/app/views/data_items/show.html.erb	                        (rev 0)
+++ branches/datasets/app/views/data_items/show.html.erb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -0,0 +1,10 @@
+<h1>Data Item</h1>
+<div class="data_set">
+  <table>
+  <tbody>
+    <tr class="data_item" id="item_<%= @data_item.id -%>">
+      <%= render :partial => "data_items/data_item", :object => @data_item %>
+    </tr>
+  </tbody>
+  </table>
+</div>

Deleted: branches/datasets/app/views/data_sets/_data_item.rhtml (2880 => 2881)


--- branches/datasets/app/views/data_sets/_data_item.rhtml	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/views/data_sets/_data_item.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -1,74 +0,0 @@
-<%
-   data = ""
-   port_type = data_item.port_type
-   port_name = data_item.port_name
-%>
-
-<% port_td = capture do %>
-  <td class="port <%= port_type -%>">
-    <h5><img src="" <%= port_type.capitalize %> Name</h5>
-    <div>
-      <input title="<%= port_name -%>" type="text" readonly="readonly" value="<%= port_name -%>" size="24" class="readonly"/>
-    </div>
-  </td>
-<% end  %>
-
-<% data_td = capture do %>
-  <td class="data">
-    <h5><img src="" Data</h5>
-    <% if data.kind_of?(TextData) %>
-      <div>
-        <%= text_area_tag :data, data.data, :readonly =>"readonly", :rows => 1, :cols => 50, :class => "readonly" %>
-      </div>
-    <% elsif data.kind_of?(Blob) %>
-      <div class="file_data">
-        <% can_download = Authorization.is_authorized?("download", nil, data, current_user) %>
-        <% can_view = can_download || Authorization.is_authorized?("view", nil, data, current_user) %>
-			  <% if can_view -%>
-          <div style="float:left">
-            <b>Title:</b> <%= link_to "#{h truncate(data.label, :length => 70)}", file_path(data), :class => "file_link" %><br/>
-            <b>Type: </b> <%= h data.content_type.title %><br/>
-            <b>Size: </b> <%= number_to_human_size(data.content_blob.data.size) %><br/>
-          </div>
-          <div class="actions">
-            <%= icon('show', file_path(data), nil, nil, 'View') %><br/>
-
-            <% if can_download %>
-              <%= icon('download', download_file_path(data), nil, nil, 'Download') %><br/>
-            <% end %>
-
-          </div>
-        <% else %>
-          <p class="denied_text" style="text-align: center;">
-            You are not authorised to view this data file.
-          </p>
-        <% end %>
-      </div>
-    <% end  %>
-  </td>
-<% end  %>
-
-<%= port_type == "input" ? data_td : port_td %>
-<td class="arrow"><img src=""
-<%= port_type == "input" ? port_td : data_td %>
-
-<%# data sets should probably have their own policy %>
-<% if mine? @workflow %>
-<td class="controls">
-  <%= icon('destroy', {:url ="" data_item_path(data_item), :method => :delete,
-                      :update => {:success => "data_set_container"},
-                      :loading => "$('data_item_#{data_item.id}_spinner').show();",
-                      :complete => "$('data_item_#{data_item.id}_spinner').hide();"},
-           nil, {:method => :delete,
-                 :confirm => "Are you sure?",
-                 :title => "Delete this #{data.kind_of?(TextData) ? "data" : "association"}"}, "", true) %>
-  <br/>
-  <%= icon('edit', {:url ="" edit_data_item_path(data_item), :method => :get,
-                    :update => {:success => "item_#{data_item.id}"},
-                    :loading => "$('data_item_#{data_item.id}_spinner').show();",
-                    :complete => "$('data_item_#{data_item.id}_spinner').hide();"},
-           nil, {:title => "Edit this association"}, "", true) %>
-  <br/>
-  <img id="data_item_<%=data_item.id-%>_spinner" src="" style="display:none; vertical-align: middle;"/>
-</td>
-<% end %>

Deleted: branches/datasets/app/views/data_sets/_data_item_form.rhtml (2880 => 2881)


--- branches/datasets/app/views/data_sets/_data_item_form.rhtml	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/views/data_sets/_data_item_form.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -1,99 +0,0 @@
-<%
-  data = ""
-  port_name = @data_item.port_name
-  port_type = @data_item.port_type || params[:port_type]
-
-  port_names_for_select = @port_names.map do |p|
-    %(<option #{"selected=\"selected\"" if (port_name == p)}
-        value="#{p}" title="#{h p}">#{h truncate(p, :length => 20)}</option>)
-  end.join.html_safe
-
-  blob_names_for_select = @blobs.map do |b|
-    %(<option #{"selected=\"selected\"" if (data == b)}
-        value="#{b.id}" title="#{h b.title}">#{h truncate(b.title, :length => 30)}</option>)
-  end.join.html_safe
-
-  container_element = @data_item.id.nil? ? "data_item_#{port_type}_form" : "address@hidden"
-  unique_id = (@data_item.id || port_type).to_s
-%>
-
-<td colspan="4" style="padding: 0">
-  <% port_td = capture do %>
-    <td class="port <%= port_type -%>" style="vertical-align: top">
-      <h5><%= port_type == "input" ? "3" : "1" -%>. Select <%= port_type %></h5>
-      <div>
-        <%= select_tag(:workflow_port, port_names_for_select) %>
-      </div>
-    </td>
-  <% end  %>
-
-  <% data_td = capture do %>
-    <td class="data">
-      <h5>
-        <%= port_type == "input" ? "1" : "2" -%>. Select data type
-        <div class="data_type">
-          <%= radio_button_tag "data_type", "TextData", data.kind_of?(TextData) || data.blank?,
-                               { :id => "data_type_text_#{unique_id}",
-                                 : "$$('##{container_element} .data_form').each(function (f){ f.hide()});"+
-                                             "$('text_data_form_#{unique_id}').show();" } %>
-          <label for=""
-
-          <span style="color: #999"> | </span>
-          <%= radio_button_tag "data_type", "Blob", data.kind_of?(Blob), { :id => "data_type_file_#{unique_id}",
-                               : "$$('##{container_element} .data_form').each(function (f){ f.hide()});"+
-                                           "$('file_data_form_#{unique_id}').show();" } %>
-          <label for=""
-        </div>
-      </h5>
-
-      <div class="data_form" id="text_data_form_<%=unique_id-%>" <%= "style=\"display: none\"" if !(data.kind_of?(TextData) || data.blank?) -%>>
-        <h5><%= port_type == "input" ? "2" : "3" -%>. Input your data</h5>
-        <%= text_area_tag(:data, (data.data if data.kind_of?(TextData)), :rows => 4, :cols => 50) %>
-      </div>
-
-      <div class="data_form" id="file_data_form_<%=unique_id-%>" <%= "style=\"display: none\"" if !data.kind_of?(Blob) -%> >
-        <h5><%= port_type == "input" ? "2" : "3" -%>. Select data file</h5>
-
-        <%= select_tag :data_id, blob_names_for_select %><br/>
-
-      </div>
-      <br class="clearer"/>
-
-    </td>
-  <% end  %>
-  <% form_remote_tag  :url ="" (@data_item.id.nil? ? data_set_data_items_path(@data_set) : data_item_path(@data_item)),
-                      :method => (@data_item.id.nil? ? :post : :put),
-                      :update => {:success => (@data_item.id.nil? ? "data_set_container" : container_element),
-                                  :failure => "data_item_form_errors"},
-                      :failure => "$('data_item_form_errors').show();",
-                      :loading => "$('data_item_form_spinner_#{unique_id}').show();",
-                      :complete => "$('data_item_form_spinner_#{unique_id}').hide();" do %>
-    <div id="data_item_form_errors" style="display:none"></div>
-
-    <table>
-      <tr>
-        <%= port_type == "input" ? data_td : port_td %>
-        <td class="arrow"><img src=""
-        <%= port_type == "input" ? port_td : data_td %>
-
-        <td class="controls">
-          <%= hidden_field_tag(:workflow_port_type, port_type) %>
-          <%= submit_tag "Save" %><br/>
-          or<br/>
-          <% if @data_item.id.nil? %>
-            <%= link_to "Cancel", "#", : "$$('##{container_element} td').each(function (e){ e.remove()});return false;" %>
-          <% else %>
-            <%= link_to "Cancel", "#", : remote_function(:url ="" data_item_path(@data_item),
-                                                     :method => :get,
-                                                     :update => {:success => container_element},
-                                                     :loading => "$('data_item_form_spinner_#{unique_id}').show();",
-                                                     :complete => "$('data_item_form_spinner_#{unique_id}').hide();")+
-                                                     ";return false" %>
-          <% end %>
-          <br/>
-          <img id="data_item_form_spinner_<%=unique_id-%>" src="" style="display:none; vertical-align: middle;"/>
-        </td>
-      </tr>
-    </table>
-  <% end %>
-</td>

Modified: branches/datasets/app/views/data_sets/_data_set.rhtml (2880 => 2881)


--- branches/datasets/app/views/data_sets/_data_set.rhtml	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/views/data_sets/_data_set.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -25,13 +25,21 @@
     <tbody>
       <% (@data_set.data_items.select{|r| r.input?}).each do |i| %>
         <tr class="data_item" id="item_<%= i.id -%>">
-          <%= render :partial => "data_sets/data_item", :object => i, :locals => {:port_type => "input"} %>
+          <% if @data_item && @data_item == i %>
+            <%= render :partial => "data_items/data_item_form" %>
+          <% else %>
+            <%= render :partial => "data_items/data_item", :object => i %>
+          <% end %>
         </tr>
         <%# Blank row for spacing %>
         <tr><td style="padding: 3px"></td></tr>
       <% end %>
       <tr id="data_item_input_form">
+        <% if @data_item && @data_item.id.blank? && @data_item.port_type == "input" %>
+          <%= render :partial => "data_items/data_item_form" %>
+        <% end %>
       </tr>
+      <tr><td style="padding: 3px"></td></tr>
     </tbody>
   </table>
 
@@ -59,13 +67,21 @@
     <tbody>
       <% (@data_set.data_items.select{|r| r.output?}).each do |o| %>
         <tr class="data_item" id="item_<%= o.id -%>">
-          <%= render :partial => "data_sets/data_item", :object => o, :locals => {:port_type => "output"} %>
+          <% if @data_item && @data_item == o %>
+            <%= render :partial => "data_items/data_item_form" %>
+          <% else %>
+            <%= render :partial => "data_items/data_item", :object => o %>
+          <% end %>
         </tr>
         <%# Blank row for spacing %>
         <tr><td style="padding: 3px"></td></tr>
       <% end %>
       <tr id="data_item_output_form">
+        <% if @data_item && @data_item.id.blank? && @data_item.port_type == "output" %>
+          <%= render :partial => "data_items/data_item_form" %>
+        <% end %>
       </tr>
+      <tr><td style="padding: 3px"></td></tr>
     </tbody>
   </table>
 

Modified: branches/datasets/app/views/data_sets/show.rhtml (2880 => 2881)


--- branches/datasets/app/views/data_sets/show.rhtml	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/app/views/data_sets/show.rhtml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -1,31 +1,22 @@
 <div id="data_sets_container">
-  <div id="data_set_selector" style="float: left" class="sectionIcons">
-    Jump to data set:
-    <%= select_tag :data_set, (@data_sets.map {|d| "<option #{"selected = \"selected\"" if d == @data_set}value=\"#{data_set_url(d.id)}\">#{truncate h(d.title), :length => 25}</option>"}).join.html_safe,
-                   : "window.location = $F('data_set');",
-                   :style => "width: 15em"%>
-  </div>
-  <div style="float: right; margin: 0.5em">
-    <ul class="sectionIcons">
-      <% if Authorization.is_authorized?("download", nil, @workflow, current_user) %>
-        <li>
-          <%= icon('download', download_data_set_path(@data_set), nil, nil, 'Download as a zip file') %>
-        </li>
-      <% end %>
-      <% if mine?(@workflow) %>
-        <li>
-          <%= icon('edit', edit_data_set_path(@data_set), nil, nil, 'Edit data set') %>
-        </li>
-        <li>
-          <%= icon('destroy', data_set_path(@data_set), nil,
-                   {:method => :delete, :confirm => "Are you sure wish to delete this data set? All associated text data "+
-                                                    "will be deleted, but any uploaded files will remain on #{Conf.sitename}."},
-                   'Delete data set') %>
-        </li>
-      <% end %>
-    </ul>
-  </div>
-  <br class="clearer"/>
+  <ul class="sectionIcons">
+    <% if Authorization.is_authorized?("download", nil, @workflow, current_user) %>
+      <li>
+        <%= icon('download', download_data_set_path(@data_set), nil, nil, 'Download as a zip file') %>
+      </li>
+    <% end %>
+    <% if mine?(@workflow) %>
+      <li>
+        <%= icon('edit', edit_data_set_path(@data_set), nil, nil, 'Edit data set') %>
+      </li>
+      <li>
+        <%= icon('destroy', data_set_path(@data_set), nil,
+                 {:method => :delete, :confirm => "Are you sure wish to delete this data set? All associated text data "+
+                                                  "will be deleted, but any uploaded files will remain on #{Conf.sitename}."},
+                 'Delete data set') %>
+      </li>
+    <% end %>
+  </ul>
 
   <div id="data_set_container">
     <% if @data_set %>

Modified: branches/datasets/config/schema.d/workflows.xml (2880 => 2881)


--- branches/datasets/config/schema.d/workflows.xml	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/config/schema.d/workflows.xml	2011-12-14 14:13:09 UTC (rev 2881)
@@ -73,6 +73,12 @@
     <column type="text"     name="data"/>
   </table>
 
+  <table name="file_data">
+    <column type="string"     name="file_name"/>
+    <column type="integer"    name="content_type_id"/>
+    <column type="integer"    name="content_blob_id"/>
+  </table>
+
   <table name="data_items">
 
     <column type="integer"  name="data_id"/>

Modified: branches/datasets/public/stylesheets/styles.css (2880 => 2881)


--- branches/datasets/public/stylesheets/styles.css	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/public/stylesheets/styles.css	2011-12-14 14:13:09 UTC (rev 2881)
@@ -2419,25 +2419,32 @@
   margin-top: 1em;
 }
 
-.data_set input[type=text].readonly, .data_set textarea {
+.data_set input[type=text].readonly,
+.data_set textarea,
+.data_set select {
   background-color: #FFF;
   border: 1px solid #CCC;
   padding: 3px;
 }
 
-.data_set input[type=text].readonly {
+.data_set input[type=text].readonly,
+.data_set select {
   width: 96%;
 }
 .data_set textarea {
   width: 97%;
 }
 
-.data_set .input input[type=text].readonly, .data_set .input textarea.readonly {
+.data_set .input input[type=text].readonly,
+.data_set .input textarea.readonly,
+.data_set .input select {
   background-color: #FEE;
   border-color: #FBB;
 }
 
-.data_set .output input[type=text].readonly, .data_set .output textarea.readonly {
+.data_set .output input[type=text].readonly,
+.data_set .output textarea.readonly,
+.data_set .output select {
   background-color: #EFE;
   border-color: #9F9;
 }

Modified: branches/datasets/test/functional/data_items_controller_test.rb (2880 => 2881)


--- branches/datasets/test/functional/data_items_controller_test.rb	2011-12-12 14:36:22 UTC (rev 2880)
+++ branches/datasets/test/functional/data_items_controller_test.rb	2011-12-14 14:13:09 UTC (rev 2881)
@@ -14,9 +14,9 @@
 
     assert_difference("TextData.count", 1) do
     assert_difference("DataItem.count", 1) do
-      post :create, :data_set_id => data_set.id,
+      xhr :post, :create, :data_set_id => data_set.id,
           :workflow_port => "string1",
-          :workflow_port_type => "input",
+          :port_type => "input",
           :data_type => "TextData",
           :data ="" "test"
     end
@@ -32,9 +32,9 @@
     login_as(:john)
 
     assert_difference("DataItem.count", 1) do
-      post :create, :data_set_id => data_set.id,
+      xhr :post, :create, :data_set_id => data_set.id,
           :workflow_port => "string1",
-          :workflow_port_type => "input",
+          :port_type => "input",
           :data_type => "Blob",
           :data_id => blobs(:picture).id
     end
@@ -51,9 +51,9 @@
 
     assert_no_difference("TextData.count") do
     assert_no_difference("DataItem.count") do
-      post :create, :data_set_id => data_set.id,
+      xhr :post, :create, :data_set_id => data_set.id,
           :workflow_port => "string1",
-          :workflow_port_type => "invalid_port_type_that_will_cause_failure",
+          :port_type => "invalid_port_type_that_will_cause_failure",
           :data_type => "TextData",
           :data ="" "anything"
     end
@@ -69,9 +69,9 @@
 
     assert_no_difference("TextData.count") do
     assert_no_difference("DataItem.count") do
-      post :create, :data_set_id => data_set.id,
+      xhr :post, :create, :data_set_id => data_set.id,
           :workflow_port => "string1",
-          :workflow_port_type => "input",
+          :port_type => "input",
           :data_type => "TextData",
           :data ="" "test"
     end
@@ -87,9 +87,9 @@
 
     assert_no_difference("TextData.count") do
     assert_no_difference("DataItem.count") do
-      post :create, :data_set_id => data_set.id,
+      xhr :post, :create, :data_set_id => data_set.id,
           :workflow_port => "string1",
-          :workflow_port_type => "input",
+          :port_type => "input",
           :data_type => "TextData",
           :data ="" "test"
     end
@@ -105,10 +105,10 @@
 
     assert_difference("TextData.count", -1) do
     assert_no_difference("DataItem.count") do
-      put :update,
+      xhr :put, :update,
           :id => data_item.id,
           :workflow_port => "result",
-          :workflow_port_type => "output",
+          :port_type => "output",
           :data_type => "Blob",
           :data_id => blobs(:picture).id
     end
@@ -125,7 +125,7 @@
 
     assert_difference("TextData.count", -1) do
     assert_difference("DataItem.count", -1) do
-      delete :destroy, :id => data_item.id
+      xhr :delete, :destroy, :id => data_item.id
     end
     end
 
@@ -137,7 +137,7 @@
 
     login_as(:john)
 
-    get :new, :data_set_id => v2_data_set.id, :port_type => "input"
+    xhr :get, :new, :data_set_id => v2_data_set.id, :port_type => "input"
     assert_response :success
     # Using (array1 == array1 & array2) to compare array contents regardless of order
     assert_equal ["string1", "string2", "string3"], assigns(:port_names) & ["string1", "string2", "string3"]

reply via email to

[Prev in Thread] Current Thread [Next in Thread]