diff --git a/Gemfile b/Gemfile index 8c3144058..f7f9c46ad 100644 --- a/Gemfile +++ b/Gemfile @@ -51,6 +51,8 @@ gem 'turnout', '~> 2.4.0' gem 'uglifier', '~> 4.1.2' gem 'unicorn', '~> 5.4.0' gem 'whenever', '~> 0.10.0', require: false +gem 'globalize', '~> 5.0.0' +gem 'globalize-accessors', '~> 0.2.1' source 'https://rails-assets.org' do gem 'rails-assets-leaflet' diff --git a/Gemfile.lock b/Gemfile.lock index 6c35b0776..aa4a00eab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -176,6 +176,11 @@ GEM geocoder (1.4.4) globalid (0.4.1) activesupport (>= 4.2.0) + globalize (5.0.1) + activemodel (>= 4.2.0, < 4.3) + activerecord (>= 4.2.0, < 4.3) + globalize-accessors (0.2.1) + globalize (~> 5.0, >= 5.0.0) graphiql-rails (1.4.8) rails graphql (1.7.8) @@ -518,6 +523,8 @@ DEPENDENCIES faker (~> 1.8.7) foundation-rails (~> 6.2.4.0) foundation_rails_helper (~> 2.0.0) + globalize (~> 5.0.0) + globalize-accessors (~> 0.2.1) graphiql-rails (~> 1.4.1) graphql (~> 1.7.8) groupdate (~> 3.2.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 7a110aa18..1c97069b0 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -77,6 +77,7 @@ //= require investment_report_alert //= require send_newsletter_alert //= require managers +//= require globalize var initialize_modules = function() { App.Comments.initialize(); @@ -121,6 +122,7 @@ var initialize_modules = function() { App.InvestmentReportAlert.initialize(); App.SendNewsletterAlert.initialize(); App.Managers.initialize(); + App.Globalize.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/globalize.js.coffee b/app/assets/javascripts/globalize.js.coffee new file mode 100644 index 000000000..6ac39e71c --- /dev/null +++ b/app/assets/javascripts/globalize.js.coffee @@ -0,0 +1,31 @@ +App.Globalize = + + display_locale: (locale) -> + $(".js-globalize-locale-link").each -> + if $(this).data("locale") == locale + $(this).show() + $(".js-globalize-locale option:selected").removeAttr("selected"); + return + + display_translations: (locale) -> + $(".js-globalize-attribute").each -> + console.log("In standard") + console.log($(this)) + if $(this).data("locale") == locale + $(this).show() + else + $(this).hide() + + highlight_locale: (element) -> + $('.js-globalize-locale-link').removeClass('highlight'); + element.addClass('highlight'); + + initialize: -> + $('.js-globalize-locale').on 'change', -> + App.Globalize.display_translations($(this).val()) + App.Globalize.display_locale($(this).val()) + + $('.js-globalize-locale-link').on 'click', -> + locale = $(this).data("locale") + App.Globalize.display_translations(locale) + App.Globalize.highlight_locale($(this)) \ No newline at end of file diff --git a/app/controllers/admin/budget_investment_milestones_controller.rb b/app/controllers/admin/budget_investment_milestones_controller.rb index e4aebd3cf..13bfb6460 100644 --- a/app/controllers/admin/budget_investment_milestones_controller.rb +++ b/app/controllers/admin/budget_investment_milestones_controller.rb @@ -1,4 +1,5 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController + include Translatable before_action :load_budget_investment, only: [:index, :new, :create, :edit, :update, :destroy] before_action :load_budget_investment_milestone, only: [:edit, :update, :destroy] @@ -46,7 +47,8 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController documents_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy] attributes = [:title, :description, :publication_date, :budget_investment_id, image_attributes: image_attributes, documents_attributes: documents_attributes] - params.require(:budget_investment_milestone).permit(*attributes) + + params.require(:budget_investment_milestone).permit(*attributes, translation_params) end def load_budget_investment diff --git a/app/controllers/concerns/translatable.rb b/app/controllers/concerns/translatable.rb new file mode 100644 index 000000000..2325fc013 --- /dev/null +++ b/app/controllers/concerns/translatable.rb @@ -0,0 +1,19 @@ +module Translatable + extend ActiveSupport::Concern + + included do + before_action :set_translation_locale + end + + private + + def translation_params + Budget::Investment::Milestone.globalize_attribute_names. + select { |k, v| params[:budget_investment_milestone].include?(k.to_sym) && params[:budget_investment_milestone][k].present? } + end + + def set_translation_locale + Globalize.locale = I18n.locale + end + +end \ No newline at end of file diff --git a/app/helpers/globalize_helper.rb b/app/helpers/globalize_helper.rb new file mode 100644 index 000000000..e0d11f611 --- /dev/null +++ b/app/helpers/globalize_helper.rb @@ -0,0 +1,33 @@ +module GlobalizeHelper + + def globalize_locale + params[:globalize_locale] || I18n.locale + end + + def options_for_locale_select + options_for_select(locale_options, nil) + end + + def locale_options + I18n.available_locales.map do |locale| + [name_for_locale(locale), locale] + end + end + + def display_translation?(locale) + I18n.locale == locale ? "" : "display: none" + end + + def css_to_display_translation?(resource, locale) + resource.translated_locales.include?(locale) || locale == I18n.locale ? "" : "display: none" + end + + def disable_translation?(locale) + locale == "en" ? "" : "disabled" + end + + def css_for_globalize_locale(locale) + globalize_locale == locale ? "highlight" : "" + end + +end \ No newline at end of file diff --git a/app/models/budget/investment/milestone.rb b/app/models/budget/investment/milestone.rb index 30acb5152..5553476ea 100644 --- a/app/models/budget/investment/milestone.rb +++ b/app/models/budget/investment/milestone.rb @@ -7,6 +7,9 @@ class Budget max_file_size: 3.megabytes, accepted_content_types: [ "application/pdf" ] + translates :description, touch: true + globalize_accessors locales: [:en, :es, :fr, :nl, :val] + belongs_to :investment validates :title, presence: true diff --git a/app/views/admin/budget_investment_milestones/_form.html.erb b/app/views/admin/budget_investment_milestones/_form.html.erb index 2b2af4b50..9dae79b6e 100644 --- a/app/views/admin/budget_investment_milestones/_form.html.erb +++ b/app/views/admin/budget_investment_milestones/_form.html.erb @@ -1,7 +1,23 @@ +
+ <%= render "budgets/investments/milestones/globalize_locales" %> +
+ <%= form_for [:admin, @investment.budget, @investment, @milestone] do |f| %> - <%= f.hidden_field :title, value: l(Time.current, format: :datetime), maxlength: Budget::Investment::Milestone.title_max_length %> - <%= f.text_area :description, rows: 5 %> + <%= f.hidden_field :title, value: l(Time.current, format: :datetime), + maxlength: Budget::Investment::Milestone.title_max_length %> + + <%= f.label :description, t("admin.milestones.new.description") %> + <% @milestone.globalize_locales.each do |locale| %> + <% Globalize.with_locale(locale) do %> + <%= f.text_area "description_#{locale}", rows: 5, + class: "js-globalize-attribute", + data: { locale: locale }, + style: display_translation?(locale), + label: false %> + <% end %> + <% end %> + <%= f.label :publication_date, t("admin.milestones.new.date") %> <%= f.text_field :publication_date, value: @milestone.publication_date.present? ? l(@milestone.publication_date.to_date) : nil, diff --git a/app/views/budgets/investments/_milestones.html.erb b/app/views/budgets/investments/_milestones.html.erb index 5fc984808..afada7fc2 100644 --- a/app/views/budgets/investments/_milestones.html.erb +++ b/app/views/budgets/investments/_milestones.html.erb @@ -23,7 +23,11 @@ { alt: milestone.image.title.unicode_normalize, class: "margin", id: "image_#{milestone.id}" }) if milestone.image.present? %> -

<%= text_with_links milestone.description %>

+

+ <% Globalize.with_locale(locale) do %> + <%= text_with_links milestone.description %> + <% end %> +

<% if milestone.documents.present? %> - + \ No newline at end of file diff --git a/app/views/budgets/investments/milestones/_globalize_locales.html.erb b/app/views/budgets/investments/milestones/_globalize_locales.html.erb new file mode 100644 index 000000000..fc291ea96 --- /dev/null +++ b/app/views/budgets/investments/milestones/_globalize_locales.html.erb @@ -0,0 +1,14 @@ +<% I18n.available_locales.each do |locale| %> + + <%= link_to name_for_locale(locale), "#", + style: css_to_display_translation?(@milestone, locale), + class: "js-globalize-locale-link", + data: { locale: locale }, + remote: true %> + +<% end %> + +<%= select_tag :translation_locale, + options_for_locale_select, + prompt: "Añadir idioma", + class: "js-globalize-locale" %> \ No newline at end of file diff --git a/app/views/budgets/investments/milestones/_milestone.html.erb b/app/views/budgets/investments/milestones/_milestone.html.erb new file mode 100644 index 000000000..2113fd06e --- /dev/null +++ b/app/views/budgets/investments/milestones/_milestone.html.erb @@ -0,0 +1,42 @@ +
  • +
    + + <% if milestone.publication_date.present? %> + + + <%= t("budgets.investments.show.milestone_publication_date", + publication_date: l(milestone.publication_date.to_date)) %> + + + <% end %> + + <% if milestone.image.present? %> + <%= image_tag(milestone.image_url(:large), + { id: "image_#{milestone.id}", + alt: milestone.image.title, + class: "margin" }) %> + <% end %> + +

    + <% Globalize.with_locale(locale) do %> + <%= text_with_links milestone.description %> + <% end %> +

    + + <% if milestone.documents.present? %> + + <% end %> + +
    +
  • \ No newline at end of file diff --git a/db/migrate/20180323190027_add_translate_milestones.rb b/db/migrate/20180323190027_add_translate_milestones.rb new file mode 100644 index 000000000..6e27583a8 --- /dev/null +++ b/db/migrate/20180323190027_add_translate_milestones.rb @@ -0,0 +1,12 @@ +class AddTranslateMilestones < ActiveRecord::Migration + def self.up + Budget::Investment::Milestone.create_translation_table!({ + title: :string, + description: :text + }) + end + + def self.down + Budget::Investment::Milestone.drop_translation_table! + end +end diff --git a/db/schema.rb b/db/schema.rb index c1ee88246..03a56453a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -118,6 +118,18 @@ ActiveRecord::Schema.define(version: 20180320104823) do add_index "budget_headings", ["group_id"], name: "index_budget_headings_on_group_id", using: :btree + create_table "budget_investment_milestone_translations", force: :cascade do |t| + t.integer "budget_investment_milestone_id", null: false + t.string "locale", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "title" + t.text "description" + end + + add_index "budget_investment_milestone_translations", ["budget_investment_milestone_id"], name: "index_6770e7675fe296cf87aa0fd90492c141b5269e0b", using: :btree + add_index "budget_investment_milestone_translations", ["locale"], name: "index_budget_investment_milestone_translations_on_locale", using: :btree + create_table "budget_investment_milestones", force: :cascade do |t| t.integer "investment_id" t.string "title", limit: 80 diff --git a/spec/features/translations_spec.rb b/spec/features/translations_spec.rb new file mode 100644 index 000000000..944f5bd22 --- /dev/null +++ b/spec/features/translations_spec.rb @@ -0,0 +1,61 @@ +require 'rails_helper' + +feature "Translations" do + + context "Milestones" do + + let(:investment) { create(:budget_investment) } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Add a translation", :js, :focus do + milestone = create(:budget_investment_milestone, description: "Description in English") + + edit_milestone_url = edit_admin_budget_budget_investment_budget_investment_milestone_path(investment.budget, investment, milestone) + visit edit_milestone_url + + select "Español", from: "translation_locale" + fill_in 'budget_investment_milestone_description_es', with: 'Descripción en Español' + + click_button 'Update milestone' + expect(page).to have_content "Milestone updated successfully" + + visit edit_milestone_url + expect(page).to have_field('budget_investment_milestone_description_en', with: 'Description in English') + + click_link "Español" + expect(page).to have_field('budget_investment_milestone_description_es', with: 'Descripción en Español') + end + + scenario "Update a translation", :js, :focus do + milestone = create(:budget_investment_milestone, + investment: investment, + description_en: "Description in English", + description_es: "Descripción en Español") + + edit_milestone_url = edit_admin_budget_budget_investment_budget_investment_milestone_path(investment.budget, investment, milestone) + visit edit_milestone_url + + select "Español", from: "translation_locale" + fill_in 'budget_investment_milestone_description_es', with: 'Descripción correcta en Español' + + click_button 'Update milestone' + expect(page).to have_content "Milestone updated successfully" + + visit budget_investment_path(investment.budget, investment) + + click_link("Milestones (1)") + expect(page).to have_content("Description in English") + + select('Español', from: 'locale-switcher') + click_link("Seguimiento (1)") + + expect(page).to have_content("Descripción correcta en Español") + end + + end + +end \ No newline at end of file