diff --git a/.gitignore b/.gitignore index 65d5268..719d82a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ tmp/ public/stylesheets/*.css .DS_Store .sass-cache/ +*.orig diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/.rvmrc b/.rvmrc index 3113a9f..3a7d36a 100644 --- a/.rvmrc +++ b/.rvmrc @@ -1 +1 @@ -rvm use 1.9.2@illumina_c_pipeline --create +rvm use 1.9.3@illumina_c_pipeline --create diff --git a/Gemfile b/Gemfile index 2aa3ffa..e3f1277 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem 'state_machine', '~>1.0.1' gem 'hashie', '~>1.0.0' gem 'exception_notification' -gem 'sequencescape-client-api', '>=0.2.6', +gem 'sequencescape-client-api', '>=0.2.9', :github => 'sanger/sequencescape-client-api', :branch => 'production', :require => 'sequencescape' @@ -19,15 +19,25 @@ gem 'sanger_barcode', '>= 0.2.0', # put test-only gems in this group so their generators # and rake tasks are available in development mode: group :test do - gem 'capybara' - gem 'cucumber-rails', :require => false gem 'launchy' + gem 'rspec-rails' + gem 'webmock' + + gem 'capybara' + gem 'phantomjs' + gem 'poltergeist' end + group :development do gem 'ruby-debug19', :require => 'ruby-debug' + gem 'ruby-debug-base19x' + gem 'pry' end group :deployment do gem 'thin' gem "psd_logger", :git => "git+ssh://git@github.com/sanger/psd_logger.git" + # Due to guar changes, can likely be fied with ruby updates + gem "rspec-legacy_formatters" + gem 'guard-rspec', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index c808fca..6042daf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,10 +13,10 @@ GIT GIT remote: git://github.com/sanger/sequencescape-client-api.git - revision: e39210258080d2011b2391d44055a849494097c6 + revision: 79a7e0818410acb62f5befcc24eb4d72f092abca branch: production specs: - sequencescape-client-api (0.2.6) + sequencescape-client-api (0.2.9) activemodel (~> 3.0.0) activesupport (~> 3.0.0) i18n @@ -56,68 +56,83 @@ GEM archive-tar-minitar (0.5.2) arel (2.0.10) builder (2.1.2) - capybara (1.1.1) + capybara (2.9.0) + addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) - selenium-webdriver (~> 2.0) - xpath (~> 0.1.4) - childprocess (0.2.2) - ffi (~> 1.0.6) + xpath (~> 2.0) chunky_png (1.2.4) + cliver (0.3.2) + coderay (1.1.1) columnize (0.3.4) compass (0.11.5) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) - cucumber (1.0.6) - builder (>= 2.1.2) - diff-lcs (>= 1.1.2) - gherkin (~> 2.4.18) - json (>= 1.4.6) - term-ansicolor (>= 1.0.6) - cucumber-rails (1.0.5) - capybara (>= 1.1.1) - cucumber (~> 1.0.6) - nokogiri (>= 1.5.0) - daemons (1.1.4) - diff-lcs (1.1.3) + crack (0.4.3) + safe_yaml (~> 1.0.0) + daemons (1.2.4) + debugger-ruby_core_source (1.3.8) + diff-lcs (1.2.5) erubis (2.6.6) abstract (>= 1.0.0) - eventmachine (0.12.10) + eventmachine (1.2.0.1) exception_notification (2.5.2) actionmailer (>= 3.0.4) - ffi (1.0.9) + ffi (1.9.14) + formatador (0.2.5) formtastic (1.2.4) actionpack (>= 2.3.7) activesupport (>= 2.3.7) i18n (~> 0.4) fssm (0.2.7) - gherkin (2.4.18) - json (>= 1.4.6) + guard (1.8.3) + formatador (>= 0.2.4) + listen (~> 1.3) + lumberjack (>= 1.0.2) + pry (>= 0.9.10) + thor (>= 0.14.6) + guard-rspec (1.2.2) + guard (>= 1.1) gyoku (1.2.2) builder (>= 2.1.2) + hashdiff (0.3.0) hashie (1.0.0) httpi (2.2.7) rack i18n (0.5.4) json (1.6.0) - json_pure (1.6.0) launchy (2.0.5) addressable (~> 2.2.6) linecache19 (0.5.12) ruby_core_source (>= 0.1.4) + listen (1.3.1) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + rb-kqueue (>= 0.2) + lumberjack (1.0.10) mail (2.2.19) activesupport (>= 2.3.6) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + method_source (0.8.2) mime-types (1.19) nokogiri (1.5.0) nori (2.4.0) + phantomjs (2.1.1.0) + poltergeist (1.10.0) + capybara (~> 2.1) + cliver (~> 0.3.1) + websocket-driver (>= 0.2.0) polyglot (0.3.3) - rack (1.2.6) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.2.8) rack-mount (0.6.14) rack (>= 1.0.0) rack-test (0.5.7) @@ -137,19 +152,50 @@ GEM rdoc (~> 3.4) thor (~> 0.14.4) rake (0.9.6) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) + ffi (>= 0.5.0) + rb-kqueue (0.2.4) + ffi (>= 0.5.0) rdoc (3.12) json (~> 1.4) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.3) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-legacy_formatters (1.0.1) + rspec (~> 3.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-rails (3.5.2) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) ruby-debug-base19 (0.11.25) columnize (>= 0.3.1) linecache19 (>= 0.5.11) ruby_core_source (>= 0.1.4) + ruby-debug-base19x (0.11.31) + debugger-ruby_core_source (> 0) + rake (>= 0.8.1) ruby-debug19 (0.11.6) columnize (>= 0.3.1) linecache19 (>= 0.5.11) ruby-debug-base19 (>= 0.11.19) ruby_core_source (0.1.5) archive-tar-minitar (>= 0.5.2) - rubyzip (0.9.4) + safe_yaml (1.0.4) sass (3.1.7) savon (0.9.2) builder (>= 2.1.2) @@ -157,23 +203,25 @@ GEM httpi (>= 0.7.8) nokogiri (>= 1.4.0) nori (>= 0.2.0) - selenium-webdriver (2.6.0) - childprocess (>= 0.2.1) - ffi (>= 1.0.7) - json_pure - rubyzip + slop (3.6.0) state_machine (1.0.2) - term-ansicolor (1.0.6) - thin (1.2.11) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) + thin (1.7.0) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) thor (0.14.6) treetop (1.4.12) polyglot polyglot (>= 0.3.1) tzinfo (0.3.35) - xpath (0.1.4) + webmock (1.22.5) + addressable (< 2.4.0) + crack (>= 0.3.2) + hashdiff + websocket-driver (0.6.4) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) + xpath (2.0.0) nokogiri (~> 1.3) yajl-ruby (1.1.0) @@ -183,16 +231,26 @@ PLATFORMS DEPENDENCIES capybara compass (>= 0.11.1) - cucumber-rails exception_notification formtastic (~> 1.2.3) + guard-rspec hashie (~> 1.0.0) launchy + phantomjs + poltergeist + pry psd_logger! rails (~> 3.0.19) rake (~> 0.9.2) + rspec-legacy_formatters + rspec-rails + ruby-debug-base19x ruby-debug19 sanger_barcode (>= 0.2.0)! - sequencescape-client-api (>= 0.2.6)! + sequencescape-client-api (>= 0.2.9)! state_machine (~> 1.0.1) thin + webmock + +BUNDLED WITH + 1.13.6 diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..ea46fe5 --- /dev/null +++ b/Guardfile @@ -0,0 +1,24 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +guard 'rspec', :version => 2 do + watch(%r{^spec/.+_spec\.rb$}) + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } + + # Rails example + watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } + watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } + watch(%r{^spec/support/(.+)\.rb$}) { "spec" } + watch('config/routes.rb') { "spec/routing" } + watch('app/controllers/application_controller.rb') { "spec/controllers" } + + # Capybara request specs + watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } + + # Turnip features and steps + watch(%r{^spec/acceptance/(.+)\.feature$}) + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } +end + diff --git a/app/controllers/creation_controller.rb b/app/controllers/creation_controller.rb index 51da100..54efa04 100644 --- a/app/controllers/creation_controller.rb +++ b/app/controllers/creation_controller.rb @@ -54,9 +54,12 @@ def create respond_to do |format| format.html do + alert = [ "Cannot create the plate: #{exception.message}"] + alert.concat << exception.resource.errors.full_messages.join('; ') if exception.respond_to?(:resource) + redirect_to( illumina_c_plate_path(@creation_form.parent), - :alert => [ "Cannot create the plate: #{exception.message}", *exception.resource.errors.full_messages ] + :alert => alert ) end end diff --git a/app/controllers/labware_controller.rb b/app/controllers/labware_controller.rb index d7721e9..5efe5ea 100644 --- a/app/controllers/labware_controller.rb +++ b/app/controllers/labware_controller.rb @@ -4,7 +4,7 @@ class LabwareController < ApplicationController before_filter :check_for_current_user!, :only => [ :update ] def locate_labware - @labware = locate_labware_identified_by(params[:id]) + @labware = locate_labware_identified_by(params[:id]) end private :locate_labware diff --git a/app/controllers/metadata_controller.rb b/app/controllers/metadata_controller.rb new file mode 100644 index 0000000..bc3500e --- /dev/null +++ b/app/controllers/metadata_controller.rb @@ -0,0 +1,20 @@ +class MetadataController < ApplicationController + + def create + metadata = metadata_hash + api.custom_metadatum_collection.create!(user: current_user_uuid, asset: params[:asset_id], metadata: metadata) + redirect_to(:back, notice: "Metadata was added successfully") + end + + def update + metadata = metadata_hash + api.custom_metadatum_collection.find(params[:id]).update_attributes!(metadata: metadata) + redirect_to(:back, notice: "Metadata was updated successfully") + end + + def metadata_hash + key_values = params[:metadata].map {|metadatum| [metadatum[:key], metadatum[:value]]} + Hash[key_values.reject {|k, v| k.blank? || v.blank? }] + end + +end \ No newline at end of file diff --git a/app/controllers/multiple_target_state_change_controller.rb b/app/controllers/multiple_target_state_change_controller.rb new file mode 100644 index 0000000..f7574f6 --- /dev/null +++ b/app/controllers/multiple_target_state_change_controller.rb @@ -0,0 +1,29 @@ +class MultipleTargetStateChangeController < ApplicationController + + def create + + if params[:tubes] + tubes_uuid = params[:tubes].keys + tubes_uuid.each do |uuid| + purpose_uuid = api.multiplexed_library_tube.find(uuid).purpose.uuid + state_changer_for(purpose_uuid, uuid).move_to!("passed") + end + tubes_ean13_barcodes = params[:tubes].values + redirect_to(search_path, :notice => "Labware: #{tubes_ean13_barcodes.join(", ")} have been changed to a state of Passed") + else + redirect_to(search_path, :notice => "Nothing to pass") + end + + rescue StateChangers::StateChangeError => exception + respond_to do |format| + format.html { redirect_to(search_path, :alert=> exception.message) } + format.csv + end + end + + def state_changer_for(purpose_uuid, labware_uuid) + StateChangers.lookup_for(purpose_uuid).new(api, labware_uuid, current_user_uuid) + end + private :state_changer_for + +end \ No newline at end of file diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index a74cf70..4d8cce4 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,5 +1,8 @@ class SearchController < ApplicationController - before_filter :clear_current_user! + + class InputError < StandardError; end + + before_filter :clear_current_user!, :except => [:qcables] before_filter :check_for_login!, :only => [:create_or_find, :stock_plates ] @@ -61,6 +64,26 @@ def create end end + def qcables + raise InputError, "You have not supplied a barcode" if params[:qcable_barcode].blank? + pruned_barcode = params[:qcable_barcode].strip + raise InputError, "#{params[:qcable_barcode]} is not a valid barcode" unless /^[0-9]{13}$/===pruned_barcode + respond_to do |format| + format.json { + redirect_to tag_plate_path(find_qcable(pruned_barcode)) + } + end + rescue Sequencescape::Api::ResourceNotFound, InputError => exception + render :json => {'error' => exception.message } + end + + def find_qcable(barcode) + api.search.find(Settings.searches['Find qcable by barcode']).first(:barcode => barcode) + rescue Sequencescape::Api::ResourceNotFound => exception + raise exception, 'Sorry, could not find qcable with the specified barcode.' + end + private :find_qcable + def clear_current_user! session[:user_uuid] = nil end diff --git a/app/controllers/tag_plates_controller.rb b/app/controllers/tag_plates_controller.rb new file mode 100644 index 0000000..7c958e3 --- /dev/null +++ b/app/controllers/tag_plates_controller.rb @@ -0,0 +1,16 @@ +#This file is part of Illumina-B Pipeline is distributed under the terms of GNU General Public License version 3 or later; +#Please refer to the LICENSE and README files for information on licensing and authorship of this file. +#Copyright (C) 2014 Genome Research Ltd. + +# Note: The name of this controller is selected to ensure consistency with the +# Illumina-B application. This is to aid with their eventual combination. +class TagPlatesController < ApplicationController + + def show + @qcable = Presenters::QcablePresenter.new(api.qcable.find(params[:id])) + respond_to do |format| + format.json { render :json => {'qcable'=> @qcable } } + end + end + +end diff --git a/app/models/forms.rb b/app/models/forms.rb index 5438cd7..eac26a9 100644 --- a/app/models/forms.rb +++ b/app/models/forms.rb @@ -101,7 +101,7 @@ def label_text end def save! - raise StandardError, 'Invalid data' unless valid? + raise StandardError, "Invalid data: #{errors.full_messages}" unless valid? create_objects! end diff --git a/app/models/forms/tagging_form.rb b/app/models/forms/tagging_form.rb index afb176a..98a1d9a 100644 --- a/app/models/forms/tagging_form.rb +++ b/app/models/forms/tagging_form.rb @@ -2,13 +2,38 @@ module Forms class TaggingForm < CreationForm include Forms::Form::CustomPage - write_inheritable_attribute :page, 'tagging' - write_inheritable_attribute :attributes, [:direction, :walking_by, :api, :purpose_uuid, :parent_uuid, :tag_group_uuid, :user_uuid, :substitutions, :offset, :tag_start] + DEFAULT_WALKING_BY = ["manual by plate","manual by pool","wells of plate"] + MULTI_TAGGING_STRATEGIES = ['as group by plate'] - validates_presence_of *(self.attributes - [:substitutions]) + write_inheritable_attribute :page, 'tagging' + write_inheritable_attribute :attributes, [ + :direction, :walking_by, :api, :purpose_uuid, + :parent_uuid, :tag_group_uuid, :user_uuid, + :substitutions, :offset, :tag_start, + :tag2_tube_barcode, :tag2_tube, :tags_per_well + ] + + validates_presence_of *(self.attributes - [:substitutions,:tag2_tube_barcode,:tag2_tube]) + + validate :walking_by, inclusion: { in: MULTI_TAGGING_STRATEGIES }, if: :multiple_tags_per_well? + validate :absense_of_substitutions, if: :multiple_tags_per_well? + + # Update to actual validator when rails updates + def absense_of_substitutions + return true if substitutions.blank? + errors.add(:substitutions,'are not supported with multiple tags per well') + false + end class InvalidTagLayout < StandardError; end + QcableObject = Struct.new(:asset_uuid,:template_uuid) + + def tag2_tube=(params) + return nil if params.blank? + @tag2_tube = QcableObject.new(params[:asset_uuid],params[:template_uuid]) + end + def initialize(*args, &block) super plate.populate_wells_with_pool @@ -88,6 +113,7 @@ def generate_layouts_and_groups ) end @tag_groups = tag_groups.select! { |tag_group| + acceptable_template?(tag_group) && (tag_group.tags_keys.length >= maximum_pool_size) } end @@ -97,7 +123,6 @@ def generate_layouts_and_groups def tag_groups generate_layouts_and_groups @tag_groups - #Settings.tag_groups end def tag_groups_with_uuid @@ -161,15 +186,64 @@ def create_plate!(&block) end private :create_plate! + def requires_tag2? + plate.submission_pools.detect {|pool| pool.plates_in_submission > 1 }.present? + end + + def tag2_field + yield if requires_tag2? + nil + end + + def acceptable_template?(template) + acceptable_templates.blank? || + acceptable_templates.include?(template.name) + end + + def acceptable_templates + Settings.purposes[purpose_uuid].fetch('tag_layout_templates',[]) + end + + def tag2s + @tag2s ||= available_tag2s + end + + def tag2_names + tag2s.values.flatten.map(&:name) + end + + def available_tags_per_well + Settings.purposes[purpose_uuid].fetch('tags_per_well',[1]) + end + + def multiple_tags_per_well? + tags_per_well.to_i > 1 + end + + def available_walking_by + awb = Settings.purposes[purpose_uuid].fetch('walking_by',DEFAULT_WALKING_BY) + awb.map {|walking_by| [I18n.t(walking_by,scope:'walking_by'),walking_by] } + end + + def available_tag2s + api.tag2_layout_template.all.reject do |template| + used_tag2s.include?(template.uuid) + end.group_by(&:uuid) + end + private :available_tag2s + + def used_tag2s + @used_tag2s ||= plate.submission_pools.map {|pool| pool.used_tag2_layout_templates.map {|used| used["uuid"] } }.flatten.uniq + end + private :used_tag2s + + + def transfer_map Hash[filled_wells.map{|w| [w.location, well_location_by_column[index_by_column_of(w)+offset.to_i]||invalid_well(w)]}] end private :transfer_map - def valid? - true - end - def invalid_well(well) raise StandardError, "The well at #{well.location} will be transfered out the bounds of the target plate." end @@ -179,13 +253,29 @@ def create_objects! create_plate! do |plate| api.tag_layout.create!( - :user => user_uuid, - :plate => plate.uuid, - :tag_group => tag_group_uuid, - :direction => direction, - :walking_by => walking_by, - :initial_tag => tag_start, - :substitutions => substitutions + user: user_uuid, + plate: plate.uuid, + tag_group: tag_group_uuid, + direction: direction, + walking_by: walking_by, + initial_tag: tag_start, + substitutions: substitutions, + tags_per_well: tags_per_well.to_i + ) + + return true unless tag2_tube_barcode.present? + + api.state_change.create!( + :user => user_uuid, + :target => tag2_tube.asset_uuid, + :reason => 'Used in library creation', + :target_state => 'exhausted' + ) + + api.tag2_layout_template.find(tag2_tube.template_uuid).create!( + :source => tag2_tube.asset_uuid, + :plate => plate.uuid, + :user => user_uuid ) end end diff --git a/app/models/illumina_c/plate.rb b/app/models/illumina_c/plate.rb index c49245f..ff3f9a2 100644 --- a/app/models/illumina_c/plate.rb +++ b/app/models/illumina_c/plate.rb @@ -9,7 +9,8 @@ def coerce FINAL_POOLING_PLATE_PURPOSES = [ 'ILC AL Libs Tagged', - 'ILC Lib PCR-XP' + 'ILC Lib PCR-XP', + 'ILC Lib Chromium' ] def is_a_final_pooling_plate? diff --git a/app/models/illumina_c/stock_library_tube.rb b/app/models/illumina_c/stock_library_tube.rb index 247febd..5fb85ee 100644 --- a/app/models/illumina_c/stock_library_tube.rb +++ b/app/models/illumina_c/stock_library_tube.rb @@ -1,2 +1,7 @@ class IlluminaC::StockLibraryTube < Sequencescape::MultiplexedLibraryTube + + def can_be_passed? + ["pending", "started"].include? state + end + end diff --git a/app/models/presenters.rb b/app/models/presenters.rb index 86c67c2..9fab565 100644 --- a/app/models/presenters.rb +++ b/app/models/presenters.rb @@ -25,10 +25,23 @@ def printer_limit @printer_limit ||= Settings.printers['limit'] end + def metadata_key_options + @key_options ||= Settings.metadata_key_options + end + def label_type nil end + def metadata + @labware.custom_metadatum_collection.metadata + end + + def custom_metadatum_collection_uuid + @labware.custom_metadatum_collection.uuid + end + alias_method :has_metadata?, :custom_metadatum_collection_uuid + end class PlatePresenter @@ -58,6 +71,7 @@ class PlatePresenter class_inheritable_reader :tab_views write_inheritable_attribute :tab_views, { 'labware-summary-button' => [ 'labware-summary', 'plate-printing' ], + 'labware-metadata-button' => [ 'labware-metadata' ], 'labware-creation-button' => [ 'labware-summary', 'plate-creation' ], 'labware-QC-button' => [ 'labware-summary', 'plate-creation' ], 'labware-state-button' => [ 'labware-summary', 'plate-state' ], @@ -71,11 +85,11 @@ class PlatePresenter class_inheritable_reader :authenticated_tab_states write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button', 'labware-state-button' ], - :started => [ 'labware-state-button', 'labware-summary-button' ], - :passed => [ 'labware-creation-button', 'labware-state-button', 'labware-summary-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :started => [ 'labware-state-button', 'labware-summary-button', 'labware-metadata-button' ], + :passed => [ 'labware-creation-button', 'labware-state-button', 'labware-summary-button', 'labware-metadata-button' ], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } def plate_to_walk diff --git a/app/models/presenters/al_libs_plate_presenter.rb b/app/models/presenters/al_libs_plate_presenter.rb index 542c17a..e17ef0c 100644 --- a/app/models/presenters/al_libs_plate_presenter.rb +++ b/app/models/presenters/al_libs_plate_presenter.rb @@ -3,11 +3,11 @@ class AlLibsPlatePresenter < PlatePresenter include Presenters::Statemachine write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button', 'labware-creation-button' ], - :started => [ 'labware-summary-button', 'labware-creation-button' ], - :passed => [ 'labware-summary-button', 'labware-creation-button', 'well-failing-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-creation-button', 'labware-metadata-button' ], + :started => [ 'labware-summary-button', 'labware-creation-button', 'labware-metadata-button' ], + :passed => [ 'labware-summary-button', 'labware-metadata-button', 'labware-creation-button', 'well-failing-button'], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } state_machine :state, :initial => :pending do diff --git a/app/models/presenters/final_plate_presenter.rb b/app/models/presenters/final_plate_presenter.rb index 8113e99..b70ff2d 100644 --- a/app/models/presenters/final_plate_presenter.rb +++ b/app/models/presenters/final_plate_presenter.rb @@ -10,12 +10,12 @@ class FinalPlatePresenter < PlatePresenter write_inheritable_attribute :additional_creation_partial, 'labware/plates/child_tube_creation' write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button', 'labware-state-button' ], - :started => [ 'labware-summary-button', 'labware-state-button' ], - :passed => [ 'labware-summary-button', 'labware-state-button', 'labware-creation-button', 'well-failing-button' ], - :qc_complete => [ 'labware-summary-button', 'labware-state-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :started => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :passed => [ 'labware-summary-button', 'labware-state-button', 'labware-creation-button', 'well-failing-button', 'labware-metadata-button' ], + :qc_complete => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } write_inheritable_attribute :printing_partial, 'labware/plates/tube_printing' diff --git a/app/models/presenters/final_tube_presenter.rb b/app/models/presenters/final_tube_presenter.rb index 3782465..371691c 100644 --- a/app/models/presenters/final_tube_presenter.rb +++ b/app/models/presenters/final_tube_presenter.rb @@ -16,6 +16,7 @@ class FinalTubePresenter class_inheritable_reader :tab_views write_inheritable_attribute :tab_views, { 'labware-summary-button' => [ 'labware-summary', 'tube-printing' ], + 'labware-metadata-button' => [ 'labware-metadata' ], 'labware-creation-button' => [ 'labware-summary', 'tube-creation' ], 'labware-state-button' => [ 'labware-summary', 'tube-state' ] } @@ -24,11 +25,11 @@ class FinalTubePresenter class_inheritable_reader :authenticated_tab_states write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button', 'labware-state-button' ], - :started => [ 'labware-state-button', 'labware-summary-button' ], - :passed => [ 'labware-summary-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :started => [ 'labware-state-button', 'labware-summary-button', 'labware-metadata-button' ], + :passed => [ 'labware-summary-button', 'labware-metadata-button' ], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } state_machine :state, :initial => :pending do diff --git a/app/models/presenters/qc_tube_presenter.rb b/app/models/presenters/qc_tube_presenter.rb index d80ee5f..1ec0074 100644 --- a/app/models/presenters/qc_tube_presenter.rb +++ b/app/models/presenters/qc_tube_presenter.rb @@ -3,11 +3,11 @@ class QCTubePresenter < TubePresenter class_inheritable_reader :authenticated_tab_states write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button', 'labware-state-button' ], - :started => [ 'labware-summary-button', 'labware-state-button' ], - :passed => [ 'labware-summary-button', 'labware-state-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :started => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :passed => [ 'labware-summary-button', 'labware-state-button', 'labware-metadata-button' ], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } write_inheritable_attribute :has_qc_data?, true diff --git a/app/models/presenters/qcable_presenter.rb b/app/models/presenters/qcable_presenter.rb new file mode 100644 index 0000000..f75174b --- /dev/null +++ b/app/models/presenters/qcable_presenter.rb @@ -0,0 +1,19 @@ +#This file is part of Illumina-B Pipeline is distributed under the terms of GNU General Public License version 3 or later; +#Please refer to the LICENSE and README files for information on licensing and authorship of this file. +#Copyright (C) 2014 Genome Research Ltd. +module Presenters + class QcablePresenter + + def initialize(qcable) + @uuid = qcable.uuid + @tag_layout = qcable.lot.template_name + @asset_uuid = qcable.asset.uuid + @state = qcable.state + @type = qcable.lot.lot_type_name + @qcable_type = qcable.lot.lot_type.qcable_name + @template_uuid = qcable.lot.template.uuid + @lot_number = qcable.lot.lot_number + end + + end +end diff --git a/app/models/presenters/statemachine/qc_completable.rb b/app/models/presenters/statemachine/qc_completable.rb index 1a487bf..9500fb8 100644 --- a/app/models/presenters/statemachine/qc_completable.rb +++ b/app/models/presenters/statemachine/qc_completable.rb @@ -42,6 +42,10 @@ def self.included(base) state :qc_complete, :human_name => 'QC Complete' do # Nope, we create the tubes in the state changer + + def default_child_purpose + labware.plate_purpose.children.detect {|purpose| ! Settings.qc_purposes.include?(purpose.name) } + end end event :fail do diff --git a/app/models/presenters/stock_plate_presenter.rb b/app/models/presenters/stock_plate_presenter.rb index cc4ff04..eb685b3 100644 --- a/app/models/presenters/stock_plate_presenter.rb +++ b/app/models/presenters/stock_plate_presenter.rb @@ -3,11 +3,11 @@ class StockPlatePresenter < PlatePresenter include Presenters::Statemachine write_inheritable_attribute :authenticated_tab_states, { - :pending => [ 'labware-summary-button' ], - :started => [ 'labware-summary-button' ], - :passed => [ 'labware-creation-button','labware-summary-button', 'well-failing-button' ], - :cancelled => [ 'labware-summary-button' ], - :failed => [ 'labware-summary-button' ] + :pending => [ 'labware-summary-button', 'labware-metadata-button' ], + :started => [ 'labware-summary-button', 'labware-metadata-button' ], + :passed => [ 'labware-creation-button','labware-summary-button', 'labware-metadata-button', 'well-failing-button' ], + :cancelled => [ 'labware-summary-button', 'labware-metadata-button' ], + :failed => [ 'labware-summary-button', 'labware-metadata-button' ] } def default_child_purpose diff --git a/app/models/presenters/tube_presenter.rb b/app/models/presenters/tube_presenter.rb index ffac42e..0168114 100644 --- a/app/models/presenters/tube_presenter.rb +++ b/app/models/presenters/tube_presenter.rb @@ -21,6 +21,7 @@ def qc_owner class_inheritable_reader :tab_views write_inheritable_attribute :tab_views, { 'labware-summary-button' => [ 'labware-summary', 'tube-printing' ], + 'labware-metadata-button' => [ 'labware-metadata' ], 'labware-creation-button' => [ 'labware-summary', 'tube-creation' ], 'labware-QC-button' => [ 'labware-summary', 'tube-creation' ], 'labware-state-button' => [ 'labware-summary', 'tube-state' ] diff --git a/app/stylesheets/screen.scss b/app/stylesheets/screen.scss index bfe402a..8524eb4 100644 --- a/app/stylesheets/screen.scss +++ b/app/stylesheets/screen.scss @@ -82,6 +82,10 @@ body { display: inline-block; text-shadow: 0 -1px 1px rgba(255,255,255,0.5); @include box-shadow(#00192B 1px 1px 1px); + overflow: hidden; + + .tag { display: none; } + .tag:nth-child(1) { display: inline; } } .aliquot:hover { diff --git a/app/views/labware/_individual_barcode_printing_form.html.erb b/app/views/labware/_individual_barcode_printing_form.html.erb index 1ead8f2..09580ce 100644 --- a/app/views/labware/_individual_barcode_printing_form.html.erb +++ b/app/views/labware/_individual_barcode_printing_form.html.erb @@ -2,7 +2,7 @@ <%# Hide the details of what is in the label to be printed %>