decidim-core 0.29.1 → 0.29.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +0 -3
  3. data/app/cells/decidim/author/show.erb +5 -4
  4. data/app/cells/decidim/author_cell.rb +26 -0
  5. data/app/cells/decidim/card_s/show.erb +5 -3
  6. data/app/cells/decidim/diff_cell.rb +4 -0
  7. data/app/cells/decidim/newsletter_templates/image_text_cta_cell.rb +1 -1
  8. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +5 -3
  9. data/app/cells/decidim/profile_actions/show.erb +1 -1
  10. data/app/cells/decidim/report_button/already_reported_modal.erb +2 -2
  11. data/app/cells/decidim/report_button/flag_modal.erb +13 -27
  12. data/app/cells/decidim/report_button_cell.rb +2 -8
  13. data/app/cells/decidim/report_user_button/already_reported_modal.erb +11 -0
  14. data/app/cells/decidim/report_user_button/flag_modal.erb +46 -0
  15. data/app/cells/decidim/report_user_button/show.erb +2 -0
  16. data/app/cells/decidim/report_user_button_cell.rb +59 -0
  17. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  18. data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
  19. data/app/cells/decidim/translation_bar/show.erb +2 -2
  20. data/app/cells/decidim/translation_bar_cell.rb +1 -1
  21. data/app/cells/decidim/user_activity/show.erb +1 -1
  22. data/app/commands/decidim/create_omniauth_registration.rb +14 -8
  23. data/app/commands/decidim/create_report.rb +1 -6
  24. data/app/commands/decidim/destroy_account.rb +3 -0
  25. data/app/commands/decidim/search.rb +14 -0
  26. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  27. data/app/controllers/decidim/links_controller.rb +1 -1
  28. data/app/controllers/decidim/profiles_controller.rb +6 -2
  29. data/app/controllers/decidim/reports_controller.rb +1 -1
  30. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  31. data/app/forms/decidim/account_form.rb +5 -2
  32. data/app/helpers/concerns/decidim/user_role_checker.rb +46 -0
  33. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  34. data/app/helpers/decidim/map_helper.rb +6 -1
  35. data/app/helpers/decidim/orders_helper.rb +2 -1
  36. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  37. data/app/helpers/decidim/sanitize_helper.rb +11 -2
  38. data/app/jobs/decidim/hide_child_resources_job.rb +24 -0
  39. data/app/mailers/decidim/reported_mailer.rb +1 -0
  40. data/app/models/decidim/action_log.rb +1 -9
  41. data/app/models/decidim/attachment.rb +1 -1
  42. data/app/models/decidim/report.rb +1 -1
  43. data/app/models/decidim/user.rb +0 -4
  44. data/app/models/decidim/user_base_entity.rb +4 -0
  45. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -6
  46. data/app/packs/src/decidim/datepicker/datepicker_functions.js +3 -3
  47. data/app/packs/src/decidim/direct_uploads/upload_field.js +21 -8
  48. data/app/packs/src/decidim/index.js +5 -0
  49. data/app/packs/src/decidim/map/provider/here.js +1 -1
  50. data/app/packs/src/decidim/remote_tooltips.js +38 -0
  51. data/app/packs/src/decidim/toggle.js +1 -1
  52. data/app/packs/src/decidim/tooltips.js +42 -22
  53. data/app/packs/stylesheets/decidim/_content_blocks.scss +4 -0
  54. data/app/packs/stylesheets/decidim/_hashtags.scss +5 -0
  55. data/app/packs/stylesheets/decidim/_header.scss +11 -5
  56. data/app/packs/stylesheets/decidim/_labels.scss +1 -1
  57. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  58. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  59. data/app/packs/stylesheets/decidim/application.scss +1 -0
  60. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +2 -1
  61. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  62. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  63. data/app/presenters/decidim/user_presenter.rb +1 -1
  64. data/app/services/decidim/base_diff_renderer.rb +28 -2
  65. data/app/services/decidim/email_notification_generator.rb +14 -5
  66. data/app/services/decidim/static_map_generator.rb +1 -1
  67. data/app/views/decidim/last_activities/index.html.erb +1 -1
  68. data/app/views/decidim/pages/_tabbed.html.erb +2 -2
  69. data/app/views/decidim/reported_mailer/hide.html.erb +17 -1
  70. data/app/views/decidim/reported_mailer/report.html.erb +1 -1
  71. data/app/views/decidim/searches/_count.html.erb +1 -1
  72. data/app/views/decidim/searches/_filters.html.erb +40 -38
  73. data/app/views/decidim/shared/_orders.html.erb +2 -2
  74. data/app/views/layouts/decidim/footer/_main_legal.html.erb +1 -1
  75. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  76. data/config/locales/ar.yml +56 -27
  77. data/config/locales/bg.yml +10 -24
  78. data/config/locales/bn-BD.yml +1 -0
  79. data/config/locales/bs-BA.yml +100 -0
  80. data/config/locales/ca-IT.yml +2111 -0
  81. data/config/locales/ca.yml +70 -38
  82. data/config/locales/cs.yml +60 -32
  83. data/config/locales/de.yml +66 -38
  84. data/config/locales/el.yml +17 -15
  85. data/config/locales/en.yml +48 -16
  86. data/config/locales/eo.yml +2 -0
  87. data/config/locales/es-MX.yml +61 -29
  88. data/config/locales/es-PY.yml +66 -34
  89. data/config/locales/es.yml +71 -39
  90. data/config/locales/eu.yml +303 -261
  91. data/config/locales/fi-plain.yml +48 -28
  92. data/config/locales/fi.yml +85 -65
  93. data/config/locales/fr-CA.yml +64 -27
  94. data/config/locales/fr.yml +62 -25
  95. data/config/locales/ga-IE.yml +13 -4
  96. data/config/locales/gl.yml +33 -15
  97. data/config/locales/hu.yml +12 -26
  98. data/config/locales/id-ID.yml +32 -16
  99. data/config/locales/is-IS.yml +18 -2
  100. data/config/locales/it.yml +54 -27
  101. data/config/locales/ja.yml +70 -38
  102. data/config/locales/lb.yml +33 -22
  103. data/config/locales/lt.yml +10 -18
  104. data/config/locales/lv.yml +26 -15
  105. data/config/locales/nl.yml +33 -19
  106. data/config/locales/no.yml +27 -16
  107. data/config/locales/pl.yml +8 -22
  108. data/config/locales/pt-BR.yml +13 -25
  109. data/config/locales/pt.yml +32 -16
  110. data/config/locales/ro-RO.yml +500 -220
  111. data/config/locales/ru.yml +31 -8
  112. data/config/locales/sk.yml +38 -19
  113. data/config/locales/sl.yml +4 -0
  114. data/config/locales/sr-CS.yml +2 -0
  115. data/config/locales/sv.yml +29 -33
  116. data/config/locales/tr-TR.yml +34 -24
  117. data/config/locales/uk.yml +20 -3
  118. data/config/locales/zh-CN.yml +27 -15
  119. data/config/locales/zh-TW.yml +16 -16
  120. data/config/routes.rb +1 -0
  121. data/decidim-core.gemspec +4 -1
  122. data/lib/decidim/api/functions/component_list.rb +1 -1
  123. data/lib/decidim/api/functions/participatory_space_finder_base.rb +11 -1
  124. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -1
  125. data/lib/decidim/api/types/component_type.rb +7 -0
  126. data/lib/decidim/api/types/user_group_type.rb +4 -0
  127. data/lib/decidim/api/types/user_type.rb +4 -0
  128. data/lib/decidim/asset_router/storage.rb +7 -2
  129. data/lib/decidim/attributes/rich_text.rb +38 -0
  130. data/lib/decidim/attributes/time_with_zone.rb +16 -2
  131. data/lib/decidim/attributes.rb +2 -0
  132. data/lib/decidim/content_parsers/blob_parser.rb +95 -0
  133. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  134. data/lib/decidim/content_parsers.rb +1 -0
  135. data/lib/decidim/content_renderers/blob_renderer.rb +90 -0
  136. data/lib/decidim/content_renderers.rb +1 -0
  137. data/lib/decidim/core/engine.rb +29 -1
  138. data/lib/decidim/core/test/factories.rb +28 -0
  139. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  140. data/lib/decidim/core/test/shared_examples/comments_examples.rb +15 -2
  141. data/lib/decidim/core/test/shared_examples/reports_examples.rb +48 -6
  142. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +32 -0
  143. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +26 -0
  144. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +26 -0
  145. data/lib/decidim/core/version.rb +1 -1
  146. data/lib/decidim/diffy_extension.rb +18 -0
  147. data/lib/decidim/form_builder.rb +1 -1
  148. data/lib/decidim/map/autocomplete.rb +1 -0
  149. data/lib/decidim/map/provider/dynamic_map/here.rb +1 -40
  150. data/lib/decidim/map/provider/static_map/here.rb +34 -0
  151. data/lib/decidim/moderation_tools.rb +16 -2
  152. data/lib/decidim/nicknamizable.rb +1 -1
  153. data/lib/decidim/participatory_space_user.rb +4 -0
  154. data/lib/decidim/query_extensions.rb +0 -26
  155. data/lib/decidim/reportable.rb +6 -2
  156. data/lib/decidim/settings_manifest.rb +2 -0
  157. data/lib/decidim/translatable_attributes.rb +10 -1
  158. data/lib/tasks/upgrade/clean_hidden_resources.rake +33 -0
  159. data/lib/tasks/upgrade/decidim_fix_categorization.rake +34 -8
  160. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +23 -20
  161. metadata +37 -15
  162. data/app/cells/decidim/author/flag.erb +0 -6
  163. data/app/cells/decidim/author/flag_user.erb +0 -14
  164. data/app/cells/decidim/flag_modal/flag_user.erb +0 -34
  165. data/app/cells/decidim/flag_modal/show.erb +0 -52
  166. data/app/cells/decidim/flag_modal_cell.rb +0 -56
  167. data/app/cells/decidim/profile_sidebar/show.erb +0 -167
  168. data/app/cells/decidim/profile_sidebar_cell.rb +0 -68
  169. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +0 -212
@@ -22,7 +22,6 @@ uk:
22
22
  attributes:
23
23
  decidim/user:
24
24
  current_password: Поточний пароль
25
- email: Адреса електронної пошти
26
25
  name: Ім'я учасника
27
26
  password: Пароль
28
27
  password_confirmation: Підтвердження паролю
@@ -37,6 +36,8 @@ uk:
37
36
  'false': 'Ні'
38
37
  'true': 'Так'
39
38
  date:
39
+ buttons:
40
+ select: Оберіть
40
41
  formats:
41
42
  decidim_short: "%d.%m.%Y"
42
43
  decidim_with_month_name: "%d %B %Y"
@@ -191,6 +192,10 @@ uk:
191
192
  name: Статистика організації
192
193
  sub_hero:
193
194
  name: Під-багатирський банер
195
+ core:
196
+ application_helper:
197
+ filter_category_values:
198
+ all: Усі
194
199
  devise:
195
200
  omniauth_registrations:
196
201
  new:
@@ -322,10 +327,18 @@ uk:
322
327
  home: Головна
323
328
  messaging:
324
329
  conversation_mailer:
330
+ comanagers_new_conversation:
331
+ greeting: Вітаємо, %{recipient}!
332
+ comanagers_new_message:
333
+ greeting: Вітаємо, %{recipient}!
325
334
  new_conversation:
326
335
  greeting: Вітаємо, %{recipient}!
327
336
  intro: "%{sender} почав з вами нову бесіду. Клацніть тут, щоб прочитати її:"
328
337
  subject: "%{sender} почав з вами бесіду"
338
+ new_group_conversation:
339
+ greeting: Вітаємо, %{recipient}!
340
+ new_group_message:
341
+ greeting: Вітаємо, %{recipient}!
329
342
  new_message:
330
343
  greeting: Доброго дня, %{recipient}!
331
344
  intro: "%{sender} написав нові повідомлення у вашій бесіді. Клацніть тут, щоб переглянути їх:"
@@ -392,7 +405,8 @@ uk:
392
405
  followers: Ті, хто стежить
393
406
  following: 'Стежить за:'
394
407
  user:
395
- edit_profile: Редагувати профіль
408
+ actions:
409
+ edit_profile: Редагувати профіль
396
410
  reported_mailer:
397
411
  hide:
398
412
  hello: Доброго дня, %{name}%!
@@ -410,7 +424,6 @@ uk:
410
424
  scopes:
411
425
  global: Всеохопний обсяг
412
426
  picker:
413
- cancel: Скасувати
414
427
  choose: Оберіть
415
428
  title: Оберіть %{field}
416
429
  prompt: Оберіть обсяг
@@ -443,6 +456,8 @@ uk:
443
456
  statistics:
444
457
  comments_count: Коментарів
445
458
  user_conversations:
459
+ reply:
460
+ send: Надіслати
446
461
  update:
447
462
  error: Повідомлення не надіслано. Спробуйте ще раз пізніше
448
463
  devise:
@@ -548,6 +563,8 @@ uk:
548
563
  weibo: Сіна Вайбо
549
564
  xing: Xing
550
565
  time:
566
+ buttons:
567
+ select: Оберіть
551
568
  formats:
552
569
  day_of_month: "%b %d"
553
570
  day_of_week: "%a"
@@ -25,6 +25,8 @@ zh-CN:
25
25
  password_confirmation: 确认您的密码
26
26
  personal_url: 个人网址
27
27
  remove_avatar: 删除头像
28
+ user_group:
29
+ avatar: 头像
28
30
  models:
29
31
  decidim/attachment_created_event: 附文
30
32
  decidim/component_published_event: 活动组件
@@ -57,6 +59,8 @@ zh-CN:
57
59
  'false': '否'
58
60
  'true': '否'
59
61
  date:
62
+ buttons:
63
+ select: 选择
60
64
  formats:
61
65
  decidim_short: "%d/%m/%Y"
62
66
  decidim_with_day_and_month_name: "%A %d %b %Y"
@@ -314,10 +318,16 @@ zh-CN:
314
318
  view_all: 查看全部
315
319
  metrics:
316
320
  name: 组织指标
321
+ participatory_space_metrics:
322
+ name: 指标
317
323
  stats:
318
324
  name: 组织统计
319
325
  sub_hero:
320
326
  name: 子英雄广告
327
+ core:
328
+ application_helper:
329
+ filter_category_values:
330
+ all: 所有的
321
331
  devise:
322
332
  omniauth_registrations:
323
333
  new:
@@ -695,6 +705,8 @@ zh-CN:
695
705
  new_conversation: 新建对话
696
706
  next: 下一个
697
707
  title: 对话
708
+ reply_form:
709
+ placeholder: 您的回复...
698
710
  show:
699
711
  back: 回到所有对话
700
712
  chat_with: 对话
@@ -709,11 +721,9 @@ zh-CN:
709
721
  participants:
710
722
  description: 组织中的活跃参与者人数
711
723
  object: 参与者
712
- title: 参加者
713
724
  users:
714
725
  description: 参加组织的人数
715
726
  object: 参与者
716
- title: 参加者
717
727
  newsletter_mailer:
718
728
  newsletter:
719
729
  unsubscribe: 选择不接收这种类型的电子邮件, <a href="%{link}" target="_blank" class="unsubscribe">取消订阅</a>。
@@ -808,23 +818,22 @@ zh-CN:
808
818
  conversations: 对话
809
819
  followers: 关注者
810
820
  following: 关注的问题
821
+ group_admins: 管理管理员
822
+ group_members: 管理成员
811
823
  groups: 群組
812
824
  members: 成员
813
825
  officialized: 官方参与者
814
- sidebar:
815
- badges:
816
- info: 徽章是通过在平台上执行特定活动赚取的。
817
- title: 徽章
818
826
  user:
819
- create_user_group: 创建组
820
- edit_profile: 编辑配置文件
821
- edit_user_group: 编辑群组资料
822
- invite_user: Invite participant
823
- join_user_group: 加入组的请求
824
- leave_user_group: 离开组
825
- manage_user_group_admins: 管理管理员
826
- manage_user_group_users: 管理成员
827
- resend_email_confirmation_instructions: 重新发送电子邮件确认说明
827
+ actions:
828
+ create_user_group: 创建组
829
+ edit_profile: 编辑配置文件
830
+ edit_user_group: 编辑群组资料
831
+ invite_user: Invite participant
832
+ join_user_group: 加入组的请求
833
+ leave_user_group: 离开组
834
+ manage_user_group_admins: 管理管理员
835
+ manage_user_group_users: 管理成员
836
+ resend_email_confirmation_instructions: 重新发送电子邮件确认说明
828
837
  reported_mailer:
829
838
  hide:
830
839
  hello: 您好 %{name},
@@ -906,6 +915,7 @@ zh-CN:
906
915
  participatory_space_filters:
907
916
  filters:
908
917
  areas: 地区
918
+ scope: 范围
909
919
  select_an_area: 选择区域
910
920
  reference:
911
921
  reference: '引用: %{reference}'
@@ -1170,6 +1180,8 @@ zh-CN:
1170
1180
  whatsapp_web: WhatsApp
1171
1181
  xing: Xing
1172
1182
  time:
1183
+ buttons:
1184
+ select: 选择
1173
1185
  formats:
1174
1186
  day_of_month: "%b %d"
1175
1187
  day_of_week: "%a"
@@ -31,6 +31,8 @@ zh-TW:
31
31
  personal_url: 個人 URL
32
32
  remove_avatar: 刪除頭像
33
33
  tos_agreement: 同意服務條款
34
+ user_group:
35
+ avatar: 頭像
34
36
  models:
35
37
  decidim/attachment_created_event: 附件
36
38
  decidim/component_published_event: 啟用組件
@@ -73,6 +75,8 @@ zh-TW:
73
75
  'false': '否'
74
76
  'true': '是'
75
77
  date:
78
+ buttons:
79
+ select: 選擇
76
80
  formats:
77
81
  decidim_short: "%d/%m/%Y"
78
82
  decidim_short_with_month_name_short: "%d %b %Y"
@@ -472,6 +476,8 @@ zh-TW:
472
476
  view_all: 檢視全部
473
477
  metrics:
474
478
  name: 組織指標
479
+ participatory_space_metrics:
480
+ name: 指標
475
481
  static_page:
476
482
  section:
477
483
  name: 節
@@ -490,6 +496,9 @@ zh-TW:
490
496
  core:
491
497
  actions:
492
498
  unauthorized: 您無權限執行此操作.
499
+ application_helper:
500
+ filter_category_values:
501
+ all: 全部
493
502
  devise:
494
503
  omniauth_registrations:
495
504
  create:
@@ -1211,14 +1220,12 @@ zh-TW:
1211
1220
  conversations: 對話
1212
1221
  followers: 追隨者
1213
1222
  following: 關注
1223
+ group_admins: 管理管理員
1224
+ group_members: 管理成員
1214
1225
  groups: 群組
1215
1226
  members: 成員
1216
1227
  officialized: 正式認證參與者
1217
1228
  send_private_message: 發送私人訊息
1218
- sidebar:
1219
- badges:
1220
- info: 徽章是通過在平台上執行特定活動而獲得的。
1221
- title: 徽章
1222
1229
  user:
1223
1230
  actions:
1224
1231
  create_user_group: 建立群組
@@ -1226,20 +1233,13 @@ zh-TW:
1226
1233
  edit_user_group: 編輯群組資料
1227
1234
  invite_user: 邀請參與者
1228
1235
  join_user_group: 申請加入群組
1236
+ leave_user_group: 退出群組
1229
1237
  manage_user_group_admins: 管理管理員
1230
1238
  manage_user_group_users: 管理成員
1231
1239
  message: 訊息
1240
+ resend_email_confirmation_instructions: 重新發送電子郵件確認指示
1232
1241
  confirmation_instructions_sent: 電子郵件確認指示已發送.
1233
- create_user_group: 建立群組
1234
- edit_profile: 編輯個人資料
1235
- edit_user_group: 編輯群組資料
1236
1242
  fill_in_email_to_confirm_it: 請填寫您的群組電子郵件以進行確認.
1237
- invite_user: 邀請參與者
1238
- join_user_group: 申請加入群組
1239
- leave_user_group: 退出群組
1240
- manage_user_group_admins: 管理管理員
1241
- manage_user_group_users: 管理成員
1242
- resend_email_confirmation_instructions: 重新發送電子郵件確認指示
1243
1243
  reported_mailer:
1244
1244
  hide:
1245
1245
  hello: 哈囉,%{name},
@@ -1326,14 +1326,11 @@ zh-TW:
1326
1326
  flag_user_modal:
1327
1327
  already_reported: 此內容已被舉報,將由管理員進行審查。
1328
1328
  block: 封鎖此參與者
1329
- close: 關閉
1330
- description: 關於該使用者有什麼不適當的行為?
1331
1329
  does_not_belong: 包含非法活動、自殺威脅、個人資訊或其他您認為不適合在%{organization_name} 上的內容。
1332
1330
  hide: 隱藏所有內容
1333
1331
  offensive: 包含種族主義、性別歧視、辱罵、人身攻擊、死亡威脅、自殺要求或任何形式的仇恨言論
1334
1332
  report: 報告
1335
1333
  spam: 包含點閱率誘導、廣告、詐騙或自動腳本。
1336
- title: 舉報不適當的使用者
1337
1334
  floating_help:
1338
1335
  help: 幫助
1339
1336
  mentions_modal:
@@ -1341,6 +1338,7 @@ zh-TW:
1341
1338
  participatory_space_filters:
1342
1339
  filters:
1343
1340
  areas: 區域
1341
+ scope: 範圍
1344
1342
  select_an_area: 選擇一個地區
1345
1343
  public_participation:
1346
1344
  public_participation: 公開展示我的出席情況。
@@ -1742,6 +1740,8 @@ zh-TW:
1742
1740
  whatsapp_web: WhatsApp
1743
1741
  xing: Xing
1744
1742
  time:
1743
+ buttons:
1744
+ select: 選擇
1745
1745
  formats:
1746
1746
  day_of_month: "%b %d"
1747
1747
  day_of_week: "%a"
data/config/routes.rb CHANGED
@@ -137,6 +137,7 @@ Decidim::Core::Engine.routes.draw do
137
137
  get "group_members", to: "profiles#group_members", as: "profile_group_members"
138
138
  get "group_admins", to: "profiles#group_admins", as: "profile_group_admins"
139
139
  get "activity", to: "user_activities#index", as: "profile_activity"
140
+ get "tooltip", to: "profiles#tooltip", as: "profile_tooltip"
140
141
  resources :conversations, except: [:destroy], controller: "user_conversations", as: "profile_conversations"
141
142
  end
142
143
 
data/decidim-core.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  }
22
22
  s.summary = "The core of the Decidim framework."
23
23
  s.description = "Adds core features so other engines can hook into the framework."
24
- s.license = "AGPL-3.0"
24
+ s.license = "AGPL-3.0-or-later"
25
25
  s.required_ruby_version = "~> 3.2.0"
26
26
 
27
27
  s.files = Dir.chdir(__dir__) do
@@ -31,6 +31,9 @@ Gem::Specification.new do |s|
31
31
  end
32
32
  end
33
33
 
34
+ # Lock Temporarily as it is failing in 0.29 branch. More info: https://github.com/rails/rails/pull/54264
35
+ s.add_dependency "concurrent-ruby", "= 1.3.4"
36
+
34
37
  s.add_dependency "active_link_to", "~> 1.0"
35
38
  s.add_dependency "acts_as_list", "~> 1.0"
36
39
  s.add_dependency "batch-loader", "~> 1.2"
@@ -27,7 +27,7 @@ module Decidim
27
27
  @query = Decidim::Component
28
28
  # remove default ordering if custom order required
29
29
  @query = @query.unscoped if args[:order]
30
- @query = @query.where(participatory_space:).published
30
+ @query = @query.where(participatory_space:)
31
31
  add_filter_keys(args[:filter])
32
32
  add_order_keys(args[:order].to_h)
33
33
  add_default_order
@@ -22,7 +22,17 @@ module Decidim
22
22
  args.compact.keys.each do |key|
23
23
  query[key] = args[key]
24
24
  end
25
- model_class.public_spaces.find_by(query)
25
+
26
+ @query =
27
+ if ctx[:current_user]&.admin?
28
+ model_class
29
+ elsif model_class.respond_to?(:visible_for)
30
+ model_class.visible_for(ctx[:current_user])
31
+ else
32
+ model_class.public_spaces
33
+ end
34
+
35
+ @query.find_by(query)
26
36
  end
27
37
  end
28
38
  end
@@ -23,7 +23,7 @@ module Decidim
23
23
  ParticipatorySpaceManifestPresenter.new(object.manifest, object.organization)
24
24
  end
25
25
 
26
- field :components, [ComponentInterface], null: true, description: "Lists the components this space contains." do
26
+ field :components, [ComponentInterface, { null: true }], null: true, description: "Lists the components this space contains." do
27
27
  argument :filter, ComponentInputFilter, "Provides several methods to filter the results", required: false
28
28
  argument :order, ComponentInputSort, "Provides several methods to order the results", required: false
29
29
  end
@@ -5,6 +5,13 @@ module Decidim
5
5
  class ComponentType < Decidim::Api::Types::BaseObject
6
6
  implements Decidim::Core::ComponentInterface
7
7
  description "A base component with no particular specificities."
8
+
9
+ def self.authorized?(object, context)
10
+ context[:component] = object
11
+ context[:current_component] = object
12
+
13
+ super && allowed_to?(:read, :component, object, context)
14
+ end
8
15
  end
9
16
  end
10
17
  end
@@ -59,6 +59,10 @@ module Decidim
59
59
  def members_count
60
60
  object.accepted_memberships.count
61
61
  end
62
+
63
+ def self.authorized?(object, context)
64
+ super && !object.blocked?
65
+ end
62
66
  end
63
67
  end
64
68
  end
@@ -62,6 +62,10 @@ module Decidim
62
62
  def groups
63
63
  object.accepted_user_groups
64
64
  end
65
+
66
+ def self.authorized?(object, context)
67
+ super && object.confirmed? && !object.blocked? && !object.deleted?
68
+ end
65
69
  end
66
70
  end
67
71
  end
@@ -52,8 +52,13 @@ module Decidim
52
52
  when ActiveStorage::Blob
53
53
  blob_url(**)
54
54
  else # ActiveStorage::VariantWithRecord, ActiveStorage::Variant
55
- ensure_current_host(nil, **)
56
- representation_url(**)
55
+ if blob && blob.attachments.any?
56
+ ensure_current_host(blob.attachments.first&.record, **)
57
+ representation_url(**)
58
+ else
59
+ ensure_current_host(nil, **)
60
+ representation_url(**, only_path: true)
61
+ end
57
62
  end
58
63
  end
59
64
 
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Attributes
5
+ # Custom attributes value to convert rich text strings in the database, i.e.
6
+ # strings that originate from the editor.
7
+ class RichText < Decidim::Attributes::CleanString
8
+ def type
9
+ :"decidim/attributes/rich_text"
10
+ end
11
+
12
+ # Serializes the value to the database.
13
+ def serialize(value)
14
+ serialize_value(value)
15
+ end
16
+
17
+ private
18
+
19
+ # From form to database
20
+ def serialize_value(value)
21
+ return value unless value.is_a?(String)
22
+
23
+ context = {}
24
+ parsed = Decidim::ContentProcessor.parse_with_processor(:blob, value, context)
25
+ parsed.rewrite
26
+ end
27
+
28
+ # From database to form
29
+ def cast_value(value)
30
+ clean_string = super
31
+ return clean_string unless clean_string.is_a?(String)
32
+
33
+ renderer = Decidim::ContentProcessor.renderer_klass(:blob).constantize.new(clean_string)
34
+ renderer.render
35
+ end
36
+ end
37
+ end
38
+ end
@@ -5,6 +5,15 @@ module Decidim
5
5
  # Custom attributes value to parse a String representing a Time using
6
6
  # the app TimeZone.
7
7
  class TimeWithZone < ActiveModel::Type::DateTime
8
+ # Date format: 2020-06-20T, 2020-06-20, 20/06/2020T or 20/06/2020
9
+ # Time format: 10:20, 10:20:30 or 10:20:30.123456
10
+ ISO_DATETIME_WITHOUT_TIMEZONE = %r{
11
+ \A
12
+ ((\d{4})-(\d\d)-(\d\d)|(\d\d)/(\d\d)/(\d{4}))(?:T|\s)
13
+ (\d\d):(\d\d)(:(\d\d)(?:\.(\d{1,6})\d*)?)?
14
+ \z
15
+ }x
16
+
8
17
  def type
9
18
  :"decidim/attributes/time_with_zone"
10
19
  end
@@ -14,12 +23,17 @@ module Decidim
14
23
  def cast_value(value)
15
24
  return value unless value.is_a?(String)
16
25
 
17
- Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
26
+ if Date._iso8601(value).present?
27
+ Time.zone.iso8601(value)
28
+ else
29
+ Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
30
+ end
18
31
  rescue ArgumentError
19
32
  fallback = super
20
33
  return fallback unless fallback.is_a?(Time)
34
+ return Time.zone.parse(fallback.strftime("%F %T")) if ISO_DATETIME_WITHOUT_TIMEZONE.match?(value)
21
35
 
22
- Time.zone.parse(fallback.strftime("%F %T"))
36
+ ActiveSupport::TimeWithZone.new(fallback, Time.zone)
23
37
  end
24
38
  end
25
39
  end
@@ -5,6 +5,7 @@ module Decidim
5
5
  autoload :TimeWithZone, "decidim/attributes/time_with_zone"
6
6
  autoload :LocalizedDate, "decidim/attributes/localized_date"
7
7
  autoload :CleanString, "decidim/attributes/clean_string"
8
+ autoload :RichText, "decidim/attributes/rich_text"
8
9
  autoload :Blob, "decidim/attributes/blob"
9
10
  autoload :Array, "decidim/attributes/array"
10
11
  autoload :Hash, "decidim/attributes/hash"
@@ -27,6 +28,7 @@ module Decidim
27
28
  ActiveModel::Type.register(:"decidim/attributes/time_with_zone", Decidim::Attributes::TimeWithZone)
28
29
  ActiveModel::Type.register(:"decidim/attributes/localized_date", Decidim::Attributes::LocalizedDate)
29
30
  ActiveModel::Type.register(:"decidim/attributes/clean_string", Decidim::Attributes::CleanString)
31
+ ActiveModel::Type.register(:"decidim/attributes/rich_text", Decidim::Attributes::RichText)
30
32
  ActiveModel::Type.register(:"decidim/attributes/blob", Decidim::Attributes::Blob)
31
33
 
32
34
  ActiveModel::Type.register(:integer, Decidim::Attributes::Integer)
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ContentParsers
5
+ # Parses any blob URLs from the content and replaces them with references
6
+ # to those blobs.
7
+ class BlobParser < BaseParser
8
+ # Matches all possible URLs pointing to ActiveStorage::Blob objects.
9
+ #
10
+ # Possible routes:
11
+ # get "/blobs/redirect/:signed_id/*filename"
12
+ # get "/blobs/proxy/:signed_id/*filename"
13
+ # get "/blobs/:signed_id/*filename"
14
+ # get "/representations/redirect/:signed_blob_id/:variation_key/*filename"
15
+ # get "/representations/proxy/:signed_blob_id/:variation_key/*filename"
16
+ # get "/representations/:signed_blob_id/:variation_key/*filename"
17
+ # get "/disk/:encoded_key/*filename"
18
+ #
19
+ # See:
20
+ # https://github.com/rails/rails/blob/a7e379896552ce43b822385c03c37f2bd47739d3/activestorage/config/routes.rb#L5-L14
21
+ BLOB_REGEX = %r{
22
+ # Group 1: Host part
23
+ (?<host_part>
24
+ # Group 2: Domain and subpath part
25
+ #{URI::DEFAULT_PARSER.make_regexp(%w(https http))}
26
+ )?
27
+ /rails/active_storage
28
+ # Group 3: Blob path, representation path or disk service path
29
+ /(?<type_part>blobs/redirect|blobs/proxy|blobs|representations/redirect|representations/proxy|representations|disk)
30
+ # Group 4: Signed ID for blobs or encoded key for disk service
31
+ /(?<key_part>[^/]+)
32
+ # Group 5: Variation part (only for representations)
33
+ (
34
+ # Group 6: Variation key for representations
35
+ /(?<variation_part>[\w.=-]+)
36
+ )?
37
+ # Group 7: Filename
38
+ /([\w.=-]+)
39
+ }x
40
+
41
+ def rewrite
42
+ replace_blobs(content)
43
+ end
44
+
45
+ private
46
+
47
+ def replace_blobs(text)
48
+ text.gsub(BLOB_REGEX) do |match|
49
+ named_captures = Regexp.last_match.named_captures
50
+
51
+ type_part = named_captures["type_part"]
52
+ key_part = named_captures["key_part"]
53
+
54
+ variation_key = nil
55
+ blob =
56
+ if type_part == "disk"
57
+ # Disk service URL
58
+ decoded = ActiveStorage.verifier.verified(key_part, purpose: :blob_key)
59
+ ActiveStorage::Blob.find_by(key: decoded[:key]) if decoded
60
+ else
61
+ # Representation or blob
62
+ if type_part.start_with?("representations")
63
+ # Representation
64
+ variation_part = named_captures["variation_part"]
65
+ variation_key = generate_variation_key(variation_part)
66
+ end
67
+
68
+ ActiveStorage::Blob.find_signed(key_part)
69
+ end
70
+ next match unless blob
71
+
72
+ "#{blob.to_global_id}#{"/#{variation_key}" if variation_key}"
73
+ end
74
+ end
75
+
76
+ def generate_variation_key(variation_part)
77
+ # The variation part has to be decoded because it will eventually
78
+ # expire. This way we can preserve the variation information
79
+ # longer.
80
+ variation = ActiveStorage.verifier.verify(variation_part, purpose: :variation)
81
+ return unless variation
82
+
83
+ # Convert to base64 encoded JSON string for better representation within
84
+ # the URLs. This manually encoded part will not expire as it is
85
+ # persisted to the database.
86
+ Base64.strict_encode64(ActiveSupport::JSON.encode(variation))
87
+ rescue ActiveSupport::MessageVerifier::InvalidSignature
88
+ # This happens if the variation key is already expired in which
89
+ # case it cannot be represented and instead a URL to the blob is
90
+ # created.
91
+ variation_part
92
+ end
93
+ end
94
+ end
95
+ end
@@ -49,7 +49,7 @@ module Decidim
49
49
 
50
50
  def existing_mentionables
51
51
  @existing_mentionables ||= mentionable_class.where(
52
- "decidim_organization_id = ? AND LOWER(nickname) IN (?)",
52
+ "decidim_organization_id = ? AND nickname IN (?)",
53
53
  current_organization.id,
54
54
  content_nicknames
55
55
  )
@@ -3,6 +3,7 @@
3
3
  module Decidim
4
4
  module ContentParsers
5
5
  autoload :BaseParser, "decidim/content_parsers/base_parser"
6
+ autoload :BlobParser, "decidim/content_parsers/blob_parser"
6
7
  autoload :UserParser, "decidim/content_parsers/user_parser"
7
8
  autoload :UserGroupParser, "decidim/content_parsers/user_group_parser"
8
9
  autoload :HashtagParser, "decidim/content_parsers/hashtag_parser"