decidim-core 0.10.1 → 0.11.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -11
  3. data/app/assets/images/decidim/icons.svg +25 -6
  4. data/app/assets/javascripts/decidim/account_form.js.es6 +8 -8
  5. data/app/assets/javascripts/decidim/append_elements.js.es6 +1 -1
  6. data/app/assets/javascripts/decidim/append_redirect_url_to_modals.js.es6 +5 -5
  7. data/app/assets/javascripts/decidim/data_picker.js.es6 +10 -10
  8. data/app/assets/javascripts/decidim/editor.js.es6 +37 -22
  9. data/app/assets/javascripts/decidim/filters.js.es6 +1 -1
  10. data/app/assets/javascripts/decidim/form_filter.component.js.es6 +15 -15
  11. data/app/assets/javascripts/decidim/form_filter.component.test.js +29 -29
  12. data/app/assets/javascripts/decidim/impersonation.js.es6 +3 -3
  13. data/app/assets/javascripts/decidim/input_mentions.js.es6 +100 -0
  14. data/app/assets/javascripts/decidim/input_tags.js.es6 +12 -0
  15. data/app/assets/javascripts/decidim/{map.js.es6.erb → map.js.es6} +9 -9
  16. data/app/assets/javascripts/decidim/notifications.js.es6 +10 -10
  17. data/app/assets/javascripts/decidim/orders.js.es6 +5 -5
  18. data/app/assets/javascripts/decidim/user_registrations.js.es6 +4 -4
  19. data/app/assets/javascripts/decidim/widget.js.es6 +1 -1
  20. data/app/assets/javascripts/decidim.js.es6 +10 -0
  21. data/app/assets/stylesheets/decidim/application.scss.erb +1 -1
  22. data/app/assets/stylesheets/decidim/modules/_author-avatar.scss +39 -0
  23. data/app/assets/stylesheets/decidim/modules/_cards.scss +158 -3
  24. data/app/assets/stylesheets/decidim/modules/_definition-data.scss +6 -0
  25. data/app/assets/stylesheets/decidim/modules/_extra.scss +1 -3
  26. data/app/assets/stylesheets/decidim/modules/_icons.scss +14 -6
  27. data/app/assets/stylesheets/decidim/modules/_inline-filters.scss +61 -0
  28. data/app/assets/stylesheets/decidim/modules/_input-mentions.scss +124 -0
  29. data/app/assets/stylesheets/decidim/modules/_input-tags.scss +55 -0
  30. data/app/assets/stylesheets/decidim/modules/_modules.scss +3 -0
  31. data/app/assets/stylesheets/decidim/modules/_status-labels.scss +4 -0
  32. data/app/assets/stylesheets/decidim/modules/_typography.scss +16 -0
  33. data/app/assets/stylesheets/decidim/utils/_helpers.scss +29 -0
  34. data/app/assets/stylesheets/decidim/utils/_mixins.scss +6 -0
  35. data/app/cells/decidim/author_box/show.erb +10 -0
  36. data/app/cells/decidim/author_box_cell.rb +21 -0
  37. data/app/cells/decidim/card/show.erb +17 -0
  38. data/app/cells/decidim/card_cell.rb +29 -0
  39. data/app/cells/decidim/profile/profile_inline.erb +21 -0
  40. data/app/cells/decidim/profile/show.erb +13 -0
  41. data/app/cells/decidim/profile_cell.rb +17 -0
  42. data/app/commands/decidim/create_omniauth_registration.rb +3 -2
  43. data/app/commands/decidim/create_report.rb +1 -1
  44. data/app/commands/decidim/invite_user.rb +2 -0
  45. data/app/constraints/decidim/current_component.rb +41 -0
  46. data/app/controllers/concerns/decidim/action_authorization.rb +3 -3
  47. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -1
  48. data/app/controllers/concerns/decidim/filter_resource.rb +1 -1
  49. data/app/controllers/concerns/decidim/form_factory.rb +1 -1
  50. data/app/controllers/concerns/decidim/impersonate_users.rb +6 -2
  51. data/app/controllers/concerns/decidim/needs_authorization.rb +2 -2
  52. data/app/controllers/concerns/decidim/participatory_space_context.rb +15 -0
  53. data/app/controllers/concerns/decidim/settings.rb +5 -5
  54. data/app/controllers/decidim/application_controller.rb +2 -1
  55. data/app/controllers/decidim/{features → components}/base_controller.rb +16 -8
  56. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +3 -1
  57. data/app/controllers/decidim/devise/registrations_controller.rb +1 -3
  58. data/app/controllers/decidim/doorkeeper/authorizations_controller.rb +16 -0
  59. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +46 -0
  60. data/app/controllers/decidim/doorkeeper/token_info_controller.rb +9 -0
  61. data/app/controllers/decidim/doorkeeper/tokens_controller.rb +9 -0
  62. data/app/controllers/decidim/widgets_controller.rb +1 -1
  63. data/app/forms/decidim/follow_form.rb +1 -1
  64. data/app/forms/decidim/form.rb +1 -1
  65. data/app/forms/decidim/omniauth_registration_form.rb +1 -0
  66. data/app/forms/decidim/registration_form.rb +5 -5
  67. data/app/helpers/decidim/card_helper.rb +16 -0
  68. data/app/helpers/decidim/component_path_helper.rb +36 -0
  69. data/app/helpers/decidim/icon_helper.rb +7 -7
  70. data/app/helpers/decidim/messaging/conversation_helper.rb +4 -3
  71. data/app/helpers/decidim/paginate_helper.rb +1 -1
  72. data/app/helpers/decidim/resource_helper.rb +2 -2
  73. data/app/jobs/decidim/export_job.rb +3 -3
  74. data/app/mailers/decidim/messaging/conversation_mailer.rb +0 -2
  75. data/app/middleware/decidim/current_organization.rb +2 -2
  76. data/app/models/decidim/abilities/admin_ability.rb +1 -1
  77. data/app/models/decidim/abilities/everyone_ability.rb +1 -1
  78. data/app/models/decidim/abilities/participatory_process_admin_ability.rb +2 -2
  79. data/app/models/decidim/abilities/participatory_process_collaborator_ability.rb +2 -2
  80. data/app/models/decidim/action_log.rb +7 -5
  81. data/app/models/decidim/area.rb +7 -0
  82. data/app/models/decidim/authorization.rb +14 -0
  83. data/app/models/decidim/{feature.rb → component.rb} +15 -15
  84. data/app/models/decidim/moderation.rb +1 -1
  85. data/app/models/decidim/oauth_application.rb +24 -0
  86. data/app/models/decidim/organization.rb +5 -0
  87. data/app/models/decidim/participatory_space_link.rb +20 -0
  88. data/app/models/decidim/participatory_space_private_user.rb +19 -0
  89. data/app/models/decidim/user.rb +7 -0
  90. data/app/presenters/decidim/admin_log/area_presenter.rb +38 -0
  91. data/app/presenters/decidim/admin_log/{feature_presenter.rb → component_presenter.rb} +5 -5
  92. data/app/presenters/decidim/admin_log/newsletter_resource_presenter.rb +1 -1
  93. data/app/presenters/decidim/admin_log/oauth_application_presenter.rb +50 -0
  94. data/app/presenters/decidim/admin_log/oauth_application_resource_presenter.rb +18 -0
  95. data/app/presenters/decidim/home_stats_presenter.rb +7 -7
  96. data/app/presenters/decidim/log/value_types/area_presenter.rb +1 -1
  97. data/app/presenters/decidim/log/value_types/area_type_presenter.rb +28 -0
  98. data/app/presenters/decidim/log/value_types/currency_presenter.rb +20 -0
  99. data/app/presenters/decidim/log/value_types/scope_presenter.rb +1 -1
  100. data/app/presenters/decidim/log/value_types/scope_type_presenter.rb +1 -1
  101. data/app/presenters/decidim/resource_locator_presenter.rb +3 -3
  102. data/app/services/decidim/action_authorizer.rb +9 -9
  103. data/app/services/decidim/action_logger.rb +9 -7
  104. data/app/services/decidim/email_notification_generator.rb +1 -1
  105. data/app/services/decidim/notification_generator_for_recipient.rb +1 -1
  106. data/app/services/decidim/resource_search.rb +8 -8
  107. data/app/services/decidim/settings_change.rb +5 -5
  108. data/app/services/decidim/static_map_generator.rb +1 -1
  109. data/app/types/decidim/core/attachment_type.rb +14 -0
  110. data/app/types/decidim/core/category_type.rb +16 -0
  111. data/app/types/decidim/core/coordinates_type.rb +19 -0
  112. data/app/types/decidim/core/scope_api_type.rb +16 -0
  113. data/app/uploaders/decidim/oauth_application_logo_uploader.rb +9 -0
  114. data/app/validators/geocoding_validator.rb +2 -2
  115. data/app/views/decidim/account/delete.html.erb +7 -7
  116. data/app/views/decidim/application/_collection.html.erb +1 -1
  117. data/app/views/decidim/application/_document.html.erb +1 -1
  118. data/app/views/decidim/application/_photos.html.erb +1 -1
  119. data/app/views/decidim/devise/invitations/edit.html.erb +1 -1
  120. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +1 -1
  121. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  122. data/app/views/decidim/devise/sessions/new.html.erb +2 -2
  123. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +1 -1
  124. data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +1 -1
  125. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +58 -0
  126. data/app/views/decidim/messaging/conversations/_show.html.erb +1 -1
  127. data/app/views/decidim/messaging/conversations/index.html.erb +1 -1
  128. data/app/views/decidim/notifications/index.html.erb +1 -1
  129. data/app/views/decidim/notifications_settings/show.html.erb +2 -2
  130. data/app/views/decidim/own_user_groups/index.html.erb +3 -3
  131. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +4 -4
  132. data/app/views/decidim/scopes/picker.html.erb +3 -3
  133. data/app/views/decidim/shared/_action_authorization_modal.html.erb +1 -1
  134. data/app/views/decidim/shared/_author.html.erb +1 -1
  135. data/app/views/decidim/shared/_author_reference.html.erb +1 -12
  136. data/app/views/decidim/shared/{_feature_announcement.html.erb → _component_announcement.html.erb} +2 -2
  137. data/app/views/decidim/shared/_embed_modal.html.erb +1 -1
  138. data/app/views/decidim/shared/_flag_modal.html.erb +5 -5
  139. data/app/views/decidim/shared/_login_modal.html.erb +3 -3
  140. data/app/views/decidim/shared/_private_participatory_space.html.erb +5 -0
  141. data/app/views/decidim/shared/_share_modal.html.erb +1 -1
  142. data/app/views/decidim/shared/_tags.html.erb +1 -1
  143. data/app/views/decidim/shared/_version_author.html.erb +1 -1
  144. data/app/views/decidim/widgets/_data_picker.html.erb +4 -4
  145. data/app/views/devise/mailer/confirmation_instructions.html.erb +3 -3
  146. data/app/views/devise/mailer/invite_private_user.html.erb +17 -0
  147. data/app/views/devise/mailer/invite_private_user.text.erb +15 -0
  148. data/app/views/devise/mailer/password_change.html.erb +2 -2
  149. data/app/views/devise/mailer/reset_password_instructions.html.erb +5 -5
  150. data/app/views/kaminari/decidim/_first_page.html.erb +2 -3
  151. data/app/views/kaminari/decidim/_gap.html.erb +2 -3
  152. data/app/views/kaminari/decidim/_last_page.html.erb +2 -3
  153. data/app/views/kaminari/decidim/_next_page.html.erb +2 -3
  154. data/app/views/kaminari/decidim/_page.html.erb +2 -3
  155. data/app/views/kaminari/decidim/_paginator.html.erb +1 -2
  156. data/app/views/kaminari/decidim/_prev_page.html.erb +2 -3
  157. data/app/views/layouts/decidim/_application.html.erb +4 -4
  158. data/app/views/layouts/decidim/_component_authorization_modals.html.erb +5 -0
  159. data/app/views/layouts/decidim/_cookie_warning.html.erb +2 -2
  160. data/app/views/layouts/decidim/_head.html.erb +4 -4
  161. data/app/views/layouts/decidim/_impersonation_warning.html.erb +4 -4
  162. data/app/views/layouts/decidim/_language_chooser.html.erb +1 -1
  163. data/app/views/layouts/decidim/_social_media_links.html.erb +5 -5
  164. data/app/views/layouts/decidim/_wrapper.html.erb +5 -5
  165. data/app/views/layouts/decidim/mailer.html.erb +1 -1
  166. data/app/views/layouts/decidim/widget.html.erb +5 -5
  167. data/app/views/pages/home/_hero.html.erb +1 -1
  168. data/app/views/pages/home.html.erb +6 -6
  169. data/config/locales/ca.yml +66 -27
  170. data/config/locales/en.yml +69 -30
  171. data/config/locales/es.yml +66 -27
  172. data/config/locales/eu.yml +69 -30
  173. data/config/locales/fi.yml +69 -30
  174. data/config/locales/fr.yml +85 -46
  175. data/config/locales/gl.yml +69 -30
  176. data/config/locales/it.yml +69 -30
  177. data/config/locales/nl.yml +122 -83
  178. data/config/locales/pl.yml +69 -30
  179. data/config/locales/pt-BR.yml +69 -30
  180. data/config/locales/pt.yml +69 -30
  181. data/config/locales/ru.yml +0 -7
  182. data/config/locales/sv.yml +69 -30
  183. data/config/locales/uk.yml +0 -13
  184. data/config/routes.rb +8 -0
  185. data/db/migrate/20180206183235_create_participatory_space_private_users.rb +15 -0
  186. data/db/migrate/20180221101934_fix_nickname_index.rb +5 -6
  187. data/db/migrate/20180226140756_add_version_to_action_logs.rb +5 -1
  188. data/db/migrate/20180227131727_create_participatory_space_links.rb +12 -0
  189. data/db/migrate/20180305132906_rename_features_to_components.rb +13 -0
  190. data/db/migrate/20180308113207_doorkeeper_models.rb +85 -0
  191. data/db/migrate/20180314085339_rename_maximum_votes_per_proposal_to_threshold_per_proposal.rb +2 -2
  192. data/db/migrate/{20180326075746_change_event_name_and_class_to_rename_to_publish_proposal_event.rb → 20180323102631_change_event_name_and_class_to_rename_to_publish_proposal_event.rb} +0 -0
  193. data/db/seeds.rb +12 -2
  194. data/lib/decidim/api/attachable_interface.rb +13 -0
  195. data/lib/decidim/api/authorable_interface.rb +13 -0
  196. data/lib/decidim/api/categorizable_interface.rb +13 -0
  197. data/lib/decidim/api/participatory_space_interface.rb +4 -4
  198. data/lib/decidim/api/scopable_interface.rb +13 -0
  199. data/lib/decidim/authorable.rb +8 -0
  200. data/lib/decidim/{feature_manifest.rb → component_manifest.rb} +24 -21
  201. data/lib/decidim/{feature_validator.rb → component_validator.rb} +6 -6
  202. data/lib/decidim/{features → components}/export_manifest.rb +4 -4
  203. data/lib/decidim/components/namer.rb +35 -0
  204. data/lib/decidim/components.rb +9 -0
  205. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  206. data/lib/decidim/core/api.rb +13 -0
  207. data/lib/decidim/core/engine.rb +76 -3
  208. data/lib/decidim/core/test/factories.rb +43 -10
  209. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +9 -9
  210. data/lib/decidim/core/test/shared_examples/attachable_interface_examples.rb +16 -0
  211. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +33 -0
  212. data/lib/decidim/core/test/shared_examples/categorizable_interface_examples.rb +19 -0
  213. data/lib/decidim/core/test/shared_examples/comments_examples.rb +3 -3
  214. data/lib/decidim/core/test/shared_examples/follows_examples.rb +1 -1
  215. data/lib/decidim/core/test/shared_examples/has_component.rb +21 -0
  216. data/lib/decidim/core/test/shared_examples/has_reference.rb +2 -2
  217. data/lib/decidim/core/test/shared_examples/localised_email.rb +1 -1
  218. data/lib/decidim/core/test/shared_examples/paginated_resource_examples.rb +1 -1
  219. data/lib/decidim/core/test/shared_examples/reportable.rb +8 -6
  220. data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -1
  221. data/lib/decidim/core/test/shared_examples/scopable_interface_examples.rb +19 -0
  222. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +8 -3
  223. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -1
  224. data/lib/decidim/core/test/shared_examples/user_localised_email_examples.rb +1 -1
  225. data/lib/decidim/core/test.rb +1 -1
  226. data/lib/decidim/core/version.rb +1 -1
  227. data/lib/decidim/core.rb +35 -37
  228. data/lib/decidim/events/base_event.rb +5 -5
  229. data/lib/decidim/events/simple_event.rb +8 -8
  230. data/lib/decidim/form_builder.rb +48 -3
  231. data/lib/decidim/has_attachment_collections.rb +1 -1
  232. data/lib/decidim/has_attachments.rb +1 -1
  233. data/lib/decidim/has_category.rb +2 -2
  234. data/lib/decidim/has_component.rb +23 -0
  235. data/lib/decidim/has_private_users.rb +26 -0
  236. data/lib/decidim/has_reference.rb +3 -3
  237. data/lib/decidim/page_finder.rb +1 -1
  238. data/lib/decidim/participatory_space_manifest.rb +3 -3
  239. data/lib/decidim/participatory_space_resourceable.rb +80 -0
  240. data/lib/decidim/publicable.rb +2 -2
  241. data/lib/decidim/query_extensions.rb +2 -2
  242. data/lib/decidim/rectify_ext.rb +32 -0
  243. data/lib/decidim/reportable.rb +1 -1
  244. data/lib/decidim/resource_manifest.rb +13 -13
  245. data/lib/decidim/resourceable.rb +8 -8
  246. data/lib/decidim/scopable.rb +1 -1
  247. data/lib/decidim/{scopable_feature.rb → scopable_component.rb} +1 -1
  248. data/lib/decidim/settings_manifest.rb +1 -1
  249. data/lib/decidim/stats_registry.rb +1 -1
  250. data/lib/decidim/view_model.rb +9 -0
  251. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fr.js +4 -1
  252. data/vendor/assets/javascripts/form_datepicker.js.es6 +10 -10
  253. data/vendor/assets/javascripts/quill.min.js +2 -2
  254. data/vendor/assets/javascripts/quill.min.js.map +1 -1
  255. data/vendor/assets/javascripts/tagsinput.js +683 -0
  256. data/vendor/assets/javascripts/tribute.js +1607 -0
  257. data/vendor/assets/stylesheets/quill.bubble.css +30 -16
  258. data/vendor/assets/stylesheets/quill.core.css +19 -9
  259. data/vendor/assets/stylesheets/quill.snow.css +30 -16
  260. data/vendor/assets/stylesheets/tagsinput.css +55 -0
  261. data/vendor/assets/stylesheets/tribute.css +27 -0
  262. metadata +164 -27
  263. data/app/constraints/decidim/current_feature.rb +0 -41
  264. data/app/helpers/decidim/feature_path_helper.rb +0 -36
  265. data/app/views/layouts/decidim/_feature_authorization_modals.html.erb +0 -5
  266. data/lib/decidim/core/test/shared_examples/has_feature.rb +0 -21
  267. data/lib/decidim/features/namer.rb +0 -35
  268. data/lib/decidim/features.rb +0 -9
  269. data/lib/decidim/has_feature.rb +0 -23
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples_for "has component" do
6
+ context "without a component" do
7
+ before do
8
+ subject.component = nil
9
+ end
10
+
11
+ it { is_expected.not_to be_valid }
12
+ end
13
+
14
+ context "without a valid component" do
15
+ before do
16
+ subject.component = build(:component, manifest_name: "foo-bar")
17
+ end
18
+
19
+ it { is_expected.not_to be_valid }
20
+ end
21
+ end
@@ -14,7 +14,7 @@ shared_examples_for "has reference" do
14
14
 
15
15
  context "when there is a custom resource reference generator present" do
16
16
  before do
17
- allow(Decidim).to receive(:reference_generator).and_return(->(resource, _feature) { "1234-#{resource.id}" })
17
+ allow(Decidim).to receive(:reference_generator).and_return(->(resource, _component) { "1234-#{resource.id}" })
18
18
  end
19
19
 
20
20
  it "generates a valid reference" do
@@ -37,7 +37,7 @@ shared_examples_for "has reference" do
37
37
  it "stores the reference" do
38
38
  subject.reference = nil
39
39
  subject.save!
40
- expect(subject.reload.reference).to_not be_blank
40
+ expect(subject.reload.reference).not_to be_blank
41
41
  end
42
42
  end
43
43
  end
@@ -14,7 +14,7 @@ shared_examples "localised email" do
14
14
  end
15
15
  end
16
16
 
17
- context "otherwise" do
17
+ context "when the user does not have a custom locale" do
18
18
  let(:locale) { nil }
19
19
 
20
20
  it "uses the default locale" do
@@ -4,7 +4,7 @@ shared_examples "a paginated resource" do
4
4
  let(:collection_size) { 30 }
5
5
 
6
6
  before do
7
- visit_feature
7
+ visit_component
8
8
  end
9
9
 
10
10
  it "lists 20 resources per page by default" do
@@ -3,9 +3,9 @@
3
3
  require "spec_helper"
4
4
 
5
5
  shared_examples_for "reportable" do
6
- context "is reportable" do
6
+ context "when reportable" do
7
7
  let(:user) { create(:user, organization: subject.organization) }
8
- let(:participatory_space) { subject.feature.participatory_space }
8
+ let(:participatory_space) { subject.component.participatory_space }
9
9
  let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 1) }
10
10
  let!(:report) { create(:report, moderation: moderation, user: user) }
11
11
 
@@ -13,29 +13,31 @@ shared_examples_for "reportable" do
13
13
  context "when the resource has not been reported by the given user" do
14
14
  let!(:report) { nil }
15
15
 
16
- it { expect(subject.reported_by?(user)).to be_falsey }
16
+ it { expect(subject).not_to be_reported_by(user) }
17
17
  end
18
18
 
19
19
  context "when the resource has been reported" do
20
- it { expect(subject.reported_by?(user)).to be_truthy }
20
+ it { expect(subject).to be_reported_by(user) }
21
21
  end
22
22
  end
23
23
 
24
- context "#hidden?" do
24
+ describe "#hidden?" do
25
25
  context "when the resource has not been hidden" do
26
26
  it { expect(subject).not_to be_hidden }
27
27
  end
28
28
 
29
29
  context "when the resource has been hidden" do
30
30
  let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 1, hidden_at: Time.current) }
31
+
31
32
  it { expect(subject).to be_hidden }
32
33
  end
33
34
  end
34
35
 
35
- context "#reported?" do
36
+ describe "#reported?" do
36
37
  context "when the report count is equal to 0" do
37
38
  let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 0) }
38
39
  let!(:report) { nil }
40
+
39
41
  it { expect(subject).not_to be_reported }
40
42
  end
41
43
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  shared_examples "reports" do
4
4
  context "when the user is not logged in" do
5
- it "should be given the option to sign in" do
5
+ it "gives the option to sign in" do
6
6
  visit reportable_path
7
7
 
8
8
  expect(page).to have_no_css("body.is-reveal-open")
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples_for "scopable interface" do
6
+ let!(:scope) { create(:scope, organization: model.participatory_space.organization) }
7
+
8
+ before do
9
+ model.update(scope: scope)
10
+ end
11
+
12
+ describe "scope" do
13
+ let(:query) { "{ scope { id } }" }
14
+
15
+ it "has a scope" do
16
+ expect(response).to include("scope" => { "id" => scope.id.to_s })
17
+ end
18
+ end
19
+ end
@@ -6,9 +6,9 @@ shared_examples "scope helpers" do
6
6
  let(:organization) { create(:organization) }
7
7
  let(:scopes_enabled) { true }
8
8
  let(:participatory_space_scope) { nil }
9
- let(:feature) { create(:feature, manifest_name: "dummy", participatory_space: participatory_space) }
9
+ let(:component) { create(:component, manifest_name: "dummy", participatory_space: participatory_space) }
10
10
  let(:scope) { create(:scope, organization: organization) }
11
- let(:resource) { create(:dummy_resource, feature: feature, scope: scope) }
11
+ let(:resource) { create(:dummy_resource, component: component, scope: scope) }
12
12
 
13
13
  before do
14
14
  allow(helper).to receive(:current_participatory_space).and_return(participatory_space)
@@ -29,29 +29,34 @@ shared_examples "scope helpers" do
29
29
 
30
30
  context "when the process has not scope enabled" do
31
31
  let(:scopes_enabled) { false }
32
+
32
33
  it { is_expected.to be_falsey }
33
34
  end
34
35
 
35
36
  context "when the process has a different scope than the organization" do
36
37
  let(:participatory_space_scope) { create(:scope, organization: organization) }
38
+
37
39
  it { is_expected.to be_truthy }
38
40
  end
39
41
 
40
42
  context "when the process has the same scope as the organization" do
41
43
  let(:participatory_space_scope) { scope }
44
+
42
45
  it { is_expected.to be_falsey }
43
46
  end
44
47
 
45
48
  context "when the resource has not a scope" do
46
49
  let(:scope) { nil }
50
+
47
51
  it { is_expected.to be_falsey }
48
52
  end
49
53
  end
50
54
 
51
55
  describe "scope_name_for_picker" do
52
- let(:global_name) { "Global name" }
53
56
  subject { helper.scope_name_for_picker(scope, global_name) }
54
57
 
58
+ let(:global_name) { "Global name" }
59
+
55
60
  context "when a scope is given" do
56
61
  context "when the scope has a scope type" do
57
62
  it { is_expected.to include(scope.name["en"]) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- shared_context "simple event" do
5
+ shared_context "when a simple event" do
6
6
  subject do
7
7
  described_class.new(
8
8
  resource: resource,
@@ -14,7 +14,7 @@ shared_examples "user localised email" do
14
14
  end
15
15
  end
16
16
 
17
- context "otherwise" do
17
+ context "when the user does not have a custom locale" do
18
18
  let(:locale) { nil }
19
19
 
20
20
  it "uses the default locale" do
@@ -5,7 +5,7 @@ require "decidim/core/test/shared_examples/publicable"
5
5
  require "decidim/core/test/shared_examples/localised_email"
6
6
  require "decidim/core/test/shared_examples/has_attachments"
7
7
  require "decidim/core/test/shared_examples/has_attachment_collections"
8
- require "decidim/core/test/shared_examples/has_feature"
8
+ require "decidim/core/test/shared_examples/has_component"
9
9
  require "decidim/core/test/shared_examples/has_scope"
10
10
  require "decidim/core/test/shared_examples/has_category"
11
11
  require "decidim/core/test/shared_examples/has_reference"
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.10.1"
7
+ "0.11.0.pre1"
8
8
  end
9
9
  end
10
10
  end
data/lib/decidim/core.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "decidim/core/engine"
4
+ require "decidim/core/api"
4
5
  require "decidim/core/version"
5
6
 
6
7
  # Decidim configuration.
@@ -9,7 +10,7 @@ module Decidim
9
10
  autoload :FormBuilder, "decidim/form_builder"
10
11
  autoload :AuthorizationFormBuilder, "decidim/authorization_form_builder"
11
12
  autoload :FilterFormBuilder, "decidim/filter_form_builder"
12
- autoload :FeatureManifest, "decidim/feature_manifest"
13
+ autoload :ComponentManifest, "decidim/component_manifest"
13
14
  autoload :ParticipatorySpaceManifest, "decidim/participatory_space_manifest"
14
15
  autoload :ResourceManifest, "decidim/resource_manifest"
15
16
  autoload :Resourceable, "decidim/resourceable"
@@ -20,16 +21,16 @@ module Decidim
20
21
  autoload :Participable, "decidim/participable"
21
22
  autoload :Publicable, "decidim/publicable"
22
23
  autoload :Scopable, "decidim/scopable"
23
- autoload :ScopableFeature, "decidim/scopable_feature"
24
+ autoload :ScopableComponent, "decidim/scopable_component"
24
25
  autoload :ContentParsers, "decidim/content_parsers"
25
26
  autoload :ContentRenderers, "decidim/content_renderers"
26
27
  autoload :ContentProcessor, "decidim/content_processor"
27
- autoload :Features, "decidim/features"
28
+ autoload :Components, "decidim/components"
28
29
  autoload :HasAttachmentCollections, "decidim/has_attachment_collections"
29
30
  autoload :HasAttachments, "decidim/has_attachments"
30
- autoload :FeatureValidator, "decidim/feature_validator"
31
+ autoload :ComponentValidator, "decidim/component_validator"
31
32
  autoload :HasSettings, "decidim/has_settings"
32
- autoload :HasFeature, "decidim/has_feature"
33
+ autoload :HasComponent, "decidim/has_component"
33
34
  autoload :HasCategory, "decidim/has_category"
34
35
  autoload :Followable, "decidim/followable"
35
36
  autoload :FriendlyDates, "decidim/friendly_dates"
@@ -50,6 +51,9 @@ module Decidim
50
51
  autoload :ViewHooks, "decidim/view_hooks"
51
52
  autoload :NewsletterEncryptor, "decidim/newsletter_encryptor"
52
53
  autoload :QueryExtensions, "decidim/query_extensions"
54
+ autoload :ParticipatorySpaceResourceable, "decidim/participatory_space_resourceable"
55
+ autoload :HasPrivateUsers, "decidim/has_private_users"
56
+ autoload :ViewModel, "decidim/view_model"
53
57
 
54
58
  include ActiveSupport::Configurable
55
59
 
@@ -123,7 +127,7 @@ module Decidim
123
127
  config_accessor :geocoder
124
128
 
125
129
  # Exposes a configuration option: a custom method to generate references.
126
- # If overwritten, it should handle both feature resources and participatory spaces.
130
+ # If overwritten, it should handle both component resources and participatory spaces.
127
131
  # Default: Calculates a unique reference for the model in
128
132
  # the following format:
129
133
  #
@@ -135,12 +139,12 @@ module Decidim
135
139
  # 2017-02: Year-Month of the resource creation date
136
140
  # 6589: ID of the resource
137
141
  config_accessor :reference_generator do
138
- lambda do |resource, feature|
142
+ lambda do |resource, component|
139
143
  ref = ""
140
144
 
141
- if resource.is_a?(Decidim::HasFeature) && feature.present?
142
- # It's a feature resource
143
- ref = feature.participatory_space.organization.reference_prefix
145
+ if resource.is_a?(Decidim::HasComponent) && component.present?
146
+ # It's a component resource
147
+ ref = component.participatory_space.organization.reference_prefix
144
148
  elsif resource.is_a?(Decidim::Participable)
145
149
  # It's a participatory space
146
150
  ref = resource.organization.reference_prefix
@@ -190,7 +194,7 @@ module Decidim
190
194
  config_accessor :base_uploads_path
191
195
 
192
196
  # Public: Registers a global engine. This method is intended to be used
193
- # by feature engines that also offer unscoped functionality
197
+ # by component engines that also offer unscoped functionality
194
198
  #
195
199
  # name - The name of the engine to register. Should be unique.
196
200
  # engine - The engine to register.
@@ -226,18 +230,18 @@ module Decidim
226
230
  @global_engines ||= {}
227
231
  end
228
232
 
229
- # Public: Registers a feature, usually held in an external library or in a
233
+ # Public: Registers a component, usually held in an external library or in a
230
234
  # separate folder in the main repository. Exposes a DSL defined by
231
- # `Decidim::FeatureManifest`.
235
+ # `Decidim::ComponentManifest`.
232
236
  #
233
- # Feature manifests are held in a global registry and are used in all kinds of
234
- # places to figure out what new components or functionalities the feature provides.
237
+ # Component manifests are held in a global registry and are used in all kinds of
238
+ # places to figure out what new components or functionalities the component provides.
235
239
  #
236
- # name - A Symbol with the feature's unique name.
240
+ # name - A Symbol with the component's unique name.
237
241
  #
238
242
  # Returns nothing.
239
- def self.register_feature(name, &block)
240
- feature_registry.register(name, &block)
243
+ def self.register_component(name, &block)
244
+ component_registry.register(name, &block)
241
245
  end
242
246
 
243
247
  # Public: Registers a participatory space, usually held in an external library
@@ -255,12 +259,12 @@ module Decidim
255
259
  participatory_space_registry.register(name, &block)
256
260
  end
257
261
 
258
- # Public: Finds all registered feature manifest's via the `register_feature`
262
+ # Public: Finds all registered component manifest's via the `register_component`
259
263
  # method.
260
264
  #
261
- # Returns an Array[FeatureManifest].
262
- def self.feature_manifests
263
- feature_registry.manifests
265
+ # Returns an Array[ComponentManifest].
266
+ def self.component_manifests
267
+ component_registry.manifests
264
268
  end
265
269
 
266
270
  # Public: Finds all registered participatory space manifest's via the
@@ -271,13 +275,13 @@ module Decidim
271
275
  participatory_space_registry.manifests
272
276
  end
273
277
 
274
- # Public: Finds a feature manifest by the feature's name.
278
+ # Public: Finds a component manifest by the component's name.
275
279
  #
276
- # name - The name of the FeatureManifest to find.
280
+ # name - The name of the ComponentManifest to find.
277
281
  #
278
- # Returns a FeatureManifest if found, nil otherwise.
279
- def self.find_feature_manifest(name)
280
- feature_registry.find(name.to_sym)
282
+ # Returns a ComponentManifest if found, nil otherwise.
283
+ def self.find_component_manifest(name)
284
+ component_registry.find(name.to_sym)
281
285
  end
282
286
 
283
287
  # Public: Finds a participatory space manifest by the participatory space's
@@ -297,12 +301,12 @@ module Decidim
297
301
  #
298
302
  # Returns a ResourceManifest if found, nil otherwise.
299
303
  def self.find_resource_manifest(resource_name_or_klass)
300
- feature_registry.find_resource_manifest(resource_name_or_klass)
304
+ component_registry.find_resource_manifest(resource_name_or_klass)
301
305
  end
302
306
 
303
- # Public: Stores the registry of features
304
- def self.feature_registry
305
- @feature_registry ||= ManifestRegistry.new(:features)
307
+ # Public: Stores the registry of components
308
+ def self.component_registry
309
+ @component_registry ||= ManifestRegistry.new(:components)
306
310
  end
307
311
 
308
312
  # Public: Stores the registry of participatory spaces
@@ -333,10 +337,4 @@ module Decidim
333
337
  def self.traceability
334
338
  @traceability ||= Traceability.new
335
339
  end
336
-
337
- module Core
338
- autoload :ParticipatorySpaceInterface, "decidim/api/participatory_space_interface"
339
- autoload :ComponentInterface, "decidim/api/component_interface"
340
- autoload :AuthorInterface, "decidim/api/author_interface"
341
- end
342
340
  end
@@ -71,7 +71,7 @@ module Decidim
71
71
  def notifiable?
72
72
  return false if resource.is_a?(Decidim::Publicable) && !resource.published?
73
73
  return false if participatory_space.is_a?(Decidim::Publicable) && !participatory_space&.published?
74
- return false unless feature&.published?
74
+ return false unless component&.published?
75
75
 
76
76
  true
77
77
  end
@@ -80,13 +80,13 @@ module Decidim
80
80
 
81
81
  attr_reader :event_name, :resource, :user, :extra
82
82
 
83
- def feature
84
- return resource.feature if resource.is_a?(Decidim::HasFeature)
85
- return resource if resource.is_a?(Decidim::Feature)
83
+ def component
84
+ return resource.component if resource.is_a?(Decidim::HasComponent)
85
+ return resource if resource.is_a?(Decidim::Component)
86
86
  end
87
87
 
88
88
  def participatory_space
89
- feature&.participatory_space
89
+ component&.participatory_space
90
90
  end
91
91
 
92
92
  def resource_title
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Events
5
- # Extends the BaseEvent to add common features to most events so you don't
5
+ # Extends the BaseEvent to add common components to most events so you don't
6
6
  # need to write each time the same code.
7
7
  #
8
8
  # The only convention you need to keep in mind is that the event name will be
@@ -10,7 +10,7 @@ module Decidim
10
10
  class SimpleEvent < BaseEvent
11
11
  include Decidim::Events::EmailEvent
12
12
  include Decidim::Events::NotificationEvent
13
- include Decidim::FeaturePathHelper
13
+ include Decidim::ComponentPathHelper
14
14
 
15
15
  class_attribute :i18n_interpolations
16
16
  self.i18n_interpolations = []
@@ -59,16 +59,16 @@ module Decidim
59
59
  default_i18n_options.merge(event_interpolations)
60
60
  end
61
61
 
62
- # Caches the path for the given resource when it's a Decidim::Feature.
62
+ # Caches the path for the given resource when it's a Decidim::Component.
63
63
  def resource_path
64
- return super unless resource.is_a?(Decidim::Feature)
65
- @resource_path ||= main_feature_path(resource)
64
+ return super unless resource.is_a?(Decidim::Component)
65
+ @resource_path ||= main_component_path(resource)
66
66
  end
67
67
 
68
- # Caches the URL for the given resource when it's a Decidim::Feature.
68
+ # Caches the URL for the given resource when it's a Decidim::Component.
69
69
  def resource_url
70
- return super unless resource.is_a?(Decidim::Feature)
71
- @resource_url ||= main_feature_url(resource)
70
+ return super unless resource.is_a?(Decidim::Component)
71
+ @resource_url ||= main_component_url(resource)
72
72
  end
73
73
 
74
74
  # Caches the URL for the resource's participatory space.
@@ -79,26 +79,71 @@ module Decidim
79
79
  safe_join [label_tabs, tabs_content]
80
80
  end
81
81
 
82
+ # Public: Generates an form field for each social.
83
+ #
84
+ # type - The form field's type, like `text_area` or `text_input`
85
+ # name - The name of the field
86
+ # handlers - The social handlers to be created
87
+ # options - The set of options to send to the field
88
+ #
89
+ # Renders form fields for each locale.
90
+ def social_field(type, name, handlers, options = {})
91
+ tabs_id = options[:tabs_id] || "#{object_name}-#{name}-tabs"
92
+
93
+ label_tabs = content_tag(:div, class: "label--tabs") do
94
+ field_label = label_i18n(name, options[:label] || label_for(name))
95
+
96
+ tabs_panels = "".html_safe
97
+ if options[:label] != false
98
+ tabs_panels = content_tag(:ul, class: "tabs tabs--lang", id: tabs_id, data: { tabs: true }) do
99
+ handlers.each_with_index.inject("".html_safe) do |string, (handler, index)|
100
+ string + content_tag(:li, class: tab_element_class_for("title", index)) do
101
+ title = I18n.t(".#{handler}", scope: "activemodel.attributes.#{object_name}")
102
+ tab_content_id = "#{tabs_id}-#{name}-panel-#{index}"
103
+ content_tag(:a, title, href: "##{tab_content_id}")
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ safe_join [field_label, tabs_panels]
110
+ end
111
+
112
+ tabs_content = content_tag(:div, class: "tabs-content", data: { tabs_content: tabs_id }) do
113
+ handlers.each_with_index.inject("".html_safe) do |string, (handler, index)|
114
+ tab_content_id = "#{tabs_id}-#{name}-panel-#{index}"
115
+ string + content_tag(:div, class: tab_element_class_for("panel", index), id: tab_content_id) do
116
+ send(type, "#{handler}_handler", options.merge(label: false))
117
+ end
118
+ end
119
+ end
120
+
121
+ safe_join [label_tabs, tabs_content]
122
+ end
123
+
82
124
  # Public: generates a hidden field and a container for WYSIWYG editor
83
125
  #
84
126
  # name - The name of the field
85
127
  # options - The set of options to send to the field
86
- # :label - The Boolean value to create or not the input label (optional) (default: true)
128
+ # :label - The Boolean value to create or not the input label (optional) (default: true)
87
129
  # :toolbar - The String value to configure WYSIWYG toolbar. It should be 'basic' or
88
130
  # or 'full' (optional) (default: 'basic')
89
- # :lines - The Integer to indicate how many lines should editor have (optional) (default: 10)
131
+ # :lines - The Integer to indicate how many lines should editor have (optional) (default: 10)
132
+ # :disabled - Whether the editor should be disabled
90
133
  #
91
134
  # Renders a container with both hidden field and editor container
92
135
  def editor(name, options = {})
93
136
  options[:toolbar] ||= "basic"
94
137
  options[:lines] ||= 10
138
+ options[:disabled] ||= false
95
139
 
96
140
  content_tag(:div, class: "editor") do
97
141
  template = ""
98
142
  template += label(name, options[:label].to_s || name) if options[:label] != false
99
143
  template += hidden_field(name, options)
100
144
  template += content_tag(:div, nil, class: "editor-container", data: {
101
- toolbar: options[:toolbar]
145
+ toolbar: options[:toolbar],
146
+ disabled: options[:disabled]
102
147
  }, style: "height: #{options[:lines]}rem")
103
148
  template += error_for(name, options) if error?(name)
104
149
  template.html_safe
@@ -3,7 +3,7 @@
3
3
  require "active_support/concern"
4
4
 
5
5
  module Decidim
6
- # A concern with the features needed when you want a model to be able to create
6
+ # A concern with the components needed when you want a model to be able to create
7
7
  # links from it to another resource.
8
8
  module HasAttachmentCollections
9
9
  extend ActiveSupport::Concern
@@ -3,7 +3,7 @@
3
3
  require "active_support/concern"
4
4
 
5
5
  module Decidim
6
- # A concern with the features needed when you want a model to be able to create
6
+ # A concern with the components needed when you want a model to be able to create
7
7
  # links from it to another resource.
8
8
  module HasAttachments
9
9
  extend ActiveSupport::Concern
@@ -3,7 +3,7 @@
3
3
  require "active_support/concern"
4
4
 
5
5
  module Decidim
6
- # A concern with the features needed when you want a model to have a category.
6
+ # A concern with the components needed when you want a model to have a category.
7
7
  module HasCategory
8
8
  extend ActiveSupport::Concern
9
9
 
@@ -22,7 +22,7 @@ module Decidim
22
22
 
23
23
  def category_belongs_to_organization
24
24
  return unless category
25
- errors.add(:category, :invalid) unless feature.categories.where(id: category.id).exists?
25
+ errors.add(:category, :invalid) unless component.categories.where(id: category.id).exists?
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+ require "decidim/component_validator"
5
+
6
+ module Decidim
7
+ # A concern with the components needed when you want a model to have a component.
8
+ module HasComponent
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ belongs_to :component, foreign_key: "decidim_component_id", class_name: "Decidim::Component"
13
+ delegate :organization, to: :component, allow_nil: true
14
+ delegate :participatory_space, to: :component, allow_nil: true
15
+ end
16
+
17
+ class_methods do
18
+ def component_manifest_name(manifest_name)
19
+ validates :component, component: { manifest: manifest_name || name.demodulize.pluralize.downcase }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ # A concern with the features needed when you want a model to be able to create
7
+ # private users
8
+ module HasPrivateUsers
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ has_many :participatory_space_private_users, class_name: "Decidim::ParticipatorySpacePrivateUser", as: :privatable_to, dependent: :destroy
13
+ has_many :users, through: :participatory_space_private_users, class_name: "Decidim::User", foreign_key: "private_user_to_id"
14
+
15
+ scope :visible_for, lambda { |user|
16
+ joins("LEFT JOIN decidim_participatory_space_private_users ON
17
+ decidim_participatory_space_private_users.privatable_to_id = #{table_name}.id")
18
+ .where("(private_space = ? and decidim_participatory_space_private_users.decidim_user_id = ?) or private_space = ? ", true, user, false)
19
+ }
20
+
21
+ def self.public_spaces
22
+ super.where(private_space: false)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -3,7 +3,7 @@
3
3
  require "active_support/concern"
4
4
 
5
5
  module Decidim
6
- # A concern with the features needed when you want a model to have a
6
+ # A concern with the components needed when you want a model to have a
7
7
  # reference.
8
8
  module HasReference
9
9
  extend ActiveSupport::Concern
@@ -20,12 +20,12 @@ module Decidim
20
20
  private
21
21
 
22
22
  # Public: Calculates a unique reference for the model using the function
23
- # provided by configuration. Works for both feature resources and
23
+ # provided by configuration. Works for both component resources and
24
24
  # participatory spaces.
25
25
  #
26
26
  # Returns a String.
27
27
  def calculate_reference
28
- Decidim.reference_generator.call(self, respond_to?(:feature) ? feature : nil)
28
+ Decidim.reference_generator.call(self, respond_to?(:component) ? component : nil)
29
29
  end
30
30
 
31
31
  # Internal: Sets the unique reference to the model. Note that if the resource