From 6a5b676c7cfa3771cca5b4827d0e8acf00968e58 Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Thu, 21 Jun 2012 16:43:42 +0200 Subject: Add Export#references --- app/assets/javascripts/exports.js.coffee | 15 ++++ app/assets/stylesheets/token-input.css | 3 + app/controllers/exports_controller.rb | 10 ++- app/controllers/stop_area_children_controller.rb | 2 + app/helpers/exports_helper.rb | 68 +++++++++++++++++ app/models/export.rb | 64 +++++++++++++++- app/views/exports/new.html.erb | 10 +++ app/views/exports/new.js.coffee | 4 + app/views/exports/show.html.erb | 11 +++ config/locales/exports.yml | 6 ++ config/routes.rb | 6 +- .../20120620064014_add_references_to_export.rb | 7 ++ db/schema.rb | 5 +- spec/models/export_spec.rb | 88 ++++++++++++++++++++++ 14 files changed, 294 insertions(+), 5 deletions(-) create mode 100644 app/views/exports/new.js.coffee create mode 100644 db/migrate/20120620064014_add_references_to_export.rb diff --git a/app/assets/javascripts/exports.js.coffee b/app/assets/javascripts/exports.js.coffee index 761567942..025f9fcce 100644 --- a/app/assets/javascripts/exports.js.coffee +++ b/app/assets/javascripts/exports.js.coffee @@ -1,3 +1,18 @@ # Place all the behaviors and hooks related to the matching controller here. # All this logic will automatically be available in application.js. # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ + +jQuery -> + export_references_type_change = (event) -> + references_type = $("select option:selected").attr("value") + + toggle_input = (li) -> + enabled = (li.data("type") == references_type) + # Hide li block + li.toggle(enabled) + # Disable textarea to ignore it in POST data + li.find("textarea").attr("disabled", ! enabled) + + toggle_input($(li)) for li in $(".export_reference_ids") + + $('#export_references_type').change(export_references_type_change) diff --git a/app/assets/stylesheets/token-input.css b/app/assets/stylesheets/token-input.css index 03bb01c4d..55a7f5656 100644 --- a/app/assets/stylesheets/token-input.css +++ b/app/assets/stylesheets/token-input.css @@ -111,3 +111,6 @@ div.token-input-dropdown ul li.token-input-selected-dropdown-item { background-color: #d0efa0; } +form.formtastic .token-input-list { +display: inline-block; +} \ No newline at end of file diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index 6a77f7f45..ee7e186b9 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -1,6 +1,6 @@ class ExportsController < ChouetteController - respond_to :html, :xml, :json + respond_to :html, :xml, :json, :js respond_to :zip, :only => :show belongs_to :referential @@ -17,6 +17,14 @@ class ExportsController < ChouetteController end end + def references + @references = referential.send(params[:type]).where("name ilike ?", "%#{params[:q]}%") + respond_to do |format| + format.json do + render :json => @references.collect { |child| { :id => child.id, :name => child.name } } + end + end + end protected diff --git a/app/controllers/stop_area_children_controller.rb b/app/controllers/stop_area_children_controller.rb index a3a59047f..111fcb93c 100644 --- a/app/controllers/stop_area_children_controller.rb +++ b/app/controllers/stop_area_children_controller.rb @@ -8,6 +8,8 @@ class StopAreaChildrenController < ChouetteController end end + protected + def children_maps children.collect do |child| { :id => child.id.to_s, :name => "#{child.name} #{child.country_code}" } diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb index bd84b9886..1b441f995 100644 --- a/app/helpers/exports_helper.rb +++ b/app/helpers/exports_helper.rb @@ -1,2 +1,70 @@ module ExportsHelper + + @@export_references_type = {} + def export_references_type(type) + @@export_references_type[type] ||= ReferencesTypeHelper.new(type) + end + + class ReferencesTypeHelper + + attr_accessor :type + + def initialize(type) + @type = type.to_s + end + + def relation_name + Export.references_relation(type) + end + + def input_id + "export_reference_#{relation_name}_ids" + end + + end + + def export_references_input(form, export, type) + ReferencesInput.new form, export, export_references_type(type) + end + + class ReferencesInput + + attr_accessor :form, :export, :type_helper + def initialize(form, export, type_helper) + @form, @export, @type_helper = form, export, type_helper + end + + delegate :input_id, :type, :to => :type_helper + + def current? + export.references_type == type + end + + def references_map + references.collect { |child| { :id => child.id, :name => child.name } } + end + + def wrapper_html_options + { + :class => "export_reference_ids", + :id => "#{input_id}_input", + :"data-type" => type, + :style => ("display: none" unless current?) + } + end + + def input_html_options + { + :id => input_id, + :"data-pre" => ( references_map.to_json if current? ), + :disabled => (true unless current?) + } + end + + def input + form.input :reference_ids, :as => :text, :wrapper_html => wrapper_html_options, :input_html => input_html_options + end + + end + end diff --git a/app/models/export.rb b/app/models/export.rb index 4fd6ff2f1..401541a13 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -46,7 +46,18 @@ class Export < ActiveRecord::Base end def export_options - { :export_id => self.id } + { :export_id => self.id, :o => export_object_type }.tap do |options| + options[:id] = reference_ids.join(',') if reference_ids.present? + end + end + + def export_object_type + case references_type + when "Chouette::Network" + "ptnetwork" + else + references_relation ? references_relation.singularize : "line" + end end before_validation :define_default_attributes, :on => :create @@ -84,4 +95,55 @@ class Export < ActiveRecord::Base end end + @@references_types = [ Chouette::Line, Chouette::Network, Chouette::Company ] + cattr_reader :references_types + + validates_inclusion_of :references_type, :in => references_types.map(&:to_s), :all_blank => true, :allow_nil => true + + def references + if references_relation.present? and reference_ids.present? + referential.send(references_relation).find(reference_ids) + else + [] + end + end + + def references=(references) + unless references.blank? + self.references_type = references.first.class.name + self.reference_ids = references.map(&:id) + else + self.references_type = nil + self.reference_ids = [] + end + end + + def references_relation + if references_type.present? + relation = self.class.references_relation(references_type) + relation if referential.respond_to?(relation) + end + end + + def self.references_relation(type) + type.to_s.demodulize.underscore.pluralize + end + + def reference_ids + if raw_reference_ids + raw_reference_ids.split(',').map(&:to_i) + else + [] + end + end + + def reference_ids=(records) + records = Array(records) + write_attribute :reference_ids, (records.present? ? records.join(',') : nil) + end + + def raw_reference_ids + read_attribute :reference_ids + end + end diff --git a/app/views/exports/new.html.erb b/app/views/exports/new.html.erb index 24022e0f8..16c6e9720 100644 --- a/app/views/exports/new.html.erb +++ b/app/views/exports/new.html.erb @@ -1,9 +1,19 @@ <%= title_tag t(".title") %> <%= semantic_form_for [@referential, @export], :as => :export, :url => referential_exports_path(@referential) do |form| %> + <%= form.inputs do %> + <%= form.input :references_type, :as => :select, :collection => Export.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %> + + <% Export.references_types.each do |type| %> + <%= export_references_input(form, @export, type).input %> + <% end %> + <% end %> + <%= form.buttons do %> <%= form.commit_button true %>