decidim-meetings 0.29.3 → 0.30.0.rc1

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/meetings/cancel_registration_meeting_button/cancelation_modal.erb +1 -1
  3. data/app/cells/decidim/meetings/cancel_registration_meeting_button/show.erb +3 -1
  4. data/app/cells/decidim/meetings/cancel_registration_meeting_button_cell.rb +1 -1
  5. data/app/cells/decidim/meetings/dates_and_map/show.erb +1 -1
  6. data/app/cells/decidim/meetings/highlighted_meetings_for_component/show.erb +1 -1
  7. data/app/cells/decidim/meetings/join_meeting_button/show.erb +5 -2
  8. data/app/cells/decidim/meetings/meeting_card_metadata_cell.rb +3 -3
  9. data/app/cells/decidim/meetings/meeting_l_cell.rb +12 -0
  10. data/app/commands/decidim/meetings/admin/copy_meeting.rb +1 -2
  11. data/app/commands/decidim/meetings/admin/create_meeting.rb +8 -2
  12. data/app/commands/decidim/meetings/admin/update_meeting.rb +8 -2
  13. data/app/commands/decidim/meetings/create_meeting.rb +2 -2
  14. data/app/commands/decidim/meetings/update_meeting.rb +2 -3
  15. data/app/controllers/concerns/decidim/meetings/admin/filterable.rb +9 -5
  16. data/app/controllers/concerns/decidim/meetings/component_filterable.rb +1 -2
  17. data/app/controllers/decidim/meetings/admin/meetings_controller.rb +14 -22
  18. data/app/controllers/decidim/meetings/admin/registration_form_controller.rb +8 -0
  19. data/app/controllers/decidim/meetings/directory/meetings_controller.rb +2 -4
  20. data/app/controllers/decidim/meetings/meetings_controller.rb +40 -6
  21. data/app/forms/decidim/meetings/admin/meeting_form.rb +16 -30
  22. data/app/forms/decidim/meetings/base_meeting_form.rb +6 -0
  23. data/app/forms/decidim/meetings/meeting_form.rb +2 -30
  24. data/app/helpers/decidim/meetings/admin/application_helper.rb +11 -1
  25. data/app/helpers/decidim/meetings/application_helper.rb +35 -1
  26. data/app/helpers/decidim/meetings/directory/application_helper.rb +9 -48
  27. data/app/helpers/decidim/meetings/meetings_helper.rb +5 -0
  28. data/app/models/decidim/meetings/invite.rb +10 -0
  29. data/app/models/decidim/meetings/meeting.rb +28 -1
  30. data/app/models/decidim/meetings/meeting_link.rb +25 -0
  31. data/app/packs/entrypoints/decidim_meetings_admin.js +1 -0
  32. data/app/packs/src/decidim/meetings/admin/meetings_components_form.js +77 -0
  33. data/app/packs/src/decidim/meetings/admin/meetings_form.js +8 -0
  34. data/app/permissions/decidim/meetings/admin/permissions.rb +1 -1
  35. data/app/permissions/decidim/meetings/permissions.rb +13 -9
  36. data/app/presenters/decidim/meetings/admin_log/meeting_presenter.rb +1 -1
  37. data/app/presenters/decidim/meetings/meeting_presenter.rb +13 -1
  38. data/app/queries/decidim/meetings/filtered_meetings.rb +2 -2
  39. data/app/queries/decidim/meetings/metrics/meeting_followers_metric_measure.rb +2 -2
  40. data/app/queries/decidim/meetings/metrics/meetings_metric_manage.rb +6 -6
  41. data/app/serializers/decidim/meetings/base_download_your_data_serializer.rb +32 -0
  42. data/app/serializers/decidim/meetings/download_your_data_invite_serializer.rb +6 -26
  43. data/app/serializers/decidim/meetings/download_your_data_meeting_serializer.rb +15 -0
  44. data/app/serializers/decidim/meetings/download_your_data_registration_serializer.rb +6 -24
  45. data/app/views/decidim/meetings/admin/meetings/_component.html.erb +15 -0
  46. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +7 -9
  47. data/app/views/decidim/meetings/admin/meetings/_linked_spaces.html.erb +53 -0
  48. data/app/views/decidim/meetings/admin/meetings/_meeting-tr.html.erb +42 -0
  49. data/app/views/decidim/meetings/admin/meetings/_meeting_actions.html.erb +70 -0
  50. data/app/views/decidim/meetings/admin/meetings/_meetings-thead.html.erb +26 -0
  51. data/app/views/decidim/meetings/admin/meetings/index.html.erb +16 -142
  52. data/app/views/decidim/meetings/admin/meetings/manage_trash.html.erb +23 -0
  53. data/app/views/decidim/meetings/admin/registration_form/edit_questions.html.erb +44 -0
  54. data/app/views/decidim/meetings/admin/registrations/edit.html.erb +1 -0
  55. data/app/views/decidim/meetings/directory/meetings/index.html.erb +1 -2
  56. data/app/views/decidim/meetings/live_events/show.html.erb +5 -5
  57. data/app/views/decidim/meetings/meetings/_form.html.erb +4 -8
  58. data/app/views/decidim/meetings/meetings/_meeting.html.erb +51 -26
  59. data/app/views/decidim/meetings/meetings/_meeting_actions.html.erb +34 -0
  60. data/app/views/decidim/meetings/meetings/_meeting_aside.html.erb +20 -59
  61. data/app/views/decidim/meetings/meetings/_meeting_poll_actions.html.erb +2 -5
  62. data/app/views/decidim/meetings/meetings/_schema_org_event_meeting.html.erb +3 -0
  63. data/app/views/decidim/meetings/meetings/index.html.erb +1 -2
  64. data/app/views/decidim/meetings/meetings/new.html.erb +0 -1
  65. data/app/views/decidim/meetings/meetings/show.html.erb +5 -5
  66. data/app/views/decidim/meetings/polls/answers/index.html.erb +5 -5
  67. data/app/views/decidim/meetings/shared/_filters.html.erb +1 -13
  68. data/app/views/decidim/meetings/shared/_index.html.erb +1 -1
  69. data/app/views/decidim/meetings/shared/_index.js.erb +3 -2
  70. data/app/views/decidim/meetings/shared/_meetings.html.erb +1 -1
  71. data/app/views/decidim/meetings/shared/_meetings_aside.html.erb +2 -2
  72. data/app/views/decidim/participatory_spaces/_conference_venues.html.erb +1 -1
  73. data/config/locales/ar.yml +23 -17
  74. data/config/locales/bg.yml +16 -25
  75. data/config/locales/ca.yml +140 -30
  76. data/config/locales/cs.yml +145 -28
  77. data/config/locales/de.yml +152 -74
  78. data/config/locales/el.yml +7 -22
  79. data/config/locales/en.yml +132 -22
  80. data/config/locales/es-MX.yml +144 -34
  81. data/config/locales/es-PY.yml +145 -35
  82. data/config/locales/es.yml +145 -35
  83. data/config/locales/eu.yml +159 -49
  84. data/config/locales/fi-plain.yml +142 -27
  85. data/config/locales/fi.yml +142 -27
  86. data/config/locales/fr-CA.yml +79 -27
  87. data/config/locales/fr.yml +79 -27
  88. data/config/locales/ga-IE.yml +0 -13
  89. data/config/locales/gl.yml +6 -12
  90. data/config/locales/hu.yml +8 -20
  91. data/config/locales/id-ID.yml +6 -13
  92. data/config/locales/is-IS.yml +0 -15
  93. data/config/locales/it.yml +7 -19
  94. data/config/locales/ja.yml +94 -26
  95. data/config/locales/lb.yml +6 -14
  96. data/config/locales/lt.yml +7 -23
  97. data/config/locales/lv.yml +6 -13
  98. data/config/locales/nl.yml +8 -18
  99. data/config/locales/no.yml +6 -16
  100. data/config/locales/pl.yml +16 -21
  101. data/config/locales/pt-BR.yml +7 -21
  102. data/config/locales/pt.yml +7 -17
  103. data/config/locales/ro-RO.yml +32 -19
  104. data/config/locales/ru.yml +6 -13
  105. data/config/locales/sk.yml +7 -14
  106. data/config/locales/sv.yml +82 -28
  107. data/config/locales/tr-TR.yml +7 -19
  108. data/config/locales/uk.yml +5 -15
  109. data/config/locales/zh-CN.yml +7 -18
  110. data/config/locales/zh-TW.yml +7 -21
  111. data/db/migrate/20181107175558_add_questionnaire_to_existing_meetings.rb +1 -1
  112. data/db/migrate/20200827153856_add_commentable_counter_cache_to_meetings.rb +1 -1
  113. data/db/migrate/20201016065302_fix_meetings_registration_terms.rb +1 -1
  114. data/db/migrate/20210310120731_add_followable_counter_cache_to_meetings.rb +1 -1
  115. data/db/migrate/20240712104245_create_decidim_meetings_meeting_link.rb +12 -0
  116. data/db/migrate/20240828103603_add_deleted_at_to_decidim_meetings_meetings.rb +8 -0
  117. data/decidim-meetings.gemspec +1 -1
  118. data/lib/decidim/api/agenda_item_type.rb +6 -7
  119. data/lib/decidim/api/agenda_type.rb +3 -4
  120. data/lib/decidim/api/meeting_type.rb +33 -41
  121. data/lib/decidim/api/meetings_type.rb +4 -5
  122. data/lib/decidim/api/service_type.rb +1 -1
  123. data/lib/decidim/meetings/admin_engine.rb +9 -1
  124. data/lib/decidim/meetings/component.rb +14 -4
  125. data/lib/decidim/meetings/download_your_data_user_answers_serializer.rb +13 -7
  126. data/lib/decidim/meetings/engine.rb +1 -6
  127. data/lib/decidim/meetings/meeting_serializer.rb +70 -59
  128. data/lib/decidim/meetings/schema_org_event_meeting_serializer.rb +151 -0
  129. data/lib/decidim/meetings/seeds.rb +2 -4
  130. data/lib/decidim/meetings/test/factories.rb +8 -0
  131. data/lib/decidim/meetings/test/translated_event.rb +3 -3
  132. data/lib/decidim/meetings/version.rb +1 -1
  133. data/lib/decidim/meetings.rb +1 -0
  134. metadata +32 -22
  135. data/app/cells/decidim/meetings/meetings_map/show.erb +0 -16
  136. data/app/cells/decidim/meetings/meetings_map_cell.rb +0 -32
  137. data/app/commands/decidim/meetings/admin/destroy_meeting.rb +0 -21
  138. data/app/helpers/decidim/meetings/map_helper.rb +0 -21
  139. data/app/views/decidim/meetings/meetings/_actions.html.erb +0 -6
  140. data/config/locales/ca-IT.yml +0 -693
@@ -18,13 +18,20 @@ module Decidim
18
18
  member do
19
19
  put :publish
20
20
  put :unpublish
21
+ patch :soft_delete
22
+ patch :restore
21
23
  end
22
24
  resources :meeting_closes, only: [:edit, :update] do
23
25
  get :proposals_picker, on: :collection
24
26
  end
25
27
  resource :registrations, only: [:edit, :update] do
26
28
  resources :invites, only: [:index, :create]
27
- resource :form, only: [:edit, :update], controller: "registration_form"
29
+ resource :form, only: [:edit, :update], controller: "registration_form" do
30
+ member do
31
+ get :edit_questions
32
+ patch :update_questions
33
+ end
34
+ end
28
35
  collection do
29
36
  get :export
30
37
  post :validate_registration_code
@@ -35,6 +42,7 @@ module Decidim
35
42
  resources :attachments, except: [:show]
36
43
  resources :copies, controller: "meeting_copies", only: [:new, :create]
37
44
  resource :poll, only: [:edit, :update], controller: "meetings_poll"
45
+ get :manage_trash, on: :collection
38
46
  end
39
47
  root to: "meetings#index"
40
48
  end
@@ -8,7 +8,11 @@ Decidim.register_component(:meetings) do |component|
8
8
  component.permissions_class_name = "Decidim::Meetings::Permissions"
9
9
 
10
10
  component.query_type = "Decidim::Meetings::MeetingsType"
11
- component.data_portable_entities = ["Decidim::Meetings::Registration"]
11
+ component.data_portable_entities = [
12
+ "Decidim::Meetings::Registration",
13
+ "Decidim::Meetings::Invite",
14
+ "Decidim::Meetings::Meeting"
15
+ ]
12
16
 
13
17
  component.on(:before_destroy) do |instance|
14
18
  raise StandardError, "Cannot remove this component" if Decidim::Meetings::Meeting.where(component: instance).any?
@@ -38,13 +42,20 @@ Decidim.register_component(:meetings) do |component|
38
42
  meetings.sum(:comments_count)
39
43
  end
40
44
 
45
+ component.register_stat :attendees_count, primary: true, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY do |components, start_at, end_at|
46
+ meetings = Decidim::Meetings::Meeting.closed.not_hidden.published.where(component: components, closing_visible: true)
47
+ meetings = meetings.where(closed_at: start_at..) if start_at.present?
48
+ meetings = meetings.where(closed_at: ..end_at) if end_at.present?
49
+ meetings.sum(:attendees_count)
50
+ end
51
+
41
52
  component.exports :meetings do |exports|
42
53
  exports.collection do |component_instance|
43
54
  Decidim::Meetings::Meeting
44
55
  .not_hidden
45
56
  .visible
46
57
  .where(component: component_instance)
47
- .includes(:scope, :category, :attachments, component: { participatory_space: :organization })
58
+ .includes(:taxonomies, :attachments, component: { participatory_space: :organization })
48
59
  end
49
60
 
50
61
  exports.include_in_open_data = true
@@ -77,8 +88,7 @@ Decidim.register_component(:meetings) do |component|
77
88
  component.actions = %w(join comment)
78
89
 
79
90
  component.settings(:global) do |settings|
80
- settings.attribute :scopes_enabled, type: :boolean, default: false
81
- settings.attribute :scope_id, type: :scope
91
+ settings.attribute :taxonomy_filters, type: :taxonomy_filters
82
92
  settings.attribute :announcement, type: :text, translated: true, editor: true
83
93
  settings.attribute :default_registration_terms, type: :text, translated: true, editor: true
84
94
  settings.attribute :comments_enabled, type: :boolean, default: true
@@ -8,16 +8,16 @@ module Decidim
8
8
  def serialize
9
9
  {
10
10
  id: resource.id,
11
- user: {
12
- name: resource.user.name,
13
- email: resource.user.email
14
- },
15
11
  questionnaire: {
16
- id: resource.question.questionnaire.id
12
+ id: resource.question.questionnaire.id,
13
+ title: translated_attribute(resource.question.questionnaire.title),
14
+ description: translated_attribute(resource.question.questionnaire.description),
15
+ tos: translated_attribute(resource.question.questionnaire.tos)
17
16
  },
18
17
  question: {
19
18
  id: resource.question.id,
20
- body: translated_attribute(resource.question.body)
19
+ body: translated_attribute(resource.question.body),
20
+ description: translated_attribute(resource.question.description)
21
21
  },
22
22
  answer: normalize_body(resource)
23
23
  }
@@ -26,7 +26,13 @@ module Decidim
26
26
  private
27
27
 
28
28
  def normalize_body(resource)
29
- resource.choices.pluck(:body)
29
+ attachments_for(resource) || resource.body || resource.choices.pluck(:body)
30
+ end
31
+
32
+ def attachments_for(resource)
33
+ return if resource.attachments.blank?
34
+
35
+ resource.attachments.map(&:url)
30
36
  end
31
37
  end
32
38
  end
@@ -81,12 +81,7 @@ module Decidim
81
81
 
82
82
  initializer "decidim_meetings.content_security_handlers" do |_app|
83
83
  Decidim.configure do |config|
84
- if config.content_security_policies_extra["frame-src"].respond_to?(:<<)
85
- config.content_security_policies_extra["frame-src"] << "player.twitch.tv"
86
- config.content_security_policies_extra["frame-src"] << "meet.jit.si"
87
- else
88
- config.content_security_policies_extra["frame-src"] = %w(player.twitch.tv meet.jit.si)
89
- end
84
+ config.content_security_policies_extra.deep_merge!({ "frame-src" => %w(player.twitch.tv meet.jit.si) })
90
85
  end
91
86
  end
92
87
 
@@ -8,63 +8,77 @@ module Decidim
8
8
  include Decidim::ApplicationHelper
9
9
  include Decidim::ResourceHelper
10
10
 
11
- # Public: Initializes the serializer with a meeting.
12
- def initialize(meeting)
13
- @meeting = meeting
14
- end
15
-
16
11
  # Public: Exports a hash with the serialized data for this meeting.
17
12
  def serialize
18
13
  {
19
- id: meeting.id,
20
- category: {
21
- id: meeting.category.try(:id),
22
- name: meeting.category.try(:name)
23
- },
24
- scope: {
25
- id: meeting.scope.try(:id),
26
- name: meeting.scope.try(:name)
27
- },
14
+ id: resource.id,
28
15
  author: {
29
16
  **author_fields
30
17
  },
31
18
  participatory_space: {
32
- id: meeting.participatory_space.id,
33
- url: Decidim::ResourceLocatorPresenter.new(meeting.participatory_space).url
19
+ id: resource.participatory_space.id,
20
+ url: Decidim::ResourceLocatorPresenter.new(resource.participatory_space).url
34
21
  },
22
+ taxonomies:,
35
23
  component: { id: component.id },
36
- title: meeting.title,
37
- description: meeting.description,
38
- start_time: meeting.start_time,
39
- end_time: meeting.end_time,
40
- attendees: meeting.attendees_count.to_i,
41
- contributions: meeting.contributions_count.to_i,
42
- organizations: meeting.attending_organizations,
43
- address: meeting.address,
44
- location: meeting.location,
45
- reference: meeting.reference,
46
- comments: meeting.comments_count,
47
- attachments: meeting.attachments.size,
48
- followers: meeting.follows.size,
24
+ title: resource.title,
25
+ description: resource.description,
26
+ start_time: resource.start_time,
27
+ end_time: resource.end_time,
28
+ attendees: resource.attendees_count.to_i,
29
+ contributions: resource.contributions_count.to_i,
30
+ organizations: resource.attending_organizations,
31
+ address: resource.address,
32
+ location: include_location? ? resource.location : nil,
33
+ reference: resource.reference,
34
+ attachments: resource.attachments.size,
49
35
  url:,
50
36
  related_proposals:,
51
37
  related_results:,
52
- published: meeting.published_at.present?,
53
- withdrawn: meeting.withdrawn?,
54
- withdrawn_at: meeting.withdrawn_at
38
+ published: resource.published_at.present?,
39
+ withdrawn: resource.withdrawn?,
40
+ withdrawn_at: resource.withdrawn_at,
41
+ location_hints: resource.location_hints,
42
+ created_at: resource.created_at,
43
+ updated_at: resource.updated_at,
44
+ latitude: resource.latitude,
45
+ longitude: resource.longitude,
46
+ follows_count: resource.follows_count,
47
+ private_meeting: resource.private_meeting,
48
+ transparent: resource.transparent,
49
+ registration_form_enabled: resource.registration_form_enabled,
50
+ comments: {
51
+ **comment_fields
52
+ },
53
+ online_meeting_url: resource.online_meeting_url,
54
+ closing_visible: resource.closing_visible,
55
+ closing_report: resource.closing_report,
56
+ attending_organizations: resource.attending_organizations,
57
+ registration_url: resource.registration_url,
58
+ decidim_user_group_id: resource.decidim_user_group_id,
59
+ decidim_author_type: resource.decidim_author_type,
60
+ video_url: resource.video_url,
61
+ audio_url: resource.audio_url,
62
+ closed_at: resource.closed_at,
63
+ registration_terms: resource.registration_terms,
64
+ available_slots: resource.available_slots,
65
+ registrations_enabled: resource.registrations_enabled,
66
+ customize_registration_email: resource.customize_registration_email,
67
+ type_of_meeting: resource.type_of_meeting,
68
+ iframe_access_level: resource.iframe_access_level,
69
+ iframe_embed_type: resource.iframe_embed_type,
70
+ reserved_slots: resource.reserved_slots,
71
+ registration_type: resource.registration_type
55
72
  }
56
73
  end
57
74
 
58
75
  private
59
76
 
60
- attr_reader :meeting
61
- alias resource meeting
62
-
63
77
  def author_fields
64
78
  {
65
- id: meeting.author.id,
66
- name: author_name(meeting.author),
67
- url: author_url(meeting.author)
79
+ id: resource.author.id,
80
+ name: author_name(resource.author),
81
+ url: author_url(resource.author)
68
82
  }
69
83
  end
70
84
 
@@ -80,38 +94,35 @@ module Decidim
80
94
  end
81
95
  end
82
96
 
83
- def profile_url(author)
84
- return "" if author.respond_to?(:deleted?) && author.deleted?
85
-
86
- Decidim::Core::Engine.routes.url_helpers.profile_url(author.nickname, host:)
87
- end
88
-
89
- def root_url
90
- Decidim::Core::Engine.routes.url_helpers.root_url(host:)
91
- end
92
-
93
- def host
94
- resource.organization.host
95
- end
96
-
97
- def component
98
- meeting.component
99
- end
100
-
101
97
  def related_proposals
102
- meeting.linked_resources(:proposals, "proposals_from_meeting").map do |proposal|
98
+ resource.linked_resources(:proposals, "proposals_from_meeting").map do |proposal|
103
99
  Decidim::ResourceLocatorPresenter.new(proposal).url
104
100
  end
105
101
  end
106
102
 
107
103
  def related_results
108
- meeting.linked_resources(:results, "meetings_through_proposals").map do |result|
104
+ resource.linked_resources(:results, "meetings_through_proposals").map do |result|
109
105
  Decidim::ResourceLocatorPresenter.new(result).url
110
106
  end
111
107
  end
112
108
 
113
109
  def url
114
- Decidim::ResourceLocatorPresenter.new(meeting).url
110
+ Decidim::ResourceLocatorPresenter.new(resource).url
111
+ end
112
+
113
+ def comment_fields
114
+ return {} unless resource.comments
115
+
116
+ {
117
+ start_time: resource.comments_start_time,
118
+ end_time: resource.comments_end_time,
119
+ enabled: resource.comments_enabled,
120
+ count: resource.comments_count
121
+ }
122
+ end
123
+
124
+ def include_location?
125
+ resource.iframe_access_level == "all"
115
126
  end
116
127
  end
117
128
  end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ class SchemaOrgEventMeetingSerializer < Decidim::Exporters::Serializer
6
+ include Decidim::TranslationsHelper
7
+ include Decidim::SanitizeHelper
8
+ include ActionView::Helpers::UrlHelper
9
+
10
+ # Public: Initializes the serializer with a meeting.
11
+ def initialize(meeting)
12
+ @meeting = meeting
13
+ end
14
+
15
+ # Serializes a meeting for the Schema.org Event type
16
+ #
17
+ # @see https://schema.org/Event
18
+ # @see https://developers.google.com/search/docs/appearance/structured-data/event?hl=en
19
+ def serialize
20
+ attributes = {
21
+ "@context": "https://schema.org",
22
+ "@type": "Event",
23
+ name: decidim_escape_translated(meeting.title),
24
+ description: decidim_escape_translated(meeting.description),
25
+ startDate: meeting.start_time.iso8601,
26
+ endDate: meeting.end_time.iso8601,
27
+ organizer:,
28
+ eventAttendanceMode: event_attendance_mode,
29
+ eventStatus: "https://schema.org/EventScheduled",
30
+ location:
31
+ }
32
+
33
+ attributes = attributes.merge(image:) if meeting.photos.any?
34
+ attributes
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :meeting
40
+ alias resource meeting
41
+
42
+ def organizer
43
+ return organizer_user_group if meeting.decidim_user_group_id?
44
+
45
+ case meeting.author.class.name
46
+ when "Decidim::Organization"
47
+ organizer_organization
48
+ when "Decidim::User"
49
+ organizer_user
50
+ end
51
+ end
52
+
53
+ def organizer_user_group
54
+ {
55
+ "@type": "Organization",
56
+ name: meeting.author.name,
57
+ url: profile_url(meeting.user_group)
58
+ }
59
+ end
60
+
61
+ def organizer_organization
62
+ {
63
+ "@type": "Organization",
64
+ name: decidim_escape_translated(meeting.author.name),
65
+ url: EngineRouter.new("decidim", router_options).root_url
66
+ }
67
+ end
68
+
69
+ def organizer_user
70
+ {
71
+ "@type": "Person",
72
+ name: decidim_escape_translated(meeting.author.name),
73
+ url: profile_url(meeting.author)
74
+ }
75
+ end
76
+
77
+ def router_options = { host: meeting.organization.host }
78
+
79
+ def event_attendance_mode
80
+ case meeting.type_of_meeting
81
+ when "online"
82
+ "https://schema.org/OnlineEventAttendanceMode"
83
+ when "hybrid"
84
+ "https://schema.org/MixedEventAttendanceMode"
85
+ else
86
+ "https://schema.org/OfflineEventAttendanceMode"
87
+ end
88
+ end
89
+
90
+ def location
91
+ case meeting.type_of_meeting
92
+ when "online"
93
+ location_virtual
94
+ when "hybrid"
95
+ [location_postal_address, location_virtual]
96
+ else
97
+ location_postal_address
98
+ end
99
+ end
100
+
101
+ def location_postal_address
102
+ address = {
103
+ "@type": "PostalAddress",
104
+ streetAddress: decidim_escape_translated(meeting.address)
105
+ }
106
+
107
+ address = address.merge({ addressLocality: geocoder_city }) if geocoder_city.present?
108
+ address = address.merge({ addressRegion: geocoder_state }) if geocoder_state.present?
109
+ address = address.merge({ postalCode: geocoder_postal_code }) if geocoder_postal_code.present?
110
+ address = address.merge({ addressCountry: geocoder_country }) if geocoder_country.present?
111
+
112
+ {
113
+ "@type": "Place",
114
+ name: decidim_escape_translated(meeting.location),
115
+ address:
116
+ }
117
+ end
118
+
119
+ def location_virtual
120
+ {
121
+ "@type": "VirtualLocation",
122
+ url: meeting.online_meeting_url
123
+ }
124
+ end
125
+
126
+ def geocoder
127
+ return if meeting.latitude.blank? || meeting.longitude.blank?
128
+
129
+ @geocoder ||= Geocoder.search([meeting.latitude, meeting.longitude]).first
130
+ end
131
+
132
+ def geocoder_city
133
+ @geocoder_city ||= geocoder&.city
134
+ end
135
+
136
+ def geocoder_state
137
+ @geocoder_state ||= geocoder&.state
138
+ end
139
+
140
+ def geocoder_postal_code
141
+ @geocoder_postal_code ||= geocoder&.postal_code
142
+ end
143
+
144
+ def geocoder_country
145
+ @geocoder_country ||= geocoder&.country
146
+ end
147
+
148
+ def image = meeting.photos.map(&:thumbnail_url)
149
+ end
150
+ end
151
+ end
@@ -63,14 +63,12 @@ module Decidim
63
63
 
64
64
  params = {
65
65
  component:,
66
- scope: random_scope(participatory_space:),
67
- category: participatory_space.categories.sample,
68
66
  title: Decidim::Faker::Localized.sentence(word_count: 2),
69
67
  description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
70
68
  Decidim::Faker::Localized.paragraph(sentence_count: 3)
71
69
  end,
72
- location: Decidim::Faker::Localized.sentence,
73
- location_hints: Decidim::Faker::Localized.sentence,
70
+ location: Decidim::Faker::Localized.sentence(word_count: rand(2..20)),
71
+ location_hints: Decidim::Faker::Localized.sentence(word_count: rand(2..20)),
74
72
  start_time:,
75
73
  end_time:,
76
74
  address: "#{::Faker::Address.street_address} #{::Faker::Address.zip} #{::Faker::Address.city}",
@@ -47,6 +47,7 @@ FactoryBot.define do
47
47
  component { build(:meeting_component) }
48
48
  iframe_access_level { :all }
49
49
  iframe_embed_type { :none }
50
+ deleted_at { nil }
50
51
 
51
52
  author do
52
53
  component.try(:organization)
@@ -73,6 +74,8 @@ FactoryBot.define do
73
74
  trait :online do
74
75
  type_of_meeting { :online }
75
76
  online_meeting_url { "https://decidim.org" }
77
+ latitude { nil }
78
+ longitude { nil }
76
79
  end
77
80
 
78
81
  trait :hybrid do
@@ -183,6 +186,11 @@ FactoryBot.define do
183
186
  end
184
187
  end
185
188
 
189
+ factory :meeting_link, class: "Decidim::Meetings::MeetingLink" do
190
+ meeting
191
+ component
192
+ end
193
+
186
194
  factory :registration, class: "Decidim::Meetings::Registration" do
187
195
  transient do
188
196
  skip_injection { false }
@@ -4,17 +4,17 @@ shared_examples_for "a translated meeting event" do
4
4
  describe "translated notifications" do
5
5
  let(:en_body) { "This is Sparta!" }
6
6
  let(:body) { { en: en_body, machine_translations: { ca: "C'est Sparta!" } } }
7
- let(:participatory_process) { create :participatory_process, organization: }
7
+ let(:participatory_process) { create(:participatory_process, organization:) }
8
8
  let(:meeting_component) { create(:meeting_component, participatory_space: participatory_process) }
9
9
  let(:translatable) { true }
10
10
  let(:en_version) { resource.description["en"] }
11
11
  let(:machine_translated) { resource.description["machine_translations"]["ca"] }
12
12
 
13
13
  let(:resource) do
14
- create :meeting,
14
+ create(:meeting,
15
15
  component: meeting_component,
16
16
  title: { en: "A nice event", machine_translations: { ca: "Une belle event" } },
17
- description: body
17
+ description: body)
18
18
  end
19
19
 
20
20
  it_behaves_like "a translated event"
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-meetings version.
5
5
  module Meetings
6
6
  def self.version
7
- "0.29.3"
7
+ "0.30.0.rc1"
8
8
  end
9
9
  end
10
10
  end
@@ -16,6 +16,7 @@ module Decidim
16
16
  autoload :MeetingSerializer, "decidim/meetings/meeting_serializer"
17
17
  autoload :UserAnswersSerializer, "decidim/meetings/user_answers_serializer"
18
18
  autoload :DownloadYourDataUserAnswersSerializer, "decidim/meetings/download_your_data_user_answers_serializer"
19
+ autoload :SchemaOrgEventMeetingSerializer, "decidim/meetings/schema_org_event_meeting_serializer"
19
20
 
20
21
  include ActiveSupport::Configurable
21
22