decidim-debates 0.23.2 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_debates_manifest.js +1 -0
  3. data/app/assets/javascripts/decidim/debates/admin/debates.js.es6 +25 -0
  4. data/app/cells/decidim/debates/debate_activity_cell.rb +13 -5
  5. data/app/cells/decidim/debates/debate_m/open_date.erb +7 -0
  6. data/app/cells/decidim/debates/debate_m_cell.rb +1 -1
  7. data/app/cells/decidim/debates/reported_content/show.erb +4 -0
  8. data/app/cells/decidim/debates/reported_content_cell.rb +13 -0
  9. data/app/commands/decidim/debates/admin/create_debate.rb +3 -2
  10. data/app/commands/decidim/debates/admin/update_debate.rb +2 -1
  11. data/app/commands/decidim/debates/create_debate.rb +1 -0
  12. data/app/commands/decidim/debates/update_debate.rb +2 -1
  13. data/app/controllers/decidim/debates/debates_controller.rb +1 -5
  14. data/app/forms/decidim/debates/admin/close_debate_form.rb +1 -1
  15. data/app/forms/decidim/debates/admin/debate_form.rb +30 -2
  16. data/app/forms/decidim/debates/close_debate_form.rb +1 -1
  17. data/app/forms/decidim/debates/debate_form.rb +17 -0
  18. data/app/models/decidim/debates/debate.rb +11 -1
  19. data/app/permissions/decidim/debates/admin/permissions.rb +8 -1
  20. data/app/views/decidim/debates/admin/debates/_form.html.erb +15 -2
  21. data/app/views/decidim/debates/admin/debates/index.html.erb +10 -2
  22. data/app/views/decidim/debates/debates/_filters.html.erb +1 -1
  23. data/app/views/decidim/debates/debates/_filters_small_view.html.erb +1 -1
  24. data/app/views/decidim/debates/debates/_form.html.erb +6 -0
  25. data/app/views/decidim/debates/debates/show.html.erb +5 -21
  26. data/config/locales/ca.yml +18 -4
  27. data/config/locales/cs.yml +18 -4
  28. data/config/locales/de.yml +18 -4
  29. data/config/locales/en.yml +18 -4
  30. data/config/locales/es-MX.yml +17 -4
  31. data/config/locales/es-PY.yml +17 -4
  32. data/config/locales/es.yml +17 -4
  33. data/config/locales/fi-plain.yml +18 -4
  34. data/config/locales/fi.yml +18 -4
  35. data/config/locales/fr-CA.yml +18 -4
  36. data/config/locales/fr.yml +18 -4
  37. data/config/locales/gl.yml +10 -4
  38. data/config/locales/ja.yml +10 -4
  39. data/config/locales/nl.yml +18 -4
  40. data/config/locales/no.yml +10 -4
  41. data/config/locales/pl.yml +37 -6
  42. data/config/locales/ro-RO.yml +64 -0
  43. data/config/locales/sv.yml +10 -4
  44. data/config/locales/tr-TR.yml +17 -4
  45. data/config/locales/zh-CN.yml +10 -4
  46. data/db/migrate/20200930145546_add_scope_to_debates_debate.rb +7 -0
  47. data/db/migrate/20201126112752_archive_debates.rb +8 -0
  48. data/db/migrate/20210125101735_revert_archive_debates.rb +8 -0
  49. data/db/migrate/20210310120652_add_followable_counter_cache_to_debates.rb +16 -0
  50. data/lib/decidim/api/debate_type.rb +26 -0
  51. data/lib/decidim/api/debates_type.rb +26 -0
  52. data/lib/decidim/debates.rb +1 -0
  53. data/lib/decidim/debates/admin_engine.rb +4 -0
  54. data/lib/decidim/debates/api.rb +8 -0
  55. data/lib/decidim/debates/component.rb +22 -10
  56. data/lib/decidim/debates/test/factories.rb +1 -1
  57. data/lib/decidim/debates/version.rb +1 -1
  58. metadata +24 -14
  59. data/app/types/decidim/debates/debate_type.rb +0 -28
  60. data/app/types/decidim/debates/debates_type.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c47dbcc65279eb8e3624a1be71fc66ca2a744216fd06bb5c744662e5bc0ecaca
4
- data.tar.gz: a9f04220070a77050aa9c92ec19b7a738098c75a62cb0d24ceaecec105739194
3
+ metadata.gz: 341ff30ce354af48c66770014f8057965627f702d4a48d563384aca2abc9b0b0
4
+ data.tar.gz: 76ca73e0dc803fbd288bd9ede3d609ed2d0e980a8e179757fc9e97d61ad90252
5
5
  SHA512:
6
- metadata.gz: d80ca09bf4782d4eaf18e3aabd6cd5e790f9edd3de608b6e61be265fe71f0f712eb3192ed8cf00d453f77ed1719c0bc09ee81573936e59ae4fa00ef1df624ed7
7
- data.tar.gz: f3301123e0b354c5797049e120b0fbe2ec99cbeec73e53d77cbe9f2e12b9e8d63cfabaa337278bd2511113e7de01bddd2788138cf131421f6bd46489719c21ed
6
+ metadata.gz: f1d7ab132c7f2ef7966f430abc65e94500df5d959de139eb094f8e4d33c29ed8bb7cc8669b54cf0dc23de8347c0c96f89903fe532f7d877022f261bc63f017e7
7
+ data.tar.gz: 9dc429cb2529da455346b7c552d09363c48cc29986e66f3a9d150a3dcbc56e6504e28e52109286a4df3e2898d6d862ef130a7b7f40cb1236f7857c80adc5cf8f
@@ -0,0 +1 @@
1
+ //= link decidim/debates/admin/debates.js
@@ -0,0 +1,25 @@
1
+ ((exports) => {
2
+ const { createFieldDependentInputs } = exports.DecidimAdmin;
3
+
4
+ const $debateType = $('[name="debate[finite]"');
5
+
6
+ createFieldDependentInputs({
7
+ controllerField: $debateType,
8
+ wrapperSelector: ".debate-fields",
9
+ dependentFieldsSelector: ".debate-fields--open",
10
+ dependentInputSelector: "input",
11
+ enablingCondition: () => {
12
+ return $("#debate_finite_false").is(":checked")
13
+ }
14
+ });
15
+
16
+ createFieldDependentInputs({
17
+ controllerField: $debateType,
18
+ wrapperSelector: ".debate-fields",
19
+ dependentFieldsSelector: ".debate-fields--finite",
20
+ dependentInputSelector: "input",
21
+ enablingCondition: () => {
22
+ return $("#debate_finite_true").is(":checked")
23
+ }
24
+ });
25
+ })(window);
@@ -2,13 +2,21 @@
2
2
 
3
3
  module Decidim
4
4
  module Debates
5
- # A cell to display when Debate has been created.
5
+ # A cell to display when actions happen on a debate.
6
6
  class DebateActivityCell < ActivityCell
7
7
  def title
8
- I18n.t(
9
- "decidim.debates.last_activity.new_debate_at_html",
10
- link: participatory_space_link
11
- )
8
+ case action
9
+ when "update"
10
+ I18n.t(
11
+ "decidim.debates.last_activity.debate_updated_at_html",
12
+ link: participatory_space_link
13
+ )
14
+ else
15
+ I18n.t(
16
+ "decidim.debates.last_activity.new_debate_at_html",
17
+ link: participatory_space_link
18
+ )
19
+ end
12
20
  end
13
21
 
14
22
  def resource_link_text
@@ -0,0 +1,7 @@
1
+ <li class="card-data__item">
2
+ <div>
3
+ <strong>
4
+ <%= t("decidim.debates.debates.show.open") %>
5
+ </strong>
6
+ </div>
7
+ </li>
@@ -52,7 +52,7 @@ module Decidim
52
52
  end
53
53
 
54
54
  def debate_date
55
- return unless start_date && end_date
55
+ return render(:open_date) unless start_date && end_date
56
56
  return render(:multiple_dates) if spans_multiple_dates?
57
57
 
58
58
  render(:single_date)
@@ -0,0 +1,4 @@
1
+ <blockquote>
2
+ <h5><%= render_value model.title %></h5>
3
+ <p><%= render_value model.description %></p>
4
+ </blockquote>
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Debates
5
+ # This cells renders a small preview of the `Debate` that is
6
+ # used in the moderations panel.
7
+ class ReportedContentCell < Decidim::ReportedContentCell
8
+ def show
9
+ render :show
10
+ end
11
+ end
12
+ end
13
+ end
@@ -36,8 +36,9 @@ module Decidim
36
36
  description: parsed_description,
37
37
  information_updates: form.information_updates,
38
38
  instructions: form.instructions,
39
- end_time: form.end_time,
40
- start_time: form.start_time,
39
+ end_time: (form.end_time if form.finite),
40
+ start_time: (form.start_time if form.finite),
41
+ scope: form.scope,
41
42
  component: form.current_component,
42
43
  author: form.current_organization
43
44
  }
@@ -42,7 +42,8 @@ module Decidim
42
42
  information_updates: form.information_updates,
43
43
  instructions: form.instructions,
44
44
  end_time: form.end_time,
45
- start_time: form.start_time
45
+ start_time: form.start_time,
46
+ scope: form.scope
46
47
  )
47
48
  end
48
49
  end
@@ -42,6 +42,7 @@ module Decidim
42
42
  description: {
43
43
  I18n.locale => parsed_description
44
44
  },
45
+ scope: form.scope,
45
46
  component: form.current_component
46
47
  }
47
48
 
@@ -48,7 +48,8 @@ module Decidim
48
48
  },
49
49
  description: {
50
50
  I18n.locale => parsed_description
51
- }
51
+ },
52
+ scope: form.scope
52
53
  }
53
54
  end
54
55
  end
@@ -13,7 +13,7 @@ module Decidim
13
13
  include Flaggable
14
14
  include Decidim::Debates::Orderable
15
15
 
16
- helper_method :debates, :debate, :form_presenter, :paginated_debates, :report_form, :close_debate_form
16
+ helper_method :debates, :debate, :form_presenter, :paginated_debates, :close_debate_form
17
17
 
18
18
  def new
19
19
  enforce_permission_to :create, :debate
@@ -105,10 +105,6 @@ module Decidim
105
105
  @debate ||= debates.find_by(id: params[:id])
106
106
  end
107
107
 
108
- def report_form
109
- @report_form ||= form(Decidim::ReportForm).from_params(reason: "spam")
110
- end
111
-
112
108
  def close_debate_form
113
109
  @close_debate_form ||= form(CloseDebateForm).from_model(debate)
114
110
  end
@@ -9,7 +9,7 @@ module Decidim
9
9
 
10
10
  mimic :debate
11
11
 
12
- translatable_attribute :conclusions, String do |translated_attribute, locale|
12
+ translatable_attribute :conclusions, Decidim::Attributes::CleanString do |translated_attribute, locale|
13
13
  validates translated_attribute, presence: true, if: ->(record) { record.default_locale?(locale) }
14
14
  validates translated_attribute, length: { minimum: 10, maximum: 10_000 }, if: ->(record) { record.default_locale?(locale) }
15
15
  end
@@ -14,14 +14,18 @@ module Decidim
14
14
  attribute :start_time, Decidim::Attributes::TimeWithZone
15
15
  attribute :end_time, Decidim::Attributes::TimeWithZone
16
16
  attribute :decidim_category_id, Integer
17
+ attribute :finite, Boolean, default: true
18
+ attribute :scope_id, Integer
17
19
 
18
20
  validates :title, translatable_presence: true
19
21
  validates :description, translatable_presence: true
20
22
  validates :instructions, translatable_presence: true
21
- validates :start_time, presence: { if: ->(object) { object.end_time.present? } }, date: { before: :end_time, allow_blank: true }
22
- validates :end_time, presence: { if: ->(object) { object.start_time.present? } }, date: { after: :start_time, allow_blank: true }
23
+ validates :start_time, presence: { if: :validate_start_time? }, date: { before: :end_time, allow_blank: true, if: :validate_start_time? }
24
+ validates :end_time, presence: { if: :validate_end_time? }, date: { after: :start_time, allow_blank: true, if: :validate_end_time? }
23
25
 
24
26
  validates :category, presence: true, if: ->(form) { form.decidim_category_id.present? }
27
+ validates :scope, presence: true, if: ->(form) { form.scope_id.present? }
28
+ validates :scope_id, scope_belongs_to_component: true, if: ->(form) { form.scope_id.present? }
25
29
 
26
30
  def map_model(model)
27
31
  self.decidim_category_id = model.categorization.decidim_category_id if model.categorization
@@ -36,6 +40,30 @@ module Decidim
36
40
 
37
41
  @category ||= current_component.categories.find_by(id: decidim_category_id)
38
42
  end
43
+
44
+ # Finds the Scope from the given decidim_scope_id, uses the compoenent scope if missing.
45
+ #
46
+ # Returns a Decidim::Scope
47
+ def scope
48
+ @scope ||= @scope_id ? current_component.scopes.find_by(id: @scope_id) : current_component.scope
49
+ end
50
+
51
+ # Scope identifier
52
+ #
53
+ # Returns the scope identifier related to the meeting
54
+ def scope_id
55
+ @scope_id || scope&.id
56
+ end
57
+
58
+ private
59
+
60
+ def validate_end_time?
61
+ finite && start_time.present?
62
+ end
63
+
64
+ def validate_start_time?
65
+ end_time.present?
66
+ end
39
67
  end
40
68
  end
41
69
  end
@@ -6,7 +6,7 @@ module Decidim
6
6
  class CloseDebateForm < Decidim::Form
7
7
  mimic :debate
8
8
 
9
- attribute :conclusions, String
9
+ attribute :conclusions, Decidim::Attributes::CleanString
10
10
  attribute :debate, Debate
11
11
 
12
12
  validates :debate, presence: true
@@ -9,6 +9,7 @@ module Decidim
9
9
  attribute :title, String
10
10
  attribute :description, String
11
11
  attribute :category_id, Integer
12
+ attribute :scope_id, Integer
12
13
  attribute :user_group_id, Integer
13
14
  attribute :debate, Debate
14
15
 
@@ -17,6 +18,8 @@ module Decidim
17
18
  validates :category, presence: true, if: ->(form) { form.category_id.present? }
18
19
  validate :editable_by_user
19
20
 
21
+ validates :scope_id, scope_belongs_to_component: true, if: ->(form) { form.scope_id.present? }
22
+
20
23
  def map_model(debate)
21
24
  super
22
25
  self.debate = debate
@@ -38,6 +41,20 @@ module Decidim
38
41
  @category ||= current_component.categories.find_by(id: category_id)
39
42
  end
40
43
 
44
+ # Finds the Scope from the given scope_id, uses component scope if missing.
45
+ #
46
+ # Returns a Decidim::Scope
47
+ def scope
48
+ @scope ||= @scope_id ? current_component.scopes.find_by(id: @scope_id) : current_component.scope
49
+ end
50
+
51
+ # Scope identifier
52
+ #
53
+ # Returns the scope identifier related to the debate
54
+ def scope_id
55
+ @scope_id || scope&.id
56
+ end
57
+
41
58
  private
42
59
 
43
60
  def editable_by_user
@@ -25,7 +25,7 @@ module Decidim
25
25
  include Decidim::Endorsable
26
26
  include Decidim::Randomable
27
27
 
28
- belongs_to :last_comment_by, polymorphic: true, foreign_key: "last_comment_by_id", foreign_type: "last_comment_by_type", optional: true
28
+ belongs_to :last_comment_by, polymorphic: true, foreign_type: "last_comment_by_type", optional: true
29
29
  component_manifest_name "debates"
30
30
 
31
31
  validates :title, presence: true
@@ -62,6 +62,16 @@ module Decidim
62
62
  ResourceLocatorPresenter.new(self).url
63
63
  end
64
64
 
65
+ # Public: Overrides the `reported_attributes` Reportable concern method.
66
+ def reported_attributes
67
+ [:title, :description]
68
+ end
69
+
70
+ # Public: Overrides the `reported_searchable_content_extras` Reportable concern method.
71
+ def reported_searchable_content_extras
72
+ [normalized_author.name]
73
+ end
74
+
65
75
  # Public: Calculates whether the current debate is an AMA-styled one or not.
66
76
  # AMA-styled debates are those that have a start and end time set, and comments
67
77
  # are only open during that timelapse. AMA stands for Ask Me Anything, a type
@@ -7,10 +7,13 @@ module Decidim
7
7
  def permissions
8
8
  # The public part needs to be implemented yet
9
9
  return permission_action if permission_action.scope != :admin
10
+
11
+ can_export_comments?
12
+
10
13
  return permission_action if permission_action.subject != :debate
11
14
 
12
15
  case permission_action.action
13
- when :create, :read
16
+ when :create, :read, :export
14
17
  allow!
15
18
  when :update
16
19
  toggle_allow(debate && !debate.closed? && debate.official?)
@@ -26,6 +29,10 @@ module Decidim
26
29
  def debate
27
30
  @debate ||= context.fetch(:debate, nil)
28
31
  end
32
+
33
+ def can_export_comments?
34
+ allow! if permission_action.subject == :comments && permission_action.action == :export
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -3,7 +3,7 @@
3
3
  <h2 class="card-title"><%= title %></h2>
4
4
  </div>
5
5
 
6
- <div class="card-section">
6
+ <div class="card-section debate-fields">
7
7
  <div class="row column hashtags__container">
8
8
  <%= form.translated :text_field, :title, autofocus: true, class: "js-hashtags", hashtaggable: true %>
9
9
  </div>
@@ -20,7 +20,12 @@
20
20
  <%= form.translated :editor, :information_updates %>
21
21
  </div>
22
22
 
23
- <div class="row">
23
+ <div class="row column">
24
+ <%= label_tag :debate_type, t(".debate_type") %>
25
+ <%= form.collection_radio_buttons(:finite, [[t(".finite"), true], [t(".open"), false]], :last, :first) %>
26
+ </div>
27
+
28
+ <div class="row debate-fields--finite">
24
29
  <div class="column xlarge-6">
25
30
  <%= form.datetime_field :start_time %>
26
31
  </div>
@@ -29,8 +34,16 @@
29
34
  </div>
30
35
  </div>
31
36
 
37
+ <% if current_component.has_subscopes? %>
38
+ <div class="row column">
39
+ <%= scopes_picker_field form, :scope_id, root: current_component.scope %>
40
+ </div>
41
+ <% end %>
42
+
32
43
  <div class="row column">
33
44
  <%= form.categories_select :decidim_category_id, current_participatory_space.categories, include_blank: "", disable_parents: false %>
34
45
  </div>
35
46
  </div>
36
47
  </div>
48
+
49
+ <%= javascript_include_tag "decidim/debates/admin/debates" %>
@@ -2,8 +2,10 @@
2
2
  <div class="card-divider">
3
3
  <h2 class="card-title">
4
4
  <%= t(".title") %>
5
-
6
- <%= link_to t("actions.new", scope: "decidim.debates", name: t("models.debate.name", scope: "decidim.debates.admin")), new_debate_path, class: "button tiny button--title" if allowed_to? :create, :debate %>
5
+ <div class="button--title">
6
+ <%= export_dropdown if allowed_to? :export, :comments %>
7
+ <%= link_to t("actions.new", scope: "decidim.debates", name: t("models.debate.name", scope: "decidim.debates.admin")), new_debate_path, class: "button tiny button--simple" if allowed_to? :create, :debate %>
8
+ </div>
7
9
  </h2>
8
10
  </div>
9
11
 
@@ -39,14 +41,20 @@
39
41
  <td class="table-list__actions">
40
42
  <% if allowed_to? :update, :debate, debate: debate %>
41
43
  <%= icon_link_to "pencil", edit_debate_path(debate), t("actions.edit", scope: "decidim.debates"), class: "action-icon--edit" %>
44
+ <% else %>
45
+ <span class="action-space icon"></span>
42
46
  <% end %>
43
47
 
44
48
  <% if allowed_to? :close, :debate, debate: debate %>
45
49
  <%= icon_link_to "lock-locked", edit_debate_debate_close_path(debate_id: debate.id, id: debate.id), t("actions.close", scope: "decidim.debates"), class: "action-icon--close" %>
50
+ <% else %>
51
+ <span class="action-space icon"></span>
46
52
  <% end %>
47
53
 
48
54
  <% if allowed_to? :delete, :debate, debate: debate %>
49
55
  <%= icon_link_to "circle-x", debate_path(debate), t("actions.destroy", scope: "decidim.debates"), method: :delete, class: "action-icon--remove", data: { confirm: t("actions.confirm_destroy", scope: "decidim.debates") } %>
56
+ <% else %>
57
+ <span class="action-space icon"></span>
50
58
  <% end %>
51
59
  </td>
52
60
  </tr>
@@ -16,7 +16,7 @@
16
16
 
17
17
  <%= form.check_boxes_tree :state, filter_debates_state_values, legend_title: t(".state"), "aria-controls": "debates" %>
18
18
 
19
- <% if current_participatory_space.has_subscopes? %>
19
+ <% if current_component.has_subscopes? %>
20
20
  <%= form.check_boxes_tree :scope_id, filter_scopes_values, legend_title: t(".scope"), "aria-controls": "debates" %>
21
21
  <% end %>
22
22
 
@@ -13,6 +13,6 @@
13
13
  </button>
14
14
  </div>
15
15
  <div class="filters">
16
- <%= render partial: "filters" %>
16
+ <%= render partial: "filters", locals: { type: :small } %>
17
17
  </div>
18
18
  </div>
@@ -6,6 +6,12 @@
6
6
  <%= text_editor_for_debate_description(form) %>
7
7
  </div>
8
8
 
9
+ <% if current_component.has_subscopes? %>
10
+ <div class="row column">
11
+ <%= scopes_picker_field form, :scope_id, root: current_component.scope %>
12
+ </div>
13
+ <% end %>
14
+
9
15
  <% if current_participatory_space.categories&.any? %>
10
16
  <div class="field">
11
17
  <%= form.categories_select :category_id, current_participatory_space.categories, include_blank: t(".select_a_category"), disable_parents: false %>