Merge pull request #3195 from consul/milestone_progress_bar

[Backport] Manage milestone progress bars
This commit is contained in:
Alberto
2019-01-24 11:59:24 +01:00
committed by GitHub
30 changed files with 659 additions and 15 deletions

View File

@@ -23,8 +23,29 @@ App.Forms =
false
)
synchronizeInputs: ->
$("[name='progress_bar[percentage]']").on
input: ->
$("[name='#{this.name}']").val($(this).val())
$("[name='progress_bar[percentage]'][type='range']").trigger("input")
hideOrShowFieldsAfterSelection: ->
$("[name='progress_bar[kind]']").on
change: ->
title_field = $("[name^='progress_bar'][name$='[title]']").parent()
if this.value == "primary"
title_field.hide()
else
title_field.show()
$("[name='progress_bar[kind]']").change()
initialize: ->
App.Forms.disableEnter()
App.Forms.submitOnChange()
App.Forms.toggleLink()
App.Forms.synchronizeInputs()
App.Forms.hideOrShowFieldsAfterSelection()
false

View File

@@ -251,6 +251,13 @@ $sidebar-active: #f4fcd0;
max-width: none;
}
form {
.input-group-label {
height: $line-height * 2;
}
}
.menu.simple {
margin-bottom: $line-height / 2;

View File

@@ -0,0 +1,8 @@
class Admin::BudgetInvestmentProgressBarsController < Admin::ProgressBarsController
private
def progressable
Budget::Investment.find(params[:budget_investment_id])
end
end

View File

@@ -0,0 +1,14 @@
class Admin::Legislation::ProgressBarsController < Admin::ProgressBarsController
include FeatureFlags
feature_flag :legislation
def index
@process = progressable
end
private
def progressable
::Legislation::Process.find(params[:process_id])
end
end

View File

@@ -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

View File

@@ -0,0 +1,7 @@
class Admin::ProposalProgressBarsController < Admin::ProgressBarsController
private
def progressable
Proposal.find(params[:proposal_id])
end
end

View File

@@ -5,5 +5,7 @@ module Milestoneable
has_many :milestones, as: :milestoneable, dependent: :destroy
scope :with_milestones, -> { joins(:milestones).distinct }
has_many :progress_bars, as: :progressable
end
end

View File

@@ -0,0 +1,28 @@
class ProgressBar < ActiveRecord::Base
self.inheritance_column = nil
RANGE = 0..100
enum kind: %i[primary secondary]
belongs_to :progressable, polymorphic: true
translates :title, touch: true
include Globalizable
validates :progressable, presence: true
validates :kind, presence: true,
uniqueness: {
scope: [:progressable_type, :progressable_id],
conditions: -> { primary }
}
validates :percentage, presence: true, inclusion: RANGE, numericality: { only_integer: true }
before_validation :assign_progress_bar_to_translations
validates_translation :title, presence: true, unless: :primary?
private
def assign_progress_bar_to_translations
translations.each { |translation| translation.globalized_model = self }
end
end

View File

@@ -0,0 +1,3 @@
class ProgressBar::Translation < Globalize::ActiveRecord::Translation
delegate :primary?, to: :globalized_model
end

View File

@@ -0,0 +1,12 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("admin.menu.legislation")}" %> -
<%= "#{@process.title} - #{t("admin.progress_bars.index.title")}" %>
<% end %>
<%= back_link_to admin_legislation_process_milestones_path(@progressable),
t("admin.legislation.processes.edit.back") %>
<h2><%= @process.title %></h2>
<%= render "admin/legislation/processes/subnav", process: @process, active: "milestones" %>
<%= render "admin/progress_bars/progress_bars", progressable: @process %>

View File

@@ -1,4 +1,8 @@
<h2><%= t("admin.milestones.index.milestone") %></h2>
<h2 class="inline-block"><%= t("admin.milestones.index.milestone") %></h2>
<%= link_to t("admin.progress_bars.manage"),
polymorphic_path([:admin, *resource_hierarchy_for(milestoneable.progress_bars.new)]),
class: "button hollow float-right" %>
<% if milestoneable.milestones.any? %>
<table>

View File

@@ -0,0 +1,31 @@
<%= render "admin/shared/globalize_locales", resource: @progress_bar %>
<%= translatable_form_for [:admin, *resource_hierarchy_for(@progress_bar)] do |f| %>
<div class="small-12 medium-6">
<%= f.enum_select :kind %>
</div>
<%= f.translatable_fields do |translations_form| %>
<div class="small-12 medium-6">
<%= translations_form.text_field :title %>
</div>
<% end %>
<% progress_options = { min: ProgressBar::RANGE.min, max: ProgressBar::RANGE.max, step: 1 } %>
<div class="small-12 medium-6 large-2">
<%= f.text_field :percentage, { type: :range,
id: "percentage_range",
class: "column" }.merge(progress_options) %>
</div>
<div class="small-12 medium-6 large-2">
<div class="input-group">
<%= f.text_field :percentage, { type: :number,
label: false,
class: "input-group-field" }.merge(progress_options) %>
<span class="input-group-label">%</span>
</div>
</div>
<%= f.submit nil, class: "button success" %>
<% end %>

View File

@@ -0,0 +1,57 @@
<h2 class="inline-block"><%= t("admin.progress_bars.index.title") %></h2>
<%= link_to t("admin.progress_bars.index.new_progress_bar"),
polymorphic_path(
[:admin, *resource_hierarchy_for(ProgressBar.new(progressable: progressable))],
action: :new
),
class: "button float-right" %>
<% if progressable.progress_bars.any? %>
<table>
<thead>
<tr>
<th><%= t("admin.progress_bars.index.table_id") %></th>
<th><%= t("admin.progress_bars.index.table_kind") %></th>
<th><%= t("admin.progress_bars.index.table_title") %></th>
<th class="text-center"><%= t("admin.progress_bars.index.table_percentage") %></th>
<th><%= t("admin.actions.actions") %></th>
</tr>
</thead>
<tbody>
<% progressable.progress_bars.each do |progress_bar| %>
<tr id="<%= dom_id(progress_bar) %>" class="progress-bar">
<td>
<%= progress_bar.id %>
</td>
<td><%= ProgressBar.human_attribute_name("kind.#{progress_bar.kind}") %></td>
<td>
<% if progress_bar.title.present? %>
<%= progress_bar.title %>
<% else %>
<strong><%= t("admin.progress_bars.index.primary") %></strong>
<% end %>
</td>
<td class="text-center">
<%= number_to_percentage(progress_bar.percentage, strip_insignificant_zeros: true) %>
</td>
<td>
<%= link_to t("admin.actions.edit"),
polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)],
action: :edit),
class: "button hollow" %>
<%= link_to t("admin.actions.delete"),
polymorphic_path([:admin, *resource_hierarchy_for(progress_bar)]),
method: :delete,
class: "button hollow alert" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="callout primary">
<%= t("admin.progress_bars.index.no_progress_bars") %>
</div>
<% end %>

View File

@@ -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 %>
<h2><%= bar_title %></h2>
<%= render "form" %>

View File

@@ -0,0 +1,9 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("admin.progress_bars.index.title")}" %>
<% end %>
<%= back_link_to polymorphic_path([:admin, *resource_hierarchy_for(@progressable)]) %>
<div class="clear"></div>
<%= render "admin/progress_bars/progress_bars", progressable: @progressable %>

View File

@@ -0,0 +1,9 @@
<% provide :title do %>
<%= "#{t("admin.header.title")} - #{t("admin.progress_bars.new.creating")}" %>
<% end %>
<%= back_link_to progress_bars_index %>
<h2><%= t("admin.progress_bars.new.creating") %></h2>
<%= render "form" %>