diff --git a/app/assets/javascripts/forms.js.coffee b/app/assets/javascripts/forms.js.coffee index edf4c525f..4e862dea8 100644 --- a/app/assets/javascripts/forms.js.coffee +++ b/app/assets/javascripts/forms.js.coffee @@ -23,8 +23,14 @@ App.Forms = false ) + synchronizeInputs: -> + $("[name='progress_bar[percentage]']").on + input: -> + $("[name='#{this.name}']").val($(this).val()) + initialize: -> App.Forms.disableEnter() App.Forms.submitOnChange() App.Forms.toggleLink() + App.Forms.synchronizeInputs() false diff --git a/app/controllers/admin/progress_bars_controller.rb b/app/controllers/admin/progress_bars_controller.rb new file mode 100644 index 000000000..a9611b364 --- /dev/null +++ b/app/controllers/admin/progress_bars_controller.rb @@ -0,0 +1,69 @@ +class Admin::ProgressBarsController < Admin::BaseController + include Translatable + + before_action :load_progressable + before_action :load_progress_bar, only: [:edit, :update, :destroy] + helper_method :progress_bars_index + + def index + end + + def new + @progress_bar = @progressable.progress_bars.new + end + + def create + @progress_bar = @progressable.progress_bars.new(progress_bar_params) + if @progress_bar.save + redirect_to progress_bars_index, notice: t("admin.progress_bars.create.notice") + else + render :new + end + end + + def edit + end + + def update + if @progress_bar.update(progress_bar_params) + redirect_to progress_bars_index, notice: t('admin.progress_bars.update.notice') + else + render :edit + end + end + + def destroy + @progress_bar.destroy + redirect_to progress_bars_index, notice: t('admin.progress_bars.delete.notice') + end + + private + + def progress_bar_params + params.require(:progress_bar).permit(allowed_params) + end + + def allowed_params + [ + :kind, + :percentage, + translation_params(ProgressBar) + ] + end + + def load_progressable + @progressable = progressable + end + + def progressable + raise "This method must be implemented in subclass #{self.class.name}" + end + + def load_progress_bar + @progress_bar = progressable.progress_bars.find(params[:id]) + end + + def progress_bars_index + polymorphic_path([:admin, *resource_hierarchy_for(@progressable), ProgressBar.new]) + end +end diff --git a/app/views/admin/progress_bars/_form.html.erb b/app/views/admin/progress_bars/_form.html.erb new file mode 100644 index 000000000..2ec756a54 --- /dev/null +++ b/app/views/admin/progress_bars/_form.html.erb @@ -0,0 +1,16 @@ +<%= render "admin/shared/globalize_locales", resource: @progress_bar %> + +<%= translatable_form_for [:admin, *resource_hierarchy_for(@progress_bar)] do |f| %> + + <%= f.enum_select :kind %> + + <%= f.translatable_fields do |translations_form| %> + <%= translations_form.text_field :title %> + <% end %> + + <% progress_options = { min: ProgressBar::RANGE.min, max: ProgressBar::RANGE.max, step: 1 } %> + <%= f.text_field :percentage, { type: :range, id: "percentage_range" }.merge(progress_options) %> + <%= f.text_field :percentage, { type: :number, label: false }.merge(progress_options) %> + + <%= f.submit nil, class: "button success" %> +<% end %> diff --git a/app/views/admin/progress_bars/_progress_bars.html.erb b/app/views/admin/progress_bars/_progress_bars.html.erb new file mode 100644 index 000000000..39d48f8c9 --- /dev/null +++ b/app/views/admin/progress_bars/_progress_bars.html.erb @@ -0,0 +1,49 @@ +

<%= t("admin.progress_bars.index.title") %>

+ +<% if progressable.progress_bars.any? %> + + + + + + + + + + + + <% progressable.progress_bars.each do |progress_bar| %> + + + + + + + + <% end %> + +
<%= ProgressBar.human_attribute_name("id") %><%= ProgressBar.human_attribute_name("kind") %><%= ProgressBar.human_attribute_name("title") %><%= ProgressBar.human_attribute_name("percentage") %><%= t("admin.actions.actions") %>
+ <%= progress_bar.id %> + <%= ProgressBar.human_attribute_name("kind.#{progress_bar.kind}") %><%= progress_bar.title %> + <%= number_to_percentage(progress_bar.percentage, strip_insignificant_zeros: true) %> + + <%= link_to t("admin.actions.edit"), + polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)], + action: :edit), + class: "button hollow expanded" %> + + <%= link_to t("admin.actions.delete"), + polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)]), + method: :delete, + class: "button hollow alert expanded" %> +
+<% else %> +

<%= t("admin.progress_bars.index.no_progress_bars") %>

+<% end %> + +

+ <%= link_to t("admin.progress_bars.index.new_progress_bar"), + polymorphic_path([:admin, *resource_hierarchy_for(progressable.progress_bars.new)], + action: :new), + class: "button hollow" %> +

diff --git a/app/views/admin/progress_bars/edit.html.erb b/app/views/admin/progress_bars/edit.html.erb new file mode 100644 index 000000000..21dd27d9a --- /dev/null +++ b/app/views/admin/progress_bars/edit.html.erb @@ -0,0 +1,15 @@ +<% if @progress_bar.primary? %> + <% bar_title = t("admin.progress_bars.edit.title.primary") %> +<% else %> + <% bar_title = t("admin.progress_bars.edit.title.secondary", title: @progress_bar.title) %> +<% end %> + +<% provide :title do %> + <%= "#{t("admin.header.title")} - #{bar_title}" %> +<% end %> + +<%= back_link_to progress_bars_index %> + +

<%= bar_title %>

+ +<%= render "form" %> diff --git a/app/views/admin/progress_bars/index.html.erb b/app/views/admin/progress_bars/index.html.erb new file mode 100644 index 000000000..ff17e5188 --- /dev/null +++ b/app/views/admin/progress_bars/index.html.erb @@ -0,0 +1,7 @@ +<% provide :title do %> + <%= "#{t("admin.header.title")} - #{t("admin.progress_bars.index.title")}" %> +<% end %> + +<%= back_link_to polymorphic_path([:admin, *resource_hierarchy_for(@progressable)]) %> + +<%= render "admin/progress_bars/progress_bars", progressable: @progressable %> diff --git a/app/views/admin/progress_bars/new.html.erb b/app/views/admin/progress_bars/new.html.erb new file mode 100644 index 000000000..8c379ac3a --- /dev/null +++ b/app/views/admin/progress_bars/new.html.erb @@ -0,0 +1,9 @@ +<% provide :title do %> + <%= "#{t("admin.header.title")} - #{t("admin.progress_bars.new.creating")}" %> +<% end %> + +<%= back_link_to progress_bars_index %> + +

<%= t("admin.progress_bars.new.creating") %>

+ +<%= render "form" %> diff --git a/config/initializers/foundation_rails_helper.rb b/config/initializers/foundation_rails_helper.rb index ff5ae4618..3e121f0d9 100644 --- a/config/initializers/foundation_rails_helper.rb +++ b/config/initializers/foundation_rails_helper.rb @@ -5,5 +5,13 @@ module FoundationRailsHelper super(attribute, opts) end end + + def enum_select(attribute, options = {}, html_options = {}) + choices = object.class.send(attribute.to_s.pluralize).keys.map do |name| + [object.class.human_attribute_name("#{attribute}.#{name}"), name] + end + + select attribute, choices, options, html_options + end end end diff --git a/config/initializers/routes_hierarchy.rb b/config/initializers/routes_hierarchy.rb index 0a712f923..06a7acc74 100644 --- a/config/initializers/routes_hierarchy.rb +++ b/config/initializers/routes_hierarchy.rb @@ -9,6 +9,8 @@ module ActionDispatch::Routing::UrlFor [resource.budget, resource] when "Milestone" [*resource_hierarchy_for(resource.milestoneable), resource] + when "ProgressBar" + [*resource_hierarchy_for(resource.progressable), resource] when "Legislation::Annotation" [resource.draft_version.process, resource.draft_version, resource] when "Legislation::Proposal", "Legislation::Question", "Legislation::DraftVersion" diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 7033fefbf..76c3b7121 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -332,6 +332,24 @@ en: notice: Milestone status created successfully delete: notice: Milestone status deleted successfully + progress_bars: + manage: "Manage progress bars" + index: + title: "Progress bars" + no_progress_bars: "There are no progress bars" + new_progress_bar: "Create new progress bar" + new: + creating: "Create progress bar" + edit: + title: + primary: "Edit primary progress bar" + secondary: "Edit progress bar %{title}" + create: + notice: "Progress bar created successfully!" + update: + notice: "Progress bar updated successfully" + delete: + notice: "Progress bar deleted successfully" comments: index: filter: Filter diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 0075225c7..a8b337ca6 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -332,6 +332,25 @@ es: notice: Estado de seguimiento creado correctamente delete: notice: Estado de seguimiento eliminado correctamente + progress_bars: + manage: "Gestionar barras de progreso" + index: + title: "Barras de progreso" + no_progress_bars: "No hay barras de progreso" + new_progress_bar: "Crear nueva barra de progreso" + new: + creating: "Crear barra de progreso" + edit: + title: + primary: "Editar barra de progreso principal" + secondary: "Editar barra de progreso %{title}" + create: + notice: "¡Barra de progreso creada con éxito!" + update: + notice: "Barra de progreso actualizada" + delete: + notice: "Barra de progreso eliminada correctamente" + comments: index: filter: Filtro diff --git a/spec/shared/features/progressable.rb b/spec/shared/features/progressable.rb new file mode 100644 index 000000000..ec4cdca29 --- /dev/null +++ b/spec/shared/features/progressable.rb @@ -0,0 +1,109 @@ +shared_examples "progressable" do |factory_name, path_name| + let!(:progressable) { create(factory_name) } + + feature "Manage progress bars" do + let(:progressable_path) { send(path_name, *resource_hierarchy_for(progressable)) } + + let(:path) do + polymorphic_path([:admin, *resource_hierarchy_for(progressable.progress_bars.new)]) + end + + context "Index" do + scenario "Link to index path" do + create(:progress_bar, :secondary, progressable: progressable, + title: "Reading documents", + percentage: 20) + + visit progressable_path + click_link "Manage progress bars" + + expect(page).to have_content "Reading documents" + end + + scenario "No progress bars" do + visit path + + expect(page).to have_content("There are no progress bars") + end + end + + context "New" do + scenario "Primary progress bar", :js do + visit path + click_link "Create new progress bar" + + select "Primary", from: "Type" + + fill_in "Current progress", with: 43 + click_button "Create Progress bar" + + expect(page).to have_content "Progress bar created successfully" + expect(page).to have_content "43%" + expect(page).to have_content "Primary" + end + + scenario "Secondary progress bar", :js do + visit path + click_link "Create new progress bar" + + select "Secondary", from: "Type" + fill_in "Current progress", with: 36 + fill_in "Title", with: "Plant trees" + click_button "Create Progress bar" + + expect(page).to have_content "Progress bar created successfully" + expect(page).to have_content "36%" + expect(page).to have_content "Secondary" + expect(page).to have_content "Plant trees" + end + end + + context "Edit" do + scenario "Primary progress bar", :js do + bar = create(:progress_bar, progressable: progressable) + + visit path + within("#progress_bar_#{bar.id}") { click_link "Edit" } + + fill_in "Current progress", with: 44 + click_button "Update Progress bar" + + expect(page).to have_content "Progress bar updated successfully" + + within("#progress_bar_#{bar.id}") do + expect(page).to have_content "44%" + end + end + + scenario "Secondary progress bar", :js do + bar = create(:progress_bar, :secondary, progressable: progressable) + + visit path + within("#progress_bar_#{bar.id}") { click_link "Edit" } + + fill_in "Current progress", with: 76 + fill_in "Title", with: "Updated title" + click_button "Update Progress bar" + + expect(page).to have_content "Progress bar updated successfully" + + within("#progress_bar_#{bar.id}") do + expect(page).to have_content "76%" + expect(page).to have_content "Updated title" + end + end + end + + context "Delete" do + scenario "Remove progress bar" do + bar = create(:progress_bar, progressable: progressable, percentage: 34) + + visit path + within("#progress_bar_#{bar.id}") { click_link "Delete" } + + expect(page).to have_content "Progress bar deleted successfully" + expect(page).not_to have_content "34%" + end + end + end +end