diff --git a/app/assets/stylesheets/budgets/investments/form.scss b/app/assets/stylesheets/budgets/investments/form.scss new file mode 100644 index 000000000..6d84a466d --- /dev/null +++ b/app/assets/stylesheets/budgets/investments/form.scss @@ -0,0 +1,62 @@ +.budget-investment-form { + + .required-fields { + @include full-width-background($adjust-padding: true); + background: $light; + margin-bottom: $line-height; + padding-top: $line-height; + } + + > fieldset > legend { + float: left; + font-size: rem-calc(36); + font-weight: bold; + margin-bottom: $line-height; + text-transform: uppercase; + + + * { + clear: left; + } + } + + select { + min-height: $line-height * 2; + + @include breakpoint(medium) { + &:not(.js-add-language):not(.js-select-language) { + width: 50%; + } + } + } + + .globalize-languages, + .translatable-fields { + @include grid-row-nest; + @include grid-column-gutter; + } + + .sdg-related-list-selector { + padding-left: 0; + padding-right: 0; + } + + [type="submit"] { + @include regular-button; + font-size: map-get($button-sizes, large); + margin-top: $line-height; + } + + .actions { + border: 6px solid $border; + border-radius: rem-calc(12); + margin-left: auto; + margin-right: auto; + margin-top: $line-height * 2; + padding: $line-height * 2 $line-height; + text-align: center; + + @include breakpoint(medium) { + width: 75%; + } + } +} diff --git a/app/assets/stylesheets/budgets/investments/new.scss b/app/assets/stylesheets/budgets/investments/new.scss index bda89bd63..f13325fbf 100644 --- a/app/assets/stylesheets/budgets/investments/new.scss +++ b/app/assets/stylesheets/budgets/investments/new.scss @@ -1,19 +1,27 @@ .budget-investment-new { $border-width: 4px; + @include grid-column-gutter; - > * { - @include grid-column-gutter; + > :first-child:not(.print-info) { + @include full-width-background($adjust-padding: true); + background: $light; + margin-top: -$line-height; + padding-top: $line-height; + } + + h1 { + margin-bottom: 0; } header { @include has-fa-icon(building, regular, after); align-items: center; + background-color: $body-background; border: $border-width solid; color: $brand-secondary; border-bottom-right-radius: rem-calc(12); border-top-right-radius: rem-calc(12); display: flex; - margin-bottom: $line-height * 2; margin-top: $line-height * 2; @include breakpoint(large) { @@ -38,7 +46,6 @@ display: flex; flex: 1; font-size: rem-calc(36); - margin-bottom: 0; padding: $line-height * 2 0; @include breakpoint(large) { diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 85778926f..ec9aef363 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1074,7 +1074,6 @@ form { .checkbox, .radio { - display: inline-block; font-weight: normal; line-height: $line-height; vertical-align: middle; diff --git a/app/components/budgets/investments/form_component.html.erb b/app/components/budgets/investments/form_component.html.erb new file mode 100644 index 000000000..34283dbd8 --- /dev/null +++ b/app/components/budgets/investments/form_component.html.erb @@ -0,0 +1,109 @@ +<%= translatable_form_for(investment, url: url, html: { class: "budget-investment-form" }) do |f| %> + + <%= render "shared/errors", resource: investment %> + +
+ <%= t("shared.required") %> + + <% unless budget.single_heading? %> +
+ <%= f.select :heading_id, budget_heading_select_options(budget), { include_blank: true } %> +
+ <% end %> + +
+ <%= render "shared/globalize_locales", resource: investment %> +
+ + <%= f.translatable_fields do |translations_form| %> +
+ <%= translations_form.text_field :title, + maxlength: Budget::Investment.title_max_length, + data: suggest_data(investment) %> +
+
+ +
+ <%= translations_form.text_area :description, + maxlength: Budget::Investment.description_max_length, + class: "html-area" %> +
+ <% end %> +
+ + <%= f.invisible_captcha :subtitle %> + +
+ <%= t("shared.optional") %> + + <% if feature?(:allow_images) %> +
+ <%= render "images/nested_image", imageable: investment, f: f %> +
+ <% end %> + + <% if feature?(:allow_attached_documents) %> +
+ <%= render "documents/nested_documents", documentable: investment, f: f %> +
+ <% end %> + + <% if feature?(:map) %> +
+ <%= render "map_locations/form_fields", + form: f, + map_location: investment.map_location || MapLocation.new, + label: t("budgets.investments.form.map_location"), + help: t("budgets.investments.form.map_location_instructions"), + remove_marker_label: t("budgets.investments.form.map_remove_marker"), + parent_class: "budget_investment", + i18n_namespace: "budgets.investments" %> +
+ <% end %> + +
+ <%= f.text_field :location %> +
+ +
+ <%= f.text_field :organization_name %> +
+ +
+ <%= f.label :tag_list, t("budgets.investments.form.tags_label") %> +

<%= t("budgets.investments.form.tags_instructions") %>

+ +
+ <%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %> + <% categories.each do |tag| %> + <%= tag.name %> + <% end %> +
+ +
+ <%= f.text_field :tag_list, value: investment.tag_list.to_s, + label: false, + placeholder: t("budgets.investments.form.tags_placeholder"), + aria: { describedby: "tags-list-help-text" }, + class: "js-tag-list tag-autocomplete", + data: { js_url: suggest_tags_path } %> +
+ + <%= render SDG::RelatedListSelectorComponent.new(f) %> +
+ +
+ <% unless current_user.manager? || investment.persisted? %> +
+ <%= f.check_box :terms_of_service, + title: t("form.accept_terms_title"), + label: t("form.accept_terms", + policy: link_to(t("form.policy"), "/privacy", target: "blank"), + conditions: link_to(t("form.conditions"), "/conditions", target: "blank") + ) %> +
+ <% end %> + + <%= f.submit %> +
+<% end %> diff --git a/app/components/budgets/investments/form_component.rb b/app/components/budgets/investments/form_component.rb new file mode 100644 index 000000000..181328e04 --- /dev/null +++ b/app/components/budgets/investments/form_component.rb @@ -0,0 +1,21 @@ +class Budgets::Investments::FormComponent < ApplicationComponent + include TranslatableFormHelper + include GlobalizeHelper + attr_reader :investment, :url + delegate :current_user, :budget_heading_select_options, :suggest_data, to: :helpers + + def initialize(investment, url:) + @investment = investment + @url = url + end + + private + + def budget + investment.budget + end + + def categories + Tag.category.order(:name) + end +end diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 6286fe13b..a06e68d1e 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -22,7 +22,7 @@ module Budgets before_action :load_ballot, only: [:index, :show] before_action :load_heading, only: [:index, :show] before_action :set_random_seed, only: :index - before_action :load_categories, only: [:index, :new, :create, :edit, :update] + before_action :load_categories, only: :index before_action :set_default_investment_filter, only: :index before_action :set_view, only: :index before_action :load_content_blocks, only: :index diff --git a/app/controllers/management/budgets/investments_controller.rb b/app/controllers/management/budgets/investments_controller.rb index 627964a69..ae3abf85d 100644 --- a/app/controllers/management/budgets/investments_controller.rb +++ b/app/controllers/management/budgets/investments_controller.rb @@ -18,7 +18,6 @@ class Management::Budgets::InvestmentsController < Management::BaseController end def new - load_categories end def create @@ -30,7 +29,6 @@ class Management::Budgets::InvestmentsController < Management::BaseController notice = t("flash.actions.create.notice", resource_name: Budget::Investment.model_name.human, count: 1) redirect_to management_budget_investment_path(@budget, @investment), notice: notice else - load_categories render :new end end @@ -59,8 +57,4 @@ class Management::Budgets::InvestmentsController < Management::BaseController def load_budget @budget = Budget.find_by_slug_or_id! params[:budget_id] end - - def load_categories - @categories = Tag.category.order(:name) - end end diff --git a/app/views/budgets/investments/_form.html.erb b/app/views/budgets/investments/_form.html.erb index 8296a2e30..4ef77fb0d 100644 --- a/app/views/budgets/investments/_form.html.erb +++ b/app/views/budgets/investments/_form.html.erb @@ -1,109 +1 @@ -<%= translatable_form_for(@investment, url: form_url, html: { multipart: true }) do |f| %> - - <%= render "shared/errors", resource: @investment %> - -
- <% unless @budget.single_heading? %> -
- <%= f.select :heading_id, budget_heading_select_options(@budget), { include_blank: true } %> -
- <% end %> - -
-
- <%= render "shared/globalize_locales", resource: @investment %> -
-
- - <%= f.translatable_fields do |translations_form| %> -
- <%= translations_form.text_field :title, - maxlength: Budget::Investment.title_max_length, - data: suggest_data(@investment) %> -
-
- -
- <%= translations_form.text_area :description, - maxlength: Budget::Investment.description_max_length, - class: "html-area" %> -
- <% end %> - - <%= f.invisible_captcha :subtitle %> - - <% if feature?(:allow_images) %> -
- <%= render "images/nested_image", imageable: @investment, f: f %> -
- <% end %> - - <% if feature?(:allow_attached_documents) %> -
- <%= render "documents/nested_documents", documentable: @investment, f: f %> -
- <% end %> - - <% if feature?(:map) %> -
- - <%= render "map_locations/form_fields", - form: f, - map_location: @investment.map_location || MapLocation.new, - label: t("budgets.investments.form.map_location"), - help: t("budgets.investments.form.map_location_instructions"), - remove_marker_label: t("budgets.investments.form.map_remove_marker"), - parent_class: "budget_investment", - i18n_namespace: "budgets.investments" %> - -
- <% end %> - -
- <%= f.text_field :location %> -
- -
- <%= f.text_field :organization_name %> -
- -
- <%= f.label :tag_list, t("budgets.investments.form.tags_label") %> -

<%= t("budgets.investments.form.tags_instructions") %>

- -
- <%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %> - <% @categories.each do |tag| %> - <%= tag.name %> - <% end %> -
- -
- <%= f.text_field :tag_list, value: @investment.tag_list.to_s, - label: false, - placeholder: t("budgets.investments.form.tags_placeholder"), - aria: { describedby: "tags-list-help-text" }, - class: "js-tag-list tag-autocomplete", - data: { js_url: suggest_tags_path } %> -
- - <%= render SDG::RelatedListSelectorComponent.new(f) %> - - <% unless current_user.manager? %> - -
- <%= f.check_box :terms_of_service, - title: t("form.accept_terms_title"), - label: t("form.accept_terms", - policy: link_to(t("form.policy"), "/privacy", target: "blank"), - conditions: link_to(t("form.conditions"), "/conditions", target: "blank") - ) %> -
- - <% end %> - -
- <%= f.submit(nil, class: "button expanded") %> -
-
-<% end %> +<%= render Budgets::Investments::FormComponent.new(@investment, url: form_url) %> diff --git a/app/views/budgets/investments/edit.html.erb b/app/views/budgets/investments/edit.html.erb index ffdb0dcdf..6821e7697 100644 --- a/app/views/budgets/investments/edit.html.erb +++ b/app/views/budgets/investments/edit.html.erb @@ -1,6 +1,7 @@ -
-
+
+

<%= t("management.budget_investments.edit") %>

- <%= render "/budgets/investments/form", form_url: budget_investment_path(@budget, @investment) %>
+ + <%= render "/budgets/investments/form", form_url: budget_investment_path(@budget, @investment) %>
diff --git a/app/views/management/budgets/investments/new.html.erb b/app/views/management/budgets/investments/new.html.erb index d8fa9048c..d2b280606 100644 --- a/app/views/management/budgets/investments/new.html.erb +++ b/app/views/management/budgets/investments/new.html.erb @@ -1,6 +1,6 @@
-
+ diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index a58e5e6ba..d0d1ff500 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -774,6 +774,8 @@ en: zero: "0 languages in use" one: "1 language in use" other: "%{count} languages in use" + optional: "Optional" + required: "Required" social: facebook: "%{org} Facebook" twitter: "%{org} Twitter" diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 81a903d8c..aa8b4b8ee 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -774,6 +774,8 @@ es: zero: "0 idiomas en uso" one: "1 idioma en uso" other: "%{count} idiomas en uso" + optional: "Opcional" + required: "Obligatorio" social: facebook: "Facebook de %{org}" twitter: "Twitter de %{org}" diff --git a/spec/components/budgets/investments/form_component_spec.rb b/spec/components/budgets/investments/form_component_spec.rb new file mode 100644 index 000000000..8e6bcfb11 --- /dev/null +++ b/spec/components/budgets/investments/form_component_spec.rb @@ -0,0 +1,36 @@ +require "rails_helper" + +describe Budgets::Investments::FormComponent, type: :component do + include Rails.application.routes.url_helpers + + let(:budget) { create(:budget) } + + before do + allow(controller).to receive(:current_user).and_return(create(:user)) + allow(request).to receive(:path_parameters).and_return(budget_id: budget.id) + end + + describe "accept terms of services field" do + it "is shown for new investments" do + investment = build(:budget_investment, budget: budget) + + render_inline Budgets::Investments::FormComponent.new( + investment, + url: budget_investments_path(budget) + ) + + expect(page).to have_field "I agree to the Privacy Policy and the Terms and conditions of use" + end + + it "is not shown for existing investments" do + investment = create(:budget_investment, budget: budget) + + render_inline Budgets::Investments::FormComponent.new( + investment, + url: budget_investment_path(budget, investment) + ) + + expect(page).not_to have_field "I agree to the Privacy Policy and the Terms and conditions of use" + end + end +end diff --git a/spec/system/budgets/investments_spec.rb b/spec/system/budgets/investments_spec.rb index 60b056d95..87a55a069 100644 --- a/spec/system/budgets/investments_spec.rb +++ b/spec/system/budgets/investments_spec.rb @@ -633,7 +633,6 @@ describe "Budget Investments" do click_link("Edit", match: :first) fill_in "Title", with: "Park improvements" - check "budget_investment_terms_of_service" click_button "Update Investment" @@ -651,7 +650,6 @@ describe "Budget Investments" do visit user_path(daniel, filter: "budget_investments") click_link("Edit", match: :first) fill_in "Title", with: "" - check "budget_investment_terms_of_service" click_button "Update Investment"