Merge pull request #4531 from consul/budget-steps
Split budget creation in steps
This commit is contained in:
20
app/assets/javascripts/admin/budgets_wizard/creation_step.js
Normal file
20
app/assets/javascripts/admin/budgets_wizard/creation_step.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
App.AdminBudgetsWizardCreationStep = {
|
||||||
|
initialize: function() {
|
||||||
|
var element, add_button, cancel_button;
|
||||||
|
|
||||||
|
element = $(".admin .budget-creation-step");
|
||||||
|
add_button = element.find(".add");
|
||||||
|
cancel_button = element.find(".delete");
|
||||||
|
|
||||||
|
add_button.click(function() {
|
||||||
|
$(this).attr("aria-expanded", true).parent().find(":input:visible:first").focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
cancel_button.click(function() {
|
||||||
|
add_button.attr("aria-expanded", false).focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}).call(this);
|
||||||
@@ -113,6 +113,7 @@
|
|||||||
//= require columns_selector
|
//= require columns_selector
|
||||||
//= require budget_edit_associations
|
//= require budget_edit_associations
|
||||||
//= require datepicker
|
//= require datepicker
|
||||||
|
//= require_tree ./admin
|
||||||
//= require_tree ./sdg
|
//= require_tree ./sdg
|
||||||
//= require_tree ./sdg_management
|
//= require_tree ./sdg_management
|
||||||
|
|
||||||
@@ -166,6 +167,7 @@ var initialize_modules = function() {
|
|||||||
if ($("#js-columns-selector").length) {
|
if ($("#js-columns-selector").length) {
|
||||||
App.ColumnsSelector.initialize();
|
App.ColumnsSelector.initialize();
|
||||||
}
|
}
|
||||||
|
App.AdminBudgetsWizardCreationStep.initialize();
|
||||||
App.BudgetEditAssociations.initialize();
|
App.BudgetEditAssociations.initialize();
|
||||||
App.Datepicker.initialize();
|
App.Datepicker.initialize();
|
||||||
App.SDGRelatedListSelector.initialize();
|
App.SDGRelatedListSelector.initialize();
|
||||||
|
|||||||
@@ -258,6 +258,11 @@ $table-header: #ecf1f6;
|
|||||||
[type="submit"] ~ a {
|
[type="submit"] ~ a {
|
||||||
margin-left: $line-height / 2;
|
margin-left: $line-height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
|
margin-bottom: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
|
|||||||
3
app/assets/stylesheets/admin/budget_groups/form.scss
Normal file
3
app/assets/stylesheets/admin/budget_groups/form.scss
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.admin .budget-groups-form {
|
||||||
|
@include full-width-form;
|
||||||
|
}
|
||||||
3
app/assets/stylesheets/admin/budget_headings/form.scss
Normal file
3
app/assets/stylesheets/admin/budget_headings/form.scss
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.admin .budget-headings-form {
|
||||||
|
@include full-width-form;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
.admin .budgets-form {
|
.admin .budgets-form {
|
||||||
|
@include full-width-form;
|
||||||
|
|
||||||
> fieldset {
|
> fieldset {
|
||||||
border-top: 4px solid $admin-border-color;
|
border-top: 4px solid $admin-border-color;
|
||||||
@@ -17,8 +18,4 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.globalize-languages {
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
.budget-creation-step {
|
||||||
|
|
||||||
|
.add {
|
||||||
|
@include has-fa-icon(plus-square, solid);
|
||||||
|
@include regular-button;
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
padding-left: rem-calc(10);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
margin-right: rem-calc(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[aria-expanded="false"] {
|
||||||
|
~ :not(.next-step) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[aria-expanded="true"] {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
~ .next-step {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-step {
|
||||||
|
@include regular-button;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
&.next-step {
|
||||||
|
@include button-style($success-color, auto, auto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
&.next-step {
|
||||||
|
@include button-style($secondary-color, auto, auto);
|
||||||
|
@include button-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
.creation-timeline {
|
||||||
|
display: flex;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: $line-height * 2 0;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
li {
|
||||||
|
border-top: 4px solid $brand;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $small-font-size;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: $line-height / 2 $line-height * 3 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background: $brand;
|
||||||
|
border-radius: 50%;
|
||||||
|
content: "";
|
||||||
|
height: 20px;
|
||||||
|
margin-left: $line-height / 2;
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[aria-current] ~ * {
|
||||||
|
border-color: $admin-border-color;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background: $admin-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
.budget-group-switcher {
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .menu > li {
|
||||||
|
|
||||||
|
> button {
|
||||||
|
align-items: center;
|
||||||
|
border: $admin-border;
|
||||||
|
border-radius: $button-radius;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: rem-calc(11) rem-calc(16);
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
@include css-triangle($dropdownmenu-arrow-size, currentcolor, down);
|
||||||
|
margin-left: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu.is-dropdown-submenu {
|
||||||
|
margin: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: default;
|
||||||
|
padding: rem-calc(11) rem-calc(16);
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
@include brand-background;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
%button {
|
@mixin base-button {
|
||||||
font-size: $base-font-size;
|
font-size: $base-font-size;
|
||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
@@ -7,16 +7,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%button {
|
||||||
|
@include base-button;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin regular-button($color: $brand) {
|
@mixin regular-button($color: $brand) {
|
||||||
@include button($background: $color);
|
@include button($background: $color);
|
||||||
@include inverted-selection;
|
@include inverted-selection;
|
||||||
@extend %button;
|
@include base-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin hollow-button($color: $link) {
|
@mixin hollow-button($color: $link) {
|
||||||
@include button($style: hollow, $background: $color);
|
@include button($style: hollow, $background: $color);
|
||||||
@include normal-selection;
|
@include normal-selection;
|
||||||
@extend %button;
|
@include base-button;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,3 +21,9 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin full-width-form {
|
||||||
|
.globalize-languages {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
33
app/components/admin/budget_groups/groups_component.html.erb
Normal file
33
app/components/admin/budget_groups/groups_component.html.erb
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<% if groups.any? %>
|
||||||
|
<h3><%= t("admin.budget_groups.amount", count: groups.count) %></h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="<%= dom_id(budget) %>">
|
||||||
|
<th><%= t("admin.budget_groups.name") %></th>
|
||||||
|
<th><%= Budget::Group.human_attribute_name(:max_votable_headings) %></th>
|
||||||
|
<th><%= t("admin.budget_groups.headings_name") %></th>
|
||||||
|
<th><%= t("admin.actions.actions") %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% groups.each do |group| %>
|
||||||
|
<tr id="<%= dom_id(group) %>">
|
||||||
|
<td><%= group.name %></td>
|
||||||
|
<td><%= group.max_votable_headings %></td>
|
||||||
|
<td><%= group.headings.count %></td>
|
||||||
|
<td>
|
||||||
|
<%= render Admin::TableActionsComponent.new(group) do |actions| %>
|
||||||
|
<%= actions.link_to t("admin.budget_groups.headings_manage"),
|
||||||
|
headings_path(actions, group),
|
||||||
|
class: "headings-link" %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<div class="callout primary clear">
|
||||||
|
<%= t("admin.budget_groups.no_groups") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
17
app/components/admin/budget_groups/groups_component.rb
Normal file
17
app/components/admin/budget_groups/groups_component.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class Admin::BudgetGroups::GroupsComponent < ApplicationComponent
|
||||||
|
attr_reader :groups
|
||||||
|
|
||||||
|
def initialize(groups)
|
||||||
|
@groups = groups
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget
|
||||||
|
@budget ||= groups.first.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def headings_path(table_actions_component, group)
|
||||||
|
send("#{table_actions_component.namespace}_budget_group_headings_path", group.budget, group)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<% if headings.any? %>
|
||||||
|
<h3><%= t("admin.budget_headings.amount", count: headings.count) %></h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="<%= dom_id(group) %>">
|
||||||
|
<th><%= Budget::Heading.human_attribute_name(:name) %></th>
|
||||||
|
<th><%= Budget::Heading.human_attribute_name(:price) %></th>
|
||||||
|
<% if budget.approval_voting? %>
|
||||||
|
<th><%= Budget::Heading.human_attribute_name(:max_ballot_lines) %></th>
|
||||||
|
<% end %>
|
||||||
|
<th><%= Budget::Heading.human_attribute_name(:population) %></th>
|
||||||
|
<th><%= Budget::Heading.human_attribute_name(:allow_custom_content) %></th>
|
||||||
|
<th><%= t("admin.actions.actions") %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% headings.each do |heading| %>
|
||||||
|
<tr id="<%= dom_id(heading) %>" class="heading">
|
||||||
|
<td><%= heading.name %></td>
|
||||||
|
<td><%= budget.formatted_heading_price(heading) %></td>
|
||||||
|
<% if budget.approval_voting? %>
|
||||||
|
<td><%= heading.max_ballot_lines %></td>
|
||||||
|
<% end %>
|
||||||
|
<td><%= heading.population %></td>
|
||||||
|
<td>
|
||||||
|
<%= heading.allow_custom_content ? t("admin.shared.true_value") : t("admin.shared.false_value") %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= render Admin::TableActionsComponent.new(heading) %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<div class="callout primary clear">
|
||||||
|
<%= t("admin.budget_headings.no_headings") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
17
app/components/admin/budget_headings/headings_component.rb
Normal file
17
app/components/admin/budget_headings/headings_component.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class Admin::BudgetHeadings::HeadingsComponent < ApplicationComponent
|
||||||
|
attr_reader :headings
|
||||||
|
|
||||||
|
def initialize(headings)
|
||||||
|
@headings = headings
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def group
|
||||||
|
@group ||= headings.first.group
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
@budget ||= headings.first.budget
|
||||||
|
end
|
||||||
|
end
|
||||||
49
app/components/admin/budget_phases/form_component.html.erb
Normal file
49
app/components/admin/budget_phases/form_component.html.erb
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<%= render "shared/globalize_locales", resource: phase %>
|
||||||
|
|
||||||
|
<%= translatable_form_for [namespace, phase.budget, phase], html: { class: "budget-phases-form" } do |f| %>
|
||||||
|
|
||||||
|
<%= render "shared/errors", resource: phase %>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend aria-describedby="phase_duration_description">
|
||||||
|
<%= t("admin.budget_phases.edit.duration") %>
|
||||||
|
</legend>
|
||||||
|
|
||||||
|
<p class="help-text" id="phase_duration_description">
|
||||||
|
<%= t("admin.budget_phases.edit.duration_description") %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="date-field">
|
||||||
|
<%= f.date_field :starts_at, id: "start_date" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="date-field">
|
||||||
|
<%= f.date_field :ends_at, id: "end_date" %>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="small-12 column margin">
|
||||||
|
<%= f.check_box :enabled %>
|
||||||
|
|
||||||
|
<span class="help-text" id="phase-summary-help-text">
|
||||||
|
<%= t("admin.budget_phases.edit.enabled_help_text") %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= f.translatable_fields do |translations_form| %>
|
||||||
|
<div class="small-12 column">
|
||||||
|
<%= translations_form.text_field :name, hint: t("admin.budget_phases.edit.name_help_text") %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="small-12 column">
|
||||||
|
<%= translations_form.text_area :description,
|
||||||
|
maxlength: Budget::Phase::DESCRIPTION_MAX_LENGTH,
|
||||||
|
class: "html-area",
|
||||||
|
hint: t("admin.budget_phases.edit.description_help_text") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="small-12 column">
|
||||||
|
<%= f.submit t("admin.budget_phases.edit.save_changes"), class: "button success" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
11
app/components/admin/budget_phases/form_component.rb
Normal file
11
app/components/admin/budget_phases/form_component.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class Admin::BudgetPhases::FormComponent < ApplicationComponent
|
||||||
|
include TranslatableFormHelper
|
||||||
|
include GlobalizeHelper
|
||||||
|
include Admin::Namespace
|
||||||
|
|
||||||
|
attr_reader :phase
|
||||||
|
|
||||||
|
def initialize(phase)
|
||||||
|
@phase = phase
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<%= enabled_text(phase) %>
|
<%= enabled_cell(phase) %>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<%= render Admin::TableActionsComponent.new(phase,
|
<%= render Admin::TableActionsComponent.new(phase,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
class Admin::BudgetPhases::PhasesComponent < ApplicationComponent
|
class Admin::BudgetPhases::PhasesComponent < ApplicationComponent
|
||||||
attr_reader :budget
|
attr_reader :budget, :form
|
||||||
|
|
||||||
def initialize(budget)
|
def initialize(budget, form: nil)
|
||||||
@budget = budget
|
@budget = budget
|
||||||
|
@form = form
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -15,6 +16,20 @@ class Admin::BudgetPhases::PhasesComponent < ApplicationComponent
|
|||||||
Admin::Budgets::DurationComponent.new(phase).dates
|
Admin::Budgets::DurationComponent.new(phase).dates
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enabled_cell(phase)
|
||||||
|
if form
|
||||||
|
form.fields_for :phases, phase do |phase_fields|
|
||||||
|
phase_fields.check_box :enabled,
|
||||||
|
label: false,
|
||||||
|
aria: {
|
||||||
|
label: t("admin.budgets.edit.enable_phase", phase: phase.name)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
enabled_text(phase)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def enabled_text(phase)
|
def enabled_text(phase)
|
||||||
if phase.enabled?
|
if phase.enabled?
|
||||||
tag.span t("shared.yes"), class: "budget-phase-enabled"
|
tag.span t("shared.yes"), class: "budget-phase-enabled"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<%= translatable_form_for [:admin, @budget], html: { class: "budgets-form" } do |f| %>
|
<%= translatable_form_for [namespace, budget], html: { class: "budgets-form" } do |f| %>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><%= t("admin.budgets.edit.info.budget_settings") %></legend>
|
<legend><%= t("admin.budgets.edit.info.budget_settings") %></legend>
|
||||||
<%= render "shared/globalize_locales", resource: @budget %>
|
<%= render "shared/globalize_locales", resource: budget %>
|
||||||
<%= render "shared/errors", resource: @budget %>
|
<%= render "shared/errors", resource: budget %>
|
||||||
|
|
||||||
<%= f.translatable_fields do |translations_form| %>
|
<%= f.translatable_fields do |translations_form| %>
|
||||||
<div class="small-12 medium-9 large-6 column end">
|
<div class="small-12 medium-9 large-6 column end">
|
||||||
@@ -13,11 +13,11 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="small-12 medium-4 column">
|
<div class="small-12 medium-4 column">
|
||||||
<%= f.select :voting_style, budget_voting_styles_select_options %>
|
<%= f.select :voting_style, voting_styles_select_options %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-2 column end">
|
<div class="small-12 medium-2 column end">
|
||||||
<%= f.select :currency_symbol, budget_currency_symbol_select_options %>
|
<%= f.select :currency_symbol, currency_symbol_select_options %>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
@@ -26,52 +26,55 @@
|
|||||||
|
|
||||||
<% %w[administrators valuators].each do |staff| %>
|
<% %w[administrators valuators].each do |staff| %>
|
||||||
<div class="small-12 medium-6 large-3 column end">
|
<div class="small-12 medium-6 large-3 column end">
|
||||||
<%= link_to t("admin.budgets.edit.#{staff}", count: @budget.send(staff).count),
|
<%= link_to t("admin.budgets.edit.#{staff}", count: budget.send(staff).count),
|
||||||
"#",
|
"#",
|
||||||
class: "button expanded hollow js-budget-show-#{staff}-list js-budget-show-users-list",
|
class: "button expanded hollow js-budget-show-#{staff}-list js-budget-show-users-list",
|
||||||
data: { toggle: "#{staff}_list", texts: t("admin.budgets.edit.#{staff}") } %>
|
data: { toggle: "#{staff}_list", texts: t("admin.budgets.edit.#{staff}") } %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "/admin/budgets/association", assignable_type: "administrators", assignables: @admins, form: f %>
|
<%= render "/admin/budgets/association", assignable_type: "administrators", assignables: admins, form: f %>
|
||||||
<%= render "/admin/budgets/association", assignable_type: "valuators", assignables: @valuators, form: f %>
|
<%= render "/admin/budgets/association", assignable_type: "valuators", assignables: valuators, form: f %>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<% unless wizard? %>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><%= t("admin.budgets.edit.info.phases_settings") %></legend>
|
<legend><%= t("admin.budgets.edit.info.phases_settings") %></legend>
|
||||||
<div class="small-12 medium-6 column">
|
<div class="small-12 medium-6 column">
|
||||||
<%= f.select :phase, budget_phases_select_options %>
|
<%= f.select :phase, phases_select_options %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= render Admin::Budgets::HelpComponent.new("budget_phases") %>
|
<%= render Admin::BudgetPhases::PhasesComponent.new(budget) %>
|
||||||
<%= render Admin::BudgetPhases::PhasesComponent.new(@budget) %>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<% if @budget.persisted? %>
|
|
||||||
<%= render "admin/shared/show_results_fields", form: f %>
|
<%= render "admin/shared/show_results_fields", form: f %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
<div class="clear small-12 medium-4 large-3 inline-block">
|
<div class="clear small-12 medium-4 large-3 inline-block">
|
||||||
|
<% if wizard? %>
|
||||||
|
<%= f.submit t("admin.budgets_wizard.budgets.continue"), class: "button success expanded" %>
|
||||||
|
<% else %>
|
||||||
<%= f.submit nil, class: "button success" %>
|
<%= f.submit nil, class: "button success" %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
<% if display_calculate_winners_button?(@budget) %>
|
<% if display_calculate_winners_button?(budget) %>
|
||||||
<%= link_to calculate_winner_button_text(@budget),
|
<%= link_to calculate_winner_button_text(budget),
|
||||||
calculate_winners_admin_budget_path(@budget),
|
calculate_winners_admin_budget_path(budget),
|
||||||
method: :put,
|
method: :put,
|
||||||
class: "button hollow" %>
|
class: "button hollow" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if @budget.has_winning_investments? %>
|
<% if budget.has_winning_investments? %>
|
||||||
<%= link_to t("budgets.show.see_results"),
|
<%= link_to t("budgets.show.see_results"),
|
||||||
budget_results_path(@budget),
|
budget_results_path(budget),
|
||||||
class: "button hollow margin-left" %>
|
class: "button hollow margin-left" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if @budget.persisted? %>
|
<% if budget.persisted? %>
|
||||||
<%= link_to t("admin.budgets.edit.delete"),
|
<%= link_to t("admin.budgets.edit.delete"),
|
||||||
admin_budget_path(@budget),
|
admin_budget_path(budget),
|
||||||
method: :delete,
|
method: :delete,
|
||||||
class: "delete float-right margin-left" %>
|
class: "delete float-right margin-left" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
41
app/components/admin/budgets/form_component.rb
Normal file
41
app/components/admin/budgets/form_component.rb
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
class Admin::Budgets::FormComponent < ApplicationComponent
|
||||||
|
include TranslatableFormHelper
|
||||||
|
include GlobalizeHelper
|
||||||
|
include Admin::Namespace
|
||||||
|
|
||||||
|
attr_reader :budget, :wizard
|
||||||
|
alias_method :wizard?, :wizard
|
||||||
|
delegate :display_calculate_winners_button?,
|
||||||
|
:calculate_winner_button_text,
|
||||||
|
:calculate_winners_admin_budget_path,
|
||||||
|
to: :helpers
|
||||||
|
|
||||||
|
def initialize(budget, wizard: false)
|
||||||
|
@budget = budget
|
||||||
|
@wizard = wizard
|
||||||
|
end
|
||||||
|
|
||||||
|
def voting_styles_select_options
|
||||||
|
Budget::VOTING_STYLES.map do |style|
|
||||||
|
[Budget.human_attribute_name("voting_style_#{style}"), style]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def currency_symbol_select_options
|
||||||
|
Budget::CURRENCY_SYMBOLS.map { |cs| [cs, cs] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def phases_select_options
|
||||||
|
Budget::Phase::PHASE_KINDS.map { |ph| [t("budgets.phase.#{ph}"), ph] }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def admins
|
||||||
|
@admins ||= Administrator.includes(:user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def valuators
|
||||||
|
@valuators ||= Valuator.includes(:user).order(description: :asc).order("users.email ASC")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<%= header do %>
|
<%= header do %>
|
||||||
<%= link_to t("admin.budgets.index.new_link"), new_admin_budget_path %>
|
<%= link_to t("admin.budgets.index.new_link"), new_admin_budgets_wizard_budget_path %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render Admin::Budgets::HelpComponent.new("budgets") %>
|
<%= render Admin::Budgets::HelpComponent.new("budgets") %>
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<%= render Admin::TableActionsComponent.new(budget, actions: [:edit], edit_text: t("admin.budgets.index.edit_budget")) do %>
|
<%= render Admin::TableActionsComponent.new(budget,
|
||||||
|
edit_text: t("admin.budgets.index.edit_budget"),
|
||||||
|
destroy_confirmation: t("admin.actions.confirm_delete", resource_name: t("admin.budgets.shared.resource_name"),
|
||||||
|
name: budget.name)
|
||||||
|
) do %>
|
||||||
<%= link_to t("admin.budgets.index.budget_investments"),
|
<%= link_to t("admin.budgets.index.budget_investments"),
|
||||||
admin_budget_budget_investments_path(budget_id: budget.id),
|
admin_budget_budget_investments_path(budget_id: budget.id),
|
||||||
class: "investments-link" %>
|
class: "investments-link" %>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<%= back_link_to admin_budgets_path %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("budget") %>
|
||||||
|
<%= render Admin::Budgets::FormComponent.new(budget, wizard: true) %>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class Admin::BudgetsWizard::Budgets::EditComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :budget
|
||||||
|
|
||||||
|
def initialize(budget)
|
||||||
|
@budget = budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
t("admin.budgets.edit.title")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<%= back_link_to admin_budgets_path %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("budget") %>
|
||||||
|
<%= render Admin::Budgets::FormComponent.new(budget, wizard: true) %>
|
||||||
12
app/components/admin/budgets_wizard/budgets/new_component.rb
Normal file
12
app/components/admin/budgets_wizard/budgets/new_component.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class Admin::BudgetsWizard::Budgets::NewComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :budget
|
||||||
|
|
||||||
|
def initialize(budget)
|
||||||
|
@budget = budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
t("admin.budgets.new.title")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="budget-creation-step">
|
||||||
|
<button type="button" class="add" aria-expanded="<%= show_form? %>">
|
||||||
|
<%= t("admin.#{i18n_namespace_with_budget}.index.new_button") %>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<%= content %>
|
||||||
|
|
||||||
|
<button type="button" class="cancel delete"><%= t("links.form.cancel_button") %></button>
|
||||||
|
|
||||||
|
<% if next_step_path %>
|
||||||
|
<%= link_to t("admin.budgets_wizard.#{i18n_namespace}.continue"),
|
||||||
|
next_step_path,
|
||||||
|
class: "next-step" %>
|
||||||
|
<% else %>
|
||||||
|
<p class="next-step">
|
||||||
|
<%= t("admin.budgets_wizard.#{i18n_namespace}.continue") %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class Admin::BudgetsWizard::CreationStepComponent < ApplicationComponent
|
||||||
|
attr_reader :record, :next_step_path
|
||||||
|
|
||||||
|
def initialize(record, next_step_path)
|
||||||
|
@record = record
|
||||||
|
@next_step_path = next_step_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def show_form?
|
||||||
|
record.errors.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def i18n_namespace
|
||||||
|
i18n_namespace_with_budget.gsub("budget_", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
def i18n_namespace_with_budget
|
||||||
|
record.class.table_name
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<ol class="creation-timeline">
|
||||||
|
<% steps.each do |step| %>
|
||||||
|
<li <%= "aria-current='step'" if step == current_step %>>
|
||||||
|
<%= t("admin.budgets_wizard.creation_timeline.#{step}") %>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ol>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class Admin::BudgetsWizard::CreationTimelineComponent < ApplicationComponent
|
||||||
|
attr_reader :current_step
|
||||||
|
|
||||||
|
def initialize(current_step)
|
||||||
|
@current_step = current_step
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def steps
|
||||||
|
%w[budget groups headings phases]
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::CreationStepComponent.new(group, next_step_path) do %>
|
||||||
|
<%= render "/admin/budget_groups/form", group: group, path: form_path, action: "create" %>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
class Admin::BudgetsWizard::Groups::CreationStepComponent < ApplicationComponent
|
||||||
|
attr_reader :group, :next_step_group
|
||||||
|
|
||||||
|
def initialize(group, next_step_group)
|
||||||
|
@group = group
|
||||||
|
@next_step_group = next_step_group
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget
|
||||||
|
group.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_path
|
||||||
|
admin_budgets_wizard_budget_groups_path(budget)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_step_path
|
||||||
|
admin_budgets_wizard_budget_group_headings_path(budget, next_step_group) if next_step_enabled?
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_step_enabled?
|
||||||
|
next_step_group.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<%= back_link_to admin_budgets_wizard_budget_groups_path(budget) %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("groups") %>
|
||||||
|
|
||||||
|
<%= render "/admin/budget_groups/form", group: group, path: form_path, action: "submit" %>
|
||||||
22
app/components/admin/budgets_wizard/groups/edit_component.rb
Normal file
22
app/components/admin/budgets_wizard/groups/edit_component.rb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
class Admin::BudgetsWizard::Groups::EditComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :group
|
||||||
|
|
||||||
|
def initialize(group)
|
||||||
|
@group = group
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
group.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
budget.name
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def form_path
|
||||||
|
admin_budgets_wizard_budget_group_path(budget, group)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<%= back_link_to edit_admin_budgets_wizard_budget_path(budget), t("admin.budgets_wizard.groups.back") %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::Budgets::HelpComponent.new("budget_groups") %>
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("groups") %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetGroups::GroupsComponent.new(groups) %>
|
||||||
|
<%= render Admin::BudgetsWizard::Groups::CreationStepComponent.new(new_group, groups.first) %>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class Admin::BudgetsWizard::Groups::IndexComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :groups, :new_group
|
||||||
|
|
||||||
|
def initialize(groups, new_group)
|
||||||
|
@groups = groups
|
||||||
|
@new_group = new_group
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
@new_group.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
budget.name
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::CreationStepComponent.new(heading, next_step_path) do %>
|
||||||
|
<%= render "/admin/budget_headings/form", heading: heading, path: form_path, action: "create" %>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
class Admin::BudgetsWizard::Headings::CreationStepComponent < ApplicationComponent
|
||||||
|
attr_reader :heading
|
||||||
|
|
||||||
|
def initialize(heading)
|
||||||
|
@heading = heading
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget
|
||||||
|
heading.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_path
|
||||||
|
admin_budgets_wizard_budget_group_headings_path(heading.group.budget, heading.group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_step_path
|
||||||
|
admin_budgets_wizard_budget_budget_phases_path(budget) if next_step_enabled?
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_step_enabled?
|
||||||
|
budget.headings.any?
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<%= back_link_to admin_budgets_wizard_budget_group_headings_path(budget, group) %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("headings") %>
|
||||||
|
|
||||||
|
<%= render "/admin/budget_headings/form", heading: heading, path: form_path, action: "submit" %>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
class Admin::BudgetsWizard::Headings::EditComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :heading
|
||||||
|
|
||||||
|
def initialize(heading)
|
||||||
|
@heading = heading
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
heading.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def group
|
||||||
|
heading.group
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
heading.name
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def form_path
|
||||||
|
admin_budgets_wizard_budget_group_heading_path(budget, group, heading)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<div class="budget-group-switcher">
|
||||||
|
<% if other_groups.one? %>
|
||||||
|
<p>
|
||||||
|
<%= t("admin.budget_headings.group_switcher.currently_showing", group: group.name) %>
|
||||||
|
<%= link_to t("admin.budget_headings.group_switcher.the_other_group", group: other_groups.first.name),
|
||||||
|
headings_path(other_groups.first) %>
|
||||||
|
</p>
|
||||||
|
<% else %>
|
||||||
|
<p><%= t("admin.budget_headings.group_switcher.currently_showing", group: group.name) %></p>
|
||||||
|
<ul class="dropdown menu" data-dropdown-menu data-disable-hover="true" data-click-open="true">
|
||||||
|
<li class="has-submenu">
|
||||||
|
<button type="button"><%= t("admin.budget_headings.group_switcher.different_group") %></button>
|
||||||
|
<ul class="menu" data-submenu>
|
||||||
|
<% other_groups.each do |other_group| %>
|
||||||
|
<li><%= link_to other_group.name, headings_path(other_group) %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
class Admin::BudgetsWizard::Headings::GroupSwitcherComponent < ApplicationComponent
|
||||||
|
attr_reader :group
|
||||||
|
|
||||||
|
def initialize(group)
|
||||||
|
@group = group
|
||||||
|
end
|
||||||
|
|
||||||
|
def render?
|
||||||
|
other_groups.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget
|
||||||
|
group.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def other_groups
|
||||||
|
@other_groups ||= budget.groups.sort_by_name - [group]
|
||||||
|
end
|
||||||
|
|
||||||
|
def headings_path(group)
|
||||||
|
admin_budgets_wizard_budget_group_headings_path(budget, group)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<%= back_link_to admin_budgets_wizard_budget_groups_path(budget), t("admin.budget_headings.index.back") %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::Budgets::HelpComponent.new("budget_headings") %>
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("headings") %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group) %>
|
||||||
|
<%= render Admin::BudgetHeadings::HeadingsComponent.new(headings) %>
|
||||||
|
<%= render Admin::BudgetsWizard::Headings::CreationStepComponent.new(new_heading) %>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
class Admin::BudgetsWizard::Headings::IndexComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :headings, :new_heading
|
||||||
|
|
||||||
|
def initialize(headings, new_heading)
|
||||||
|
@headings = headings
|
||||||
|
@new_heading = new_heading
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
group.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def group
|
||||||
|
new_heading.group
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
t("admin.budget_headings.index.title", budget: budget.name, group: group.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<%= back_link_to admin_budgets_wizard_budget_budget_phases_path(budget) %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("phases") %>
|
||||||
|
<%= render "/admin/budget_phases/form" %>
|
||||||
22
app/components/admin/budgets_wizard/phases/edit_component.rb
Normal file
22
app/components/admin/budgets_wizard/phases/edit_component.rb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
class Admin::BudgetsWizard::Phases::EditComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :phase
|
||||||
|
|
||||||
|
def initialize(phase)
|
||||||
|
@phase = phase
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
phase.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
"#{t("admin.budget_phases.edit.title")} - #{phase.name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def form_path
|
||||||
|
admin_budgets_wizard_budget_budget_phases_path(budget)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<%= back_link_to back_link_path, t("admin.budgets_wizard.phases.back") %>
|
||||||
|
|
||||||
|
<%= header %>
|
||||||
|
|
||||||
|
<%= render Admin::Budgets::HelpComponent.new("budget_phases") %>
|
||||||
|
<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("phases") %>
|
||||||
|
|
||||||
|
<%= form_for budget, url: update_all_admin_budgets_wizard_budget_budget_phases_path(budget) do |f| %>
|
||||||
|
<%= render Admin::BudgetPhases::PhasesComponent.new(budget, form: f) %>
|
||||||
|
<%= f.submit t("admin.budgets_wizard.phases.continue"), class: "button success" %>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class Admin::BudgetsWizard::Phases::IndexComponent < ApplicationComponent
|
||||||
|
include Header
|
||||||
|
attr_reader :budget
|
||||||
|
|
||||||
|
def initialize(budget)
|
||||||
|
@budget = budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
t("admin.budget_phases.index.title", budget: budget.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def back_link_path
|
||||||
|
admin_budgets_wizard_budget_group_headings_path(budget, budget.groups.first)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -13,7 +13,7 @@ class Admin::MenuComponent < ApplicationComponent
|
|||||||
end
|
end
|
||||||
|
|
||||||
def budgets?
|
def budgets?
|
||||||
controller_name.starts_with?("budget")
|
controller_name.starts_with?("budget") || controller_path =~ /budgets_wizard/
|
||||||
end
|
end
|
||||||
|
|
||||||
def polls?
|
def polls?
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
class Admin::TableActionsComponent < ApplicationComponent
|
class Admin::TableActionsComponent < ApplicationComponent
|
||||||
include TableActionLink
|
include TableActionLink
|
||||||
|
include Admin::Namespace
|
||||||
attr_reader :record, :options
|
attr_reader :record, :options
|
||||||
delegate :namespace, to: :helpers
|
|
||||||
|
|
||||||
def initialize(record = nil, **options)
|
def initialize(record = nil, **options)
|
||||||
@record = record
|
@record = record
|
||||||
|
|||||||
9
app/components/concerns/admin/namespace.rb
Normal file
9
app/components/concerns/admin/namespace.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
module Admin::Namespace
|
||||||
|
def namespace
|
||||||
|
if controller.class.name.starts_with?("Admin::BudgetsWizard")
|
||||||
|
:admin_budgets_wizard
|
||||||
|
else
|
||||||
|
helpers.namespace.to_sym
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,64 +1,22 @@
|
|||||||
class Admin::BudgetGroupsController < Admin::BaseController
|
class Admin::BudgetGroupsController < Admin::BaseController
|
||||||
include Translatable
|
include Admin::BudgetGroupsActions
|
||||||
include FeatureFlags
|
|
||||||
feature_flag :budgets
|
|
||||||
|
|
||||||
before_action :load_budget
|
before_action :load_groups, only: :index
|
||||||
before_action :load_group, except: [:index, :new, :create]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@groups = @budget.groups.order(:id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@group = @budget.groups.new
|
@group = @budget.groups.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@group = @budget.groups.new(budget_group_params)
|
|
||||||
if @group.save
|
|
||||||
redirect_to groups_index, notice: t("admin.budget_groups.create.notice")
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if @group.update(budget_group_params)
|
|
||||||
redirect_to groups_index, notice: t("admin.budget_groups.update.notice")
|
|
||||||
else
|
|
||||||
render :edit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @group.headings.any?
|
|
||||||
redirect_to groups_index, alert: t("admin.budget_groups.destroy.unable_notice")
|
|
||||||
else
|
|
||||||
@group.destroy!
|
|
||||||
redirect_to groups_index, notice: t("admin.budget_groups.destroy.success_notice")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_budget
|
|
||||||
@budget = Budget.find_by_slug_or_id! params[:budget_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_group
|
|
||||||
@group = @budget.groups.find_by_slug_or_id! params[:id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def groups_index
|
def groups_index
|
||||||
admin_budget_groups_path(@budget)
|
admin_budget_groups_path(@budget)
|
||||||
end
|
end
|
||||||
|
|
||||||
def budget_group_params
|
def new_action
|
||||||
valid_attributes = [:max_votable_headings]
|
:new
|
||||||
params.require(:budget_group).permit(*valid_attributes, translation_params(Budget::Group))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,69 +1,20 @@
|
|||||||
class Admin::BudgetHeadingsController < Admin::BaseController
|
class Admin::BudgetHeadingsController < Admin::BaseController
|
||||||
include Translatable
|
include Admin::BudgetHeadingsActions
|
||||||
include FeatureFlags
|
|
||||||
feature_flag :budgets
|
|
||||||
|
|
||||||
before_action :load_budget
|
|
||||||
before_action :load_group
|
|
||||||
before_action :load_heading, except: [:index, :new, :create]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@headings = @group.headings.order(:id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@heading = @group.headings.new
|
@heading = @group.headings.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@heading = @group.headings.new(budget_heading_params)
|
|
||||||
if @heading.save
|
|
||||||
redirect_to headings_index, notice: t("admin.budget_headings.create.notice")
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if @heading.update(budget_heading_params)
|
|
||||||
redirect_to headings_index, notice: t("admin.budget_headings.update.notice")
|
|
||||||
else
|
|
||||||
render :edit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @heading.can_be_deleted?
|
|
||||||
@heading.destroy!
|
|
||||||
redirect_to headings_index, notice: t("admin.budget_headings.destroy.success_notice")
|
|
||||||
else
|
|
||||||
redirect_to headings_index, alert: t("admin.budget_headings.destroy.unable_notice")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_budget
|
|
||||||
@budget = Budget.find_by_slug_or_id! params[:budget_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_group
|
|
||||||
@group = @budget.groups.find_by_slug_or_id! params[:group_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_heading
|
|
||||||
@heading = @group.headings.find_by_slug_or_id! params[:id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def headings_index
|
def headings_index
|
||||||
admin_budget_group_headings_path(@budget, @group)
|
admin_budget_group_headings_path(@budget, @group)
|
||||||
end
|
end
|
||||||
|
|
||||||
def budget_heading_params
|
def new_action
|
||||||
valid_attributes = [:price, :population, :allow_custom_content, :latitude, :longitude, :max_ballot_lines]
|
:new
|
||||||
params.require(:budget_heading).permit(*valid_attributes, translation_params(Budget::Heading))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,28 +1,9 @@
|
|||||||
class Admin::BudgetPhasesController < Admin::BaseController
|
class Admin::BudgetPhasesController < Admin::BaseController
|
||||||
include Translatable
|
include Admin::BudgetPhasesActions
|
||||||
|
|
||||||
before_action :load_phase, only: [:edit, :update]
|
|
||||||
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if @phase.update(budget_phase_params)
|
|
||||||
notice = t("flash.actions.save_changes.notice")
|
|
||||||
redirect_to edit_admin_budget_path(@phase.budget), notice: notice
|
|
||||||
else
|
|
||||||
render :edit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_phase
|
def phases_index
|
||||||
@phase = Budget::Phase.find(params[:id])
|
edit_admin_budget_path(@phase.budget)
|
||||||
end
|
|
||||||
|
|
||||||
def budget_phase_params
|
|
||||||
valid_attributes = [:starts_at, :ends_at, :enabled]
|
|
||||||
params.require(:budget_phase).permit(*valid_attributes, translation_params(Budget::Phase))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ class Admin::BudgetsController < Admin::BaseController
|
|||||||
|
|
||||||
has_filters %w[all open finished], only: :index
|
has_filters %w[all open finished], only: :index
|
||||||
|
|
||||||
before_action :load_budget, except: [:index, :new, :create]
|
before_action :load_budget, except: [:index]
|
||||||
before_action :load_staff, only: [:new, :create, :edit, :update, :show]
|
|
||||||
load_and_authorize_resource
|
load_and_authorize_resource
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@@ -18,9 +17,6 @@ class Admin::BudgetsController < Admin::BaseController
|
|||||||
render :edit
|
render :edit
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -47,15 +43,6 @@ class Admin::BudgetsController < Admin::BaseController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
|
||||||
@budget = Budget.new(budget_params.merge(published: false))
|
|
||||||
if @budget.save
|
|
||||||
redirect_to edit_admin_budget_path(@budget), notice: t("admin.budgets.create.notice")
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
if @budget.investments.any?
|
if @budget.investments.any?
|
||||||
redirect_to admin_budgets_path, alert: t("admin.budgets.destroy.unable_notice")
|
redirect_to admin_budgets_path, alert: t("admin.budgets.destroy.unable_notice")
|
||||||
@@ -83,9 +70,4 @@ class Admin::BudgetsController < Admin::BaseController
|
|||||||
def load_budget
|
def load_budget
|
||||||
@budget = Budget.find_by_slug_or_id! params[:id]
|
@budget = Budget.find_by_slug_or_id! params[:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_staff
|
|
||||||
@admins = Administrator.includes(:user)
|
|
||||||
@valuators = Valuator.includes(:user).order(description: :asc).order("users.email ASC")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
47
app/controllers/admin/budgets_wizard/budgets_controller.rb
Normal file
47
app/controllers/admin/budgets_wizard/budgets_controller.rb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
class Admin::BudgetsWizard::BudgetsController < Admin::BaseController
|
||||||
|
include Translatable
|
||||||
|
include FeatureFlags
|
||||||
|
feature_flag :budgets
|
||||||
|
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@budget.published = false
|
||||||
|
|
||||||
|
if @budget.save
|
||||||
|
redirect_to groups_index, notice: t("admin.budgets.create.notice")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @budget.update(budget_params)
|
||||||
|
redirect_to groups_index, notice: t("admin.budgets.update.notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget_params
|
||||||
|
params.require(:budget).permit(*allowed_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_params
|
||||||
|
valid_attributes = [:currency_symbol, :voting_style, administrator_ids: [], valuator_ids: []]
|
||||||
|
|
||||||
|
valid_attributes + [translation_params(Budget)]
|
||||||
|
end
|
||||||
|
|
||||||
|
def groups_index
|
||||||
|
admin_budgets_wizard_budget_groups_path(@budget)
|
||||||
|
end
|
||||||
|
end
|
||||||
19
app/controllers/admin/budgets_wizard/groups_controller.rb
Normal file
19
app/controllers/admin/budgets_wizard/groups_controller.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class Admin::BudgetsWizard::GroupsController < Admin::BaseController
|
||||||
|
include Admin::BudgetGroupsActions
|
||||||
|
|
||||||
|
before_action :load_groups, only: [:index, :create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@group = @budget.groups.new
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def groups_index
|
||||||
|
admin_budgets_wizard_budget_groups_path(@budget)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_action
|
||||||
|
:index
|
||||||
|
end
|
||||||
|
end
|
||||||
19
app/controllers/admin/budgets_wizard/headings_controller.rb
Normal file
19
app/controllers/admin/budgets_wizard/headings_controller.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class Admin::BudgetsWizard::HeadingsController < Admin::BaseController
|
||||||
|
include Admin::BudgetHeadingsActions
|
||||||
|
|
||||||
|
before_action :load_headings, only: [:index, :create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@heading = @group.headings.new
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def headings_index
|
||||||
|
admin_budgets_wizard_budget_group_headings_path(@budget, @group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_action
|
||||||
|
:index
|
||||||
|
end
|
||||||
|
end
|
||||||
26
app/controllers/admin/budgets_wizard/phases_controller.rb
Normal file
26
app/controllers/admin/budgets_wizard/phases_controller.rb
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class Admin::BudgetsWizard::PhasesController < Admin::BaseController
|
||||||
|
include Admin::BudgetPhasesActions
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_all
|
||||||
|
@budget.update!(phases_params)
|
||||||
|
|
||||||
|
redirect_to admin_budgets_path, notice: t("admin.budgets_wizard.phases.update_all.notice")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def phases_index
|
||||||
|
admin_budgets_wizard_budget_budget_phases_path(@phase.budget)
|
||||||
|
end
|
||||||
|
|
||||||
|
def phases_params
|
||||||
|
params.require(:budget).permit(allowed_phases_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_phases_params
|
||||||
|
{ phases_attributes: [:id, :enabled] }
|
||||||
|
end
|
||||||
|
end
|
||||||
60
app/controllers/concerns/admin/budget_groups_actions.rb
Normal file
60
app/controllers/concerns/admin/budget_groups_actions.rb
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
module Admin::BudgetGroupsActions
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
include Translatable
|
||||||
|
include FeatureFlags
|
||||||
|
feature_flag :budgets
|
||||||
|
|
||||||
|
before_action :load_budget
|
||||||
|
before_action :load_group, only: [:edit, :update, :destroy]
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@group = @budget.groups.new(budget_group_params)
|
||||||
|
if @group.save
|
||||||
|
redirect_to groups_index, notice: t("admin.budget_groups.create.notice")
|
||||||
|
else
|
||||||
|
render new_action
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @group.update(budget_group_params)
|
||||||
|
redirect_to groups_index, notice: t("admin.budget_groups.update.notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @group.headings.any?
|
||||||
|
redirect_to groups_index, alert: t("admin.budget_groups.destroy.unable_notice")
|
||||||
|
else
|
||||||
|
@group.destroy!
|
||||||
|
redirect_to groups_index, notice: t("admin.budget_groups.destroy.success_notice")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_budget
|
||||||
|
@budget = Budget.find_by_slug_or_id! params[:budget_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_groups
|
||||||
|
@groups = @budget.groups.order(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_group
|
||||||
|
@group = @budget.groups.find_by_slug_or_id! params[:id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget_group_params
|
||||||
|
valid_attributes = [:max_votable_headings]
|
||||||
|
params.require(:budget_group).permit(*valid_attributes, translation_params(Budget::Group))
|
||||||
|
end
|
||||||
|
end
|
||||||
66
app/controllers/concerns/admin/budget_headings_actions.rb
Normal file
66
app/controllers/concerns/admin/budget_headings_actions.rb
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
module Admin::BudgetHeadingsActions
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
include Translatable
|
||||||
|
include FeatureFlags
|
||||||
|
feature_flag :budgets
|
||||||
|
|
||||||
|
before_action :load_budget
|
||||||
|
before_action :load_group
|
||||||
|
before_action :load_headings, only: :index
|
||||||
|
before_action :load_heading, only: [:edit, :update, :destroy]
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@heading = @group.headings.new(budget_heading_params)
|
||||||
|
if @heading.save
|
||||||
|
redirect_to headings_index, notice: t("admin.budget_headings.create.notice")
|
||||||
|
else
|
||||||
|
render new_action
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @heading.update(budget_heading_params)
|
||||||
|
redirect_to headings_index, notice: t("admin.budget_headings.update.notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @heading.can_be_deleted?
|
||||||
|
@heading.destroy!
|
||||||
|
redirect_to headings_index, notice: t("admin.budget_headings.destroy.success_notice")
|
||||||
|
else
|
||||||
|
redirect_to headings_index, alert: t("admin.budget_headings.destroy.unable_notice")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_budget
|
||||||
|
@budget = Budget.find_by_slug_or_id! params[:budget_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_group
|
||||||
|
@group = @budget.groups.find_by_slug_or_id! params[:group_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_headings
|
||||||
|
@headings = @group.headings.order(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_heading
|
||||||
|
@heading = @group.headings.find_by_slug_or_id! params[:id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget_heading_params
|
||||||
|
valid_attributes = [:price, :population, :allow_custom_content, :latitude, :longitude, :max_ballot_lines]
|
||||||
|
params.require(:budget_heading).permit(*valid_attributes, translation_params(Budget::Heading))
|
||||||
|
end
|
||||||
|
end
|
||||||
36
app/controllers/concerns/admin/budget_phases_actions.rb
Normal file
36
app/controllers/concerns/admin/budget_phases_actions.rb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
module Admin::BudgetPhasesActions
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
include Translatable
|
||||||
|
|
||||||
|
before_action :load_budget
|
||||||
|
before_action :load_phase, only: [:edit, :update]
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @phase.update(budget_phase_params)
|
||||||
|
redirect_to phases_index, notice: t("flash.actions.save_changes.notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_budget
|
||||||
|
@budget = Budget.find_by_slug_or_id!(params[:budget_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_phase
|
||||||
|
@phase = @budget.phases.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def budget_phase_params
|
||||||
|
valid_attributes = [:starts_at, :ends_at, :enabled]
|
||||||
|
params.require(:budget_phase).permit(*valid_attributes, translation_params(Budget::Phase))
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
module BudgetsHelper
|
module BudgetsHelper
|
||||||
def budget_voting_styles_select_options
|
|
||||||
Budget::VOTING_STYLES.map do |style|
|
|
||||||
[Budget.human_attribute_name("voting_style_#{style}"), style]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def csv_params
|
def csv_params
|
||||||
csv_params = params.clone.merge(format: :csv)
|
csv_params = params.clone.merge(format: :csv)
|
||||||
csv_params = csv_params.to_unsafe_h.map { |k, v| [k.to_sym, v] }.to_h
|
csv_params = csv_params.to_unsafe_h.map { |k, v| [k.to_sym, v] }.to_h
|
||||||
@@ -12,14 +6,6 @@ module BudgetsHelper
|
|||||||
csv_params
|
csv_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def budget_phases_select_options
|
|
||||||
Budget::Phase::PHASE_KINDS.map { |ph| [t("budgets.phase.#{ph}"), ph] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def budget_currency_symbol_select_options
|
|
||||||
Budget::CURRENCY_SYMBOLS.map { |cs| [cs, cs] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def namespaced_budget_investment_path(investment, options = {})
|
def namespaced_budget_investment_path(investment, options = {})
|
||||||
case namespace
|
case namespace
|
||||||
when "management"
|
when "management"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class Budget < ApplicationRecord
|
|||||||
has_one :poll
|
has_one :poll
|
||||||
|
|
||||||
after_create :generate_phases
|
after_create :generate_phases
|
||||||
|
accepts_nested_attributes_for :phases
|
||||||
|
|
||||||
scope :published, -> { where(published: true) }
|
scope :published, -> { where(published: true) }
|
||||||
scope :drafting, -> { where.not(id: published) }
|
scope :drafting, -> { where.not(id: published) }
|
||||||
|
|||||||
@@ -1,30 +1,23 @@
|
|||||||
<%= render "shared/globalize_locales", resource: @group %>
|
<%= translatable_form_for group, url: path, html: { class: "budget-groups-form" } do |f| %>
|
||||||
|
<%= render "shared/globalize_locales", resource: group %>
|
||||||
|
|
||||||
<%= translatable_form_for [:admin, @budget, @group], url: path do |f| %>
|
<%= render "shared/errors", resource: group %>
|
||||||
|
|
||||||
<%= render "shared/errors", resource: @group %>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<%= f.translatable_fields do |translations_form| %>
|
<%= f.translatable_fields do |translations_form| %>
|
||||||
<div class="small-12 medium-6 column end">
|
<div class="small-12 medium-6 column end">
|
||||||
<%= translations_form.text_field :name, maxlength: 50 %>
|
<%= translations_form.text_field :name, maxlength: 50 %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
|
||||||
|
|
||||||
<% if @group.persisted? %>
|
<% if group.persisted? && group.headings.any? %>
|
||||||
<div class="row">
|
<div class="small-12 medium-6 column margin">
|
||||||
<div class="small-12 medium-6 column">
|
|
||||||
<%= f.select :max_votable_headings,
|
<%= f.select :max_votable_headings,
|
||||||
(1..@group.headings.count),
|
(1..group.headings.count),
|
||||||
hint: t("admin.budget_groups.form.max_votable_headings_info") %>
|
hint: t("admin.budget_groups.form.max_votable_headings_info") %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="row">
|
<div class="clear">
|
||||||
<div class="small-12 medium-6 column">
|
<%= f.submit t("admin.budget_groups.form.#{action}"), class: "button hollow" %>
|
||||||
<%= f.submit t("admin.budget_groups.form.#{action}"), class: "button success" %>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<%= render "header", action: "edit" %>
|
<%= render "header", action: "edit" %>
|
||||||
|
|
||||||
<%= render "form", path: admin_budget_group_path(@budget, @group), action: "submit" %>
|
<%= render "form", group: @group, path: admin_budget_group_path(@budget, @group), action: "submit" %>
|
||||||
|
|||||||
@@ -8,37 +8,4 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<%= render Admin::Budgets::HelpComponent.new("budget_groups") %>
|
<%= render Admin::Budgets::HelpComponent.new("budget_groups") %>
|
||||||
|
<%= render Admin::BudgetGroups::GroupsComponent.new(@groups) %>
|
||||||
<% if @groups.any? %>
|
|
||||||
<h3><%= t("admin.budget_groups.amount", count: @groups.count) %></h3>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr id="<%= dom_id(@budget) %>">
|
|
||||||
<th><%= t("admin.budget_groups.name") %></th>
|
|
||||||
<th><%= Budget::Group.human_attribute_name(:max_votable_headings) %></th>
|
|
||||||
<th><%= t("admin.budget_groups.headings_name") %></th>
|
|
||||||
<th><%= t("admin.actions.actions") %></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @groups.each do |group| %>
|
|
||||||
<tr id="<%= dom_id(group) %>">
|
|
||||||
<td><%= group.name %></td>
|
|
||||||
<td><%= group.max_votable_headings %></td>
|
|
||||||
<td><%= group.headings.count %></td>
|
|
||||||
<td>
|
|
||||||
<%= render Admin::TableActionsComponent.new(group) do |actions| %>
|
|
||||||
<%= actions.link_to t("admin.budget_groups.headings_manage"),
|
|
||||||
admin_budget_group_headings_path(@budget, group),
|
|
||||||
class: "headings-link" %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% else %>
|
|
||||||
<div class="callout primary clear">
|
|
||||||
<%= t("admin.budget_groups.no_groups") %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<%= render "header", action: "create" %>
|
<%= render "header", action: "create" %>
|
||||||
|
|
||||||
<%= render "form", path: admin_budget_groups_path(@budget), action: "create" %>
|
<%= render "form", group: @group, path: admin_budget_groups_path(@budget), action: "create" %>
|
||||||
|
|||||||
@@ -1,25 +1,20 @@
|
|||||||
<%= render "shared/globalize_locales", resource: @heading %>
|
<%= translatable_form_for heading, url: path, html: { class: "budget-headings-form" } do |f| %>
|
||||||
|
<%= render "shared/globalize_locales", resource: heading %>
|
||||||
|
|
||||||
<%= translatable_form_for [:admin, @budget, @group, @heading], url: path do |f| %>
|
<%= render "shared/errors", resource: heading %>
|
||||||
|
|
||||||
<%= render "shared/errors", resource: @heading %>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<%= f.translatable_fields do |translations_form| %>
|
<%= f.translatable_fields do |translations_form| %>
|
||||||
<div class="small-12 medium-6 column end">
|
<div class="small-12 medium-6 column end">
|
||||||
<%= translations_form.text_field :name, maxlength: 50 %>
|
<%= translations_form.text_field :name, maxlength: 50 %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="small-12 medium-6">
|
||||||
<div class="small-12 medium-6 column">
|
|
||||||
<%= f.text_field :price, maxlength: 8 %>
|
<%= f.text_field :price, maxlength: 8 %>
|
||||||
|
|
||||||
<% if @heading.budget.approval_voting? %>
|
<% if heading.budget.approval_voting? %>
|
||||||
<%= f.number_field :max_ballot_lines,
|
<%= f.number_field :max_ballot_lines,
|
||||||
hint: t("admin.budget_headings.form.max_ballot_lines_info") %>
|
hint: t("admin.budget_headings.form.max_ballot_lines_info") %>
|
||||||
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= f.text_field :population,
|
<%= f.text_field :population,
|
||||||
@@ -37,8 +32,9 @@
|
|||||||
<p class="help-text" id="budgets-content-blocks-help-text">
|
<p class="help-text" id="budgets-content-blocks-help-text">
|
||||||
<%= t("admin.budget_headings.form.content_blocks_info") %>
|
<%= t("admin.budget_headings.form.content_blocks_info") %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<%= f.submit t("admin.budget_headings.form.#{action}"), class: "button success" %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="clear">
|
||||||
|
<%= f.submit t("admin.budget_headings.form.#{action}"), class: "button hollow" %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<%= render "header", action: "edit" %>
|
<%= render "header", action: "edit" %>
|
||||||
|
|
||||||
<%= render "form", path: admin_budget_group_heading_path(@budget, @group, @heading), action: "submit" %>
|
<%= render "form", heading: @heading, path: admin_budget_group_heading_path(@budget, @group, @heading), action: "submit" %>
|
||||||
|
|||||||
@@ -1,48 +1,9 @@
|
|||||||
<%= back_link_to admin_budget_groups_path(@budget), t("admin.budget_headings.index.back") %>
|
<%= back_link_to admin_budget_groups_path(@budget), t("admin.budget_headings.index.back") %>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h2><%= "#{@budget.name} / #{@group.name}" %></h2>
|
<h2><%= t("admin.budget_headings.index.title", budget: @budget.name, group: @group.name) %></h2>
|
||||||
<%= link_to t("admin.budget_headings.form.create"), new_admin_budget_group_heading_path %>
|
<%= link_to t("admin.budget_headings.form.create"), new_admin_budget_group_heading_path %>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<%= render Admin::Budgets::HelpComponent.new("budget_headings") %>
|
<%= render Admin::Budgets::HelpComponent.new("budget_headings") %>
|
||||||
|
<%= render Admin::BudgetHeadings::HeadingsComponent.new(@headings) %>
|
||||||
<% if @headings.any? %>
|
|
||||||
<h3><%= t("admin.budget_headings.amount", count: @headings.count) %></h3>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr id="<%= dom_id(@group) %>">
|
|
||||||
<th><%= Budget::Heading.human_attribute_name(:name) %></th>
|
|
||||||
<th><%= Budget::Heading.human_attribute_name(:price) %></th>
|
|
||||||
<% if @budget.approval_voting? %>
|
|
||||||
<th><%= Budget::Heading.human_attribute_name(:max_ballot_lines) %></th>
|
|
||||||
<% end %>
|
|
||||||
<th><%= Budget::Heading.human_attribute_name(:population) %></th>
|
|
||||||
<th><%= Budget::Heading.human_attribute_name(:allow_custom_content) %></th>
|
|
||||||
<th><%= t("admin.actions.actions") %></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @headings.each do |heading| %>
|
|
||||||
<tr id="<%= dom_id(heading) %>" class="heading">
|
|
||||||
<td><%= heading.name %></td>
|
|
||||||
<td><%= @budget.formatted_heading_price(heading) %></td>
|
|
||||||
<% if @budget.approval_voting? %>
|
|
||||||
<td><%= heading.max_ballot_lines %></td>
|
|
||||||
<% end %>
|
|
||||||
<td><%= heading.population %></td>
|
|
||||||
<td>
|
|
||||||
<%= heading.allow_custom_content ? t("admin.shared.true_value") : t("admin.shared.false_value") %>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<%= render Admin::TableActionsComponent.new(heading) %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% else %>
|
|
||||||
<div class="callout primary clear">
|
|
||||||
<%= t("admin.budget_headings.no_headings") %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<%= render "header", action: "create" %>
|
<%= render "header", action: "create" %>
|
||||||
|
|
||||||
<%= render "form", path: admin_budget_group_headings_path(@budget, @group), action: "create" %>
|
<%= render "form", heading: @heading, path: admin_budget_group_headings_path(@budget, @group), action: "create" %>
|
||||||
|
|||||||
@@ -1,49 +1 @@
|
|||||||
<%= render "shared/globalize_locales", resource: @phase %>
|
<%= render Admin::BudgetPhases::FormComponent.new(@phase) %>
|
||||||
|
|
||||||
<%= translatable_form_for [:admin, @phase.budget, @phase], html: { class: "budget-phases-form" } do |f| %>
|
|
||||||
|
|
||||||
<%= render "shared/errors", resource: @phase %>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend aria-describedby="phase_duration_description">
|
|
||||||
<%= t("admin.budget_phases.edit.duration") %>
|
|
||||||
</legend>
|
|
||||||
|
|
||||||
<p class="help-text" id="phase_duration_description">
|
|
||||||
<%= t("admin.budget_phases.edit.duration_description") %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="date-field">
|
|
||||||
<%= f.date_field :starts_at, id: "start_date" %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="date-field">
|
|
||||||
<%= f.date_field :ends_at, id: "end_date" %>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<div class="small-12 column margin">
|
|
||||||
<%= f.check_box :enabled %>
|
|
||||||
|
|
||||||
<span class="help-text" id="phase-summary-help-text">
|
|
||||||
<%= t("admin.budget_phases.edit.enabled_help_text") %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%= f.translatable_fields do |translations_form| %>
|
|
||||||
<div class="small-12 column">
|
|
||||||
<%= translations_form.text_field :name, hint: t("admin.budget_phases.edit.name_help_text") %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="small-12 column">
|
|
||||||
<%= translations_form.text_area :description,
|
|
||||||
maxlength: Budget::Phase::DESCRIPTION_MAX_LENGTH,
|
|
||||||
class: "html-area",
|
|
||||||
hint: t("admin.budget_phases.edit.description_help_text") %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="small-12 column">
|
|
||||||
<%= f.submit t("admin.budget_phases.edit.save_changes"), class: "button success" %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|||||||
@@ -1,5 +1 @@
|
|||||||
<%= back_link_to edit_admin_budget_path(@phase.budget) %>
|
<%= render Admin::BudgetsWizard::Phases::EditComponent.new(@phase) %>
|
||||||
|
|
||||||
<h2><%= t("admin.budgets.edit.title") %> - <%= @phase.name %></h2>
|
|
||||||
|
|
||||||
<%= render "/admin/budget_phases/form" %>
|
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
<%= render Admin::Budgets::DraftingComponent.new(@budget) %>
|
<%= render Admin::Budgets::DraftingComponent.new(@budget) %>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<%= render "/admin/budgets/form" %>
|
<%= render Admin::Budgets::FormComponent.new(@budget) %>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
<%= back_link_to admin_budgets_path %>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<h2><%= t("admin.budgets.new.title") %></h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<%= render "/admin/budgets/form" %>
|
|
||||||
1
app/views/admin/budgets_wizard/budgets/edit.html.erb
Normal file
1
app/views/admin/budgets_wizard/budgets/edit.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Budgets::EditComponent.new(@budget) %>
|
||||||
1
app/views/admin/budgets_wizard/budgets/new.html.erb
Normal file
1
app/views/admin/budgets_wizard/budgets/new.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Budgets::NewComponent.new(@budget) %>
|
||||||
1
app/views/admin/budgets_wizard/groups/edit.html.erb
Normal file
1
app/views/admin/budgets_wizard/groups/edit.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Groups::EditComponent.new(@group) %>
|
||||||
1
app/views/admin/budgets_wizard/groups/index.html.erb
Normal file
1
app/views/admin/budgets_wizard/groups/index.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Groups::IndexComponent.new(@groups, @group) %>
|
||||||
1
app/views/admin/budgets_wizard/headings/edit.html.erb
Normal file
1
app/views/admin/budgets_wizard/headings/edit.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Headings::EditComponent.new(@heading) %>
|
||||||
1
app/views/admin/budgets_wizard/headings/index.html.erb
Normal file
1
app/views/admin/budgets_wizard/headings/index.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Headings::IndexComponent.new(@headings, @heading) %>
|
||||||
1
app/views/admin/budgets_wizard/phases/edit.html.erb
Normal file
1
app/views/admin/budgets_wizard/phases/edit.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Phases::EditComponent.new(@phase) %>
|
||||||
1
app/views/admin/budgets_wizard/phases/index.html.erb
Normal file
1
app/views/admin/budgets_wizard/phases/index.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::BudgetsWizard::Phases::IndexComponent.new(@budget) %>
|
||||||
@@ -147,6 +147,9 @@ ignore_unused:
|
|||||||
- "admin.hidden_proposal_notifications.index.filter*"
|
- "admin.hidden_proposal_notifications.index.filter*"
|
||||||
- "admin.budgets.index.filter*"
|
- "admin.budgets.index.filter*"
|
||||||
- "admin.budgets.edit.(administrators|valuators).*"
|
- "admin.budgets.edit.(administrators|valuators).*"
|
||||||
|
- "admin.budget_groups.index.*.help_block"
|
||||||
|
- "admin.budget_headings.index.*.help_block"
|
||||||
|
- "admin.budget_phases.index.help_block"
|
||||||
- "admin.budget_investments.index.filter*"
|
- "admin.budget_investments.index.filter*"
|
||||||
- "admin.organizations.index.filter*"
|
- "admin.organizations.index.filter*"
|
||||||
- "admin.hidden_users.index.filter*"
|
- "admin.hidden_users.index.filter*"
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ en:
|
|||||||
latitude: "Latitude (optional)"
|
latitude: "Latitude (optional)"
|
||||||
longitude: "Longitude (optional)"
|
longitude: "Longitude (optional)"
|
||||||
name: "Heading name"
|
name: "Heading name"
|
||||||
price: "Amount"
|
price: "Money amount"
|
||||||
population: "Population (optional)"
|
population: "Population (optional)"
|
||||||
max_ballot_lines: "Votes allowed"
|
max_ballot_lines: "Votes allowed"
|
||||||
budget/heading/translation:
|
budget/heading/translation:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ en:
|
|||||||
edit: Edit
|
edit: Edit
|
||||||
configure: Configure
|
configure: Configure
|
||||||
delete: Delete
|
delete: Delete
|
||||||
|
confirm_delete: "Are you sure? This action will delete %{resource_name} '%{name}' and can't be undone."
|
||||||
officing_booth:
|
officing_booth:
|
||||||
title: "You are officing the booth located at %{booth}. If this is not correct, do not continue and call the help phone number. Thank you."
|
title: "You are officing the booth located at %{booth}. If this is not correct, do not continue and call the help phone number. Thank you."
|
||||||
banners:
|
banners:
|
||||||
@@ -106,6 +107,7 @@ en:
|
|||||||
enabled: Enabled
|
enabled: Enabled
|
||||||
actions: Actions
|
actions: Actions
|
||||||
edit_phase: Edit phase
|
edit_phase: Edit phase
|
||||||
|
enable_phase: "Enable %{phase} phase"
|
||||||
active: Active
|
active: Active
|
||||||
blank_dates: Dates are blank
|
blank_dates: Dates are blank
|
||||||
administrators:
|
administrators:
|
||||||
@@ -133,6 +135,8 @@ en:
|
|||||||
calculate: Calculate Winner Investments
|
calculate: Calculate Winner Investments
|
||||||
calculated: Winners being calculated, it may take a minute.
|
calculated: Winners being calculated, it may take a minute.
|
||||||
recalculate: Recalculate Winner Investments
|
recalculate: Recalculate Winner Investments
|
||||||
|
shared:
|
||||||
|
resource_name: "the budget"
|
||||||
budget_groups:
|
budget_groups:
|
||||||
name: "Name"
|
name: "Name"
|
||||||
headings_name: "Headings"
|
headings_name: "Headings"
|
||||||
@@ -156,6 +160,7 @@ en:
|
|||||||
index:
|
index:
|
||||||
back: "Go back to budgets"
|
back: "Go back to budgets"
|
||||||
help: "Groups are meant to organize headings. After a group is created and it contais headings, it's possible to determine in how many headings a user can vote per group."
|
help: "Groups are meant to organize headings. After a group is created and it contais headings, it's possible to determine in how many headings a user can vote per group."
|
||||||
|
new_button: "Add new group"
|
||||||
budget_headings:
|
budget_headings:
|
||||||
no_headings: "There are no headings."
|
no_headings: "There are no headings."
|
||||||
amount:
|
amount:
|
||||||
@@ -176,11 +181,18 @@ en:
|
|||||||
create: "Create new heading"
|
create: "Create new heading"
|
||||||
edit: "Edit heading"
|
edit: "Edit heading"
|
||||||
submit: "Save heading"
|
submit: "Save heading"
|
||||||
|
group_switcher:
|
||||||
|
currently_showing: "Showing headings from the %{group} group."
|
||||||
|
different_group: "Manage headings from a different group"
|
||||||
|
the_other_group: "Manage headings from the %{group} group."
|
||||||
index:
|
index:
|
||||||
back: "Go back to groups"
|
back: "Go back to groups"
|
||||||
help: "Headings are meant to divide the money of the participatory budget. Here you can add headings for this group and assign the amount of money that will be used for each heading."
|
help: "Headings are meant to divide the money of the participatory budget. Here you can add headings for this group and assign the amount of money that will be used for each heading."
|
||||||
|
new_button: "Add new heading"
|
||||||
|
title: "%{budget} / %{group} headings"
|
||||||
budget_phases:
|
budget_phases:
|
||||||
edit:
|
edit:
|
||||||
|
title: "Edit phase"
|
||||||
description_help_text: This text will appear in the header when the phase is active
|
description_help_text: This text will appear in the header when the phase is active
|
||||||
duration: "Phase's duration"
|
duration: "Phase's duration"
|
||||||
duration_description: "The period of time this phase will be active."
|
duration_description: "The period of time this phase will be active."
|
||||||
@@ -189,6 +201,7 @@ en:
|
|||||||
save_changes: Save changes
|
save_changes: Save changes
|
||||||
index:
|
index:
|
||||||
help: "Participatory budgets have different phases. Here you can enable or disable phases and also customize each individual phase."
|
help: "Participatory budgets have different phases. Here you can enable or disable phases and also customize each individual phase."
|
||||||
|
title: "%{budget} phases"
|
||||||
budget_investments:
|
budget_investments:
|
||||||
index:
|
index:
|
||||||
heading_filter_all: All headings
|
heading_filter_all: All headings
|
||||||
@@ -284,6 +297,24 @@ en:
|
|||||||
tags_placeholder: "Write the tags you want separated by commas (,)"
|
tags_placeholder: "Write the tags you want separated by commas (,)"
|
||||||
undefined: Undefined
|
undefined: Undefined
|
||||||
search_unfeasible: Search unfeasible
|
search_unfeasible: Search unfeasible
|
||||||
|
budgets_wizard:
|
||||||
|
creation_timeline:
|
||||||
|
budget: Budget
|
||||||
|
groups: Groups
|
||||||
|
headings: Headings
|
||||||
|
phases: Phases
|
||||||
|
budgets:
|
||||||
|
continue: "Continue to groups"
|
||||||
|
groups:
|
||||||
|
back: "Go back to edit budget"
|
||||||
|
continue: "Continue to headings"
|
||||||
|
headings:
|
||||||
|
continue: "Continue to phases"
|
||||||
|
phases:
|
||||||
|
back: "Go back to headings"
|
||||||
|
continue: "Finish"
|
||||||
|
update_all:
|
||||||
|
notice: "Phases configured successfully"
|
||||||
milestones:
|
milestones:
|
||||||
index:
|
index:
|
||||||
table_id: "ID"
|
table_id: "ID"
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ es:
|
|||||||
latitude: "Latitud (opcional)"
|
latitude: "Latitud (opcional)"
|
||||||
longitude: "Longitud (opcional)"
|
longitude: "Longitud (opcional)"
|
||||||
name: "Nombre de la partida"
|
name: "Nombre de la partida"
|
||||||
price: "Cantidad"
|
price: "Cantidad de dinero"
|
||||||
population: "Población (opcional)"
|
population: "Población (opcional)"
|
||||||
max_ballot_lines: "Votos permitidos"
|
max_ballot_lines: "Votos permitidos"
|
||||||
budget/heading/translation:
|
budget/heading/translation:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ es:
|
|||||||
unmark_featured: Quitar destacado
|
unmark_featured: Quitar destacado
|
||||||
edit: Editar
|
edit: Editar
|
||||||
configure: Configurar
|
configure: Configurar
|
||||||
|
confirm_delete: "¿Estás seguro? Esta acción borrará %{resource_name} '%{name}' y no se puede deshacer."
|
||||||
delete: Borrar
|
delete: Borrar
|
||||||
officing_booth:
|
officing_booth:
|
||||||
title: "Estás ahora mismo en la mesa ubicada en %{booth}. Si esto no es correcto no sigas adelante y llama al teléfono de incidencias. Gracias."
|
title: "Estás ahora mismo en la mesa ubicada en %{booth}. Si esto no es correcto no sigas adelante y llama al teléfono de incidencias. Gracias."
|
||||||
@@ -106,6 +107,7 @@ es:
|
|||||||
enabled: Habilitada
|
enabled: Habilitada
|
||||||
actions: Acciones
|
actions: Acciones
|
||||||
edit_phase: Editar fase
|
edit_phase: Editar fase
|
||||||
|
enable_phase: "Habilitar fase de %{phase}"
|
||||||
active: Activa
|
active: Activa
|
||||||
blank_dates: Sin fechas
|
blank_dates: Sin fechas
|
||||||
administrators:
|
administrators:
|
||||||
@@ -133,6 +135,8 @@ es:
|
|||||||
calculate: Calcular proyectos ganadores
|
calculate: Calcular proyectos ganadores
|
||||||
calculated: Calculando ganadores, puede tardar un minuto.
|
calculated: Calculando ganadores, puede tardar un minuto.
|
||||||
recalculate: Recalcular proyectos ganadores
|
recalculate: Recalcular proyectos ganadores
|
||||||
|
shared:
|
||||||
|
resource_name: "el presupuesto"
|
||||||
budget_groups:
|
budget_groups:
|
||||||
name: "Nombre"
|
name: "Nombre"
|
||||||
headings_name: "Partidas"
|
headings_name: "Partidas"
|
||||||
@@ -156,6 +160,7 @@ es:
|
|||||||
index:
|
index:
|
||||||
back: "Volver a presupuestos"
|
back: "Volver a presupuestos"
|
||||||
help: "Los grupos sirven para organizar las partidas del presupuesto. Después de que un grupo sea creado y éste contenga partidas, es posible determinar el número de partidas a las que un usuario puede votar por grupo."
|
help: "Los grupos sirven para organizar las partidas del presupuesto. Después de que un grupo sea creado y éste contenga partidas, es posible determinar el número de partidas a las que un usuario puede votar por grupo."
|
||||||
|
new_button: "Añadir un grupo nuevo"
|
||||||
budget_headings:
|
budget_headings:
|
||||||
no_headings: "No hay partidas."
|
no_headings: "No hay partidas."
|
||||||
amount:
|
amount:
|
||||||
@@ -176,9 +181,15 @@ es:
|
|||||||
create: "Crear nueva partida"
|
create: "Crear nueva partida"
|
||||||
edit: "Editar partida"
|
edit: "Editar partida"
|
||||||
submit: "Guardar partida"
|
submit: "Guardar partida"
|
||||||
|
group_switcher:
|
||||||
|
currently_showing: "Mostrando las partidas del grupo: %{group}"
|
||||||
|
different_group: "Ir a partidas de otro grupo"
|
||||||
|
the_other_group: "Ir a partidas del grupo %{group}."
|
||||||
index:
|
index:
|
||||||
back: "Volver a grupos"
|
back: "Volver a grupos"
|
||||||
help: "Las partidas sirven para dividir el dinero del presupuesto participativo. Aquí puedes ir añadiendo partidas para cada grupo y establecer la cantidad de dinero que se gastará en cada partida."
|
help: "Las partidas sirven para dividir el dinero del presupuesto participativo. Aquí puedes ir añadiendo partidas para cada grupo y establecer la cantidad de dinero que se gastará en cada partida."
|
||||||
|
new_button: "Añadir una partida nueva"
|
||||||
|
title: "Partidas de %{budget} / %{group}"
|
||||||
budget_phases:
|
budget_phases:
|
||||||
edit:
|
edit:
|
||||||
description_help_text: Este texto aparecerá en la cabecera cuando la fase esté activa
|
description_help_text: Este texto aparecerá en la cabecera cuando la fase esté activa
|
||||||
@@ -187,8 +198,10 @@ es:
|
|||||||
enabled_help_text: Esta fase será pública en el calendario de fases del presupuesto y estará activa para otros propósitos
|
enabled_help_text: Esta fase será pública en el calendario de fases del presupuesto y estará activa para otros propósitos
|
||||||
name_help_text: "Este es el título de la fase que los usuarios leerán en el encabezado cuando la fase esté activa."
|
name_help_text: "Este es el título de la fase que los usuarios leerán en el encabezado cuando la fase esté activa."
|
||||||
save_changes: Guardar cambios
|
save_changes: Guardar cambios
|
||||||
|
title: "Editar fase"
|
||||||
index:
|
index:
|
||||||
help: "Los presupuestos participativos tienen distintas fases. Aquí puedes habilitar o deshabilitar fases y también personalizar cada una de las fases."
|
help: "Los presupuestos participativos tienen distintas fases. Aquí puedes habilitar o deshabilitar fases y también personalizar cada una de las fases."
|
||||||
|
title: "Fases de %{budget}"
|
||||||
budget_investments:
|
budget_investments:
|
||||||
index:
|
index:
|
||||||
heading_filter_all: Todas las partidas
|
heading_filter_all: Todas las partidas
|
||||||
@@ -284,6 +297,24 @@ es:
|
|||||||
tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)"
|
tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)"
|
||||||
undefined: Sin definir
|
undefined: Sin definir
|
||||||
search_unfeasible: Buscar inviables
|
search_unfeasible: Buscar inviables
|
||||||
|
budgets_wizard:
|
||||||
|
creation_timeline:
|
||||||
|
budget: Presupuesto
|
||||||
|
groups: Grupos
|
||||||
|
headings: Partidas
|
||||||
|
phases: Fases
|
||||||
|
budgets:
|
||||||
|
continue: "Continuar a grupos"
|
||||||
|
groups:
|
||||||
|
back: "Volver a editar presupuesto"
|
||||||
|
continue: "Continuar a partidas"
|
||||||
|
headings:
|
||||||
|
continue: "Continuar a fases"
|
||||||
|
phases:
|
||||||
|
back: "Volver a partidas"
|
||||||
|
continue: "Finalizar"
|
||||||
|
update_all:
|
||||||
|
notice: "Fases configuradas con éxito"
|
||||||
milestones:
|
milestones:
|
||||||
index:
|
index:
|
||||||
table_id: "ID"
|
table_id: "ID"
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace :admin do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :budgets do
|
resources :budgets, except: [:create, :new] do
|
||||||
member do
|
member do
|
||||||
patch :publish
|
patch :publish
|
||||||
put :calculate_winners
|
put :calculate_winners
|
||||||
@@ -72,6 +72,18 @@ namespace :admin do
|
|||||||
resources :budget_phases, only: [:edit, :update]
|
resources :budget_phases, only: [:edit, :update]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
namespace :budgets_wizard do
|
||||||
|
resources :budgets, only: [:create, :new, :edit, :update] do
|
||||||
|
resources :groups, only: [:index, :create, :edit, :update, :destroy] do
|
||||||
|
resources :headings, only: [:index, :create, :edit, :update, :destroy]
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :phases, as: "budget_phases", only: [:index, :edit, :update] do
|
||||||
|
collection { patch :update_all }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
resources :milestone_statuses, only: [:index, :new, :create, :update, :edit, :destroy]
|
resources :milestone_statuses, only: [:index, :new, :create, :update, :edit, :destroy]
|
||||||
|
|
||||||
resources :signature_sheets, only: [:index, :new, :create, :show]
|
resources :signature_sheets, only: [:index, :new, :create, :show]
|
||||||
|
|||||||
16
spec/components/admin/budgets/form_component_spec.rb
Normal file
16
spec/components/admin/budgets/form_component_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::Budgets::FormComponent, type: :component do
|
||||||
|
describe "#voting_styles_select_options" do
|
||||||
|
it "provides vote kinds" do
|
||||||
|
types = [
|
||||||
|
["Knapsack", "knapsack"],
|
||||||
|
["Approval", "approval"]
|
||||||
|
]
|
||||||
|
|
||||||
|
component = Admin::Budgets::FormComponent.new(double)
|
||||||
|
|
||||||
|
expect(component.voting_styles_select_options).to eq(types)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -8,15 +8,16 @@ describe Admin::Budgets::TableActionsComponent, type: :component do
|
|||||||
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
|
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders links to edit budget, manage investments and edit groups and manage ballots" do
|
it "renders links to edit and delete budget, manage investments and edit groups and manage ballots" do
|
||||||
render_inline component
|
render_inline component
|
||||||
|
|
||||||
expect(page).to have_css "a", count: 5
|
expect(page).to have_css "a", count: 6
|
||||||
expect(page).to have_link "Manage projects", href: /investments/
|
expect(page).to have_link "Manage projects", href: /investments/
|
||||||
expect(page).to have_link "Edit headings groups", href: /groups/
|
expect(page).to have_link "Edit headings groups", href: /groups/
|
||||||
expect(page).to have_link "Edit budget", href: /edit/
|
expect(page).to have_link "Edit budget", href: /edit/
|
||||||
expect(page).to have_link "Admin ballots"
|
expect(page).to have_link "Admin ballots"
|
||||||
expect(page).to have_link "Preview budget", href: /budgets/
|
expect(page).to have_link "Preview budget", href: /budgets/
|
||||||
|
expect(page).to have_link "Delete", href: /budgets/
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders link to create new poll for budgets without polls" do
|
it "renders link to create new poll for budgets without polls" do
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::BudgetsWizard::Headings::GroupSwitcherComponent, type: :component do
|
||||||
|
it "is not rendered for budgets with one group" do
|
||||||
|
group = create(:budget_group, budget: create(:budget))
|
||||||
|
|
||||||
|
render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
|
||||||
|
|
||||||
|
expect(page.text).to be_empty
|
||||||
|
expect(page).not_to have_css ".budget-group-switcher"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a link to switch group for budgets with two groups" do
|
||||||
|
budget = create(:budget)
|
||||||
|
group = create(:budget_group, budget: budget, name: "Parks")
|
||||||
|
create(:budget_group, budget: budget, name: "Recreation")
|
||||||
|
|
||||||
|
render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
|
||||||
|
|
||||||
|
expect(page).to have_content "Showing headings from the Parks group"
|
||||||
|
expect(page).to have_link "Manage headings from the Recreation group."
|
||||||
|
expect(page).not_to have_css "ul"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a menu to switch group for budgets with more than two groups" do
|
||||||
|
budget = create(:budget)
|
||||||
|
group = create(:budget_group, budget: budget, name: "Parks")
|
||||||
|
create(:budget_group, budget: budget, name: "Recreation")
|
||||||
|
create(:budget_group, budget: budget, name: "Entertainment")
|
||||||
|
|
||||||
|
render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
|
||||||
|
|
||||||
|
expect(page).to have_content "Showing headings from the Parks group"
|
||||||
|
expect(page).to have_button "Manage headings from a different group"
|
||||||
|
|
||||||
|
within "button + ul" do
|
||||||
|
expect(page).to have_link "Recreation"
|
||||||
|
expect(page).to have_link "Entertainment"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
require "rails_helper"
|
|
||||||
|
|
||||||
describe BudgetsHelper do
|
|
||||||
describe "#budget_voting_styles_select_options" do
|
|
||||||
it "provides vote kinds" do
|
|
||||||
types = [
|
|
||||||
["Knapsack", "knapsack"],
|
|
||||||
["Approval", "approval"]
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(budget_voting_styles_select_options).to eq(types)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -129,6 +129,25 @@ describe "Admin budget groups", :admin do
|
|||||||
expect(page).to have_field "Maximum number of headings in which a user can select projects", with: "2"
|
expect(page).to have_field "Maximum number of headings in which a user can select projects", with: "2"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Select for maxium number of headings to select projects" do
|
||||||
|
scenario "is present if there are headings in the group" do
|
||||||
|
group = create(:budget_group, budget: budget)
|
||||||
|
create(:budget_heading, group: group)
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_path(budget, group)
|
||||||
|
|
||||||
|
expect(page).to have_field "Maximum number of headings in which a user can select projects"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "is not present if there are no headings in the group" do
|
||||||
|
group = create(:budget_group, budget: budget)
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_path(budget, group)
|
||||||
|
|
||||||
|
expect(page).not_to have_field "Maximum number of headings in which a user can select projects"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
scenario "Changing name for current locale will update the slug if budget is in draft phase" do
|
scenario "Changing name for current locale will update the slug if budget is in draft phase" do
|
||||||
group = create(:budget_group, budget: budget, name: "Old English Name")
|
group = create(:budget_group, budget: budget, name: "Old English Name")
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ describe "Admin budget headings", :admin do
|
|||||||
click_link "Create new heading"
|
click_link "Create new heading"
|
||||||
|
|
||||||
fill_in "Heading name", with: "All City"
|
fill_in "Heading name", with: "All City"
|
||||||
fill_in "Amount", with: "1000"
|
fill_in "Money amount", with: "1000"
|
||||||
fill_in "Population (optional)", with: "10000"
|
fill_in "Population (optional)", with: "10000"
|
||||||
check "Allow content block"
|
check "Allow content block"
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ describe "Admin budget headings", :admin do
|
|||||||
click_button "Create new heading"
|
click_button "Create new heading"
|
||||||
|
|
||||||
expect(page).not_to have_content "Heading created successfully!"
|
expect(page).not_to have_content "Heading created successfully!"
|
||||||
expect(page).to have_css(".is-invalid-label", text: "Amount")
|
expect(page).to have_css(".is-invalid-label", text: "Money amount")
|
||||||
expect(page).to have_content "can't be blank"
|
expect(page).to have_content "can't be blank"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ describe "Admin budget headings", :admin do
|
|||||||
expect(page).to have_field "Votes allowed", with: 1
|
expect(page).to have_field "Votes allowed", with: 1
|
||||||
|
|
||||||
fill_in "Heading name", with: "All City"
|
fill_in "Heading name", with: "All City"
|
||||||
fill_in "Amount", with: "1000"
|
fill_in "Money amount", with: "1000"
|
||||||
fill_in "Votes allowed", with: 14
|
fill_in "Votes allowed", with: 14
|
||||||
click_button "Create new heading"
|
click_button "Create new heading"
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ describe "Admin budget headings", :admin do
|
|||||||
within("#budget_heading_#{heading.id}") { click_link "Edit" }
|
within("#budget_heading_#{heading.id}") { click_link "Edit" }
|
||||||
|
|
||||||
expect(page).to have_field "Heading name", with: heading.name
|
expect(page).to have_field "Heading name", with: heading.name
|
||||||
expect(page).to have_field "Amount", with: heading.price
|
expect(page).to have_field "Money amount", with: heading.price
|
||||||
expect(page).to have_field "Population (optional)", with: heading.population
|
expect(page).to have_field "Population (optional)", with: heading.population
|
||||||
expect(page).to have_field "Longitude (optional)", with: heading.longitude
|
expect(page).to have_field "Longitude (optional)", with: heading.longitude
|
||||||
expect(page).to have_field "Latitude (optional)", with: heading.latitude
|
expect(page).to have_field "Latitude (optional)", with: heading.latitude
|
||||||
@@ -204,14 +204,14 @@ describe "Admin budget headings", :admin do
|
|||||||
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
||||||
|
|
||||||
expect(page).to have_field "Heading name", with: "All City"
|
expect(page).to have_field "Heading name", with: "All City"
|
||||||
expect(page).to have_field "Amount", with: 1000
|
expect(page).to have_field "Money amount", with: 1000
|
||||||
expect(page).to have_field "Population (optional)", with: 10000
|
expect(page).to have_field "Population (optional)", with: 10000
|
||||||
expect(page).to have_field "Longitude (optional)", with: 20.50
|
expect(page).to have_field "Longitude (optional)", with: 20.50
|
||||||
expect(page).to have_field "Latitude (optional)", with: -10.50
|
expect(page).to have_field "Latitude (optional)", with: -10.50
|
||||||
expect(find_field("Allow content block")).to be_checked
|
expect(find_field("Allow content block")).to be_checked
|
||||||
|
|
||||||
fill_in "Heading name", with: "Districts"
|
fill_in "Heading name", with: "Districts"
|
||||||
fill_in "Amount", with: "2000"
|
fill_in "Money amount", with: "2000"
|
||||||
fill_in "Population (optional)", with: "20000"
|
fill_in "Population (optional)", with: "20000"
|
||||||
fill_in "Longitude (optional)", with: "-40.47"
|
fill_in "Longitude (optional)", with: "-40.47"
|
||||||
fill_in "Latitude (optional)", with: "25.25"
|
fill_in "Latitude (optional)", with: "25.25"
|
||||||
@@ -222,7 +222,7 @@ describe "Admin budget headings", :admin do
|
|||||||
|
|
||||||
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
||||||
expect(page).to have_field "Heading name", with: "Districts"
|
expect(page).to have_field "Heading name", with: "Districts"
|
||||||
expect(page).to have_field "Amount", with: 2000
|
expect(page).to have_field "Money amount", with: 2000
|
||||||
expect(page).to have_field "Population (optional)", with: 20000
|
expect(page).to have_field "Population (optional)", with: 20000
|
||||||
expect(page).to have_field "Longitude (optional)", with: -40.47
|
expect(page).to have_field "Longitude (optional)", with: -40.47
|
||||||
expect(page).to have_field "Latitude (optional)", with: 25.25
|
expect(page).to have_field "Latitude (optional)", with: 25.25
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe "Admin budget phases" do
|
|||||||
within("tr", text: "Accepting projects") { click_link "Edit phase" }
|
within("tr", text: "Accepting projects") { click_link "Edit phase" }
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_css "h2", exact_text: "Edit Participatory budget - Accepting projects"
|
expect(page).to have_css "h2", exact_text: "Edit phase - Accepting projects"
|
||||||
|
|
||||||
fill_in "Name", with: "My phase custom name"
|
fill_in "Name", with: "My phase custom name"
|
||||||
click_button "Save changes"
|
click_button "Save changes"
|
||||||
|
|||||||
@@ -82,87 +82,21 @@ describe "Admin budgets", :admin do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context "New" do
|
scenario "Delete budget from index" do
|
||||||
scenario "Create budget - Knapsack voting (default)" do
|
create(:budget, name: "To be deleted")
|
||||||
visit admin_budgets_path
|
|
||||||
click_link "Create new budget"
|
|
||||||
|
|
||||||
fill_in "Name", with: "M30 - Summer campaign"
|
|
||||||
select "Accepting projects", from: "budget[phase]"
|
|
||||||
|
|
||||||
click_button "Create Budget"
|
|
||||||
|
|
||||||
expect(page).to have_content "New participatory budget created successfully!"
|
|
||||||
expect(page).to have_field "Name", with: "M30 - Summer campaign"
|
|
||||||
expect(page).to have_select "Final voting style", selected: "Knapsack"
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Create budget - Approval voting" do
|
|
||||||
admin = Administrator.first
|
|
||||||
|
|
||||||
visit admin_budgets_path
|
visit admin_budgets_path
|
||||||
click_link "Create new budget"
|
|
||||||
|
|
||||||
fill_in "Name", with: "M30 - Summer campaign"
|
within "tr", text: "To be deleted" do
|
||||||
select "Accepting projects", from: "budget[phase]"
|
message = "Are you sure? This action will delete the budget 'To be deleted' and can't be undone."
|
||||||
select "Approval", from: "Final voting style"
|
|
||||||
click_button "Create Budget"
|
|
||||||
|
|
||||||
expect(page).to have_content "New participatory budget created successfully!"
|
accept_confirm(message) { click_link "Delete" }
|
||||||
expect(page).to have_field "Name", with: "M30 - Summer campaign"
|
|
||||||
expect(page).to have_select "Final voting style", selected: "Approval"
|
|
||||||
|
|
||||||
click_link "Select administrators"
|
|
||||||
|
|
||||||
expect(page).to have_field admin.name
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Name is mandatory" do
|
expect(page).to have_content("Budget deleted successfully")
|
||||||
visit new_admin_budget_path
|
expect(page).to have_content("There are no budgets.")
|
||||||
click_button "Create Budget"
|
expect(page).not_to have_content "To be deleted"
|
||||||
|
|
||||||
expect(page).not_to have_content "New participatory budget created successfully!"
|
|
||||||
expect(page).to have_css(".is-invalid-label", text: "Name")
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Name should be unique" do
|
|
||||||
create(:budget, name: "Existing Name")
|
|
||||||
|
|
||||||
visit new_admin_budget_path
|
|
||||||
fill_in "Name", with: "Existing Name"
|
|
||||||
click_button "Create Budget"
|
|
||||||
|
|
||||||
expect(page).not_to have_content "New participatory budget created successfully!"
|
|
||||||
expect(page).to have_css(".is-invalid-label", text: "Name")
|
|
||||||
expect(page).to have_css("small.form-error", text: "has already been taken")
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Do not show results and stats settings on new budget" do
|
|
||||||
visit new_admin_budget_path
|
|
||||||
|
|
||||||
expect(page).not_to have_content "Show results and stats"
|
|
||||||
expect(page).not_to have_field "Show results"
|
|
||||||
expect(page).not_to have_field "Show stats"
|
|
||||||
expect(page).not_to have_field "Show advanced stats"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "Create" do
|
|
||||||
scenario "A new budget is always created in draft mode" do
|
|
||||||
visit admin_budgets_path
|
|
||||||
click_link "Create new budget"
|
|
||||||
|
|
||||||
fill_in "Name", with: "M30 - Summer campaign"
|
|
||||||
select "Accepting projects", from: "budget[phase]"
|
|
||||||
|
|
||||||
click_button "Create Budget"
|
|
||||||
|
|
||||||
expect(page).to have_content "New participatory budget created successfully!"
|
|
||||||
expect(page).to have_content "This participatory budget is in draft mode"
|
|
||||||
expect(page).to have_link "Preview budget"
|
|
||||||
expect(page).to have_link "Publish budget"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -197,8 +131,7 @@ describe "Admin budgets", :admin do
|
|||||||
let(:heading) { create(:budget_heading, budget: budget) }
|
let(:heading) { create(:budget_heading, budget: budget) }
|
||||||
|
|
||||||
scenario "Destroy a budget without investments" do
|
scenario "Destroy a budget without investments" do
|
||||||
visit admin_budgets_path
|
visit edit_admin_budget_path(budget)
|
||||||
click_link "Edit budget"
|
|
||||||
click_link "Delete budget"
|
click_link "Delete budget"
|
||||||
|
|
||||||
expect(page).to have_content("Budget deleted successfully")
|
expect(page).to have_content("Budget deleted successfully")
|
||||||
@@ -209,8 +142,7 @@ describe "Admin budgets", :admin do
|
|||||||
budget.administrators << Administrator.first
|
budget.administrators << Administrator.first
|
||||||
budget.valuators << create(:valuator)
|
budget.valuators << create(:valuator)
|
||||||
|
|
||||||
visit admin_budgets_path
|
visit edit_admin_budget_path(budget)
|
||||||
click_link "Edit budget"
|
|
||||||
click_link "Delete budget"
|
click_link "Delete budget"
|
||||||
|
|
||||||
expect(page).to have_content "Budget deleted successfully"
|
expect(page).to have_content "Budget deleted successfully"
|
||||||
@@ -220,8 +152,7 @@ describe "Admin budgets", :admin do
|
|||||||
scenario "Try to destroy a budget with investments" do
|
scenario "Try to destroy a budget with investments" do
|
||||||
create(:budget_investment, heading: heading)
|
create(:budget_investment, heading: heading)
|
||||||
|
|
||||||
visit admin_budgets_path
|
visit edit_admin_budget_path(budget)
|
||||||
click_link "Edit budget"
|
|
||||||
click_link "Delete budget"
|
click_link "Delete budget"
|
||||||
|
|
||||||
expect(page).to have_content("You cannot delete a budget that has associated investments")
|
expect(page).to have_content("You cannot delete a budget that has associated investments")
|
||||||
|
|||||||
132
spec/system/admin/budgets_wizard/budgets_spec.rb
Normal file
132
spec/system/admin/budgets_wizard/budgets_spec.rb
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe "Budgets wizard, first step", :admin do
|
||||||
|
describe "New" do
|
||||||
|
scenario "Create budget - Knapsack voting (default)" do
|
||||||
|
visit admin_budgets_path
|
||||||
|
click_link "Create new budget"
|
||||||
|
|
||||||
|
fill_in "Name", with: "M30 - Summer campaign"
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_content "New participatory budget created successfully!"
|
||||||
|
|
||||||
|
click_link "Go back to edit budget"
|
||||||
|
|
||||||
|
expect(page).to have_field "Name", with: "M30 - Summer campaign"
|
||||||
|
expect(page).to have_select "Final voting style", selected: "Knapsack"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Create budget - Approval voting" do
|
||||||
|
admin = Administrator.first
|
||||||
|
|
||||||
|
visit admin_budgets_path
|
||||||
|
click_link "Create new budget"
|
||||||
|
|
||||||
|
fill_in "Name", with: "M30 - Summer campaign"
|
||||||
|
select "Approval", from: "Final voting style"
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_content "New participatory budget created successfully!"
|
||||||
|
|
||||||
|
click_link "Go back to edit budget"
|
||||||
|
|
||||||
|
expect(page).to have_field "Name", with: "M30 - Summer campaign"
|
||||||
|
expect(page).to have_select "Final voting style", selected: "Approval"
|
||||||
|
|
||||||
|
click_link "Select administrators"
|
||||||
|
|
||||||
|
expect(page).to have_field admin.name
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Submit the form with errors" do
|
||||||
|
visit new_admin_budgets_wizard_budget_path
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "New participatory budget created successfully!"
|
||||||
|
expect(page).to have_css ".is-invalid-label", text: "Name"
|
||||||
|
expect(page).to have_css ".creation-timeline"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Name should be unique" do
|
||||||
|
create(:budget, name: "Existing Name")
|
||||||
|
|
||||||
|
visit new_admin_budgets_wizard_budget_path
|
||||||
|
fill_in "Name", with: "Existing Name"
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "New participatory budget created successfully!"
|
||||||
|
expect(page).to have_css(".is-invalid-label", text: "Name")
|
||||||
|
expect(page).to have_css("small.form-error", text: "has already been taken")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Do not show results and stats settings on new budget" do
|
||||||
|
visit new_admin_budgets_wizard_budget_path
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Show results and stats"
|
||||||
|
expect(page).not_to have_field "Show results"
|
||||||
|
expect(page).not_to have_field "Show stats"
|
||||||
|
expect(page).not_to have_field "Show advanced stats"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Create" do
|
||||||
|
scenario "A new budget is always created in draft mode" do
|
||||||
|
visit admin_budgets_path
|
||||||
|
click_link "Create new budget"
|
||||||
|
|
||||||
|
fill_in "Name", with: "M30 - Summer campaign"
|
||||||
|
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_content "New participatory budget created successfully!"
|
||||||
|
|
||||||
|
within("#side_menu") { click_link "Participatory budgets" }
|
||||||
|
within("tr", text: "M30 - Summer campaign") { click_link "Edit budget" }
|
||||||
|
|
||||||
|
expect(page).to have_content "This participatory budget is in draft mode"
|
||||||
|
expect(page).to have_link "Preview budget"
|
||||||
|
expect(page).to have_link "Publish budget"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Edit" do
|
||||||
|
scenario "update budget" do
|
||||||
|
budget = create(:budget, name: "Budget wiht typo")
|
||||||
|
|
||||||
|
visit admin_budgets_wizard_budget_groups_path(budget)
|
||||||
|
|
||||||
|
click_link "Go back to edit budget"
|
||||||
|
|
||||||
|
expect(page).to have_content "Edit Participatory budget"
|
||||||
|
expect(page).to have_css ".creation-timeline"
|
||||||
|
expect(page).to have_field "Name", with: "Budget wiht typo"
|
||||||
|
|
||||||
|
fill_in "Name", with: "Budget without typos"
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_content "Participatory budget updated successfully"
|
||||||
|
expect(page).to have_content "Budget without typos"
|
||||||
|
expect(page).to have_css ".creation-timeline"
|
||||||
|
expect(page).to have_content "There are no groups"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "submit the form with errors and then without errors" do
|
||||||
|
budget = create(:budget, name: "Budget wiht typo")
|
||||||
|
|
||||||
|
visit edit_admin_budgets_wizard_budget_path(budget)
|
||||||
|
fill_in "Name", with: ""
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_css "#error_explanation"
|
||||||
|
|
||||||
|
fill_in "Name", with: "Budget without typos"
|
||||||
|
click_button "Continue to groups"
|
||||||
|
|
||||||
|
expect(page).to have_content "Participatory budget updated successfully"
|
||||||
|
expect(page).to have_content "Budget without typos"
|
||||||
|
expect(page).to have_css ".creation-timeline"
|
||||||
|
expect(page).to have_content "There are no groups"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user