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? %>
+
+
+
+ | <%= ProgressBar.human_attribute_name("id") %> |
+ <%= ProgressBar.human_attribute_name("kind") %> |
+ <%= ProgressBar.human_attribute_name("title") %> |
+ <%= ProgressBar.human_attribute_name("percentage") %> |
+ <%= t("admin.actions.actions") %> |
+
+
+
+ <% progressable.progress_bars.each do |progress_bar| %>
+
+ |
+ <%= 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" %>
+ |
+
+ <% end %>
+
+
+<% 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