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.
Files changed (32) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +6 -1
  3. data/app/assets/javascripts/decidim/proposals/utils.js.es6 +11 -0
  4. data/app/commands/decidim/proposals/update_proposal.rb +121 -0
  5. data/app/controllers/decidim/proposals/application_controller.rb +2 -0
  6. data/app/controllers/decidim/proposals/proposals_controller.rb +26 -0
  7. data/app/models/decidim/proposals/abilities/current_user_ability.rb +3 -0
  8. data/app/models/decidim/proposals/proposal.rb +23 -0
  9. data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
  10. data/app/views/decidim/proposals/proposals/_author.html.erb +1 -1
  11. data/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +3 -1
  12. data/app/views/decidim/proposals/proposals/_vote_button.html.erb +1 -1
  13. data/app/views/decidim/proposals/proposals/edit.html.erb +77 -0
  14. data/app/views/decidim/proposals/proposals/new.html.erb +6 -0
  15. data/app/views/decidim/proposals/proposals/show.html.erb +11 -3
  16. data/config/locales/ca.yml +31 -15
  17. data/config/locales/en.yml +18 -2
  18. data/config/locales/es.yml +18 -2
  19. data/config/locales/eu.yml +18 -3
  20. data/config/locales/fi.yml +18 -3
  21. data/config/locales/fr.yml +18 -3
  22. data/config/locales/it.yml +24 -9
  23. data/config/locales/nl.yml +48 -33
  24. data/config/locales/pl.yml +20 -4
  25. data/config/locales/pt.yml +192 -0
  26. data/config/locales/ru.yml +23 -7
  27. data/config/locales/uk.yml +21 -5
  28. data/lib/decidim/proposals/engine.rb +1 -1
  29. data/lib/decidim/proposals/feature.rb +1 -0
  30. data/lib/decidim/proposals/test/factories.rb +7 -3
  31. data/lib/decidim/proposals/version.rb +1 -1
  32. metadata +30 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: acab113b60556459cc59ae1328d6fbf71b7a84126a62787ebaca71deac6576d4
4
- data.tar.gz: 1bc2d1b5aba3ddccef8ebce7290de7d6cf0cbba9b96d5f0e3e40d00993bba547
2
+ SHA1:
3
+ metadata.gz: dd92afffe4d54576836db8fc75463fe8573cc096
4
+ data.tar.gz: 2e9aecf15cfed4d537d97181d5aa8e022c81daaf
5
5
  SHA512:
6
- metadata.gz: 2320bdc81d1cb6eaf8166a915ba01b8870e1f7f1fdf5a500121a525e1d8feb3e3d1c3ae552c20d798142ada1f88a4f1dde3891b421925388bf30960feea523a3
7
- data.tar.gz: 73abc903447deb8ccec3c3b3dcb98416dc2d79ab23a5c9fcd3cd68215cab18260f0d638ca4fbab82141d0ad304ccdce56b9a57c33d896576c5120f42cfd684a8
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
- $ bundle
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,11 @@
1
+ /* eslint-disable no-invalid-this */
2
+
3
+ (() => {
4
+ $("#vote_button").mouseover(function () {
5
+ $(this).text($(this).data('replace'));
6
+ });
7
+
8
+ $("#vote_button").mouseout(function () {
9
+ $(this).text($(this).data('original'));
10
+ });
11
+ })(this);
@@ -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
@@ -25,6 +25,9 @@ module Decidim
25
25
  end
26
26
 
27
27
  can :create, Proposal if authorized?(:create) && creation_enabled?
28
+ can :edit, Proposal do |proposal|
29
+ proposal.editable_by?(user)
30
+ end
28
31
 
29
32
  can :report, Proposal
30
33
  end
@@ -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 "chat", edit_proposal_proposal_answer_path(proposal_id: proposal.id, id: proposal.id), t("actions.answer", scope: "decidim.proposals"), class: "action-icon--edit-answer" %>
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>
@@ -18,6 +18,6 @@
18
18
  <%= t ".verified_user_group" %>
19
19
  </span>
20
20
  <% end %>
21
- <%= l proposal.created_at, format: "%d/%m/%Y" %>
21
+ <%= l proposal.created_at, format: :decidim_short %>
22
22
  </div>
23
23
  </div>
@@ -20,7 +20,9 @@
20
20
  </div>
21
21
  </div>
22
22
  <div class="card--list__data">
23
- <%==t(".proposal_votes", count: proposal.votes.size) %>
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><%= sanitize translated_attribute @proposal.answer %></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><%= sanitize translated_attribute @proposal.answer %></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><%= sanitize translated_attribute @proposal.answer %></p>
74
+ <p><%= decidim_sanitize translated_attribute @proposal.answer %></p>
67
75
  </div>
68
76
  </div>
69
77
  <% end %>
@@ -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: Vots màxims per proposta
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 vots per usuari
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: Vots ocults (si els vots estan habilitats, marcant aquesta opció amagarà el nombre de vots)
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: Vots
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 votar la proposta.
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: Votat
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: <span class="card--list__data__number">1</span>suport
135
- other: <span class="card--list__data__number">%{count}</span>suports
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: Més votat
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 votat
156
- maximum_votes_reached: S'ha arribat al límit de vots
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} vots.
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 votació es regeix per les següents normes:'
182
+ title: 'La selecció de propostes es regeix per les següents normes:'
170
183
  vote_limit:
171
- description: Pots votar fins a %{limit} propostes.
184
+ description: Pots donar suport a %{limit} propostes.
172
185
  left: Restant
173
- votes: Vots
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:'
@@ -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: <span class="card--list__data__number">1</span>vote
135
- other: <span class="card--list__data__number">%{count}</span>votes
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:'