# frozen_string_literal: true
require "decidim/components/namer"
Decidim.register_component(:meetings) do |component|
component.engine = Decidim::Meetings::Engine
component.admin_engine = Decidim::Meetings::AdminEngine
component.icon = "media/images/decidim_meetings.svg"
component.permissions_class_name = "Decidim::Meetings::Permissions"
component.query_type = "Decidim::Meetings::MeetingsType"
component.data_portable_entities = ["Decidim::Meetings::Registration"]
component.on(:before_destroy) do |instance|
raise StandardError, "Can't remove this component" if Decidim::Meetings::Meeting.where(component: instance).any?
end
component.register_resource(:meeting) do |resource|
resource.model_class_name = "Decidim::Meetings::Meeting"
resource.template = "decidim/meetings/meetings/linked_meetings"
resource.card = "decidim/meetings/meeting"
resource.reported_content_cell = "decidim/meetings/reported_content"
resource.actions = %w(join comment)
resource.searchable = true
end
component.register_stat :meetings_count, primary: true, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY do |components, start_at, end_at|
meetings = Decidim::Meetings::FilteredMeetings.for(components, start_at, end_at).except_withdrawn
meetings.count
end
component.register_stat :followers_count, tag: :followers, priority: Decidim::StatsRegistry::LOW_PRIORITY do |components, start_at, end_at|
meetings_ids = Decidim::Meetings::FilteredMeetings.for(components, start_at, end_at).pluck(:id)
Decidim::Follow.where(decidim_followable_type: "Decidim::Meetings::Meeting", decidim_followable_id: meetings_ids).count
end
component.register_stat :comments_count, tag: :comments do |components, start_at, end_at|
meetings = Decidim::Meetings::FilteredMeetings.for(components, start_at, end_at).not_hidden
meetings.sum(:comments_count)
end
component.exports :meetings do |exports|
exports.collection do |component_instance|
Decidim::Meetings::Meeting
.not_hidden
.visible
.where(component: component_instance)
.includes(:scope, :category, :attachments, component: { participatory_space: :organization })
end
exports.include_in_open_data = true
exports.serializer Decidim::Meetings::MeetingSerializer
end
component.exports :meeting_comments do |exports|
exports.collection do |component_instance|
Decidim::Comments::Export.comments_for_resource(
Decidim::Meetings::Meeting, component_instance
).includes(:author, :user_group, root_commentable: { component: { participatory_space: :organization } })
end
exports.include_in_open_data = true
exports.serializer Decidim::Comments::CommentSerializer
end
component.exports :answers do |exports|
exports.collection do |_component, _user, resource_id|
Decidim::Meetings::QuestionnaireUserAnswers.for(resource_id)
end
exports.formats %w(CSV JSON Excel FormPDF)
exports.serializer Decidim::Meetings::UserAnswersSerializer
end
component.actions = %w(join comment)
component.settings(:global) do |settings|
settings.attribute :scopes_enabled, type: :boolean, default: false
settings.attribute :scope_id, type: :scope
settings.attribute :announcement, type: :text, translated: true, editor: true
settings.attribute :default_registration_terms, type: :text, translated: true, editor: true
settings.attribute :comments_enabled, type: :boolean, default: true
settings.attribute :comments_max_length, type: :integer, required: true
settings.attribute :registration_code_enabled, type: :boolean, default: true
settings.attribute :resources_permissions_enabled, type: :boolean, default: true
settings.attribute :enable_pads_creation, type: :boolean, default: false
settings.attribute :creation_enabled_for_participants, type: :boolean, default: false
settings.attribute :maps_enabled, type: :boolean, default: true
end
component.settings(:step) do |settings|
settings.attribute :announcement, type: :text, translated: true, editor: true
settings.attribute :comments_blocked, type: :boolean, default: false
end
component.seeds do |participatory_space|
admin_user = Decidim::User.find_by(
organization: participatory_space.organization,
email: "admin@example.org"
)
params = {
name: Decidim::Components::Namer.new(participatory_space.organization.available_locales, :meetings).i18n_name,
published_at: Time.current,
manifest_name: :meetings,
participatory_space: participatory_space
}
component = Decidim.traceability.perform_action!(
"publish",
Decidim::Component,
admin_user,
visibility: "all"
) do
Decidim::Component.create!(params)
end
if participatory_space.scope
scopes = participatory_space.scope.descendants
global = participatory_space.scope
else
scopes = participatory_space.organization.scopes
global = nil
end
2.times do
start_time = Faker::Date.between(from: 20.weeks.ago, to: 20.weeks.from_now)
end_time = start_time + [rand(1..4).hours, rand(1..20).days].sample
params = {
component: component,
scope: Faker::Boolean.boolean(true_ratio: 0.5) ? global : scopes.sample,
category: participatory_space.categories.sample,
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
Decidim::Faker::Localized.paragraph(sentence_count: 3)
end,
location: Decidim::Faker::Localized.sentence,
location_hints: Decidim::Faker::Localized.sentence,
start_time: start_time,
end_time: end_time,
address: "#{Faker::Address.street_address} #{Faker::Address.zip} #{Faker::Address.city}",
latitude: Faker::Address.latitude,
longitude: Faker::Address.longitude,
registrations_enabled: [true, false].sample,
available_slots: (10..50).step(10).to_a.sample,
author: participatory_space.organization,
registration_terms: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
Decidim::Faker::Localized.paragraph(sentence_count: 3)
end,
published_at: Faker::Boolean.boolean(true_ratio: 0.8) ? Time.current : nil
}
_hybrid_meeting = Decidim.traceability.create!(
Decidim::Meetings::Meeting,
admin_user,
params.merge(
title: Decidim::Faker::Localized.sentence(word_count: 2),
type_of_meeting: :hybrid,
online_meeting_url: "http://example.org"
),
visibility: "all"
)
_online_meeting = Decidim.traceability.create!(
Decidim::Meetings::Meeting,
admin_user,
params.merge(
title: Decidim::Faker::Localized.sentence(word_count: 2),
type_of_meeting: :online,
online_meeting_url: "http://example.org"
),
visibility: "all"
)
meeting = Decidim.traceability.create!(
Decidim::Meetings::Meeting,
admin_user,
params,
visibility: "all"
)
2.times do
Decidim::Meetings::Service.create!(
meeting: meeting,
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.sentence(word_count: 5)
)
end
Decidim::Forms::Questionnaire.create!(
title: Decidim::Faker::Localized.paragraph,
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
Decidim::Faker::Localized.paragraph(sentence_count: 3)
end,
tos: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
Decidim::Faker::Localized.paragraph(sentence_count: 2)
end,
questionnaire_for: meeting
)
2.times do |n|
email = "meeting-registered-user-#{meeting.id}-#{n}@example.org"
name = "#{Faker::Name.name} #{meeting.id} #{n}"
user = Decidim::User.find_or_initialize_by(email: email)
user.update!(
password: "decidim123456789",
password_confirmation: "decidim123456789",
name: name,
nickname: Faker::Twitter.unique.screen_name,
organization: component.organization,
tos_agreement: "1",
confirmed_at: Time.current,
personal_url: Faker::Internet.url,
about: Faker::Lorem.paragraph(sentence_count: 2)
)
Decidim::Meetings::Registration.create!(
meeting: meeting,
user: user
)
end
attachment_collection = Decidim::AttachmentCollection.create!(
name: Decidim::Faker::Localized.word,
description: Decidim::Faker::Localized.sentence(word_count: 5),
collection_for: meeting
)
Decidim::Attachment.create!(
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.sentence(word_count: 5),
attachment_collection: attachment_collection,
attached_to: meeting,
content_type: "application/pdf",
file: ActiveStorage::Blob.create_and_upload!(
io: File.open(File.join(__dir__, "seeds", "Exampledocument.pdf")),
filename: "Exampledocument.pdf",
content_type: "application/pdf",
metadata: nil
) # Keep after attached_to
)
Decidim::Attachment.create!(
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.sentence(word_count: 5),
attached_to: meeting,
content_type: "image/jpeg",
file: ActiveStorage::Blob.create_and_upload!(
io: File.open(File.join(__dir__, "seeds", "city.jpeg")),
filename: "city.jpeg",
content_type: "image/jpeg",
metadata: nil
) # Keep after attached_to
)
Decidim::Attachment.create!(
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.sentence(word_count: 5),
attached_to: meeting,
content_type: "application/pdf",
file: ActiveStorage::Blob.create_and_upload!(
io: File.open(File.join(__dir__, "seeds", "Exampledocument.pdf")),
filename: "Exampledocument.pdf",
content_type: "application/pdf",
metadata: nil
) # Keep after attached_to
)
end
authors = [
Decidim::UserGroup.where(decidim_organization_id: participatory_space.decidim_organization_id).verified.sample,
Decidim::User.where(decidim_organization_id: participatory_space.decidim_organization_id).all.sample
]
authors.each do |author|
user_group = nil
if author.is_a?(Decidim::UserGroup)
user_group = author
author = user_group.users.sample
end
start_time = Faker::Date.between(from: 20.weeks.ago, to: 20.weeks.from_now)
params = {
component: component,
scope: Faker::Boolean.boolean(true_ratio: 0.5) ? global : scopes.sample,
category: participatory_space.categories.sample,
title: Decidim::Faker::Localized.sentence(word_count: 2),
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
Decidim::Faker::Localized.paragraph(sentence_count: 3)
end,
location: Decidim::Faker::Localized.sentence,
location_hints: Decidim::Faker::Localized.sentence,
start_time: start_time,
end_time: start_time + rand(1..4).hours,
address: "#{Faker::Address.street_address} #{Faker::Address.zip} #{Faker::Address.city}",
latitude: Faker::Address.latitude,
longitude: Faker::Address.longitude,
registrations_enabled: [true, false].sample,
available_slots: (10..50).step(10).to_a.sample,
author: author,
user_group: user_group
}
Decidim.traceability.create!(
Decidim::Meetings::Meeting,
authors[0],
params,
visibility: "all"
)
end
end
end
Decidim.register_global_engine(
:meetings_directory,
Decidim::Meetings::DirectoryEngine,
at: "/meetings"
)