diff --git a/app/assets/images/budgets/budget_multiple_heading_icon.png b/app/assets/images/budgets/budget_multiple_heading_icon.png new file mode 100644 index 000000000..14a3ec1eb Binary files /dev/null and b/app/assets/images/budgets/budget_multiple_heading_icon.png differ diff --git a/app/assets/images/budgets/budget_single_heading_icon.png b/app/assets/images/budgets/budget_single_heading_icon.png new file mode 100644 index 000000000..2a1f72e35 Binary files /dev/null and b/app/assets/images/budgets/budget_single_heading_icon.png differ diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index fbb7a3176..a634ecf07 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -665,7 +665,8 @@ code { display: flex; flex-wrap: wrap; - a { + a, + button { @include regular-button; margin-left: auto; } diff --git a/app/assets/stylesheets/admin/budgets/heading_mode.scss b/app/assets/stylesheets/admin/budgets/heading_mode.scss new file mode 100644 index 000000000..d3ee8eadd --- /dev/null +++ b/app/assets/stylesheets/admin/budgets/heading_mode.scss @@ -0,0 +1,77 @@ +.admin .heading-mode { + border-radius: rem-calc(12); + color: $admin-text; + display: flex; + flex-wrap: wrap; + max-width: $global-width * 0.6; + width: 100%; + + section { + @include grid-column-gutter; + display: flex; + flex-flow: column; + margin-bottom: $line-height; + width: 100%; + + @include breakpoint(medium) { + width: 50%; + + &:last-of-type { + border-left: $admin-border; + } + } + + &.single-heading-option h2::after { + content: image-url("budgets/budget_single_heading_icon.png"); + } + + &.multiple-heading-option h2::after { + content: image-url("budgets/budget_multiple_heading_icon.png"); + } + + h2::after { + display: block; + text-align: center; + } + } + + h1 { + margin-bottom: $line-height * 2; + margin-top: $line-height; + text-transform: uppercase; + width: 100%; + } + + h1, + h2 { + font-size: rem-calc(24); + text-align: center; + } + + h2 { + font-weight: 500; + padding-top: $line-height; + } + + p { + font-size: $small-font-size; + font-style: italic; + flex: 1; + } + + a { + @include hollow-button; + margin: 0 auto; + max-width: max-content; + } + + .close-button { + border: 3px solid $admin-text; + border-radius: 50%; + color: $admin-text; + font-size: rem-calc(23); + font-weight: bold; + height: rem-calc(30); + width: rem-calc(30); + } +} diff --git a/app/components/admin/budget_phases/form_component.html.erb b/app/components/admin/budget_phases/form_component.html.erb index e8e0822c0..3fcaab81c 100644 --- a/app/components/admin/budget_phases/form_component.html.erb +++ b/app/components/admin/budget_phases/form_component.html.erb @@ -4,6 +4,8 @@ <%= render "shared/errors", resource: phase %> + <%= render Admin::BudgetsWizard::ModelFieldComponent.new %> +
<%= t("admin.budget_phases.edit.duration") %> diff --git a/app/components/admin/budget_phases/phases_component.html.erb b/app/components/admin/budget_phases/phases_component.html.erb index 787508634..836ca925e 100644 --- a/app/components/admin/budget_phases/phases_component.html.erb +++ b/app/components/admin/budget_phases/phases_component.html.erb @@ -31,6 +31,7 @@ <%= render Admin::TableActionsComponent.new(phase, actions: [:edit], + edit_path: edit_path(phase), edit_text: t("admin.budgets.edit.edit_phase") ) %> diff --git a/app/components/admin/budget_phases/phases_component.rb b/app/components/admin/budget_phases/phases_component.rb index 25a2d0280..383f46c53 100644 --- a/app/components/admin/budget_phases/phases_component.rb +++ b/app/components/admin/budget_phases/phases_component.rb @@ -37,4 +37,10 @@ class Admin::BudgetPhases::PhasesComponent < ApplicationComponent tag.span t("shared.no"), class: "budget-phase-disabled" end end + + def edit_path(phase) + if helpers.respond_to?(:single_heading?) && helpers.single_heading? + edit_admin_budgets_wizard_budget_budget_phase_path(budget, phase, helpers.url_params) + end + end end diff --git a/app/components/admin/budgets/duration_component.rb b/app/components/admin/budgets/duration_component.rb index 3e7a80207..177845928 100644 --- a/app/components/admin/budgets/duration_component.rb +++ b/app/components/admin/budgets/duration_component.rb @@ -24,6 +24,6 @@ class Admin::Budgets::DurationComponent < ApplicationComponent end def formatted_date(time) - time_tag(time, format: :datetime) + time_tag(time, format: :short_datetime) end end diff --git a/app/components/admin/budgets/form_component.html.erb b/app/components/admin/budgets/form_component.html.erb index 12464d641..6000b586d 100644 --- a/app/components/admin/budgets/form_component.html.erb +++ b/app/components/admin/budgets/form_component.html.erb @@ -1,4 +1,6 @@ <%= translatable_form_for [namespace, budget], html: { class: "budgets-form" } do |f| %> + <%= render Admin::BudgetsWizard::ModelFieldComponent.new %> +
<%= t("admin.budgets.edit.info.budget_settings") %> <%= render "shared/globalize_locales", resource: budget %> diff --git a/app/components/admin/budgets/heading_mode_component.html.erb b/app/components/admin/budgets/heading_mode_component.html.erb new file mode 100644 index 000000000..3e8e0f7be --- /dev/null +++ b/app/components/admin/budgets/heading_mode_component.html.erb @@ -0,0 +1,17 @@ +
+

<%= t("#{i18n_namespace}.title") %>

+ + <% modes.each do |mode| %> +
+

<%= sanitize(t("#{i18n_namespace}.#{mode}.title")) %>

+

<%= t("#{i18n_namespace}.#{mode}.description") %>

+ <%= link_to t("#{i18n_namespace}.#{mode}.link"), + new_admin_budgets_wizard_budget_path(mode: mode), data: { close: "" } %> +
+ <% end %> + + +
diff --git a/app/components/admin/budgets/heading_mode_component.rb b/app/components/admin/budgets/heading_mode_component.rb new file mode 100644 index 000000000..00cfea5bb --- /dev/null +++ b/app/components/admin/budgets/heading_mode_component.rb @@ -0,0 +1,11 @@ +class Admin::Budgets::HeadingModeComponent < ApplicationComponent + private + + def i18n_namespace + "admin.budgets_wizard.heading_mode" + end + + def modes + %w[single multiple] + end +end diff --git a/app/components/admin/budgets/help_component.rb b/app/components/admin/budgets/help_component.rb index ecde7a43d..bd47604d4 100644 --- a/app/components/admin/budgets/help_component.rb +++ b/app/components/admin/budgets/help_component.rb @@ -5,9 +5,17 @@ class Admin::Budgets::HelpComponent < ApplicationComponent @i18n_namespace = i18n_namespace end + def budget_mode + (helpers.budget_mode if helpers.respond_to?(:budget_mode)) || "multiple" + end + private def text - t("admin.#{i18n_namespace}.index.help") + if t("admin.budgets.help.#{i18n_namespace}").is_a?(Hash) + t("admin.budgets.help.#{i18n_namespace}.#{budget_mode}") + else + t("admin.budgets.help.#{i18n_namespace}") + end end end diff --git a/app/components/admin/budgets/index_component.html.erb b/app/components/admin/budgets/index_component.html.erb index 35e6fce7f..fa4d60d4b 100644 --- a/app/components/admin/budgets/index_component.html.erb +++ b/app/components/admin/budgets/index_component.html.erb @@ -1,7 +1,8 @@ <%= header do %> - <%= link_to t("admin.budgets.index.new_link"), new_admin_budgets_wizard_budget_path %> + <% end %> +<%= render Admin::Budgets::HeadingModeComponent.new %> <%= render Admin::Budgets::HelpComponent.new("budgets") %> <%= render "shared/filter_subnav", i18n_namespace: "admin.budgets.index" %> @@ -13,6 +14,7 @@ <%= t("admin.budgets.index.table_name") %> <%= t("admin.budgets.index.table_phase") %> + <%= t("admin.budgets.index.table_budget_type") %> <%= t("admin.budgets.index.table_duration") %> <%= t("admin.actions.actions") %> @@ -28,6 +30,7 @@ <%= budget.current_phase.name %> <%= phase_progress_text(budget) %> + <%= type(budget) %> <%= dates(budget) %> <%= duration(budget) %> diff --git a/app/components/admin/budgets/index_component.rb b/app/components/admin/budgets/index_component.rb index 58203a206..53f1d5d6f 100644 --- a/app/components/admin/budgets/index_component.rb +++ b/app/components/admin/budgets/index_component.rb @@ -26,6 +26,16 @@ class Admin::Budgets::IndexComponent < ApplicationComponent budget.phases.enabled.order(:id).pluck(:kind).index(budget.phase) || -1 end + def type(budget) + if budget.single_heading? + t("admin.budgets.index.type_single") + elsif budget.headings.blank? + t("admin.budgets.index.type_pending") + else + t("admin.budgets.index.type_multiple") + end + end + def dates(budget) Admin::Budgets::DurationComponent.new(budget).dates end diff --git a/app/components/admin/budgets_wizard/base_component.rb b/app/components/admin/budgets_wizard/base_component.rb new file mode 100644 index 000000000..b2aba71cd --- /dev/null +++ b/app/components/admin/budgets_wizard/base_component.rb @@ -0,0 +1,7 @@ +class Admin::BudgetsWizard::BaseComponent < ApplicationComponent + delegate :single_heading?, :url_params, to: :helpers + + def budget_mode + helpers.budget_mode || "multiple" + end +end diff --git a/app/components/admin/budgets_wizard/budgets/new_component.html.erb b/app/components/admin/budgets_wizard/budgets/new_component.html.erb index 672f3e8ca..f5c54c957 100644 --- a/app/components/admin/budgets_wizard/budgets/new_component.html.erb +++ b/app/components/admin/budgets_wizard/budgets/new_component.html.erb @@ -2,5 +2,6 @@ <%= header %> +<%= render Admin::Budgets::HelpComponent.new("budgets") %> <%= render Admin::BudgetsWizard::CreationTimelineComponent.new("budget") %> <%= render Admin::Budgets::FormComponent.new(budget, wizard: true) %> diff --git a/app/components/admin/budgets_wizard/budgets/new_component.rb b/app/components/admin/budgets_wizard/budgets/new_component.rb index 09502de89..38fbb9bfa 100644 --- a/app/components/admin/budgets_wizard/budgets/new_component.rb +++ b/app/components/admin/budgets_wizard/budgets/new_component.rb @@ -1,12 +1,17 @@ class Admin::BudgetsWizard::Budgets::NewComponent < ApplicationComponent include Header attr_reader :budget + delegate :single_heading?, to: :helpers def initialize(budget) @budget = budget end def title - t("admin.budgets.new.title") + if single_heading? + t("admin.budgets.new.title_single") + else + t("admin.budgets.new.title_multiple") + end end end diff --git a/app/components/admin/budgets_wizard/creation_step_component.html.erb b/app/components/admin/budgets_wizard/creation_step_component.html.erb index b6ecad267..b42ce98e5 100644 --- a/app/components/admin/budgets_wizard/creation_step_component.html.erb +++ b/app/components/admin/budgets_wizard/creation_step_component.html.erb @@ -1,19 +1,23 @@
- - - <%= content %> - - - - <% if next_step_path %> - <%= link_to t("admin.budgets_wizard.#{i18n_namespace}.continue"), - next_step_path, - class: "next-step" %> + <% if single_heading? %> + <%= content %> <% else %> -

- <%= t("admin.budgets_wizard.#{i18n_namespace}.continue") %> -

+ + + <%= content %> + + + + <% if next_step_path %> + <%= link_to t("admin.budgets_wizard.#{i18n_namespace}.continue"), + next_step_path, + class: "next-step" %> + <% else %> +

+ <%= t("admin.budgets_wizard.#{i18n_namespace}.continue") %> +

+ <% end %> <% end %>
diff --git a/app/components/admin/budgets_wizard/creation_step_component.rb b/app/components/admin/budgets_wizard/creation_step_component.rb index 2bd220146..575ac11e1 100644 --- a/app/components/admin/budgets_wizard/creation_step_component.rb +++ b/app/components/admin/budgets_wizard/creation_step_component.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::CreationStepComponent < ApplicationComponent +class Admin::BudgetsWizard::CreationStepComponent < Admin::BudgetsWizard::BaseComponent attr_reader :record, :next_step_path def initialize(record, next_step_path) diff --git a/app/components/admin/budgets_wizard/groups/creation_step_component.rb b/app/components/admin/budgets_wizard/groups/creation_step_component.rb index 8a5e3bfa9..f2faeea77 100644 --- a/app/components/admin/budgets_wizard/groups/creation_step_component.rb +++ b/app/components/admin/budgets_wizard/groups/creation_step_component.rb @@ -13,7 +13,11 @@ class Admin::BudgetsWizard::Groups::CreationStepComponent < ApplicationComponent end def form_path - admin_budgets_wizard_budget_groups_path(budget) + if group.persisted? + admin_budgets_wizard_budget_group_path(budget, group) + else + admin_budgets_wizard_budget_groups_path(budget) + end end def next_step_path diff --git a/app/components/admin/budgets_wizard/groups/index_component.html.erb b/app/components/admin/budgets_wizard/groups/index_component.html.erb index 04a0059aa..d9b859b3a 100644 --- a/app/components/admin/budgets_wizard/groups/index_component.html.erb +++ b/app/components/admin/budgets_wizard/groups/index_component.html.erb @@ -2,8 +2,10 @@ <%= header %> -<%= render Admin::Budgets::HelpComponent.new("budget_groups") %> +<%= render Admin::Budgets::HelpComponent.new("groups") %> <%= render Admin::BudgetsWizard::CreationTimelineComponent.new("groups") %> -<%= render Admin::BudgetGroups::GroupsComponent.new(groups) %> +<% unless single_heading? %> + <%= render Admin::BudgetGroups::GroupsComponent.new(groups) %> +<% end %> <%= render Admin::BudgetsWizard::Groups::CreationStepComponent.new(new_group, groups.first) %> diff --git a/app/components/admin/budgets_wizard/groups/index_component.rb b/app/components/admin/budgets_wizard/groups/index_component.rb index d15414e54..5c9b206b1 100644 --- a/app/components/admin/budgets_wizard/groups/index_component.rb +++ b/app/components/admin/budgets_wizard/groups/index_component.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::Groups::IndexComponent < ApplicationComponent +class Admin::BudgetsWizard::Groups::IndexComponent < Admin::BudgetsWizard::BaseComponent include Header attr_reader :groups, :new_group diff --git a/app/components/admin/budgets_wizard/headings/creation_step_component.rb b/app/components/admin/budgets_wizard/headings/creation_step_component.rb index 6c07c6670..cd8e0ada1 100644 --- a/app/components/admin/budgets_wizard/headings/creation_step_component.rb +++ b/app/components/admin/budgets_wizard/headings/creation_step_component.rb @@ -12,7 +12,11 @@ class Admin::BudgetsWizard::Headings::CreationStepComponent < ApplicationCompone end def form_path - admin_budgets_wizard_budget_group_headings_path(heading.group.budget, heading.group) + if heading.persisted? + admin_budgets_wizard_budget_group_heading_path(heading.group.budget, heading.group, heading) + else + admin_budgets_wizard_budget_group_headings_path(heading.group.budget, heading.group) + end end def next_step_path diff --git a/app/components/admin/budgets_wizard/headings/index_component.html.erb b/app/components/admin/budgets_wizard/headings/index_component.html.erb index 21e0d538d..211f74d63 100644 --- a/app/components/admin/budgets_wizard/headings/index_component.html.erb +++ b/app/components/admin/budgets_wizard/headings/index_component.html.erb @@ -1,10 +1,12 @@ -<%= back_link_to admin_budgets_wizard_budget_groups_path(budget), t("admin.budget_headings.index.back") %> +<%= back_link_to admin_budgets_wizard_budget_groups_path(budget, url_params), back_link_text %> <%= header %> -<%= render Admin::Budgets::HelpComponent.new("budget_headings") %> +<%= render Admin::Budgets::HelpComponent.new("headings") %> <%= render Admin::BudgetsWizard::CreationTimelineComponent.new("headings") %> -<%= render Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group) %> -<%= render Admin::BudgetHeadings::HeadingsComponent.new(headings) %> +<% unless single_heading? %> + <%= render Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group) %> + <%= render Admin::BudgetHeadings::HeadingsComponent.new(headings) %> +<% end %> <%= render Admin::BudgetsWizard::Headings::CreationStepComponent.new(new_heading) %> diff --git a/app/components/admin/budgets_wizard/headings/index_component.rb b/app/components/admin/budgets_wizard/headings/index_component.rb index 76aa584a9..f789a00e8 100644 --- a/app/components/admin/budgets_wizard/headings/index_component.rb +++ b/app/components/admin/budgets_wizard/headings/index_component.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::Headings::IndexComponent < ApplicationComponent +class Admin::BudgetsWizard::Headings::IndexComponent < Admin::BudgetsWizard::BaseComponent include Header attr_reader :headings, :new_heading @@ -18,4 +18,12 @@ class Admin::BudgetsWizard::Headings::IndexComponent < ApplicationComponent def title t("admin.budget_headings.index.title", budget: budget.name, group: group.name) end + + def back_link_text + if single_heading? + t("admin.budgets_wizard.headings.single.back") + else + t("admin.budget_headings.index.back") + end + end end diff --git a/app/components/admin/budgets_wizard/model_field_component.html.erb b/app/components/admin/budgets_wizard/model_field_component.html.erb new file mode 100644 index 000000000..f862d30b7 --- /dev/null +++ b/app/components/admin/budgets_wizard/model_field_component.html.erb @@ -0,0 +1 @@ +<%= hidden_field_tag(:mode, helpers.budget_mode) if helpers.respond_to?(:budget_mode) %> diff --git a/app/components/admin/budgets_wizard/model_field_component.rb b/app/components/admin/budgets_wizard/model_field_component.rb new file mode 100644 index 000000000..adb2d32ad --- /dev/null +++ b/app/components/admin/budgets_wizard/model_field_component.rb @@ -0,0 +1,2 @@ +class Admin::BudgetsWizard::ModelFieldComponent < ApplicationComponent +end diff --git a/app/components/admin/budgets_wizard/phases/index_component.html.erb b/app/components/admin/budgets_wizard/phases/index_component.html.erb index a97812cfb..e0cf8c9b7 100644 --- a/app/components/admin/budgets_wizard/phases/index_component.html.erb +++ b/app/components/admin/budgets_wizard/phases/index_component.html.erb @@ -1,8 +1,8 @@ -<%= back_link_to back_link_path, t("admin.budgets_wizard.phases.back") %> +<%= back_link_to back_link_path, back_link_text %> <%= header %> -<%= render Admin::Budgets::HelpComponent.new("budget_phases") %> +<%= render Admin::Budgets::HelpComponent.new("phases") %> <%= render Admin::BudgetsWizard::CreationTimelineComponent.new("phases") %> <%= form_for budget, url: update_all_admin_budgets_wizard_budget_budget_phases_path(budget) do |f| %> diff --git a/app/components/admin/budgets_wizard/phases/index_component.rb b/app/components/admin/budgets_wizard/phases/index_component.rb index a1b680003..b0236804f 100644 --- a/app/components/admin/budgets_wizard/phases/index_component.rb +++ b/app/components/admin/budgets_wizard/phases/index_component.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::Phases::IndexComponent < ApplicationComponent +class Admin::BudgetsWizard::Phases::IndexComponent < Admin::BudgetsWizard::BaseComponent include Header attr_reader :budget @@ -13,6 +13,10 @@ class Admin::BudgetsWizard::Phases::IndexComponent < ApplicationComponent private def back_link_path - admin_budgets_wizard_budget_group_headings_path(budget, budget.groups.first) + admin_budgets_wizard_budget_group_headings_path(budget, budget.groups.first, url_params) + end + + def back_link_text + t("admin.budgets_wizard.phases.#{budget_mode}.back") end end diff --git a/app/controllers/admin/budgets_wizard/base_controller.rb b/app/controllers/admin/budgets_wizard/base_controller.rb new file mode 100644 index 000000000..d8798c8e7 --- /dev/null +++ b/app/controllers/admin/budgets_wizard/base_controller.rb @@ -0,0 +1,17 @@ +class Admin::BudgetsWizard::BaseController < Admin::BaseController + helper_method :budget_mode, :single_heading?, :url_params + + private + + def budget_mode + params[:mode] + end + + def single_heading? + budget_mode == "single" + end + + def url_params + budget_mode.present? ? { mode: budget_mode } : {} + end +end diff --git a/app/controllers/admin/budgets_wizard/budgets_controller.rb b/app/controllers/admin/budgets_wizard/budgets_controller.rb index 68e590dec..e3efe9739 100644 --- a/app/controllers/admin/budgets_wizard/budgets_controller.rb +++ b/app/controllers/admin/budgets_wizard/budgets_controller.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::BudgetsController < Admin::BaseController +class Admin::BudgetsWizard::BudgetsController < Admin::BudgetsWizard::BaseController include Translatable include ImageAttributes include FeatureFlags @@ -44,6 +44,6 @@ class Admin::BudgetsWizard::BudgetsController < Admin::BaseController end def groups_index - admin_budgets_wizard_budget_groups_path(@budget) + admin_budgets_wizard_budget_groups_path(@budget, url_params) end end diff --git a/app/controllers/admin/budgets_wizard/groups_controller.rb b/app/controllers/admin/budgets_wizard/groups_controller.rb index 4d8c8895c..b8d180a64 100644 --- a/app/controllers/admin/budgets_wizard/groups_controller.rb +++ b/app/controllers/admin/budgets_wizard/groups_controller.rb @@ -1,16 +1,24 @@ -class Admin::BudgetsWizard::GroupsController < Admin::BaseController +class Admin::BudgetsWizard::GroupsController < Admin::BudgetsWizard::BaseController include Admin::BudgetGroupsActions before_action :load_groups, only: [:index, :create] def index - @group = @budget.groups.new + if single_heading? + @group = @budget.groups.first_or_initialize("name_#{I18n.locale}" => @budget.name) + else + @group = @budget.groups.new + end end private def groups_index - admin_budgets_wizard_budget_groups_path(@budget) + if single_heading? + admin_budgets_wizard_budget_group_headings_path(@budget, @group, url_params) + else + admin_budgets_wizard_budget_groups_path(@budget, url_params) + end end def new_action diff --git a/app/controllers/admin/budgets_wizard/headings_controller.rb b/app/controllers/admin/budgets_wizard/headings_controller.rb index 5eb78e5d3..3b4ee532f 100644 --- a/app/controllers/admin/budgets_wizard/headings_controller.rb +++ b/app/controllers/admin/budgets_wizard/headings_controller.rb @@ -1,16 +1,24 @@ -class Admin::BudgetsWizard::HeadingsController < Admin::BaseController +class Admin::BudgetsWizard::HeadingsController < Admin::BudgetsWizard::BaseController include Admin::BudgetHeadingsActions before_action :load_headings, only: [:index, :create] def index - @heading = @group.headings.new + if single_heading? + @heading = @group.headings.first_or_initialize + else + @heading = @group.headings.new + end end private def headings_index - admin_budgets_wizard_budget_group_headings_path(@budget, @group) + if single_heading? + admin_budgets_wizard_budget_budget_phases_path(@budget, url_params) + else + admin_budgets_wizard_budget_group_headings_path(@budget, @group, url_params) + end end def new_action diff --git a/app/controllers/admin/budgets_wizard/phases_controller.rb b/app/controllers/admin/budgets_wizard/phases_controller.rb index 5376e93b7..59903c3b5 100644 --- a/app/controllers/admin/budgets_wizard/phases_controller.rb +++ b/app/controllers/admin/budgets_wizard/phases_controller.rb @@ -1,4 +1,4 @@ -class Admin::BudgetsWizard::PhasesController < Admin::BaseController +class Admin::BudgetsWizard::PhasesController < Admin::BudgetsWizard::BaseController include Admin::BudgetPhasesActions def index @@ -13,7 +13,7 @@ class Admin::BudgetsWizard::PhasesController < Admin::BaseController private def phases_index - admin_budgets_wizard_budget_budget_phases_path(@phase.budget) + admin_budgets_wizard_budget_budget_phases_path(@phase.budget, url_params) end def phases_params diff --git a/app/models/budget.rb b/app/models/budget.rb index f17b38f59..a1ee86954 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -162,6 +162,10 @@ class Budget < ApplicationRecord current_phase&.balloting_or_later? end + def single_heading? + groups.one? && headings.one? + end + def heading_price(heading) heading_ids.include?(heading.id) ? heading.price : -1 end diff --git a/app/views/admin/budget_groups/_form.html.erb b/app/views/admin/budget_groups/_form.html.erb index 5e86059c0..4c70672cf 100644 --- a/app/views/admin/budget_groups/_form.html.erb +++ b/app/views/admin/budget_groups/_form.html.erb @@ -3,6 +3,8 @@ <%= render "shared/errors", resource: group %> + <%= render Admin::BudgetsWizard::ModelFieldComponent.new %> + <%= f.translatable_fields do |translations_form| %>
<%= translations_form.text_field :name, maxlength: 50 %> @@ -18,6 +20,10 @@ <% end %>
- <%= f.submit t("admin.budget_groups.form.#{action}"), class: "button hollow" %> + <% if respond_to?(:single_heading?) && single_heading? %> + <%= f.submit t("admin.budgets_wizard.groups.continue"), class: "button success" %> + <% else %> + <%= f.submit t("admin.budget_groups.form.#{action}"), class: "button hollow" %> + <% end %>
<% end %> diff --git a/app/views/admin/budget_groups/index.html.erb b/app/views/admin/budget_groups/index.html.erb index f89d3ee20..dbddbab42 100644 --- a/app/views/admin/budget_groups/index.html.erb +++ b/app/views/admin/budget_groups/index.html.erb @@ -7,5 +7,5 @@ <%= link_to t("admin.budget_groups.form.create"), new_admin_budget_group_path %> -<%= render Admin::Budgets::HelpComponent.new("budget_groups") %> +<%= render Admin::Budgets::HelpComponent.new("groups") %> <%= render Admin::BudgetGroups::GroupsComponent.new(@groups) %> diff --git a/app/views/admin/budget_headings/_form.html.erb b/app/views/admin/budget_headings/_form.html.erb index f1424bb10..ba8110542 100644 --- a/app/views/admin/budget_headings/_form.html.erb +++ b/app/views/admin/budget_headings/_form.html.erb @@ -3,6 +3,8 @@ <%= render "shared/errors", resource: heading %> + <%= render Admin::BudgetsWizard::ModelFieldComponent.new %> + <%= f.translatable_fields do |translations_form| %>
<%= translations_form.text_field :name, maxlength: 50 %> @@ -35,6 +37,10 @@
- <%= f.submit t("admin.budget_headings.form.#{action}"), class: "button hollow" %> + <% if respond_to?(:single_heading?) && single_heading? %> + <%= f.submit t("admin.budgets_wizard.headings.continue"), class: "button success" %> + <% else %> + <%= f.submit t("admin.budget_headings.form.#{action}"), class: "button hollow" %> + <% end %>
<% end %> diff --git a/app/views/admin/budget_headings/index.html.erb b/app/views/admin/budget_headings/index.html.erb index 48bfb4c9e..fcc2b9886 100644 --- a/app/views/admin/budget_headings/index.html.erb +++ b/app/views/admin/budget_headings/index.html.erb @@ -5,5 +5,5 @@ <%= link_to t("admin.budget_headings.form.create"), new_admin_budget_group_heading_path %> -<%= render Admin::Budgets::HelpComponent.new("budget_headings") %> +<%= render Admin::Budgets::HelpComponent.new("headings") %> <%= render Admin::BudgetHeadings::HeadingsComponent.new(@headings) %> diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 97bb35653..aa6a54f0a 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -147,10 +147,9 @@ ignore_unused: - "admin.hidden_proposal_notifications.index.filter*" - "admin.budgets.index.filter*" - "admin.budgets.edit.(administrators|valuators).*" - - "admin.budget_groups.index.*.help_block" - - "admin.budget_headings.index.*.help_block" - - "admin.budget_phases.index.help_block" + - "admin.budgets.help.*" - "admin.budget_investments.index.filter*" + - "admin.budgets_wizard.heading_mode.*" - "admin.organizations.index.filter*" - "admin.hidden_users.index.filter*" - "admin.hidden_budget_investments.index.filter*" diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index 5539f91b0..5b12917fd 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -155,7 +155,7 @@ en: description_balloting: "Description during Balloting phase" description_reviewing_ballots: "Description during Reviewing Ballots phase" description_finished: "Description when the budget is finished" - phase: "Phase" + phase: "Active phase" currency_symbol: "Currency" voting_style: "Final voting style" voting_style_knapsack: "Knapsack" diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index b6d1329b3..647ad90fd 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -78,14 +78,17 @@ en: all: All open: Open finished: Finished - help: "Participatory budgets allow citizens to propose and decide directly how to spend part of the budget, with monitoring and rigorous evaluation of proposals by the institution." budget_investments: Manage projects + table_budget_type: "Type" table_completed: Completed table_draft: "Draft" table_duration: "Duration" table_name: Name table_phase: Phase table_phase_progress: "(%{current_phase_number}/%{total_phases})" + type_multiple: "Multiple headings" + type_pending: "Pending: No headings yet" + type_single: "Single heading" edit_groups: Edit headings groups edit_budget: Edit budget admin_ballots: Admin ballots @@ -133,7 +136,17 @@ en: unable_notice: You cannot delete a budget that has associated investments unable_notice_polls: You cannot delete a budget that has an associated poll new: - title: New participatory budget + title_multiple: New multiple headings budget + title_single: New single heading budget + help: + budgets: "Participatory budgets allow citizens to propose and decide directly how to spend part of the budget, with monitoring and rigorous evaluation of proposals by the institution." + groups: + multiple: "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." + single: "Groups are meant to organize headings, since this budget will only contain one heading, the same name can be used because it will not appear anywhere. You can just continue with the next step." + headings: + multiple: "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." + single: "Headings are meant to divide the money of the participatory budget. Since this budget will only contain one heading, this is the place where you stablish the money that will be spent in this participaroty budget." + phases: "Participatory budgets have different phases. Here you can enable or disable phases and also customize each individual phase." winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. @@ -162,7 +175,6 @@ en: submit: "Save group" index: 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." new_button: "Add new group" budget_headings: no_headings: "There are no headings." @@ -190,7 +202,6 @@ en: the_other_group: "Manage headings from the %{group} group." index: 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." new_button: "Add new heading" title: "%{budget} / %{group} headings" budget_phases: @@ -206,7 +217,6 @@ en: name_help_text: "This is the title of the phase users will read on the header whenever this phase is active." save_changes: Save changes index: - help: "Participatory budgets have different phases. Here you can enable or disable phases and also customize each individual phase." title: "%{budget} phases" budget_investments: index: @@ -316,9 +326,24 @@ en: continue: "Continue to headings" headings: continue: "Continue to phases" + single: + back: "Go back to edit group" + heading_mode: + multiple: + description: "Create a process with multiple groups, districts or topics. You have something like several bags of money. For example, 25,000€ for \"North District\", 30,000€ for \"Center District\", 28,000€ for \"South District\" and the whole city. Or for several themes like sport, culture or health." + link: "Create multiple headings budget" + title: "Multiple headings budget" + single: + description: "Create a process with a group, district or topic. You have something like a bag of money. For example, 25,000€ for the district, or 10,000€ for culture." + link: "Create single heading budget" + title: "Single heading budget" + title: "Participatory budget type" phases: - back: "Go back to headings" continue: "Finish" + multiple: + back: "Go back to headings" + single: + back: "Go back to edit heading" update_all: notice: "Phases configured successfully" milestones: @@ -1357,6 +1382,7 @@ en: example_url: "https://consulproject.org" show_results_and_stats: "Show results and stats" results_and_stats_reminder: "Marking these checkboxes the results and/or stats will be publicly available and every user will see them." + close_modal: Close modal example_url: "https://consulproject.org" geozones: index: diff --git a/config/locales/en/rails.yml b/config/locales/en/rails.yml index 460857624..1c653dbde 100644 --- a/config/locales/en/rails.yml +++ b/config/locales/en/rails.yml @@ -199,5 +199,6 @@ en: default: "%a, %d %b %Y %H:%M:%S %z" long: "%B %d, %Y %H:%M" short: "%d %b %H:%M" + short_datetime: "%Y-%m-%d %H:%M" api: "%Y-%m-%d %H" pm: pm diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index d37a8a155..43bd93700 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -155,7 +155,7 @@ es: description_balloting: "Descripción durante la fase de votación" description_reviewing_ballots: "Descripción durante la fase de revisión de votos" description_finished: "Descripción cuando el presupuesto ha finalizado / Resultados" - phase: "Fase" + phase: "Fase activa" currency_symbol: "Divisa" voting_style: "Estilo de la votación final" voting_style_knapsack: Bolsa de dinero diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index a5d7fe170..7971a0665 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -78,14 +78,17 @@ es: all: Todos open: Abiertos finished: Terminados - help: "Los presupuestos participativos permiten que los ciudadanos propongan y decidan de manera directa cómo gastar parte del presupuesto, con un seguimiento y evaluación riguroso de las propuestas por parte de la institución." budget_investments: Gestionar proyectos de gasto + table_budget_type: "Tipo" table_completed: Completado table_draft: "Borrador" table_duration: "Duración" table_name: Nombre table_phase: Fase table_phase_progress: "(%{current_phase_number}/%{total_phases})" + type_multiple: "Múltiples partidas" + type_pending: "Pendiente: Aún no hay partidas" + type_single: "Partida única" edit_groups: Editar grupos de partidas edit_budget: Editar presupuesto admin_ballots: Gestionar urnas @@ -133,7 +136,17 @@ es: unable_notice: No se puede eliminar un presupuesto con proyectos asociados unable_notice_polls: No se puede eliminar un presupuesto con una votación asociada new: - title: Nuevo presupuesto ciudadano + title_multiple: Nuevo presupuesto de múltiples partidas + title_single: Nuevo presupuesto de partida única + help: + budgets: "Los presupuestos participativos permiten que los ciudadanos propongan y decidan de manera directa cómo gastar parte del presupuesto, con un seguimiento y evaluación riguroso de las propuestas por parte de la institución." + groups: + multiple: "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." + single: "Los grupos sirven para organizar las partidas del presupuesto, como este presupuesto sólo contendrá una partida, se puede usar el mismo nombre y éste no aparecerá en ninguna parte. Puedes continuar con el siguiente paso." + headings: + multiple: "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." + single: "Las partidas sirven para dividir el dinero del presupuesto participativo. Como este presupuesto solo tendrá una partida aquí podrás establecer la cantidad de dinero que se gastará en este presupuesto participativo." + phases: "Los presupuestos participativos tienen distintas fases. Aquí puedes habilitar o deshabilitar fases y también personalizar cada una de las fases." winners: calculate: Calcular proyectos ganadores calculated: Calculando ganadores, puede tardar un minuto. @@ -162,7 +175,6 @@ es: submit: "Guardar grupo" index: 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." new_button: "Añadir un grupo nuevo" budget_headings: no_headings: "No hay partidas." @@ -190,7 +202,6 @@ es: the_other_group: "Ir a partidas del grupo %{group}." index: 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." new_button: "Añadir una partida nueva" title: "Partidas de %{budget} / %{group}" budget_phases: @@ -206,7 +217,6 @@ es: save_changes: Guardar cambios title: "Editar fase" index: - 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: index: @@ -316,9 +326,24 @@ es: continue: "Continuar a partidas" headings: continue: "Continuar a fases" + single: + back: "Volver a editar grupo" + heading_mode: + multiple: + description: "Crea un proceso con múltiples grupos, distritos o temas. Tienes algo como varias bolsas de dinero. Por ejemplo, 25.000€ para \"Distrito norte\", 30.000€ para \"Distrito centro\", 28.000€ para \"Distrito sur\" y toda la ciudad. O para varios temas como deporte, cultura o salud." + link: "Crear presupuesto de múltiples partidas" + title: "Presupuesto de múltiples partidas" + single: + description: "Crea un proceso con un grupo, distrito o tema. Tienes algo como una bolsa de dinero. Por ejemplo, 25.000€ para un distrito, o 10.000€ para cultura." + link: "Crear presupuesto de partida única" + title: "Presupuesto de partida única" + title: Tipo de presupuesto participativo phases: - back: "Volver a partidas" continue: "Finalizar" + multiple: + back: "Volver a partidas" + single: + back: "Volver a editar partida" update_all: notice: "Fases configuradas con éxito" milestones: @@ -1356,6 +1381,7 @@ es: example_url: "https://consulproject.org" show_results_and_stats: "Mostrar resultados y estadísticas" results_and_stats_reminder: "Si marcas estas casillas los resultados y/o estadísticas serán públicos y podrán verlos todos los usuarios." + close_modal: Cerrar ventana emergente example_url: "https://consulproject.org" geozones: index: diff --git a/config/locales/es/rails.yml b/config/locales/es/rails.yml index eaff6932d..eade2c082 100644 --- a/config/locales/es/rails.yml +++ b/config/locales/es/rails.yml @@ -9,7 +9,7 @@ es: - vie - sáb abbr_month_names: - - + - - ene - feb - mar @@ -35,7 +35,7 @@ es: long: "%d de %B de %Y" short: "%d de %b" month_names: - - + - - enero - febrero - marzo @@ -193,5 +193,6 @@ es: default: "%A, %d de %B de %Y %H:%M:%S %z" long: "%d de %B de %Y %H:%M" short: "%d de %b %H:%M" + short_datetime: "%d/%m/%Y %H:%M" api: "%d/%m/%Y %H" pm: pm diff --git a/spec/components/admin/budgets/duration_component_spec.rb b/spec/components/admin/budgets/duration_component_spec.rb index fbbd51b73..5e6c78e24 100644 --- a/spec/components/admin/budgets/duration_component_spec.rb +++ b/spec/components/admin/budgets/duration_component_spec.rb @@ -12,7 +12,7 @@ describe Admin::Budgets::DurationComponent, type: :component do render dates - expect(page.text).to eq "2015-08-01 12:00:00 - 2016-09-30 16:29:59" + expect(page.text).to eq "2015-08-01 12:00 - 2016-09-30 16:29" expect(dates).to be_html_safe end @@ -20,7 +20,7 @@ describe Admin::Budgets::DurationComponent, type: :component do durable = double(starts_at: Time.zone.local(2015, 8, 1, 12, 0, 0), ends_at: nil) render Admin::Budgets::DurationComponent.new(durable).dates - expect(page.text).to eq "2015-08-01 12:00:00 - " + expect(page.text).to eq "2015-08-01 12:00 - " end it "shows the end date when no start date is defined" do @@ -28,7 +28,7 @@ describe Admin::Budgets::DurationComponent, type: :component do render Admin::Budgets::DurationComponent.new(durable).dates - expect(page.text).to eq "- 2016-09-30 16:29:59" + expect(page.text).to eq "- 2016-09-30 16:29" end end diff --git a/spec/components/admin/budgets/index_component_spec.rb b/spec/components/admin/budgets/index_component_spec.rb index c8e94ed6a..e55a30cc7 100644 --- a/spec/components/admin/budgets/index_component_spec.rb +++ b/spec/components/admin/budgets/index_component_spec.rb @@ -7,21 +7,54 @@ describe Admin::Budgets::IndexComponent, type: :component do allow_any_instance_of(Admin::BudgetsController).to receive(:current_filter).and_return("all") end - it "displays current phase zero for budgets with no current phase" do - budget = create(:budget, :accepting, name: "Not enabled phase") - budget.phases.accepting.update!(enabled: false) + describe "#phase_progress_text" do + it "displays current phase zero for budgets with no current phase" do + budget = create(:budget, :accepting, name: "Not enabled phase") + budget.phases.accepting.update!(enabled: false) - render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) - expect(page.find("tr", text: "Not enabled phase")).to have_content "0/8" + expect(page.find("tr", text: "Not enabled phase")).to have_content "0/8" + end + + it "displays phase zero out of zero for budgets with no enabled phases" do + budget = create(:budget, name: "Without phases") + budget.phases.each { |phase| phase.update!(enabled: false) } + + render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + + expect(page.find("tr", text: "Without phases")).to have_content "0/0" + end end - it "displays phase zero out of zero for budgets with no enabled phases" do - budget = create(:budget, name: "Without phases") - budget.phases.each { |phase| phase.update!(enabled: false) } + describe "#type" do + let(:budget) { create(:budget, name: "With type") } - render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + it "displays 'single heading' for budgets with one heading" do + create(:budget_heading, budget: budget) - expect(page.find("tr", text: "Without phases")).to have_content "0/0" + render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + + expect(page.find("thead")).to have_content "Type" + expect(page.find("tr", text: "With type")).to have_content "Single heading" + end + + it "displays 'multiple headings' for budgets with multiple headings" do + 2.times { create(:budget_heading, budget: budget) } + + render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + + expect(page.find("thead")).to have_content "Type" + expect(page.find("tr", text: "With type")).to have_content "Multiple headings" + end + + it "displays 'pending: no headings yet' for budgets without headings" do + create(:budget, name: "Without headings") + + render_inline Admin::Budgets::IndexComponent.new(Budget.page(1)) + + expect(page.find("thead")).to have_content "Type" + expect(page.find("tr", text: "Without headings")).to have_content "Pending: No headings yet" + end end end diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index bbe5835f1..75c2e0234 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -447,4 +447,43 @@ describe Budget do expect(Valuator.count).to be 1 end end + + describe "#single_heading?" do + it "returns false for budgets with no groups nor headings" do + expect(create(:budget).single_heading?).to be false + end + + it "returns false for budgets with one group and no headings" do + create(:budget_group, budget: budget) + + expect(budget.single_heading?).to be false + end + + it "returns false for budgets with multiple groups and one heading" do + 2.times { create(:budget_group, budget: budget) } + create(:budget_heading, group: budget.groups.last) + + expect(budget.single_heading?).to be false + end + + it "returns false for budgets with one group and multiple headings" do + group = create(:budget_group, budget: budget) + 2.times { create(:budget_heading, group: group) } + + expect(budget.single_heading?).to be false + end + + it "returns false for budgets with one group and multiple headings" do + 2.times { create(:budget_group, budget: budget) } + 2.times { create(:budget_heading, group: budget.groups.sample) } + + expect(budget.single_heading?).to be false + end + + it "returns true for budgets with one group and one heading" do + create(:budget_heading, group: create(:budget_group, budget: budget)) + + expect(budget.single_heading?).to be true + end + end end diff --git a/spec/system/admin/budget_investments_spec.rb b/spec/system/admin/budget_investments_spec.rb index 1aece2f90..00291061d 100644 --- a/spec/system/admin/budget_investments_spec.rb +++ b/spec/system/admin/budget_investments_spec.rb @@ -529,7 +529,7 @@ describe "Admin budget investments", :admin do expect(page).to have_link "Calculate Winner Investments" - select "Accepting projects", from: "Phase" + select "Accepting projects", from: "Active phase" click_button "Update Budget" expect(page).to have_content "Participatory budget updated successfully" diff --git a/spec/system/admin/budgets_spec.rb b/spec/system/admin/budgets_spec.rb index bab9408fe..b7c2b9395 100644 --- a/spec/system/admin/budgets_spec.rb +++ b/spec/system/admin/budgets_spec.rb @@ -30,8 +30,10 @@ describe "Admin budgets", :admin do budget = create(:budget, :accepting) visit admin_budgets_path - expect(page).to have_content budget.name - expect(page).to have_content "Accepting projects" + within "tr", text: budget.name do + expect(page).to have_content "Accepting projects" + expect(page).to have_content "Pending: No headings yet" + end end scenario "Filters by phase" do @@ -188,7 +190,7 @@ describe "Admin budgets", :admin do visit edit_admin_budget_path(budget) - expect(page).to have_select "Phase", selected: "Selecting projects" + expect(page).to have_select "Active phase", selected: "Selecting projects" expect(page).to have_table "Phases", with_cols: [ [ @@ -202,14 +204,14 @@ describe "Admin budgets", :admin do "Reviewing voting" ], [ - "2015-07-15 00:00:00 - 2015-08-14 23:59:59", - "2015-08-15 00:00:00 - 2015-09-14 23:59:59", - "2015-09-15 00:00:00 - 2015-10-14 23:59:59", - "2015-10-15 00:00:00 - 2015-11-14 23:59:59", - "2015-11-15 00:00:00 - 2015-12-14 23:59:59", - "2015-11-15 00:00:00 - 2016-01-14 23:59:59", - "2016-01-15 00:00:00 - 2016-02-14 23:59:59", - "2016-02-15 00:00:00 - 2016-03-14 23:59:59" + "2015-07-15 00:00 - 2015-08-14 23:59", + "2015-08-15 00:00 - 2015-09-14 23:59", + "2015-09-15 00:00 - 2015-10-14 23:59", + "2015-10-15 00:00 - 2015-11-14 23:59", + "2015-11-15 00:00 - 2015-12-14 23:59", + "2015-11-15 00:00 - 2016-01-14 23:59", + "2016-01-15 00:00 - 2016-02-14 23:59", + "2016-02-15 00:00 - 2016-03-14 23:59" ], [ "Yes", diff --git a/spec/system/admin/budgets_wizard/budgets_spec.rb b/spec/system/admin/budgets_wizard/budgets_spec.rb index ac4722bad..a062d9492 100644 --- a/spec/system/admin/budgets_wizard/budgets_spec.rb +++ b/spec/system/admin/budgets_wizard/budgets_spec.rb @@ -4,7 +4,8 @@ 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" + click_button "Create new budget" + click_link "Create multiple headings budget" fill_in "Name", with: "M30 - Summer campaign" click_button "Continue to groups" @@ -21,7 +22,8 @@ describe "Budgets wizard, first step", :admin do admin = Administrator.first visit admin_budgets_path - click_link "Create new budget" + click_button "Create new budget" + click_link "Create multiple headings budget" fill_in "Name", with: "M30 - Summer campaign" select "Approval", from: "Final voting style" @@ -73,7 +75,8 @@ describe "Budgets wizard, first step", :admin do describe "Create" do scenario "A new budget is always created in draft mode" do visit admin_budgets_path - click_link "Create new budget" + click_button "Create new budget" + click_link "Create multiple headings budget" fill_in "Name", with: "M30 - Summer campaign" diff --git a/spec/system/admin/budgets_wizard/groups_spec.rb b/spec/system/admin/budgets_wizard/groups_spec.rb index be2e84d05..e5e237c87 100644 --- a/spec/system/admin/budgets_wizard/groups_spec.rb +++ b/spec/system/admin/budgets_wizard/groups_spec.rb @@ -97,6 +97,26 @@ describe "Budgets wizard, groups step", :admin do expect(page).to have_css ".creation-timeline" expect(page).to have_css "td", exact_text: "Group without typos" end + + scenario "update group in single heading budget" do + visit admin_budgets_wizard_budget_groups_path(budget, mode: "single") + fill_in "Group name", with: "Group wiht typo" + click_button "Continue to headings" + + click_link "Go back to edit group" + + expect(page).to have_field "Group name", with: "Group wiht typo" + + fill_in "Group name", with: "Group without typos" + click_button "Continue to headings" + + expect(page).to have_content "Group updated successfully" + + visit admin_budget_groups_path(budget) + + expect(page).to have_content "There is 1 group" + within("tbody tr") { expect(page).to have_content "Group without typos" } + end end describe "Destroy" do diff --git a/spec/system/admin/budgets_wizard/headings_spec.rb b/spec/system/admin/budgets_wizard/headings_spec.rb index d3823347e..de4c9dfcb 100644 --- a/spec/system/admin/budgets_wizard/headings_spec.rb +++ b/spec/system/admin/budgets_wizard/headings_spec.rb @@ -118,6 +118,29 @@ describe "Budgets wizard, headings step", :admin do expect(page).to have_css ".creation-timeline" expect(page).to have_css "td", exact_text: "Heading without typos" end + + scenario "update heading in single heading budget" do + visit admin_budgets_wizard_budget_group_headings_path(budget, group, mode: "single") + fill_in "Heading name", with: "Heading wiht typo" + fill_in "Money amount", with: "300000" + click_button "Continue to phases" + + expect(page).to have_content "Heading created successfully" + + click_link "Go back to edit heading" + + expect(page).to have_field "Heading name", with: "Heading wiht typo" + + fill_in "Heading name", with: "Heading without typos" + click_button "Continue to phases" + + expect(page).to have_content "Heading updated successfully" + + visit admin_budget_group_headings_path(budget, group) + + expect(page).to have_content "There is 1 heading" + within("tbody tr") { expect(page).to have_content "Heading without typos" } + end end describe "Destroy" do diff --git a/spec/system/admin/budgets_wizard/phases_spec.rb b/spec/system/admin/budgets_wizard/phases_spec.rb index eb2e0b50b..e1f8e7be2 100644 --- a/spec/system/admin/budgets_wizard/phases_spec.rb +++ b/spec/system/admin/budgets_wizard/phases_spec.rb @@ -82,5 +82,18 @@ describe "Budgets wizard, phases step", :admin do expect(page).to have_css ".creation-timeline" within_table("Phases") { expect(page).to have_content "Welcoming projects" } end + + scenario "update phase in single heading budget" do + visit admin_budgets_wizard_budget_budget_phases_path(budget, mode: "single") + + within("tr", text: "Selecting projects") { click_link "Edit phase" } + fill_in "Name", with: "Choosing projects" + click_button "Save changes" + + expect(page).to have_content "Changes saved" + expect(page).to have_css ".creation-timeline" + within_table("Phases") { expect(page).to have_content "Choosing projects" } + expect(page).to have_link "Go back to edit heading" + end end end diff --git a/spec/system/admin/budgets_wizard/wizard_spec.rb b/spec/system/admin/budgets_wizard/wizard_spec.rb new file mode 100644 index 000000000..2cd89198e --- /dev/null +++ b/spec/system/admin/budgets_wizard/wizard_spec.rb @@ -0,0 +1,148 @@ +require "rails_helper" + +describe "Budgets creation wizard", :admin do + scenario "Creation of a single-heading budget by steps" do + visit admin_budgets_path + click_button "Create new budget" + click_link "Create single heading budget" + + fill_in "Name", with: "Single heading budget" + click_button "Continue to groups" + + expect(page).to have_content "New participatory budget created successfully!" + expect(page).to have_field "Group name", with: "Single heading budget" + + click_button "Continue to headings" + + expect(page).to have_content "Group created successfully" + + fill_in "Heading name", with: "One and only heading" + fill_in "Money amount", with: "1000000" + click_button "Continue to phases" + + expect(page).to have_css ".budget-phases-table" + + click_button "Finish" + + expect(page).to have_content "Phases configured successfully" + + within "tr", text: "Single heading budget" do + click_link "Edit headings groups" + end + + expect(page).to have_content "There is 1 group" + + within "tr", text: "Single heading budget" do + click_link "Manage headings" + end + + expect(page).to have_content "There is 1 heading" + + within "tbody" do + expect(page).to have_content "One and only heading" + end + end + + scenario "Creation of a multiple-headings budget by steps" do + visit admin_budgets_path + click_button "Create new budget" + click_link "Create multiple headings budget" + + fill_in "Name", with: "Multiple headings budget" + click_button "Continue to groups" + + expect(page).to have_content "New participatory budget created successfully!" + expect(page).to have_content "There are no groups." + + click_button "Add new group" + fill_in "Group name", with: "All city" + click_button "Create new group" + + expect(page).to have_content "Group created successfully!" + within("table") { expect(page).to have_content "All city" } + expect(page).not_to have_content "There are no groups." + + click_button "Add new group" + fill_in "Group name", with: "Districts" + click_button "Create new group" + + expect(page).to have_content "Group created successfully!" + within("table") { expect(page).to have_content "Districts" } + + click_link "Continue to headings" + + expect(page).to have_content "Showing headings from the All city group" + expect(page).to have_content "There are no headings." + + click_button "Add new heading" + fill_in "Heading name", with: "All city" + fill_in "Money amount", with: "1000000" + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + within("table") { expect(page).to have_content "All city" } + expect(page).not_to have_content "There are no headings." + + click_link "Manage headings from the Districts group." + expect(page).to have_content "There are no headings." + + click_button "Add new heading" + fill_in "Heading name", with: "North" + fill_in "Money amount", with: "500000" + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + within("table") { expect(page).to have_content "North" } + expect(page).not_to have_content "There are no headings." + + click_button "Add new heading" + fill_in "Heading name", with: "South" + fill_in "Money amount", with: "500000" + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + within("table") { expect(page).to have_content "South" } + + click_link "Continue to phases" + + expect(page).to have_css ".budget-phases-table" + + within("tr", text: "Voting projects") { click_link "Edit phase" } + fill_in "Name", with: "Custom phase name" + uncheck "Phase enabled" + click_button "Save changes" + + expect(page).to have_content "Changes saved" + + within "table" do + expect(page).to have_content "Custom phase name" + expect(page).not_to have_content "Voting projects" + end + + click_button "Finish" + + expect(page).to have_content "Phases configured successfully" + + within "tr", text: "Multiple headings budget" do + click_link "Edit headings groups" + end + + expect(page).to have_content "There are 2 groups" + + within "tbody" do + expect(page).to have_content "All city" + expect(page).to have_content "Districts" + end + + within "tr", text: "Districts" do + click_link "Manage headings" + end + + expect(page).to have_content "There are 2 headings" + + within "tbody" do + expect(page).to have_content "North" + expect(page).to have_content "South" + end + end +end