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>»</b></li>
+<li><%= link_to h(@workflow.title), workflow_path(@workflow) -%></li>
+
+<li><b>»</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>»</b></li>
+ <li>Viewing data item</li>
+<% when "new" %>
+ <li><b>»</b></li>
+ <li>Create new data item</li>
+<% when "edit" %>
+ <li><b>»</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"]