decidim-proposals 0.7.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +6 -1
- data/app/assets/javascripts/decidim/proposals/utils.js.es6 +11 -0
- data/app/commands/decidim/proposals/update_proposal.rb +121 -0
- data/app/controllers/decidim/proposals/application_controller.rb +2 -0
- data/app/controllers/decidim/proposals/proposals_controller.rb +26 -0
- data/app/models/decidim/proposals/abilities/current_user_ability.rb +3 -0
- data/app/models/decidim/proposals/proposal.rb +23 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_author.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +3 -1
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/edit.html.erb +77 -0
- data/app/views/decidim/proposals/proposals/new.html.erb +6 -0
- data/app/views/decidim/proposals/proposals/show.html.erb +11 -3
- data/config/locales/ca.yml +31 -15
- data/config/locales/en.yml +18 -2
- data/config/locales/es.yml +18 -2
- data/config/locales/eu.yml +18 -3
- data/config/locales/fi.yml +18 -3
- data/config/locales/fr.yml +18 -3
- data/config/locales/it.yml +24 -9
- data/config/locales/nl.yml +48 -33
- data/config/locales/pl.yml +20 -4
- data/config/locales/pt.yml +192 -0
- data/config/locales/ru.yml +23 -7
- data/config/locales/uk.yml +21 -5
- data/lib/decidim/proposals/engine.rb +1 -1
- data/lib/decidim/proposals/feature.rb +1 -0
- data/lib/decidim/proposals/test/factories.rb +7 -3
- data/lib/decidim/proposals/version.rb +1 -1
- metadata +30 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dd92afffe4d54576836db8fc75463fe8573cc096
|
4
|
+
data.tar.gz: 2e9aecf15cfed4d537d97181d5aa8e022c81daaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51c6c265feecc09e53c25fba2133b3c991a885483147a584b146412f68a206d90fb31b3545a061e36f20c6767875640099e78e7a26df62bfaf1690e0bbc43d78
|
7
|
+
data.tar.gz: 6dd296da8b15bace994407f59b4059a4e4019a6c9f75edf78411570d2d8a41230ed74db705302fc44a0edac7d7d9dce1dc451abff27406357886913abe099356
|
data/README.md
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
The Proposals module adds one of the main features of Decidim: allows users to contribute to a particiaptory process by creating proposals.
|
4
4
|
|
5
5
|
## Usage
|
6
|
+
|
6
7
|
Proposals will be available as a Feature for a Participatory Process.
|
7
8
|
|
8
9
|
## Installation
|
10
|
+
|
9
11
|
Add this line to your application's Gemfile:
|
10
12
|
|
11
13
|
```ruby
|
@@ -13,12 +15,15 @@ gem 'decidim-proposals
|
|
13
15
|
```
|
14
16
|
|
15
17
|
And then execute:
|
18
|
+
|
16
19
|
```bash
|
17
|
-
|
20
|
+
bundle
|
18
21
|
```
|
19
22
|
|
20
23
|
## Contributing
|
24
|
+
|
21
25
|
See [Decidim](https://github.com/decidim/decidim).
|
22
26
|
|
23
27
|
## License
|
28
|
+
|
24
29
|
See [Decidim](https://github.com/decidim/decidim).
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# A command with all the business logic when a user updates a proposal.
|
6
|
+
class UpdateProposal < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# form - A form object with the params.
|
10
|
+
# current_user - The current user.
|
11
|
+
# proposal - the proposal to update.
|
12
|
+
def initialize(form, current_user, proposal)
|
13
|
+
@form = form
|
14
|
+
@current_user = current_user
|
15
|
+
@proposal = proposal
|
16
|
+
end
|
17
|
+
|
18
|
+
# Executes the command. Broadcasts these events:
|
19
|
+
#
|
20
|
+
# - :ok when everything is valid, together with the proposal.
|
21
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
22
|
+
#
|
23
|
+
# Returns nothing.
|
24
|
+
def call
|
25
|
+
return broadcast(:invalid) if form.invalid?
|
26
|
+
return broadcast(:invalid) unless proposal.editable_by?(current_user)
|
27
|
+
return broadcast(:invalid) if proposal_limit_reached?
|
28
|
+
|
29
|
+
if process_attachments?
|
30
|
+
build_attachment
|
31
|
+
return broadcast(:invalid) if attachment_invalid?
|
32
|
+
end
|
33
|
+
|
34
|
+
transaction do
|
35
|
+
update_proposal
|
36
|
+
create_attachment if process_attachments?
|
37
|
+
end
|
38
|
+
|
39
|
+
broadcast(:ok, proposal)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :form, :proposal, :attachment, :current_user
|
45
|
+
|
46
|
+
def update_proposal
|
47
|
+
@proposal.update_attributes!(
|
48
|
+
title: form.title,
|
49
|
+
body: form.body,
|
50
|
+
category: form.category,
|
51
|
+
scope: form.scope,
|
52
|
+
author: current_user,
|
53
|
+
decidim_user_group_id: user_group.try(:id),
|
54
|
+
address: form.address,
|
55
|
+
latitude: form.latitude,
|
56
|
+
longitude: form.longitude
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_attachment
|
61
|
+
@attachment = Attachment.new(
|
62
|
+
title: form.attachment.title,
|
63
|
+
file: form.attachment.file,
|
64
|
+
attached_to: proposal
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def attachment_invalid?
|
69
|
+
if attachment.invalid? && attachment.errors.has_key?(:file)
|
70
|
+
form.attachment.errors.add :file, attachment.errors[:file]
|
71
|
+
true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def attachment_present?
|
76
|
+
form.attachment.file.present?
|
77
|
+
end
|
78
|
+
|
79
|
+
def create_attachment
|
80
|
+
attachment.attached_to = proposal
|
81
|
+
attachment.save!
|
82
|
+
end
|
83
|
+
|
84
|
+
def attachments_allowed?
|
85
|
+
form.current_feature.settings.attachments_allowed?
|
86
|
+
end
|
87
|
+
|
88
|
+
def process_attachments?
|
89
|
+
attachments_allowed? && attachment_present?
|
90
|
+
end
|
91
|
+
|
92
|
+
def proposal_limit_reached?
|
93
|
+
proposal_limit = form.current_feature.settings.proposal_limit
|
94
|
+
|
95
|
+
return false if proposal_limit.zero?
|
96
|
+
|
97
|
+
if user_group
|
98
|
+
user_group_proposals.count >= proposal_limit
|
99
|
+
else
|
100
|
+
current_user_proposals.count >= proposal_limit
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def user_group
|
105
|
+
@user_group ||= Decidim::UserGroup.where(organization: organization, id: form.user_group_id).first
|
106
|
+
end
|
107
|
+
|
108
|
+
def organization
|
109
|
+
@organization ||= current_user.organization
|
110
|
+
end
|
111
|
+
|
112
|
+
def current_user_proposals
|
113
|
+
Proposal.where(author: current_user, feature: form.current_feature).where.not(id: proposal.id)
|
114
|
+
end
|
115
|
+
|
116
|
+
def user_group_proposals
|
117
|
+
Proposal.where(user_group: user_group, feature: form.current_feature).where.not(id: proposal.id)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -8,6 +8,8 @@ module Decidim
|
|
8
8
|
# Note that it inherits from `Decidim::Features::BaseController`, which
|
9
9
|
# override its layout and provide all kinds of useful methods.
|
10
10
|
class ApplicationController < Decidim::Features::BaseController
|
11
|
+
helper Decidim::Messaging::ConversationHelper
|
12
|
+
|
11
13
|
helper_method :proposal_limit_reached?
|
12
14
|
|
13
15
|
private
|
@@ -65,6 +65,32 @@ module Decidim
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
def edit
|
69
|
+
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
70
|
+
authorize! :edit, @proposal
|
71
|
+
|
72
|
+
@form = form(ProposalForm).from_model(@proposal)
|
73
|
+
end
|
74
|
+
|
75
|
+
def update
|
76
|
+
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
77
|
+
authorize! :edit, @proposal
|
78
|
+
|
79
|
+
@form = form(ProposalForm).from_params(params)
|
80
|
+
|
81
|
+
UpdateProposal.call(@form, current_user, @proposal) do
|
82
|
+
on(:ok) do |proposal|
|
83
|
+
flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
|
84
|
+
redirect_to proposal_path(proposal)
|
85
|
+
end
|
86
|
+
|
87
|
+
on(:invalid) do
|
88
|
+
flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim")
|
89
|
+
render :new
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
68
94
|
private
|
69
95
|
|
70
96
|
def geocoded_proposals
|
@@ -132,6 +132,29 @@ module Decidim
|
|
132
132
|
|
133
133
|
votes.count >= maximum_votes
|
134
134
|
end
|
135
|
+
|
136
|
+
# Checks whether the user is author of the given proposal, either directly
|
137
|
+
# authoring it or via a user group.
|
138
|
+
#
|
139
|
+
# user - the user to check for authorship
|
140
|
+
def authored_by?(user)
|
141
|
+
author == user || user.user_groups.include?(user_group)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Checks whether the user can edit the given proposal.
|
145
|
+
#
|
146
|
+
# user - the user to check for authorship
|
147
|
+
def editable_by?(user)
|
148
|
+
authored_by?(user) && !answered? && within_edit_time_limit?
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# Checks whether the proposal is inside the time window to be editable or not.
|
154
|
+
def within_edit_time_limit?
|
155
|
+
limit = created_at + feature.settings.proposal_edit_before_minutes.minutes
|
156
|
+
Time.current < limit
|
157
|
+
end
|
135
158
|
end
|
136
159
|
end
|
137
160
|
end
|
@@ -70,7 +70,7 @@
|
|
70
70
|
<% end %>
|
71
71
|
<td class="table-list__actions">
|
72
72
|
<% if can? :update, proposal %>
|
73
|
-
<%= icon_link_to "
|
73
|
+
<%= icon_link_to "conversation", edit_proposal_proposal_answer_path(proposal_id: proposal.id, id: proposal.id), t("actions.answer", scope: "decidim.proposals"), class: "action-icon--edit-answer" %>
|
74
74
|
<% end %>
|
75
75
|
<%= icon_link_to "eye", resource_locator(proposal).path, t("actions.preview", scope: "decidim.proposals.admin"), class: "action-icon--preview", target: :blank %>
|
76
76
|
</td>
|
@@ -20,7 +20,9 @@
|
|
20
20
|
</div>
|
21
21
|
</div>
|
22
22
|
<div class="card--list__data">
|
23
|
-
|
23
|
+
<span class="card--list__data__number">
|
24
|
+
<%= proposal.votes.size %>
|
25
|
+
</span> <%= t(".proposal_votes", count: proposal.votes.size) %>
|
24
26
|
</div>
|
25
27
|
</div>
|
26
28
|
<% end %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<% end %>
|
9
9
|
<% else %>
|
10
10
|
<% if @voted_proposals ? @voted_proposals.include?(proposal.id) : proposal.voted_by?(current_user) %>
|
11
|
-
<%= action_authorized_button_to :vote, t('.already_voted'), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), method: :delete, remote: true, data: { disable: true }, class: "card__button button #{vote_button_classes(from_proposals_list)} success" %>
|
11
|
+
<%= action_authorized_button_to :vote, t('.already_voted'), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), method: :delete, remote: true, data: { disable: true, original: t('.already_voted'), replace: t('.already_voted_hover') }, class: "card__button button #{vote_button_classes(from_proposals_list)} success", id: "vote_button" %>
|
12
12
|
<% else %>
|
13
13
|
<% if proposal.maximum_votes_reached? %>
|
14
14
|
<%= content_tag :span, t('.maximum_votes_reached'), class: "card__button button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<div class="row columns">
|
2
|
+
<%= link_to :back, class: "muted-link" do %>
|
3
|
+
<%= icon "chevron-left", class: "icon--small" %>
|
4
|
+
<%= t(".back") %>
|
5
|
+
<% end %>
|
6
|
+
<h2 class="section-heading"><%= t(".title") %></h2>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="row">
|
10
|
+
<div class="columns large-6 medium-centered">
|
11
|
+
<div class="card">
|
12
|
+
<% if translated_attribute(feature_settings.new_proposal_help_text).present? %>
|
13
|
+
<%= render partial: "decidim/shared/announcement", locals: { announcement: feature_settings.new_proposal_help_text } %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<div class="card__content">
|
17
|
+
<%= decidim_form_for(@form) do |form| %>
|
18
|
+
<div class="field">
|
19
|
+
<%= form.text_field :title %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="field">
|
23
|
+
<%= form.text_area :body, rows: 10 %>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<% if feature_settings.geocoding_enabled? %>
|
27
|
+
<div class="field">
|
28
|
+
<%= form.check_box :has_address %>
|
29
|
+
</div>
|
30
|
+
<div class="field" id="address_input">
|
31
|
+
<%= form.text_field :address %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% if @form.categories&.any? %>
|
36
|
+
<div class="field">
|
37
|
+
<%= form.categories_select :category_id, @form.categories, prompt: t(".select_a_category") %>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
<% if current_participatory_space.has_subscopes? %>
|
42
|
+
<div class="field">
|
43
|
+
<%= form.scopes_select :scope_id, prompt: I18n.t("decidim.scopes.global"), remote_path: decidim.scopes_search_path(root: current_participatory_space.scope) %>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
<% if current_user.user_groups.verified.any? %>
|
48
|
+
<div class="field">
|
49
|
+
<%= form.select :user_group_id, current_user.user_groups.verified.map{|g| [g.name, g.id]}, prompt: current_user.name %>
|
50
|
+
</div>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
<% if feature_settings.attachments_allowed? %>
|
54
|
+
<fieldset>
|
55
|
+
<legend><%= t('.attachment_legend') %></legend>
|
56
|
+
<%= form.fields_for :attachment, @form.attachment do |form| %>
|
57
|
+
<div class="field">
|
58
|
+
<%= form.text_field :title %>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<div class="field">
|
62
|
+
<%= form.upload :file, optional: false %>
|
63
|
+
</div>
|
64
|
+
<% end %>
|
65
|
+
</fieldset>
|
66
|
+
<% end %>
|
67
|
+
|
68
|
+
<div class="actions">
|
69
|
+
<%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
|
70
|
+
</div>
|
71
|
+
<% end %>
|
72
|
+
</div>
|
73
|
+
</div>
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<%= javascript_include_tag "decidim/proposals/add_proposal" %>
|
@@ -13,6 +13,12 @@
|
|
13
13
|
<%= render partial: "decidim/shared/announcement", locals: { announcement: feature_settings.new_proposal_help_text } %>
|
14
14
|
<% end %>
|
15
15
|
|
16
|
+
<div class="row column">
|
17
|
+
<div class="callout warning">
|
18
|
+
<%= t(".proposal_edit_before_minutes", count: feature_settings.proposal_edit_before_minutes) %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
16
22
|
<div class="card__content">
|
17
23
|
<%= decidim_form_for(@form) do |form| %>
|
18
24
|
<div class="field">
|
@@ -13,11 +13,19 @@
|
|
13
13
|
<button type="button" data-open="<%= current_user.present? ? 'flagModal' : 'loginModal' %>" title="<%= t('.report') %>" aria-controls="<%= current_user.present? ? 'flagModal' : 'loginModal' %>" aria-haspopup="true" tabindex="0">
|
14
14
|
<%= icon "flag", aria_label: t('.report'), class: 'icon--small' %>
|
15
15
|
</button>
|
16
|
+
<% unless @proposal.official? %>
|
17
|
+
<%= link_to link_to_current_or_new_conversation_with(@proposal.author), title: t('.contact') do %>
|
18
|
+
<%= icon "envelope-closed", aria_label: t('.contact'), class: 'icon--small' %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
16
21
|
</div>
|
17
22
|
</div>
|
18
23
|
</div>
|
19
24
|
<div class="row">
|
20
25
|
<div class="columns section view-side mediumlarge-4 mediumlarge-push-8 large-3 large-push-9">
|
26
|
+
<% if can?(:edit, @proposal) %>
|
27
|
+
<%= link_to t(".edit_proposal"), edit_proposal_path(@proposal), class: "button secondary hollow expanded button-sc button--icon follow-button" %>
|
28
|
+
<% end %>
|
21
29
|
<% if current_settings.votes_enabled? || current_user %>
|
22
30
|
<div class="card extra">
|
23
31
|
<div class="card__content">
|
@@ -49,21 +57,21 @@
|
|
49
57
|
<div class="section">
|
50
58
|
<div class="callout success">
|
51
59
|
<h5><%= t(".proposal_accepted_reason") %></h5>
|
52
|
-
<p><%=
|
60
|
+
<p><%= decidim_sanitize translated_attribute @proposal.answer %></p>
|
53
61
|
</div>
|
54
62
|
</div>
|
55
63
|
<% elsif @proposal.rejected? %>
|
56
64
|
<div class="section">
|
57
65
|
<div class="callout warning">
|
58
66
|
<h5><%= t(".proposal_rejected_reason") %></h5>
|
59
|
-
<p><%=
|
67
|
+
<p><%= decidim_sanitize translated_attribute @proposal.answer %></p>
|
60
68
|
</div>
|
61
69
|
</div>
|
62
70
|
<% else %>
|
63
71
|
<div class="section">
|
64
72
|
<div class="callout secondary">
|
65
73
|
<h5><%= t(".proposal_in_evaluation_reason") %></h5>
|
66
|
-
<p><%=
|
74
|
+
<p><%= decidim_sanitize translated_attribute @proposal.answer %></p>
|
67
75
|
</div>
|
68
76
|
</div>
|
69
77
|
<% end %>
|
data/config/locales/ca.yml
CHANGED
@@ -23,12 +23,13 @@ ca:
|
|
23
23
|
attachments_allowed: Permetre arxius adjunts
|
24
24
|
comments_enabled: Comentaris habilitats
|
25
25
|
geocoding_enabled: Geocodificació habilitada
|
26
|
-
maximum_votes_per_proposal:
|
26
|
+
maximum_votes_per_proposal: Suports màxims per proposta
|
27
27
|
new_proposal_help_text: Text d'ajuda al crear una nova proposta
|
28
28
|
official_proposals_enabled: Propostes oficials habilitades
|
29
29
|
proposal_answering_enabled: Resposta oficial a propostes activades
|
30
|
+
proposal_edit_before_minutes: Les propostes poden ser editades pels autors abans que passin aquest nombre de minuts
|
30
31
|
proposal_limit: Límit de propostes per usuari
|
31
|
-
vote_limit: Límit de
|
32
|
+
vote_limit: Límit de suports per usuari
|
32
33
|
step:
|
33
34
|
announcement: Avís
|
34
35
|
comments_blocked: Comentaris bloquejats
|
@@ -36,7 +37,7 @@ ca:
|
|
36
37
|
proposal_answering_enabled: Resposta oficial a propostes activades
|
37
38
|
votes_blocked: Suports bloquejats
|
38
39
|
votes_enabled: Suports habilitats
|
39
|
-
votes_hidden:
|
40
|
+
votes_hidden: Suports ocults (si els suports estan habilitats, marcant aquesta opció amagarà el nombre de suports)
|
40
41
|
proposals:
|
41
42
|
actions:
|
42
43
|
answer: Respondre
|
@@ -90,12 +91,12 @@ ca:
|
|
90
91
|
scope: Àmbit
|
91
92
|
state: Estat
|
92
93
|
title: Títol
|
93
|
-
votes:
|
94
|
+
votes: Suports
|
94
95
|
new:
|
95
96
|
limit_reached: No pots crear noves propostes ja que has superat el límit.
|
96
97
|
proposal_votes:
|
97
98
|
create:
|
98
|
-
error: Hi ha hagut errors en
|
99
|
+
error: Hi ha hagut errors en donar suport a la proposta.
|
99
100
|
proposals:
|
100
101
|
author:
|
101
102
|
deleted: Usuari eliminat
|
@@ -104,6 +105,12 @@ ca:
|
|
104
105
|
proposals_count:
|
105
106
|
one: 1 proposta
|
106
107
|
other: "%{count} propostes"
|
108
|
+
edit:
|
109
|
+
attachment_legend: "(Opcional) Afegir un fitxer adjunt"
|
110
|
+
back: Enrere
|
111
|
+
select_a_category: Si us plau, selecciona una categoria
|
112
|
+
send: Enviar
|
113
|
+
title: Editar proposta
|
107
114
|
filters:
|
108
115
|
accepted: Acceptades
|
109
116
|
activity: Activitat
|
@@ -120,7 +127,7 @@ ca:
|
|
120
127
|
scopes: Àmbits
|
121
128
|
search: Cerca
|
122
129
|
state: Estat
|
123
|
-
voted:
|
130
|
+
voted: Has donat suport
|
124
131
|
filters_small_view:
|
125
132
|
close_modal: Tancar finestra
|
126
133
|
filter: Filtra
|
@@ -131,29 +138,35 @@ ca:
|
|
131
138
|
view_proposal: Veure proposta
|
132
139
|
linked_proposals:
|
133
140
|
proposal_votes:
|
134
|
-
one:
|
135
|
-
other:
|
141
|
+
one: suport
|
142
|
+
other: suports
|
136
143
|
new:
|
137
144
|
attachment_legend: "(Opcional) Afegiu un fitxer adjunt"
|
138
145
|
back: Enrere
|
146
|
+
proposal_edit_before_minutes:
|
147
|
+
one: Podràs editar aquesta proposta durant el primer minut després de la creació de la proposta. Un cop passada aquesta finestra de temps, no podràs editar la proposta.
|
148
|
+
other: Podràs editar aquesta proposta durant els primers %{count} minuts després de la creació de la proposta. Un cop passada aquesta finestra de temps, no podràs editar la proposta.
|
139
149
|
select_a_category: Si us plau, seleccioni una categoria
|
140
150
|
send: Enviar
|
141
151
|
title: Nova proposta
|
142
152
|
orders:
|
143
153
|
label: 'Ordenar propostes per:'
|
144
|
-
most_voted:
|
154
|
+
most_voted: Ha rebut més suports
|
145
155
|
random: Aleatori
|
146
156
|
recent: Recent
|
147
157
|
proposal:
|
148
158
|
view_proposal: Veure proposta
|
149
159
|
show:
|
160
|
+
contact: Contactar
|
161
|
+
edit_proposal: Editar proposta
|
150
162
|
proposal_accepted_reason: 'Aquesta proposta ha estat acceptada perquè:'
|
151
163
|
proposal_in_evaluation_reason: S'està avaluant aquesta proposta
|
152
164
|
proposal_rejected_reason: 'Aquesta proposta ha estat rebutjada perquè:'
|
153
165
|
report: Informe
|
154
166
|
vote_button:
|
155
|
-
already_voted: Ja has
|
156
|
-
|
167
|
+
already_voted: Ja li has donat suport
|
168
|
+
already_voted_hover: Retirar suport
|
169
|
+
maximum_votes_reached: S'ha arribat al límit de suports
|
157
170
|
no_votes_remaining: No hi ha suports restants
|
158
171
|
vote: Donar suport
|
159
172
|
votes_blocked: Recollida de suports desactivada
|
@@ -163,14 +176,17 @@ ca:
|
|
163
176
|
other: SUPORTS
|
164
177
|
voting_rules:
|
165
178
|
maximum_votes_per_proposal:
|
166
|
-
description: Cada proposta pot rebre un màxim de %{limit}
|
179
|
+
description: Cada proposta pot rebre un màxim de %{limit} suports.
|
167
180
|
proposal_limit:
|
168
181
|
description: Pots crear fins a %{limit} propostes.
|
169
|
-
title: 'La
|
182
|
+
title: 'La selecció de propostes es regeix per les següents normes:'
|
170
183
|
vote_limit:
|
171
|
-
description: Pots
|
184
|
+
description: Pots donar suport a %{limit} propostes.
|
172
185
|
left: Restant
|
173
|
-
votes:
|
186
|
+
votes: Suports
|
187
|
+
update:
|
188
|
+
error: Hi ha hagut errors en desar la proposta.
|
189
|
+
success: La proposta s'ha actualitzat correctament.
|
174
190
|
resource_links:
|
175
191
|
included_proposals:
|
176
192
|
proposal_projects: 'Proposta formulada en aquests projectes:'
|
data/config/locales/en.yml
CHANGED
@@ -27,6 +27,7 @@ en:
|
|
27
27
|
new_proposal_help_text: New proposal help text
|
28
28
|
official_proposals_enabled: Official proposals enabled
|
29
29
|
proposal_answering_enabled: Proposal answering enabled
|
30
|
+
proposal_edit_before_minutes: Proposals can be edited by authors before this many minutes passes
|
30
31
|
proposal_limit: Proposal limit per user
|
31
32
|
vote_limit: Vote limit per user
|
32
33
|
step:
|
@@ -104,6 +105,12 @@ en:
|
|
104
105
|
proposals_count:
|
105
106
|
one: 1 proposal
|
106
107
|
other: "%{count} proposals"
|
108
|
+
edit:
|
109
|
+
attachment_legend: "(Optional) Add an attachment"
|
110
|
+
back: Back
|
111
|
+
select_a_category: Please select a category
|
112
|
+
send: Send
|
113
|
+
title: Edit proposal
|
107
114
|
filters:
|
108
115
|
accepted: Accepted
|
109
116
|
activity: Activity
|
@@ -131,11 +138,14 @@ en:
|
|
131
138
|
view_proposal: View proposal
|
132
139
|
linked_proposals:
|
133
140
|
proposal_votes:
|
134
|
-
one:
|
135
|
-
other:
|
141
|
+
one: vote
|
142
|
+
other: votes
|
136
143
|
new:
|
137
144
|
attachment_legend: "(Optional) Add an attachment"
|
138
145
|
back: Back
|
146
|
+
proposal_edit_before_minutes:
|
147
|
+
one: You will be able to edit this proposal during the first minute after the proposal was created. Once this time window passes, you will not be able to edit the proposal.
|
148
|
+
other: You will be able to edit this proposal during the first %{count} minutes after the proposal was created. Once this time window passes, you will not be able to edit the proposal.
|
139
149
|
select_a_category: Please select a category
|
140
150
|
send: Send
|
141
151
|
title: New proposal
|
@@ -147,12 +157,15 @@ en:
|
|
147
157
|
proposal:
|
148
158
|
view_proposal: View proposal
|
149
159
|
show:
|
160
|
+
contact: Contact
|
161
|
+
edit_proposal: Edit proposal
|
150
162
|
proposal_accepted_reason: 'This proposal has been accepted because:'
|
151
163
|
proposal_in_evaluation_reason: This proposal is being evaluated
|
152
164
|
proposal_rejected_reason: 'This proposal has been rejected because:'
|
153
165
|
report: Report
|
154
166
|
vote_button:
|
155
167
|
already_voted: Already voted
|
168
|
+
already_voted_hover: Unvote
|
156
169
|
maximum_votes_reached: Vote limit reached
|
157
170
|
no_votes_remaining: No votes remaining
|
158
171
|
vote: Vote
|
@@ -171,6 +184,9 @@ en:
|
|
171
184
|
description: You can vote up to %{limit} proposals.
|
172
185
|
left: Remaining
|
173
186
|
votes: Votes
|
187
|
+
update:
|
188
|
+
error: There's been errors when saving the proposal.
|
189
|
+
success: Proposal updated successfully.
|
174
190
|
resource_links:
|
175
191
|
included_proposals:
|
176
192
|
proposal_projects: 'Proposal appearing in these projects:'
|