decidim 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +2 -5
  3. data/.mention-bot +2 -1
  4. data/.yardopts +8 -0
  5. data/Gemfile.lock +64 -62
  6. data/README.md +11 -9
  7. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +3 -3
  8. data/decidim-admin/app/assets/stylesheets/decidim/admin/_email_preview.scss +5 -0
  9. data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +1 -0
  10. data/decidim-admin/app/commands/decidim/admin/create_newsletter.rb +30 -0
  11. data/decidim-admin/app/commands/decidim/admin/deliver_newsletter.rb +29 -0
  12. data/decidim-admin/app/commands/decidim/admin/destroy_participatory_process_step.rb +9 -0
  13. data/decidim-admin/app/commands/decidim/admin/update_newsletter.rb +33 -0
  14. data/decidim-admin/app/constraints/decidim/admin/organization_dashboard_constraint.rb +1 -1
  15. data/decidim-admin/app/controllers/decidim/admin/features_controller.rb +2 -2
  16. data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +115 -0
  17. data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +4 -4
  18. data/decidim-admin/app/forms/decidim/admin/newsletter_form.rb +15 -0
  19. data/decidim-admin/app/jobs/decidim/admin/newsletter_delivery_job.rb +18 -0
  20. data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +32 -0
  21. data/decidim-admin/app/models/decidim/admin/abilities/admin_user.rb +4 -0
  22. data/decidim-admin/app/models/decidim/admin/abilities/base.rb +4 -0
  23. data/decidim-admin/app/models/decidim/admin/abilities/collaborator_user.rb +19 -0
  24. data/decidim-admin/app/models/decidim/admin/abilities/participatory_process_admin.rb +1 -1
  25. data/decidim-admin/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +1 -1
  26. data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +5 -0
  27. data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +11 -0
  28. data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +47 -0
  29. data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +11 -0
  30. data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +14 -0
  31. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +1 -1
  32. data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +1 -1
  33. data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  34. data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +1 -0
  35. data/decidim-admin/config/locales/ca.yml +40 -0
  36. data/decidim-admin/config/locales/en.yml +40 -0
  37. data/decidim-admin/config/locales/es.yml +40 -0
  38. data/decidim-admin/config/routes.rb +7 -0
  39. data/decidim-admin/decidim-admin.gemspec +0 -1
  40. data/decidim-admin/lib/decidim/admin/engine.rb +1 -0
  41. data/decidim-admin/lib/decidim/admin/features/base_controller.rb +5 -1
  42. data/decidim-admin/spec/commands/create_newsletter_spec.rb +62 -0
  43. data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +45 -0
  44. data/decidim-admin/spec/commands/destroy_participatory_process_step_spec.rb +12 -0
  45. data/decidim-admin/spec/commands/update_newsletter_spec.rb +64 -0
  46. data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +147 -0
  47. data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +1 -5
  48. data/decidim-admin/spec/features/static_pages_spec.rb +16 -0
  49. data/decidim-admin/spec/forms/newsletter_form_spec.rb +47 -0
  50. data/decidim-admin/spec/jobs/newsletter_delivery_job_spec.rb +25 -0
  51. data/decidim-admin/spec/jobs/newsletter_job_spec.rb +29 -0
  52. data/decidim-admin/spec/models/abilities/collaborator_user_spec.rb +66 -0
  53. data/decidim-admin/spec/organization_dashboard_constraint_spec.rb +55 -0
  54. data/decidim-admin/spec/queries/manageable_participatory_processes_for_user_spec.rb +8 -0
  55. data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -5
  56. data/decidim-api/lib/decidim/api.rb +2 -7
  57. data/decidim-api/lib/decidim/api/{types/mutation.rb → mutation_type.rb} +0 -0
  58. data/decidim-api/lib/decidim/api/{types/query.rb → query_type.rb} +0 -0
  59. data/decidim-budgets/app/assets/javascripts/decidim/budgets/projects.js.es6 +4 -4
  60. data/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb +4 -2
  61. data/decidim-budgets/app/commands/decidim/budgets/checkout.rb +7 -3
  62. data/decidim-budgets/app/models/decidim/budgets/order.rb +16 -1
  63. data/decidim-budgets/app/models/decidim/budgets/project.rb +16 -0
  64. data/decidim-budgets/app/views/decidim/budgets/line_items/update_budget.js.erb +7 -7
  65. data/decidim-budgets/app/views/decidim/budgets/projects/_budget_confirm.html.erb +27 -25
  66. data/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb +4 -13
  67. data/decidim-budgets/app/views/decidim/budgets/projects/_order_progress.html.erb +23 -21
  68. data/decidim-budgets/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +25 -23
  69. data/decidim-budgets/app/views/decidim/budgets/projects/_order_total_budget.html.erb +3 -1
  70. data/decidim-budgets/app/views/decidim/budgets/projects/_project.html.erb +32 -30
  71. data/decidim-budgets/app/views/decidim/budgets/projects/_projects.html.erb +1 -3
  72. data/decidim-budgets/app/views/decidim/budgets/projects/index.html.erb +0 -4
  73. data/decidim-budgets/app/views/decidim/budgets/projects/show.html.erb +5 -6
  74. data/decidim-budgets/config/i18n-tasks.yml +1 -0
  75. data/decidim-budgets/config/locales/ca.yml +7 -2
  76. data/decidim-budgets/config/locales/en.yml +17 -6
  77. data/decidim-budgets/config/locales/es.yml +7 -2
  78. data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
  79. data/decidim-budgets/spec/commands/add_line_item_spec.rb +16 -3
  80. data/decidim-budgets/spec/commands/cancel_order_spec.rb +7 -1
  81. data/decidim-budgets/spec/commands/checkout_spec.rb +9 -2
  82. data/decidim-budgets/spec/commands/remove_line_item_spec.rb +16 -5
  83. data/decidim-budgets/spec/features/orders_spec.rb +8 -2
  84. data/decidim-budgets/spec/models/order_spec.rb +31 -2
  85. data/decidim-budgets/spec/shared/admin_shared_context.rb +1 -1
  86. data/decidim-comments/README.md +1 -1
  87. data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
  88. data/decidim-comments/app/frontend/comments/add_comment_form.component.jsx +156 -93
  89. data/decidim-comments/app/frontend/comments/add_comment_form.component.test.jsx +36 -23
  90. data/decidim-comments/app/frontend/comments/add_comment_form.mutation.graphql +5 -3
  91. data/decidim-comments/app/frontend/comments/add_comment_form_commentable.fragment.graphql +4 -0
  92. data/decidim-comments/app/frontend/comments/add_comment_form_session.fragment.graphql +6 -0
  93. data/decidim-comments/app/frontend/comments/comment.component.jsx +11 -13
  94. data/decidim-comments/app/frontend/comments/comment.component.test.jsx +22 -21
  95. data/decidim-comments/app/frontend/comments/comment.fragment.graphql +4 -4
  96. data/decidim-comments/app/frontend/comments/comment_data.fragment.graphql +4 -3
  97. data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +1 -1
  98. data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +3 -3
  99. data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +3 -3
  100. data/decidim-comments/app/frontend/comments/comment_thread.fragment.graphql +1 -1
  101. data/decidim-comments/app/frontend/comments/comments.component.jsx +47 -39
  102. data/decidim-comments/app/frontend/comments/comments.component.test.jsx +51 -38
  103. data/decidim-comments/app/frontend/comments/comments.query.graphql +10 -4
  104. data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +6 -3
  105. data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +7 -4
  106. data/decidim-comments/app/frontend/support/generate_comments_data.js +4 -4
  107. data/decidim-comments/app/models/decidim/comments/comment.rb +7 -9
  108. data/decidim-comments/app/queries/decidim/comments/{comments_with_replies.rb → sorted_comments.rb} +3 -8
  109. data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +44 -0
  110. data/decidim-comments/app/types/decidim/comments/commentable_mutation_type.rb +29 -0
  111. data/decidim-comments/app/types/decidim/comments/commentable_type.rb +14 -0
  112. data/decidim-comments/config/locales/ca.yml +3 -1
  113. data/decidim-comments/config/locales/en.yml +5 -2
  114. data/decidim-comments/config/locales/es.yml +3 -1
  115. data/decidim-comments/lib/decidim/comments.rb +4 -0
  116. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/add_comment_type.rb +0 -0
  117. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_mutation_type.rb +0 -0
  118. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_type.rb +11 -17
  119. data/decidim-comments/lib/decidim/comments/commentable.rb +45 -0
  120. data/decidim-comments/lib/decidim/comments/comments_helper.rb +15 -10
  121. data/decidim-comments/lib/decidim/comments/mutation_extensions.rb +8 -16
  122. data/decidim-comments/lib/decidim/comments/query_extensions.rb +5 -8
  123. data/decidim-comments/lib/decidim/comments/test/factories.rb +3 -3
  124. data/decidim-comments/spec/commands/vote_comment_spec.rb +3 -1
  125. data/decidim-comments/spec/features/comments_spec.rb +28 -14
  126. data/decidim-comments/spec/features/notifications_spec.rb +1 -1
  127. data/decidim-comments/spec/helpers/comments_helper_spec.rb +4 -27
  128. data/decidim-comments/spec/models/comment_spec.rb +7 -11
  129. data/decidim-comments/spec/models/comment_vote_spec.rb +3 -1
  130. data/decidim-comments/spec/models/seed_spec.rb +3 -4
  131. data/decidim-comments/spec/queries/{comments_with_replies_spec.rb → sorted_comments_spec.rb} +12 -29
  132. data/decidim-comments/spec/types/comment_type_spec.rb +23 -17
  133. data/decidim-comments/spec/types/commentable_mutation_type_spec.rb +34 -0
  134. data/decidim-comments/spec/types/commentable_type_spec.rb +48 -0
  135. data/decidim-comments/spec/types/mutation_type_spec.rb +5 -22
  136. data/decidim-comments/spec/types/query_type_spec.rb +0 -24
  137. data/decidim-dev/config/i18n-tasks.yml +4 -0
  138. data/decidim-dev/decidim-dev.gemspec +1 -1
  139. data/decidim-dev/lib/decidim/dev/test/rspec_support/action_mailer.rb +10 -4
  140. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +6 -5
  141. data/decidim-dev/lib/decidim/dev/test/rspec_support/i18n.rb +0 -1
  142. data/decidim-meetings/app/assets/javascripts/decidim/meetings/map.js.es6.erb +8 -3
  143. data/decidim-meetings/app/assets/stylesheets/decidim/meetings/map.css +3 -1
  144. data/decidim-meetings/app/controllers/decidim/meetings/meetings_controller.rb +2 -2
  145. data/decidim-meetings/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
  146. data/decidim-meetings/app/helpers/decidim/meetings/map_helper.rb +1 -0
  147. data/decidim-meetings/app/services/decidim/meetings/meeting_search.rb +7 -3
  148. data/decidim-meetings/app/views/decidim/meetings/meetings/_datetime.html.erb +1 -1
  149. data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +5 -5
  150. data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
  151. data/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +1 -5
  152. data/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +16 -9
  153. data/decidim-meetings/config/locales/ca.yml +2 -3
  154. data/decidim-meetings/config/locales/en.yml +2 -3
  155. data/decidim-meetings/config/locales/es.yml +2 -3
  156. data/decidim-meetings/spec/features/explore_meetings_spec.rb +75 -24
  157. data/decidim-meetings/spec/forms/close_meeting_form_spec.rb +1 -1
  158. data/decidim-meetings/spec/services/meeting_search_spec.rb +15 -12
  159. data/decidim-meetings/vendor/assets/javascripts/leaflet.markercluster.js +7 -0
  160. data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.Default.css +60 -0
  161. data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.css +14 -0
  162. data/decidim-pages/app/models/decidim/pages/page.rb +22 -0
  163. data/decidim-pages/app/views/decidim/pages/application/show.html.erb +2 -6
  164. data/decidim-pages/config/locales/ca.yml +2 -2
  165. data/decidim-pages/config/locales/en.yml +2 -2
  166. data/decidim-pages/config/locales/es.yml +2 -2
  167. data/decidim-pages/lib/decidim/pages/feature.rb +2 -2
  168. data/decidim-pages/spec/features/page_show_spec.rb +0 -33
  169. data/decidim-proposals/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -0
  170. data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -0
  171. data/decidim-proposals/app/models/decidim/proposals/abilities/admin_user.rb +45 -0
  172. data/decidim-proposals/app/models/decidim/proposals/abilities/process_admin_user.rb +57 -0
  173. data/decidim-proposals/app/models/decidim/proposals/proposal.rb +21 -0
  174. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
  175. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +16 -10
  176. data/decidim-proposals/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +4 -4
  177. data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +7 -3
  178. data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +2 -6
  179. data/decidim-proposals/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +3 -1
  180. data/decidim-proposals/app/views/decidim/proposals/proposals/_tags.html.erb +1 -1
  181. data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +23 -21
  182. data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_count.html.erb +9 -6
  183. data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_limit.html.erb +1 -3
  184. data/decidim-proposals/app/views/decidim/proposals/proposals/index.html.erb +0 -4
  185. data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
  186. data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +2 -6
  187. data/decidim-proposals/config/locales/ca.yml +8 -1
  188. data/decidim-proposals/config/locales/en.yml +8 -1
  189. data/decidim-proposals/config/locales/es.yml +8 -1
  190. data/decidim-proposals/lib/decidim/proposals/admin_engine.rb +7 -0
  191. data/decidim-proposals/lib/decidim/proposals/feature.rb +6 -2
  192. data/decidim-proposals/spec/features/proposals_spec.rb +226 -40
  193. data/decidim-proposals/spec/models/decidim/proposals/abilities/admin_user_spec.rb +62 -0
  194. data/decidim-proposals/spec/models/decidim/proposals/abilities/process_admin_user_spec.rb +63 -0
  195. data/decidim-proposals/spec/shared/manage_proposals_examples.rb +161 -50
  196. data/decidim-results/app/models/decidim/results/result.rb +21 -0
  197. data/decidim-results/app/views/decidim/results/results/index.html.erb +0 -4
  198. data/decidim-results/app/views/decidim/results/results/show.html.erb +2 -8
  199. data/decidim-results/config/i18n-tasks.yml +1 -0
  200. data/decidim-results/config/locales/ca.yml +5 -2
  201. data/decidim-results/config/locales/en.yml +5 -2
  202. data/decidim-results/config/locales/es.yml +5 -2
  203. data/decidim-results/lib/decidim/results/feature.rb +2 -2
  204. data/decidim-results/spec/services/result_stats_calculator_spec.rb +2 -2
  205. data/decidim-results/spec/shared/admin_shared_context.rb +1 -1
  206. data/decidim-system/config/i18n-tasks.yml +1 -1
  207. data/package.json +50 -51
  208. data/yarn.lock +198 -151
  209. metadata +69 -36
  210. data/decidim-admin/spec/features/admin_access_control.rb +0 -52
  211. data/decidim-api/lib/decidim/api/types/author_interface.rb +0 -13
  212. data/decidim-api/lib/decidim/api/types/localized_string.rb +0 -13
  213. data/decidim-api/lib/decidim/api/types/translated_field.rb +0 -44
  214. data/decidim-api/spec/types/localized_string_type_spec.rb +0 -31
  215. data/decidim-api/spec/types/translated_field_type_spec.rb +0 -69
  216. data/decidim-comments/app/frontend/comments/add_comment_form.fragment.graphql +0 -6
@@ -6,6 +6,7 @@ module Decidim
6
6
  # to discuss or share their thoughts about the resource.
7
7
  class Comment < ApplicationRecord
8
8
  include Decidim::Authorable
9
+ include Decidim::Comments::Commentable
9
10
 
10
11
  # Limit the max depth of a comment tree. If C is a comment and R is a reply:
11
12
  # C (depth 0)
@@ -16,7 +17,6 @@ module Decidim
16
17
  MAX_DEPTH = 3
17
18
 
18
19
  belongs_to :commentable, foreign_key: "decidim_commentable_id", foreign_type: "decidim_commentable_type", polymorphic: true
19
- has_many :replies, as: :commentable, foreign_key: "decidim_commentable_id", foreign_type: "decidim_commentable_type", class_name: Comment
20
20
  has_many :up_votes, -> { where(weight: 1) }, foreign_key: "decidim_comment_id", class_name: CommentVote, dependent: :destroy
21
21
  has_many :down_votes, -> { where(weight: -1) }, foreign_key: "decidim_comment_id", class_name: CommentVote, dependent: :destroy
22
22
 
@@ -24,16 +24,14 @@ module Decidim
24
24
  validates :depth, numericality: { greater_than_or_equal_to: 0 }
25
25
  validates :alignment, inclusion: { in: [0, 1, -1] }
26
26
 
27
- validate :commentable_can_have_replies
27
+ validate :commentable_can_have_comments
28
28
 
29
29
  before_save :compute_depth
30
30
 
31
31
  delegate :organization, to: :commentable
32
32
 
33
- # Public: Define if a comment can have replies or not
34
- #
35
- # Returns a bool value to indicate if comment can have replies
36
- def can_have_replies?
33
+ # Public: Override Commentable concern method `accepts_new_comments?`
34
+ def accepts_new_comments?
37
35
  depth < MAX_DEPTH
38
36
  end
39
37
 
@@ -59,10 +57,10 @@ module Decidim
59
57
 
60
58
  private
61
59
 
62
- # Private: Check if commentable can have replies and if not adds
60
+ # Private: Check if commentable can have comments and if not adds
63
61
  # a validation error to the model
64
- def commentable_can_have_replies
65
- errors.add(:commentable, :cannot_have_replies) if commentable.respond_to?(:can_have_replies?) && !commentable.can_have_replies?
62
+ def commentable_can_have_comments
63
+ errors.add(:commentable, :cannot_have_comments) unless commentable.accepts_new_comments?
66
64
  end
67
65
 
68
66
  # Private: Compute comment depth inside the current comment tree
@@ -2,7 +2,7 @@
2
2
  module Decidim
3
3
  module Comments
4
4
  # A class used to find comments for a commentable resource
5
- class CommentsWithReplies < Rectify::Query
5
+ class SortedComments < Rectify::Query
6
6
  attr_reader :commentable
7
7
 
8
8
  # Syntactic sugar to initialize the class and return the queried objects.
@@ -32,11 +32,6 @@ module Decidim
32
32
  scope = Comment
33
33
  .where(commentable: commentable)
34
34
  .includes(:author, :up_votes, :down_votes)
35
- .includes(
36
- replies: [:author, :up_votes, :down_votes,
37
- replies: [:author, :up_votes, :down_votes,
38
- replies: [:author, :up_votes, :down_votes]]]
39
- )
40
35
 
41
36
  scope = case @options[:order_by]
42
37
  when "older"
@@ -77,8 +72,8 @@ module Decidim
77
72
  end
78
73
 
79
74
  def count_replies(comment)
80
- if comment.replies.size.positive?
81
- comment.replies.size + comment.replies.map { |reply| count_replies(reply) }.sum
75
+ if comment.comments.size.positive?
76
+ comment.comments.size + comment.comments.sum { |reply| count_replies(reply) }
82
77
  else
83
78
  0
84
79
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Comments
4
+ # This interface represents a commentable object.
5
+ CommentableInterface = GraphQL::InterfaceType.define do
6
+ name "CommentableInterface"
7
+ description "A commentable interface"
8
+
9
+ field :id, !types.ID, "The commentable's ID"
10
+
11
+ field :type, !types.String, "The commentable's class name. i.e. `Decidim::ParticipatoryProcess`" do
12
+ property :commentable_type
13
+ end
14
+
15
+ field :acceptsNewComments, !types.Boolean, "Wether the object can have new comments or not" do
16
+ property :accepts_new_comments?
17
+ end
18
+
19
+ field :commentsHaveAlignment, !types.Boolean, "Wether the object comments have alignment or not" do
20
+ property :comments_have_alignment?
21
+ end
22
+
23
+ field :commentsHaveVotes, !types.Boolean, "Wether the object comments have votes or not" do
24
+ property :comments_have_votes?
25
+ end
26
+
27
+ field :comments do
28
+ type !types[CommentType]
29
+
30
+ argument :orderBy, types.String, "Order the comments"
31
+
32
+ resolve lambda { |obj, args, _ctx|
33
+ SortedComments.for(obj, order_by: args[:orderBy])
34
+ }
35
+ end
36
+
37
+ field :hasComments, !types.Boolean, "Check if the commentable has comments" do
38
+ resolve lambda { |obj, _args, _ctx|
39
+ obj.comments.size.positive?
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Comments
4
+ CommentableMutationType = GraphQL::ObjectType.define do
5
+ name "CommentableMutation"
6
+ description "A commentable which includes its available mutations"
7
+
8
+ field :id, !types.ID, "The Commentable's unique ID"
9
+
10
+ field :addComment, Decidim::Comments::CommentType do
11
+ description "Add a new comment to a commentable"
12
+
13
+ argument :body, !types.String, "The comments's body"
14
+ argument :alignment, types.Int, "The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'", default_value: 0
15
+ argument :userGroupId, types.ID, "The comment's user group id. Replaces the author."
16
+
17
+ resolve lambda { |obj, args, ctx|
18
+ params = { "comment" => { "body" => args[:body], "alignment" => args[:alignment], "user_group_id" => args[:userGroupId] } }
19
+ form = Decidim::Comments::CommentForm.from_params(params)
20
+ Decidim::Comments::CreateComment.call(form, ctx[:current_user], obj) do
21
+ on(:ok) do |comment|
22
+ return comment
23
+ end
24
+ end
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Comments
4
+ # This type represents a commentable object.
5
+ CommentableType = GraphQL::ObjectType.define do
6
+ name "Commentable"
7
+ description "A commentable object"
8
+
9
+ interfaces [
10
+ Decidim::Comments::CommentableInterface
11
+ ]
12
+ end
13
+ end
14
+ end
@@ -2,7 +2,7 @@ ca:
2
2
  activerecord:
3
3
  errors:
4
4
  messages:
5
- cannot_have_replies: no pot tenir respostes
5
+ cannot_have_comments: no pot tenir comentaris
6
6
  decidim:
7
7
  comments:
8
8
  comment_notification_mailer:
@@ -21,6 +21,7 @@ ca:
21
21
  subject: Tens una nova resposta del teu comentari
22
22
  components:
23
23
  add_comment_form:
24
+ account_message: "<a href=\"%{sign_in_url}\">Entra amb el teu compte</a> o <a href=\"%{sign_up_url}\">registra't</a> per a deixar un comentari.\n"
24
25
  form:
25
26
  body:
26
27
  label: Comentari
@@ -47,6 +48,7 @@ ca:
47
48
  comment_thread:
48
49
  title: Conversa amb %{authorName}
49
50
  comments:
51
+ blocked_comments_warning: Els comentaris estan desactivats a la fase actual però pots llegir els comentaris de les fases anteriors.
50
52
  loading: Carregant els comentaris ...
51
53
  title: "%{count} comentaris"
52
54
  featured_comment:
@@ -3,7 +3,7 @@ en:
3
3
  activerecord:
4
4
  errors:
5
5
  messages:
6
- cannot_have_replies: can't have replies
6
+ cannot_have_comments: can't have comments
7
7
  decidim:
8
8
  comments:
9
9
  comment_notification_mailer:
@@ -22,6 +22,8 @@ en:
22
22
  subject: You have a new reply of your comment
23
23
  components:
24
24
  add_comment_form:
25
+ account_message: "<a href=\"%{sign_in_url}\">Sign in with your account</a> or <a href=\"%{sign_up_url}\">sign up</a> to add your comment.
26
+ "
25
27
  form:
26
28
  body:
27
29
  label: Comment
@@ -32,7 +34,7 @@ en:
32
34
  label: Comment as
33
35
  opinion:
34
36
  neutral: Neutral
35
- title: Leave your comment
37
+ title: Add your comment
36
38
  comment:
37
39
  alignment:
38
40
  against: Against
@@ -48,6 +50,7 @@ en:
48
50
  comment_thread:
49
51
  title: Conversation with %{authorName}
50
52
  comments:
53
+ blocked_comments_warning: Comments are disabled in the current step, but you can read the comments from previous steps.
51
54
  loading: Loading comments ...
52
55
  title: "%{count} comments"
53
56
  featured_comment:
@@ -2,7 +2,7 @@ es:
2
2
  activerecord:
3
3
  errors:
4
4
  messages:
5
- cannot_have_replies: no pueden tener respuestas
5
+ cannot_have_comments: no puede tener comentarios
6
6
  decidim:
7
7
  comments:
8
8
  comment_notification_mailer:
@@ -21,6 +21,7 @@ es:
21
21
  subject: Uno de tus comentarios ha recibido respuesta
22
22
  components:
23
23
  add_comment_form:
24
+ account_message: "<a href=\"%{sign_in_url}\">Entra con tu cuenta</a> o <a href=\"%{sign_up_url}\">regístrate</a> para dejar tu comentario.\n"
24
25
  form:
25
26
  body:
26
27
  label: Comentario
@@ -47,6 +48,7 @@ es:
47
48
  comment_thread:
48
49
  title: Conversación con %{authorName}
49
50
  comments:
51
+ blocked_comments_warning: Los comentarios estan desactivados en la fase actual pero puedes leer los comentarios de las fases anteriores.
50
52
  loading: Cargando los comentarios ...
51
53
  title: "%{count} comentarios"
52
54
  featured_comment:
@@ -7,5 +7,9 @@ module Decidim
7
7
  # a React component which handle all the comments render and logic.
8
8
  module Comments
9
9
  autoload :CommentsHelper, "decidim/comments/comments_helper"
10
+ autoload :AddCommentType, "decidim/comments/api/add_comment_type"
11
+ autoload :CommentMutationType, "decidim/comments/api/comment_mutation_type"
12
+ autoload :CommentType, "decidim/comments/api/comment_type"
13
+ autoload :Commentable, "decidim/comments/commentable"
10
14
  end
11
15
  end
@@ -6,6 +6,10 @@ module Decidim
6
6
  name "Comment"
7
7
  description "A comment"
8
8
 
9
+ interfaces [
10
+ Decidim::Comments::CommentableInterface
11
+ ]
12
+
9
13
  field :id, !types.ID, "The Comment's unique ID"
10
14
 
11
15
  field :body, !types.String, "The comment message"
@@ -16,28 +20,12 @@ module Decidim
16
20
  }
17
21
  end
18
22
 
19
- field :author, !Decidim::Api::AuthorInterface, "The comment's author" do
23
+ field :author, !Decidim::AuthorInterface, "The comment's author" do
20
24
  resolve lambda { |obj, _args, _ctx|
21
25
  obj.user_group || obj.author
22
26
  }
23
27
  end
24
28
 
25
- field :replies, !types[CommentType], "The comment's replies" do
26
- resolve lambda { |obj, _args, _ctx|
27
- obj.replies.sort_by(&:created_at)
28
- }
29
- end
30
-
31
- field :hasReplies, !types.Boolean, "Check if the comment has replies" do
32
- resolve lambda { |obj, _args, _ctx|
33
- obj.replies.size.positive?
34
- }
35
- end
36
-
37
- field :canHaveReplies, !types.Boolean, "Define if a comment can or not have replies" do
38
- property :can_have_replies?
39
- end
40
-
41
29
  field :alignment, types.Int, "The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'"
42
30
 
43
31
  field :upVotes, !types.Int, "The number of comment's upVotes" do
@@ -63,6 +51,12 @@ module Decidim
63
51
  obj.down_voted_by?(ctx[:current_user])
64
52
  }
65
53
  end
54
+
55
+ field :hasComments, !types.Boolean, "Check if the commentable has comments" do
56
+ resolve lambda { |obj, _args, _ctx|
57
+ obj.accepts_new_comments? && obj.comments.size.positive?
58
+ }
59
+ end
66
60
  end
67
61
  end
68
62
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Comments
7
+ # Shared behaviour for commentable models.
8
+ module Commentable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Authorable
13
+
14
+ has_many :comments, as: :commentable, foreign_key: "decidim_commentable_id", foreign_type: "decidim_commentable_type", class_name: "Decidim::Comments::Comment"
15
+
16
+ # Public: Wether the object's comments are visible or not.
17
+ def commentable?
18
+ true
19
+ end
20
+
21
+ # Public: Wether the object can have new comments or not.
22
+ def accepts_new_comments?
23
+ true
24
+ end
25
+
26
+ # Public: Wether the object's comments can have alignment or not. It enables the
27
+ # alignment selector in the add new comment form.
28
+ def comments_have_alignment?
29
+ false
30
+ end
31
+
32
+ # Public: Wether the object's comments can have have votes or not. It enables the
33
+ # upvote and downvote buttons for comments.
34
+ def comments_have_votes?
35
+ false
36
+ end
37
+
38
+ # Public: Identifies the commentable type in the API.
39
+ def commentable_type
40
+ self.class.name
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -3,22 +3,28 @@ module Decidim
3
3
  module Comments
4
4
  # A helper to expose the comments component for a commentable
5
5
  module CommentsHelper
6
- # Creates a Comments component which is rendered using `react_ujs`
7
- # from react-rails gem
6
+ # Render commentable comments inside the `expanded` template content.
8
7
  #
9
8
  # resource - A commentable resource
10
- # options - A hash of options (default: {})
11
- # :arguable - A boolean value to indicate if tihs option is available
9
+ def comments_for(resource)
10
+ return unless resource.commentable?
11
+ content_for :expanded do
12
+ inline_comments_for(resource)
13
+ end
14
+ end
15
+
16
+ # Creates a Comments component which is rendered using `ReactDOM`
12
17
  #
13
- # Returns a div which contain a RectComponent to be rendered by `react_ujs`
14
- def comments_for(resource, options = {})
15
- commentable_type = resource.class.name
18
+ # resource - A commentable resource
19
+ #
20
+ # Returns a div which contain a RectComponent
21
+ def inline_comments_for(resource)
22
+ return unless resource.commentable?
23
+ commentable_type = resource.commentable_type
16
24
  commentable_id = resource.id.to_s
17
25
  node_id = "comments-for-#{commentable_type.demodulize}-#{commentable_id}"
18
-
19
26
  react_comments_component(node_id, commentableType: commentable_type,
20
27
  commentableId: commentable_id,
21
- options: options.slice(:arguable, :votable),
22
28
  locale: I18n.locale)
23
29
  end
24
30
 
@@ -35,7 +41,6 @@ module Decidim
35
41
  {
36
42
  commentableType: "#{props[:commentableType]}",
37
43
  commentableId: "#{props[:commentableId]}",
38
- options: JSON.parse("#{j(props[:options].to_json)}"),
39
44
  locale: "#{props[:locale]}"
40
45
  }
41
46
  );
@@ -11,28 +11,20 @@ module Decidim
11
11
  # Returns nothing.
12
12
  def self.extend!(type)
13
13
  type.define do
14
- field :addComment, Decidim::Comments::CommentType do
15
- description "Add a new comment to a commentable"
16
- argument :commentableId, !types.String, "The commentable's ID"
17
- argument :commentableType, !types.String, "The commentable's class name. i.e. `Decidim::ParticipatoryProcess`"
18
- argument :body, !types.String, "The comments's body"
19
- argument :alignment, types.Int, "The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'", default_value: 0
20
- argument :userGroupId, types.ID, "The comment's user group id. Replaces the author."
14
+ field :commentable, Decidim::Comments::CommentableMutationType do
15
+ description "A commentable"
21
16
 
22
- resolve lambda { |_obj, args, ctx|
23
- params = { "comment" => { "body" => args[:body], "alignment" => args[:alignment], "user_group_id" => args[:userGroupId] } }
24
- form = Decidim::Comments::CommentForm.from_params(params)
25
- commentable = args[:commentableType].constantize.find(args[:commentableId])
26
- Decidim::Comments::CreateComment.call(form, ctx[:current_user], commentable) do
27
- on(:ok) do |comment|
28
- return comment
29
- end
30
- end
17
+ argument :id, !types.String, "The commentable's ID"
18
+ argument :type, !types.String, "The commentable's class name. i.e. `Decidim::ParticipatoryProcess`"
19
+
20
+ resolve lambda { |_obj, args, _ctx|
21
+ args[:type].constantize.find(args[:id])
31
22
  }
32
23
  end
33
24
 
34
25
  field :comment, Decidim::Comments::CommentMutationType do
35
26
  description "A comment"
27
+
36
28
  argument :id, !types.ID, "The comment's id"
37
29
 
38
30
  resolve lambda { |_obj, args, _ctx|