Merge pull request #3228 from consul/milestones_public_progress_bar
[Backport] Add progress bars to milestones public view
This commit is contained in:
@@ -37,8 +37,10 @@ App.Forms =
|
||||
|
||||
if this.value == "primary"
|
||||
title_field.hide()
|
||||
$("#globalize_locales").hide()
|
||||
else
|
||||
title_field.show()
|
||||
$("#globalize_locales").show()
|
||||
|
||||
$("[name='progress_bar[kind]']").change()
|
||||
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
border: 1px solid $border;
|
||||
display: block;
|
||||
margin: rem-calc(-1) 0;
|
||||
min-height: $line-height * 3;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
|
||||
@include breakpoint(large down) {
|
||||
|
||||
|
||||
@@ -1,6 +1,38 @@
|
||||
.tab-milestones ul {
|
||||
margin-top: rem-calc(40);
|
||||
position: relative;
|
||||
$progress-bar-background: #fef0e2;
|
||||
$progress-bar-color: #fea230;
|
||||
|
||||
.tab-milestones {
|
||||
|
||||
.progress-bars {
|
||||
margin-bottom: $line-height * 2;
|
||||
margin-top: $line-height;
|
||||
|
||||
h5 {
|
||||
font-size: rem-calc(24);
|
||||
}
|
||||
|
||||
.progress {
|
||||
background: $progress-bar-background;
|
||||
border-radius: rem-calc(6);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-meter {
|
||||
background: $progress-bar-color;
|
||||
border-radius: rem-calc(6);
|
||||
}
|
||||
|
||||
.progress-meter-text {
|
||||
color: #000;
|
||||
right: 12px;
|
||||
text-align: right;
|
||||
transform: translate(0%, -50%);
|
||||
}
|
||||
|
||||
.milestone-progress .row {
|
||||
margin-bottom: $line-height / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-milestones .timeline li {
|
||||
|
||||
18
app/helpers/milestones_helper.rb
Normal file
18
app/helpers/milestones_helper.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module MilestonesHelper
|
||||
def progress_tag_for(progress_bar)
|
||||
text = number_to_percentage(progress_bar.percentage, precision: 0)
|
||||
|
||||
content_tag :div, class: "progress",
|
||||
role: "progressbar",
|
||||
"aria-valuenow": "#{progress_bar.percentage}",
|
||||
"aria-valuetext": "#{progress_bar.percentage}%",
|
||||
"aria-valuemax": ProgressBar::RANGE.max,
|
||||
"aria-valuemin": "0",
|
||||
tabindex: "0" do
|
||||
content_tag(:span, "",
|
||||
class: "progress-meter",
|
||||
style: "width: #{progress_bar.percentage}%;") +
|
||||
content_tag(:p, text, class: "progress-meter-text")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,5 +7,13 @@ module Milestoneable
|
||||
scope :with_milestones, -> { joins(:milestones).distinct }
|
||||
|
||||
has_many :progress_bars, as: :progressable
|
||||
|
||||
def primary_progress_bar
|
||||
progress_bars.primary.first
|
||||
end
|
||||
|
||||
def secondary_progress_bars
|
||||
progress_bars.secondary
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<% I18n.available_locales.each do |locale| %>
|
||||
<div class="text-right">
|
||||
<%= link_to t("admin.translations.remove_language"), "#",
|
||||
id: "js_delete_#{locale}",
|
||||
style: display_translation_style(resource, locale),
|
||||
class: 'delete js-delete-language',
|
||||
data: { locale: locale } %>
|
||||
<div id="globalize_locales">
|
||||
<% I18n.available_locales.each do |locale| %>
|
||||
<div class="text-right">
|
||||
<%= link_to t("admin.translations.remove_language"), "#",
|
||||
id: "js_delete_#{locale}",
|
||||
style: display_translation_style(resource, locale),
|
||||
class: 'delete js-delete-language',
|
||||
data: { locale: locale } %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render "admin/shared/globalize_tabs", resource: resource, display_style: display_style %>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<%= select_tag :translation_locale,
|
||||
options_for_locale_select,
|
||||
prompt: t("admin.translations.add_language"),
|
||||
class: "js-globalize-locale" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render "admin/shared/globalize_tabs", resource: resource, display_style: display_style %>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<%= select_tag :translation_locale,
|
||||
options_for_locale_select,
|
||||
prompt: t("admin.translations.add_language"),
|
||||
class: "js-globalize-locale" %>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<ul class="tabs" data-tabs id="globalize_locale">
|
||||
<ul class="tabs" data-tabs>
|
||||
<% I18n.available_locales.each do |locale| %>
|
||||
<li class="tabs-title">
|
||||
<%= link_to name_for_locale(locale), "#",
|
||||
|
||||
@@ -42,11 +42,13 @@
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if process.milestones.any? %>
|
||||
<% if process.milestones.any? || process.progress_bars.any? %>
|
||||
<li class="milestones <%= "is-active" if phase == :milestones %>">
|
||||
<%= link_to milestones_legislation_process_path(process) do %>
|
||||
<h4><%= t("legislation.processes.shared.milestones_date") %></h4>
|
||||
<span><%= format_date(process.milestones.order_by_publication_date.last.publication_date) %></span>
|
||||
<% if process.milestones.any? %>
|
||||
<span><%= format_date(process.milestones.order_by_publication_date.last.publication_date) %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= render "milestones/progress_bars", milestoneable: milestoneable %>
|
||||
|
||||
<% if milestoneable.milestones.blank? %>
|
||||
<div class="callout primary text-center">
|
||||
<div class="callout primary text-center margin-top">
|
||||
<%= t("milestones.index.no_milestones") %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<section class="timeline">
|
||||
<ul class="no-bullet">
|
||||
<% milestoneable.milestones.order_by_publication_date.each do |milestone| %>
|
||||
|
||||
24
app/views/milestones/_progress_bars.html.erb
Normal file
24
app/views/milestones/_progress_bars.html.erb
Normal file
@@ -0,0 +1,24 @@
|
||||
<% if milestoneable.primary_progress_bar %>
|
||||
<section class="progress-bars">
|
||||
<h5><%= t("milestones.index.progress") %></h5>
|
||||
|
||||
<div class="margin">
|
||||
<%= progress_tag_for(milestoneable.primary_progress_bar) %>
|
||||
</div>
|
||||
|
||||
<% if milestoneable.secondary_progress_bars.any? %>
|
||||
<div class="milestone-progress">
|
||||
<% milestoneable.secondary_progress_bars.each do |progress_bar| %>
|
||||
<div class="row margin-bottom">
|
||||
<div class="small-12 medium-6 large-4 column">
|
||||
<%= progress_bar.title %>
|
||||
</div>
|
||||
<div class="small-12 medium-6 large-8 column end">
|
||||
<%= progress_tag_for(progress_bar) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
<% end %>
|
||||
@@ -2,6 +2,7 @@ en:
|
||||
milestones:
|
||||
index:
|
||||
no_milestones: Don't have defined milestones
|
||||
progress: Progress
|
||||
show:
|
||||
publication_date: "Published %{publication_date}"
|
||||
status_changed: Status changed to
|
||||
|
||||
@@ -2,6 +2,7 @@ es:
|
||||
milestones:
|
||||
index:
|
||||
no_milestones: No hay hitos definidos
|
||||
progress: Progreso
|
||||
show:
|
||||
publication_date: "Publicado el %{publication_date}"
|
||||
status_changed: El proyecto ha cambiado al estado
|
||||
|
||||
@@ -376,9 +376,9 @@ feature 'Legislation' do
|
||||
end
|
||||
|
||||
context "Milestones" do
|
||||
scenario "Without milestones" do
|
||||
process = create(:legislation_process, :upcoming_proposals_phase)
|
||||
let(:process) { create(:legislation_process, :upcoming_proposals_phase) }
|
||||
|
||||
scenario "Without milestones" do
|
||||
visit legislation_process_path(process)
|
||||
|
||||
within(".legislation-process-list") do
|
||||
@@ -387,7 +387,6 @@ feature 'Legislation' do
|
||||
end
|
||||
|
||||
scenario "With milestones" do
|
||||
process = create(:legislation_process, :upcoming_proposals_phase)
|
||||
create(:milestone,
|
||||
milestoneable: process,
|
||||
description: "Something important happened",
|
||||
@@ -408,6 +407,39 @@ feature 'Legislation' do
|
||||
expect(page).to have_content "Something important happened"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "With main progress bar" do
|
||||
create(:progress_bar, progressable: process)
|
||||
|
||||
visit milestones_legislation_process_path(process)
|
||||
|
||||
within(".tab-milestones") do
|
||||
expect(page).to have_content "Progress"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "With main and secondary progress bar" do
|
||||
create(:progress_bar, progressable: process)
|
||||
create(:progress_bar, :secondary, progressable: process, title: "Build laboratory")
|
||||
|
||||
visit milestones_legislation_process_path(process)
|
||||
|
||||
within(".tab-milestones") do
|
||||
expect(page).to have_content "Progress"
|
||||
expect(page).to have_content "Build laboratory"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "No main progress bar" do
|
||||
create(:progress_bar, :secondary, progressable: process, title: "Defeat Evil Lords")
|
||||
|
||||
visit milestones_legislation_process_path(process)
|
||||
|
||||
within(".tab-milestones") do
|
||||
expect(page).not_to have_content "Progress"
|
||||
expect(page).not_to have_content "Defeat Evil Lords"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
shared_examples "admin_milestoneable" do |factory_name, path_name|
|
||||
it_behaves_like "progressable", factory_name, path_name
|
||||
it_behaves_like "admin_progressable", factory_name, path_name
|
||||
|
||||
feature "Admin milestones" do
|
||||
let!(:milestoneable) { create(factory_name) }
|
||||
|
||||
122
spec/shared/features/admin_progressable.rb
Normal file
122
spec/shared/features/admin_progressable.rb
Normal file
@@ -0,0 +1,122 @@
|
||||
shared_examples "admin_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"
|
||||
|
||||
expect(page).not_to have_field "Title"
|
||||
expect(page).not_to have_content "Add language"
|
||||
|
||||
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"
|
||||
expect(page).to have_content "Primary progress bar"
|
||||
end
|
||||
|
||||
scenario "Secondary progress bar", :js do
|
||||
visit path
|
||||
click_link "Create new progress bar"
|
||||
|
||||
select "Secondary", from: "Type"
|
||||
|
||||
expect(page).to have_content "Add language"
|
||||
|
||||
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" }
|
||||
|
||||
expect(page).to have_field "Current progress"
|
||||
expect(page).not_to have_field "Title"
|
||||
expect(page).not_to have_content "Add language"
|
||||
|
||||
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" }
|
||||
|
||||
expect(page).to have_content "Add language"
|
||||
|
||||
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
|
||||
@@ -1,4 +1,6 @@
|
||||
shared_examples "milestoneable" do |factory_name, path_name|
|
||||
it_behaves_like "progressable", factory_name, path_name
|
||||
|
||||
let!(:milestoneable) { create(factory_name) }
|
||||
|
||||
feature "Show milestones" do
|
||||
|
||||
@@ -1,114 +1,44 @@
|
||||
shared_examples "progressable" do |factory_name, path_name|
|
||||
let!(:progressable) { create(factory_name) }
|
||||
feature "Progress bars", :js do
|
||||
let!(:progressable) { create(factory_name) }
|
||||
let(:path) { send(path_name, *resource_hierarchy_for(progressable)) }
|
||||
|
||||
feature "Manage progress bars" do
|
||||
let(:progressable_path) { send(path_name, *resource_hierarchy_for(progressable)) }
|
||||
scenario "With main progress bar" do
|
||||
create(:progress_bar, progressable: progressable)
|
||||
|
||||
let(:path) do
|
||||
polymorphic_path([:admin, *resource_hierarchy_for(progressable.progress_bars.new)])
|
||||
end
|
||||
visit path
|
||||
|
||||
context "Index" do
|
||||
scenario "Link to index path" do
|
||||
create(:progress_bar, :secondary, progressable: progressable,
|
||||
title: "Reading documents",
|
||||
percentage: 20)
|
||||
find("#tab-milestones-label").click
|
||||
|
||||
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")
|
||||
within("#tab-milestones") do
|
||||
expect(page).to have_content "Progress"
|
||||
end
|
||||
end
|
||||
|
||||
context "New" do
|
||||
scenario "Primary progress bar", :js do
|
||||
visit path
|
||||
click_link "Create new progress bar"
|
||||
scenario "With main and secondary progress bar" do
|
||||
create(:progress_bar, progressable: progressable)
|
||||
create(:progress_bar, :secondary, progressable: progressable, title: "Build laboratory")
|
||||
|
||||
select "Primary", from: "Type"
|
||||
visit path
|
||||
|
||||
expect(page).not_to have_field "Title"
|
||||
find("#tab-milestones-label").click
|
||||
|
||||
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"
|
||||
expect(page).to have_content "Primary progress bar"
|
||||
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"
|
||||
within("#tab-milestones") do
|
||||
expect(page).to have_content "Progress"
|
||||
expect(page).to have_content "Build laboratory"
|
||||
end
|
||||
end
|
||||
|
||||
context "Edit" do
|
||||
scenario "Primary progress bar", :js do
|
||||
bar = create(:progress_bar, progressable: progressable)
|
||||
scenario "No main progress bar" do
|
||||
create(:progress_bar, :secondary, progressable: progressable, title: "Defeat Evil Lords")
|
||||
|
||||
visit path
|
||||
within("#progress_bar_#{bar.id}") { click_link "Edit" }
|
||||
visit path
|
||||
|
||||
expect(page).to have_field "Current progress"
|
||||
expect(page).not_to have_field "Title"
|
||||
find("#tab-milestones-label").click
|
||||
|
||||
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%"
|
||||
within("#tab-milestones") do
|
||||
expect(page).not_to have_content "Progress"
|
||||
expect(page).not_to have_content "Defeat Evil Lords"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user