Merge pull request #4580 from consul/improve-investment-form
Improve investment form
This commit is contained in:
62
app/assets/stylesheets/budgets/investments/form.scss
Normal file
62
app/assets/stylesheets/budgets/investments/form.scss
Normal file
@@ -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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -1074,7 +1074,6 @@ form {
|
||||
|
||||
.checkbox,
|
||||
.radio {
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
line-height: $line-height;
|
||||
vertical-align: middle;
|
||||
|
||||
109
app/components/budgets/investments/form_component.html.erb
Normal file
109
app/components/budgets/investments/form_component.html.erb
Normal file
@@ -0,0 +1,109 @@
|
||||
<%= translatable_form_for(investment, url: url, html: { class: "budget-investment-form" }) do |f| %>
|
||||
|
||||
<%= render "shared/errors", resource: investment %>
|
||||
|
||||
<fieldset class="required-fields">
|
||||
<legend><%= t("shared.required") %></legend>
|
||||
|
||||
<% unless budget.single_heading? %>
|
||||
<div>
|
||||
<%= f.select :heading_id, budget_heading_select_options(budget), { include_blank: true } %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<%= render "shared/globalize_locales", resource: investment %>
|
||||
</div>
|
||||
|
||||
<%= f.translatable_fields do |translations_form| %>
|
||||
<div>
|
||||
<%= translations_form.text_field :title,
|
||||
maxlength: Budget::Investment.title_max_length,
|
||||
data: suggest_data(investment) %>
|
||||
</div>
|
||||
<div class="js-suggest" data-locale="<%= translations_form.locale %>"></div>
|
||||
|
||||
<div>
|
||||
<%= translations_form.text_area :description,
|
||||
maxlength: Budget::Investment.description_max_length,
|
||||
class: "html-area" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</fieldset>
|
||||
|
||||
<%= f.invisible_captcha :subtitle %>
|
||||
|
||||
<fieldset>
|
||||
<legend><%= t("shared.optional") %></legend>
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images">
|
||||
<%= render "images/nested_image", imageable: investment, f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:allow_attached_documents) %>
|
||||
<div class="documents">
|
||||
<%= render "documents/nested_documents", documentable: investment, f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:map) %>
|
||||
<div>
|
||||
<%= 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" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<%= f.text_field :location %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.text_field :organization_name %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.label :tag_list, t("budgets.investments.form.tags_label") %>
|
||||
<p class="help-text" id="tags-list-help-text"><%= t("budgets.investments.form.tags_instructions") %></p>
|
||||
|
||||
<div id="category_tags" class="tags">
|
||||
<%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %>
|
||||
<% categories.each do |tag| %>
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<%= 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 } %>
|
||||
</div>
|
||||
|
||||
<%= render SDG::RelatedListSelectorComponent.new(f) %>
|
||||
</fieldset>
|
||||
|
||||
<div class="actions">
|
||||
<% unless current_user.manager? || investment.persisted? %>
|
||||
<div>
|
||||
<%= 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")
|
||||
) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
21
app/components/budgets/investments/form_component.rb
Normal file
21
app/components/budgets/investments/form_component.rb
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,109 +1 @@
|
||||
<%= translatable_form_for(@investment, url: form_url, html: { multipart: true }) do |f| %>
|
||||
|
||||
<%= render "shared/errors", resource: @investment %>
|
||||
|
||||
<div class="row column">
|
||||
<% unless @budget.single_heading? %>
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= f.select :heading_id, budget_heading_select_options(@budget), { include_blank: true } %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= render "shared/globalize_locales", resource: @investment %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= f.translatable_fields do |translations_form| %>
|
||||
<div class="small-12 column">
|
||||
<%= translations_form.text_field :title,
|
||||
maxlength: Budget::Investment.title_max_length,
|
||||
data: suggest_data(@investment) %>
|
||||
</div>
|
||||
<div class="js-suggest" data-locale="<%= translations_form.locale %>"></div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= translations_form.text_area :description,
|
||||
maxlength: Budget::Investment.description_max_length,
|
||||
class: "html-area" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= f.invisible_captcha :subtitle %>
|
||||
|
||||
<% if feature?(:allow_images) %>
|
||||
<div class="images small-12 column">
|
||||
<%= render "images/nested_image", imageable: @investment, f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:allow_attached_documents) %>
|
||||
<div class="documents small-12 column">
|
||||
<%= render "documents/nested_documents", documentable: @investment, f: f %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feature?(:map) %>
|
||||
<div class="small-12 column">
|
||||
|
||||
<%= 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" %>
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :location %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :organization_name %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :tag_list, t("budgets.investments.form.tags_label") %>
|
||||
<p class="help-text" id="tags-list-help-text"><%= t("budgets.investments.form.tags_instructions") %></p>
|
||||
|
||||
<div id="category_tags" class="tags">
|
||||
<%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %>
|
||||
<% @categories.each do |tag| %>
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<%= 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 } %>
|
||||
</div>
|
||||
|
||||
<%= render SDG::RelatedListSelectorComponent.new(f) %>
|
||||
|
||||
<% unless current_user.manager? %>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= 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")
|
||||
) %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<div class="actions small-12 medium-6 large-4 end column">
|
||||
<%= f.submit(nil, class: "button expanded") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= render Budgets::Investments::FormComponent.new(@investment, url: form_url) %>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<div class="budget-investment-new row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="budget-investment-new">
|
||||
<div>
|
||||
<h1><%= t("management.budget_investments.edit") %></h1>
|
||||
<%= render "/budgets/investments/form", form_url: budget_investment_path(@budget, @investment) %>
|
||||
</div>
|
||||
|
||||
<%= render "/budgets/investments/form", form_url: budget_investment_path(@budget, @investment) %>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="budget-investment-new">
|
||||
|
||||
<div class="clear float-right">
|
||||
<div class="print-info clear float-right">
|
||||
<%= render "/shared/print" %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}"
|
||||
|
||||
36
spec/components/budgets/investments/form_component_spec.rb
Normal file
36
spec/components/budgets/investments/form_component_spec.rb
Normal file
@@ -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
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user