decidim-conferences 0.29.4 → 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.
- checksums.yaml +4 -4
- data/app/cells/decidim/conferences/content_blocks/highlighted_conferences_settings_form/show.erb +1 -1
- data/app/commands/decidim/conferences/admin/copy_conference.rb +2 -12
- data/app/commands/decidim/conferences/admin/create_conference.rb +1 -1
- data/app/commands/decidim/conferences/admin/invite_user_to_join_conference.rb +1 -1
- data/app/commands/decidim/conferences/admin/update_conference.rb +1 -1
- data/app/controllers/decidim/conferences/admin/component_share_tokens_controller.rb +18 -0
- data/app/controllers/decidim/conferences/admin/concerns/conference_admin.rb +1 -1
- data/app/controllers/decidim/conferences/admin/conference_share_tokens_controller.rb +18 -0
- data/app/controllers/decidim/conferences/admin/conferences_controller.rb +17 -4
- data/app/forms/decidim/conferences/admin/conference_copy_form.rb +0 -1
- data/app/forms/decidim/conferences/admin/conference_form.rb +3 -8
- data/app/helpers/decidim/conferences/conference_program_helper.rb +4 -2
- data/app/mailers/decidim/conferences/admin/send_conference_diploma_mailer.rb +1 -11
- data/app/models/decidim/conference.rb +19 -0
- data/app/models/decidim/conferences/conference_invite.rb +10 -0
- data/app/permissions/decidim/conferences/permissions.rb +11 -10
- data/app/presenters/decidim/conferences/admin_log/conference_presenter.rb +1 -1
- data/app/presenters/decidim/conferences/conference_presenter.rb +19 -0
- data/app/serializers/decidim/conferences/conference_serializer.rb +24 -0
- data/app/serializers/decidim/conferences/download_your_data_conference_invite_serializer.rb +3 -4
- data/app/serializers/decidim/conferences/download_your_data_conference_registration_serializer.rb +4 -4
- data/app/serializers/decidim/conferences/open_data_conference_serializer.rb +30 -0
- data/app/views/decidim/conferences/admin/conference_copies/_form.html.erb +0 -3
- data/app/views/decidim/conferences/admin/conferences/_actions.html.erb +35 -0
- data/app/views/decidim/conferences/admin/conferences/_conference_row.html.erb +28 -0
- data/app/views/decidim/conferences/admin/conferences/_conferences_thead.html.erb +8 -0
- data/app/views/decidim/conferences/admin/conferences/_form.html.erb +27 -8
- data/app/views/decidim/conferences/admin/conferences/index.html.erb +14 -52
- data/app/views/decidim/conferences/admin/conferences/manage_trash.html.erb +20 -0
- data/app/views/decidim/conferences/admin/send_conference_diploma_mailer/diploma_user.html.erb +3 -1
- data/app/views/decidim/conferences/conference_program/show.html.erb +3 -1
- data/app/views/decidim/conferences/conference_speakers/index.html.erb +4 -1
- data/app/views/decidim/conferences/conferences/index.html.erb +3 -2
- data/app/views/decidim/conferences/conferences/show.html.erb +6 -6
- data/app/views/decidim/conferences/media/index.html.erb +3 -1
- data/app/views/decidim/conferences/registration_types/index.html.erb +3 -1
- data/app/views/layouts/decidim/admin/conference.html.erb +1 -1
- data/config/locales/ar.yml +10 -3
- data/config/locales/bg.yml +0 -3
- data/config/locales/ca.yml +61 -3
- data/config/locales/cs.yml +61 -3
- data/config/locales/de.yml +61 -3
- data/config/locales/el.yml +0 -3
- data/config/locales/en.yml +61 -3
- data/config/locales/es-MX.yml +61 -3
- data/config/locales/es-PY.yml +61 -3
- data/config/locales/es.yml +61 -3
- data/config/locales/eu.yml +77 -19
- data/config/locales/fi-plain.yml +61 -3
- data/config/locales/fi.yml +61 -3
- data/config/locales/fr-CA.yml +20 -3
- data/config/locales/fr.yml +20 -3
- data/config/locales/ga-IE.yml +0 -2
- data/config/locales/gl.yml +0 -3
- data/config/locales/hu.yml +0 -3
- data/config/locales/id-ID.yml +0 -3
- data/config/locales/it.yml +0 -3
- data/config/locales/ja.yml +61 -3
- data/config/locales/lb.yml +0 -3
- data/config/locales/lt.yml +0 -3
- data/config/locales/lv.yml +0 -3
- data/config/locales/nl.yml +0 -3
- data/config/locales/no.yml +0 -3
- data/config/locales/pl.yml +0 -3
- data/config/locales/pt-BR.yml +0 -3
- data/config/locales/pt.yml +0 -3
- data/config/locales/ro-RO.yml +0 -5
- data/config/locales/sk.yml +0 -3
- data/config/locales/sv.yml +31 -41
- data/config/locales/tr-TR.yml +0 -3
- data/config/locales/zh-CN.yml +0 -3
- data/config/locales/zh-TW.yml +0 -3
- data/db/migrate/20210310134942_add_followable_counter_cache_to_conferences.rb +1 -1
- data/db/migrate/20240822161330_add_deleted_at_to_decidim_conferences.rb +8 -0
- data/decidim-conferences.gemspec +1 -2
- data/lib/decidim/api/conference_media_link_type.rb +4 -4
- data/lib/decidim/api/conference_partner_type.rb +4 -4
- data/lib/decidim/api/conference_speaker_type.rb +7 -8
- data/lib/decidim/api/conference_type.rb +17 -19
- data/lib/decidim/conferences/admin_engine.rb +87 -58
- data/lib/decidim/conferences/conference_diploma_pdf.rb +242 -0
- data/lib/decidim/conferences/engine.rb +6 -1
- data/lib/decidim/conferences/menu.rb +23 -9
- data/lib/decidim/conferences/participatory_space.rb +13 -0
- data/lib/decidim/conferences/seeds.rb +134 -115
- data/lib/decidim/conferences/test/factories.rb +10 -9
- data/lib/decidim/conferences/version.rb +1 -1
- data/lib/decidim/conferences.rb +1 -0
- metadata +23 -29
- data/app/controllers/decidim/conferences/admin/categories_controller.rb +0 -13
- data/config/initializers/wicked_pdf.rb +0 -22
- data/config/locales/ca-IT.yml +0 -603
data/decidim-conferences.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
"homepage_uri" => "https://decidim.org",
|
18
18
|
"source_code_uri" => "https://github.com/decidim/decidim"
|
19
19
|
}
|
20
|
-
s.required_ruby_version = "~> 3.
|
20
|
+
s.required_ruby_version = "~> 3.3.0"
|
21
21
|
|
22
22
|
s.name = "decidim-conferences"
|
23
23
|
s.summary = "Decidim conferences module"
|
@@ -32,7 +32,6 @@ Gem::Specification.new do |s|
|
|
32
32
|
|
33
33
|
s.add_dependency "decidim-core", Decidim::Conferences.version
|
34
34
|
s.add_dependency "decidim-meetings", Decidim::Conferences.version
|
35
|
-
s.add_dependency "wicked_pdf", "~> 2.7"
|
36
35
|
|
37
36
|
s.add_development_dependency "decidim-admin", Decidim::Conferences.version
|
38
37
|
s.add_development_dependency "decidim-dev", Decidim::Conferences.version
|
@@ -4,15 +4,15 @@ module Decidim
|
|
4
4
|
module Conferences
|
5
5
|
# This type represents a conference.
|
6
6
|
class ConferenceMediaLinkType < Decidim::Api::Types::BaseObject
|
7
|
+
implements Decidim::Core::TimestampsInterface
|
8
|
+
|
7
9
|
description "A conference media link"
|
8
10
|
|
11
|
+
field :date, Decidim::Core::DateType, "Relevant date for the media link", null: true
|
9
12
|
field :id, GraphQL::Types::ID, "Internal ID for this media link", null: false
|
10
|
-
field :title, Decidim::Core::TranslatedFieldType, "Title for this media link", null: true
|
11
13
|
field :link, GraphQL::Types::String, "URL for this media link", null: true
|
12
|
-
field :
|
14
|
+
field :title, Decidim::Core::TranslatedFieldType, "Title for this media link", null: true
|
13
15
|
field :weight, GraphQL::Types::Int, "Order of appearance in which it should be presented", null: true
|
14
|
-
field :created_at, Decidim::Core::DateTimeType, "The time this entry was created", null: true
|
15
|
-
field :updated_at, Decidim::Core::DateTimeType, "The time this entry was updated", null: true
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -4,16 +4,16 @@ module Decidim
|
|
4
4
|
module Conferences
|
5
5
|
# This type represents a conference.
|
6
6
|
class ConferencePartnerType < Decidim::Api::Types::BaseObject
|
7
|
+
implements Decidim::Core::TimestampsInterface
|
8
|
+
|
7
9
|
description "A conference partner"
|
8
10
|
|
9
11
|
field :id, GraphQL::Types::ID, "ID of the resource", null: false
|
12
|
+
field :link, GraphQL::Types::String, "Relevant URL for this partner", null: true
|
13
|
+
field :logo, GraphQL::Types::String, "Link to the partner's logo", null: true
|
10
14
|
field :name, GraphQL::Types::String, "Partner name", null: true
|
11
15
|
field :partner_type, GraphQL::Types::String, "Partner type", null: true
|
12
16
|
field :weight, GraphQL::Types::Int, "Order of appearance in which it should be presented", null: true
|
13
|
-
field :link, GraphQL::Types::String, "Relevant URL for this partner", null: true
|
14
|
-
field :logo, GraphQL::Types::String, "Link to the partner's logo", null: true
|
15
|
-
field :created_at, Decidim::Core::DateTimeType, "The time this partner was created", null: true
|
16
|
-
field :updated_at, Decidim::Core::DateTimeType, "The time this partner was updated", null: true
|
17
17
|
|
18
18
|
def logo
|
19
19
|
object.attached_uploader(:logo).url
|
@@ -4,21 +4,20 @@ module Decidim
|
|
4
4
|
module Conferences
|
5
5
|
# This type represents a conference.
|
6
6
|
class ConferenceSpeakerType < Decidim::Api::Types::BaseObject
|
7
|
+
implements Decidim::Core::TimestampsInterface
|
8
|
+
|
7
9
|
description "A conference speaker"
|
8
10
|
|
9
|
-
field :
|
11
|
+
field :affiliation, Decidim::Core::TranslatedFieldType, "Affiliation of the speaker", null: true
|
12
|
+
field :avatar, GraphQL::Types::String, "Avatar of the speaker", null: true
|
10
13
|
field :full_name, GraphQL::Types::String, "Full name of the speaker", null: true
|
14
|
+
field :id, GraphQL::Types::ID, "Internal ID of the speaker", null: false
|
15
|
+
field :personal_url, GraphQL::Types::String, "Personal URL of the speaker", null: true
|
11
16
|
field :position, Decidim::Core::TranslatedFieldType, "Position of the speaker in the conference", null: true
|
12
|
-
field :affiliation, Decidim::Core::TranslatedFieldType, "Affiliation of the speaker", null: true
|
13
|
-
field :twitter_handle, GraphQL::Types::String, "X handle", null: true
|
14
17
|
field :short_bio, Decidim::Core::TranslatedFieldType, "Short biography of the speaker", null: true
|
15
|
-
field :
|
16
|
-
field :avatar, GraphQL::Types::String, "Avatar of the speaker", null: true
|
18
|
+
field :twitter_handle, GraphQL::Types::String, "X handle", null: true
|
17
19
|
field :user, Decidim::Core::UserType, "Decidim user corresponding to this speaker", null: true
|
18
20
|
|
19
|
-
field :created_at, Decidim::Core::DateTimeType, "The time this member was created ", null: true
|
20
|
-
field :updated_at, Decidim::Core::DateTimeType, "The time this member was updated", null: true
|
21
|
-
|
22
21
|
def avatar
|
23
22
|
object.attached_uploader(:avatar).url
|
24
23
|
end
|
@@ -7,36 +7,34 @@ module Decidim
|
|
7
7
|
implements Decidim::Core::ParticipatorySpaceInterface
|
8
8
|
implements Decidim::Core::ScopableInterface
|
9
9
|
implements Decidim::Core::AttachableInterface
|
10
|
+
implements Decidim::Core::TaxonomizableInterface
|
11
|
+
implements Decidim::Core::TimestampsInterface
|
10
12
|
implements Decidim::Core::CategoriesContainerInterface
|
11
13
|
|
12
14
|
description "A conference"
|
13
15
|
|
14
|
-
field :
|
15
|
-
field :
|
16
|
+
field :available_slots, GraphQL::Types::Int, "The number of available slots in this conference", null: true
|
17
|
+
field :banner_image, GraphQL::Types::String, "The banner image for this conference", null: true
|
16
18
|
field :description, Decidim::Core::TranslatedFieldType, "The description of this conference", null: true
|
17
|
-
field :
|
19
|
+
field :end_date, Decidim::Core::DateType, "The date this conference ends", null: true
|
18
20
|
field :hashtag, GraphQL::Types::String, "The hashtag for this conference", null: true
|
19
|
-
field :
|
21
|
+
field :hero_image, GraphQL::Types::String, "The hero image for this conference", null: true
|
22
|
+
field :id, GraphQL::Types::ID, "Internal ID for this conference", null: false
|
20
23
|
field :location, String, "The location of this conference", null: true
|
21
|
-
field :
|
22
|
-
field :
|
24
|
+
field :media_links, [Decidim::Conferences::ConferenceMediaLinkType, { null: true }], "List of media links in this conference", null: true
|
25
|
+
field :objectives, Decidim::Core::TranslatedFieldType, "The objectives of the conference", null: true
|
26
|
+
field :partners, [Decidim::Conferences::ConferencePartnerType, { null: true }], "List of partners in this conference", null: true
|
27
|
+
field :promoted, GraphQL::Types::Boolean, "If this conference is promoted (therefore in the homepage)", null: true
|
23
28
|
field :published_at, Decidim::Core::DateTimeType, "The time this conference was published", null: true
|
24
29
|
field :reference, GraphQL::Types::String, "Reference prefix for this conference", null: true
|
25
|
-
|
26
|
-
field :hero_image, GraphQL::Types::String, "The hero image for this conference", null: true
|
27
|
-
field :banner_image, GraphQL::Types::String, "The banner image for this conference", null: true
|
28
|
-
field :promoted, GraphQL::Types::Boolean, "If this conference is promoted (therefore in the homepage)", null: true
|
29
|
-
field :objectives, Decidim::Core::TranslatedFieldType, "The objectives of the conference", null: true
|
30
|
-
field :show_statistics, GraphQL::Types::Boolean, "If this conference shows the statistics", null: true
|
31
|
-
field :start_date, Decidim::Core::DateType, "The date this conference starts", null: true
|
32
|
-
field :end_date, Decidim::Core::DateType, "The date this conference ends", null: true
|
33
|
-
field :registrations_enabled, GraphQL::Types::Boolean, "If the registrations are enabled in this conference", null: true
|
34
|
-
field :available_slots, GraphQL::Types::Int, "The number of available slots in this conference", null: true
|
35
30
|
field :registration_terms, Decidim::Core::TranslatedFieldType, "The registration terms of this conference", null: true
|
36
|
-
|
31
|
+
field :registrations_enabled, GraphQL::Types::Boolean, "If the registrations are enabled in this conference", null: true
|
32
|
+
field :short_description, Decidim::Core::TranslatedFieldType, "The short description of this conference", null: true
|
33
|
+
field :show_statistics, GraphQL::Types::Boolean, "If this conference shows the statistics", null: true
|
34
|
+
field :slogan, Decidim::Core::TranslatedFieldType, "The slogan of the conference", null: true
|
35
|
+
field :slug, GraphQL::Types::String, "The slug of this conference", null: true
|
37
36
|
field :speakers, [Decidim::Conferences::ConferenceSpeakerType, { null: true }], "List of speakers in this conference", null: true
|
38
|
-
field :
|
39
|
-
field :media_links, [Decidim::Conferences::ConferenceMediaLinkType, { null: true }], "List of media links in this conference", null: true
|
37
|
+
field :start_date, Decidim::Core::DateType, "The date this conference starts", null: true
|
40
38
|
|
41
39
|
def hero_image
|
42
40
|
object.attached_uploader(:hero_image).url
|
@@ -15,89 +15,118 @@ module Decidim
|
|
15
15
|
paths["lib/tasks"] = nil
|
16
16
|
|
17
17
|
routes do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
constraints(->(request) { Decidim::Admin::OrganizationDashboardConstraint.new(request).matches? }) do
|
19
|
+
resources :conferences, param: :slug, except: [:show, :destroy] do
|
20
|
+
resource :publish, controller: "conference_publications", only: [:create, :destroy]
|
21
|
+
resources :copies, controller: "conference_copies", only: [:new, :create]
|
22
|
+
resources :speakers, controller: "conference_speakers" do
|
23
|
+
member do
|
24
|
+
put :publish
|
25
|
+
put :unpublish
|
26
|
+
end
|
25
27
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
resources :partners, controller: "partners", except: [:show]
|
29
|
+
resources :media_links, controller: "media_links"
|
30
|
+
resources :registration_types, controller: "registration_types" do
|
31
|
+
resource :publish, controller: "registration_type_publications", only: [:create, :destroy]
|
32
|
+
collection do
|
33
|
+
get :conference_meetings
|
34
|
+
end
|
33
35
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
resources :conference_invites, only: [:index, :new, :create]
|
37
|
+
resources :conference_registrations, only: :index do
|
38
|
+
member do
|
39
|
+
post :confirm
|
40
|
+
end
|
41
|
+
collection do
|
42
|
+
get :export
|
43
|
+
end
|
39
44
|
end
|
40
|
-
|
41
|
-
|
45
|
+
resource :diploma, only: [:edit, :update] do
|
46
|
+
member do
|
47
|
+
post :send, to: "diplomas#send_diplomas"
|
48
|
+
end
|
42
49
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
50
|
+
resources :user_roles, controller: "conference_user_roles" do
|
51
|
+
member do
|
52
|
+
post :resend_invitation, to: "conference_user_roles#resend_invitation"
|
53
|
+
end
|
47
54
|
end
|
48
|
-
|
49
|
-
resources :user_roles, controller: "conference_user_roles" do
|
55
|
+
|
50
56
|
member do
|
51
|
-
|
57
|
+
patch :soft_delete
|
58
|
+
patch :restore
|
52
59
|
end
|
53
|
-
end
|
54
60
|
|
55
|
-
|
56
|
-
|
57
|
-
|
61
|
+
collection do
|
62
|
+
get :manage_trash, to: "conferences#manage_trash"
|
63
|
+
end
|
58
64
|
|
59
|
-
|
60
|
-
|
65
|
+
resources :attachment_collections, controller: "conference_attachment_collections", except: [:show]
|
66
|
+
resources :attachments, controller: "conference_attachments", except: [:show]
|
67
|
+
end
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
scope "/conferences/:conference_slug" do
|
70
|
+
resources :components do
|
71
|
+
collection do
|
72
|
+
put :reorder
|
73
|
+
end
|
74
|
+
resource :permissions, controller: "component_permissions"
|
75
|
+
member do
|
76
|
+
put :publish
|
77
|
+
put :unpublish
|
78
|
+
get :share
|
79
|
+
patch :soft_delete
|
80
|
+
patch :restore
|
81
|
+
end
|
82
|
+
collection do
|
83
|
+
get :manage_trash, to: "components#manage_trash"
|
84
|
+
put :hide
|
85
|
+
end
|
86
|
+
resources :component_share_tokens, except: [:show], path: "share_tokens", as: "share_tokens"
|
87
|
+
resources :exports, only: :create
|
88
|
+
resources :imports, only: [:new, :create] do
|
89
|
+
get :example, on: :collection
|
90
|
+
end
|
91
|
+
resources :reminders, only: [:new, :create]
|
72
92
|
end
|
73
|
-
resources :reminders, only: [:new, :create]
|
74
|
-
end
|
75
93
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
94
|
+
resources :moderations do
|
95
|
+
member do
|
96
|
+
put :unreport
|
97
|
+
put :hide
|
98
|
+
put :unhide
|
99
|
+
end
|
100
|
+
patch :bulk_action, on: :collection
|
101
|
+
resources :reports, controller: "moderations/reports", only: [:index, :show]
|
81
102
|
end
|
82
|
-
|
103
|
+
|
104
|
+
resources :conference_share_tokens, except: [:show], path: "share_tokens"
|
83
105
|
end
|
84
|
-
end
|
85
106
|
|
86
|
-
|
87
|
-
|
88
|
-
|
107
|
+
scope "/conferences/:conference_slug/components/:component_id/manage" do
|
108
|
+
Decidim.component_manifests.each do |manifest|
|
109
|
+
next unless manifest.admin_engine
|
89
110
|
|
90
|
-
|
91
|
-
|
111
|
+
constraints CurrentComponent.new(manifest) do
|
112
|
+
mount manifest.admin_engine, at: "/", as: "decidim_admin_conference_#{manifest.name}"
|
113
|
+
end
|
92
114
|
end
|
93
115
|
end
|
94
116
|
end
|
95
117
|
end
|
96
118
|
|
119
|
+
initializer "decidim_conferences_admin.mount_routes" do
|
120
|
+
Decidim::Core::Engine.routes do
|
121
|
+
mount Decidim::Conferences::AdminEngine, at: "/admin", as: "decidim_admin_conferences"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
97
125
|
initializer "decidim_conferences_admin.menu" do
|
98
126
|
Decidim::Conferences::Menu.register_admin_conferences_components_menu!
|
99
127
|
Decidim::Conferences::Menu.register_conferences_admin_registrations_menu!
|
100
128
|
Decidim::Conferences::Menu.register_conferences_admin_attachments_menu!
|
129
|
+
Decidim::Conferences::Menu.register_conference_admin_menu!
|
101
130
|
Decidim::Conferences::Menu.register_conferences_admin_menu!
|
102
131
|
Decidim::Conferences::Menu.register_admin_menu_modules!
|
103
132
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hexapdf"
|
4
|
+
require "open-uri"
|
5
|
+
|
6
|
+
module Decidim
|
7
|
+
module Conferences
|
8
|
+
class ConferenceDiplomaPDF
|
9
|
+
include ActionView::Helpers::AssetUrlHelper
|
10
|
+
include Shakapacker::Helper
|
11
|
+
include Decidim::TranslatableAttributes
|
12
|
+
include Decidim::SanitizeHelper
|
13
|
+
|
14
|
+
def initialize(conference, user)
|
15
|
+
@conference = conference
|
16
|
+
@user = user
|
17
|
+
end
|
18
|
+
|
19
|
+
def render
|
20
|
+
composer.styles(**styles)
|
21
|
+
|
22
|
+
create_border
|
23
|
+
add_logo
|
24
|
+
|
25
|
+
add_text
|
26
|
+
|
27
|
+
add_hr_line
|
28
|
+
add_verified_by_text
|
29
|
+
add_signature_picture
|
30
|
+
add_verified_by_signature
|
31
|
+
|
32
|
+
document.write_to_string
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :conference
|
38
|
+
|
39
|
+
delegate :document, to: :composer
|
40
|
+
|
41
|
+
def page_orientation = :landscape
|
42
|
+
|
43
|
+
def page = document.pages.first
|
44
|
+
|
45
|
+
def page_width = page.box(:media).width
|
46
|
+
|
47
|
+
def page_height = page.box(:media).height
|
48
|
+
|
49
|
+
def layout = document.layout
|
50
|
+
|
51
|
+
def box_width = page_width * 0.9
|
52
|
+
|
53
|
+
def box_height = page_height * 0.7
|
54
|
+
|
55
|
+
def styles
|
56
|
+
{
|
57
|
+
h1: { font: bold_font, text_align: :center, font_size: 18 },
|
58
|
+
h2: { font: bold_font, text_align: :center, font_size: 15 },
|
59
|
+
text: { font:, text_align: :center, font_size: 10 },
|
60
|
+
verified: { font:, text_align: :center, font_size: 8 },
|
61
|
+
bold: { font: bold_font, text_align: :center, font_size: 10 }
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def composer
|
66
|
+
@composer ||= ::HexaPDF::Composer.new(page_orientation:)
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_text
|
70
|
+
width = 710
|
71
|
+
|
72
|
+
composer.text(translated_attribute(conference.title), style: :h1, position: [30, box_height - 130], width:)
|
73
|
+
composer.text(I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.certificate_of_attendance"),
|
74
|
+
style: :h2, position: [30, box_height - 160], width:)
|
75
|
+
|
76
|
+
text = I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.certificate_of_attendance_description",
|
77
|
+
user: @user.name,
|
78
|
+
title: translated_attribute(@conference.title),
|
79
|
+
location: @conference.location,
|
80
|
+
start: I18n.l(@conference.start_date, format: :decidim_short),
|
81
|
+
end: I18n.l(@conference.end_date, format: :decidim_short))
|
82
|
+
|
83
|
+
texts_to_bold = [
|
84
|
+
@user.name,
|
85
|
+
translated_attribute(@conference.title),
|
86
|
+
I18n.l(@conference.start_date, format: :decidim_short),
|
87
|
+
I18n.l(@conference.end_date, format: :decidim_short)
|
88
|
+
]
|
89
|
+
|
90
|
+
texts_to_bold = texts_to_bold.map { |bold| decidim_sanitize(bold, strip_tags: true) }
|
91
|
+
|
92
|
+
text = decidim_sanitize(text, strip_tags: true)
|
93
|
+
text_fragments = create_text_fragments(text, texts_to_bold)
|
94
|
+
|
95
|
+
result = HexaPDF::Layout::TextLayouter.new.fit(text_fragments, 710, 30)
|
96
|
+
|
97
|
+
x_width = (page_width - result.lines.first.width) / 2
|
98
|
+
|
99
|
+
result.draw(composer.canvas, x_width, 260)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Function to create text fragments with bold parts
|
103
|
+
def create_text_fragments(text, texts_to_bold)
|
104
|
+
fragments = []
|
105
|
+
current_position = 0
|
106
|
+
|
107
|
+
texts_to_bold.sort_by! { |bold_text| text.index(bold_text) }
|
108
|
+
|
109
|
+
texts_to_bold.each do |bold_text|
|
110
|
+
bold_position = text.index(bold_text, current_position)
|
111
|
+
|
112
|
+
if bold_position > current_position
|
113
|
+
part = text[current_position...bold_position]
|
114
|
+
fragments << HexaPDF::Layout::TextFragment.create(part, styles[:text])
|
115
|
+
end
|
116
|
+
|
117
|
+
fragments << HexaPDF::Layout::TextFragment.create(bold_text, styles[:bold])
|
118
|
+
|
119
|
+
current_position = bold_position + bold_text.length
|
120
|
+
end
|
121
|
+
|
122
|
+
if current_position < text.length
|
123
|
+
part = text[current_position..-1]
|
124
|
+
fragments << HexaPDF::Layout::TextFragment.create(part, font: styles[:text])
|
125
|
+
end
|
126
|
+
|
127
|
+
fragments
|
128
|
+
end
|
129
|
+
|
130
|
+
def compute_dimensions(attached_image, max_width, max_height)
|
131
|
+
# Retrieve the image metadata
|
132
|
+
metadata = attached_image.blob.metadata
|
133
|
+
|
134
|
+
# If metadata does not contain width and height, return the max dimensions
|
135
|
+
return max_height, max_width unless metadata.has_key?(:width) && metadata.has_key?(:height)
|
136
|
+
|
137
|
+
# Calculate the aspect ratio of the image
|
138
|
+
aspect_ratio = metadata[:width].to_f / metadata[:height]
|
139
|
+
|
140
|
+
# Adjust the width based on the max height while preserving the aspect ratio
|
141
|
+
adjusted_width = (max_height * aspect_ratio).round
|
142
|
+
|
143
|
+
# Return the max height and the adjusted width
|
144
|
+
return max_height, adjusted_width
|
145
|
+
end
|
146
|
+
|
147
|
+
def font
|
148
|
+
@font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-regular.ttf")
|
149
|
+
end
|
150
|
+
|
151
|
+
def bold_font
|
152
|
+
@bold_font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-700.ttf")
|
153
|
+
end
|
154
|
+
|
155
|
+
def load_font(path)
|
156
|
+
document.fonts.add(Decidim::Core::Engine.root.join("app/packs/fonts/decidim/").join(path))
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_verified_by_text
|
160
|
+
composer.text(I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.attendance_verified_by"),
|
161
|
+
style: :bold, position: [30, 160], width: 710)
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_signature_picture
|
165
|
+
attached_image = conference.attached_uploader(:signature).variant(:original)
|
166
|
+
logo = document.images.add(StringIO.new(attached_image.download))
|
167
|
+
max_height, max_width = compute_dimensions(attached_image, 80, 40)
|
168
|
+
|
169
|
+
box_x = (page_width - max_width) / 2
|
170
|
+
box_y = 150
|
171
|
+
frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, 80, 40)
|
172
|
+
|
173
|
+
box = document.layout.box do |canvas, _box|
|
174
|
+
canvas.image(logo, at: [0, 0], width: max_width, height: max_height)
|
175
|
+
end
|
176
|
+
|
177
|
+
result = frame.fit(box)
|
178
|
+
frame.draw(page.canvas, result)
|
179
|
+
end
|
180
|
+
|
181
|
+
def add_hr_line
|
182
|
+
frame = ::HexaPDF::Layout::Frame.new(66, 210, 710, 10)
|
183
|
+
|
184
|
+
box = document.layout.box do |canvas, _box|
|
185
|
+
canvas.line_width = 0.5
|
186
|
+
canvas.stroke_color(0, 0, 0)
|
187
|
+
canvas.line(0, 10, 710, 10).stroke
|
188
|
+
end
|
189
|
+
result = frame.fit(box)
|
190
|
+
frame.draw(page.canvas, result)
|
191
|
+
end
|
192
|
+
|
193
|
+
def add_verified_by_signature
|
194
|
+
composer.text([
|
195
|
+
I18n.l(conference.sign_date, format: :decidim_short),
|
196
|
+
conference.signature_name
|
197
|
+
].join(", "), style: :verified, position: [30, 95], width: 710)
|
198
|
+
end
|
199
|
+
|
200
|
+
def add_logo
|
201
|
+
attached_image = conference.attached_uploader(:main_logo).variant(:original)
|
202
|
+
logo = document.images.add(StringIO.new(attached_image.download))
|
203
|
+
max_height, max_width = compute_dimensions(attached_image, 160, 80)
|
204
|
+
|
205
|
+
box_x = (page_width - max_width) / 2
|
206
|
+
box_y = page_height - 220
|
207
|
+
frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, 160, 80)
|
208
|
+
|
209
|
+
box = document.layout.box do |canvas, _box|
|
210
|
+
canvas.image(logo, at: [0, 0], width: max_width, height: max_height)
|
211
|
+
end
|
212
|
+
|
213
|
+
result = frame.fit(box)
|
214
|
+
frame.draw(page.canvas, result)
|
215
|
+
end
|
216
|
+
|
217
|
+
def create_border
|
218
|
+
background_image = StringIO.new(Rails.root.join("public/#{image_pack_path("media/images/pattern.png")}").read)
|
219
|
+
|
220
|
+
box_x = (page_width - box_width) / 2
|
221
|
+
box_y = (page_height - box_height) / 2
|
222
|
+
|
223
|
+
frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, box_width, box_height)
|
224
|
+
|
225
|
+
box = document.layout.image_box(background_image, width: box_width, height: box_height)
|
226
|
+
result = frame.fit(box)
|
227
|
+
frame.draw(page.canvas, result)
|
228
|
+
|
229
|
+
frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, box_width, box_height)
|
230
|
+
|
231
|
+
box = document.layout.box do |canvas, _box|
|
232
|
+
canvas.fill_color("FFFFFF")
|
233
|
+
canvas.rectangle(10, 10, box_width - 20, box_height - 20)
|
234
|
+
canvas.fill
|
235
|
+
end
|
236
|
+
|
237
|
+
result = frame.fit(box)
|
238
|
+
frame.draw(page.canvas, result)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require "rails"
|
4
4
|
require "active_support/all"
|
5
5
|
require "decidim/core"
|
6
|
-
require "wicked_pdf"
|
7
6
|
|
8
7
|
require "decidim/conferences/query_extensions"
|
9
8
|
require "decidim/conferences/content_blocks/registry_manager"
|
@@ -51,6 +50,12 @@ module Decidim
|
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
53
|
+
initializer "decidim_conferences.mount_routes" do
|
54
|
+
Decidim::Core::Engine.routes do
|
55
|
+
mount Decidim::Conferences::Engine, at: "/", as: "decidim_conferences"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
54
59
|
initializer "decidim_conferences.register_icons" do
|
55
60
|
Decidim.icons.register(name: "Decidim::Conference", icon: "mic-line", description: "Conference", category: "activity", engine: :conferences)
|
56
61
|
Decidim.icons.register(name: "conference_speaker", icon: "user-voice-line", description: "Speaker", category: "conferences", engine: :conferences)
|
@@ -48,6 +48,7 @@ module Decidim
|
|
48
48
|
active: is_active_link?(manage_component_path(component)) ||
|
49
49
|
is_active_link?(decidim_admin_conferences.edit_component_path(current_participatory_space, component)) ||
|
50
50
|
is_active_link?(decidim_admin_conferences.edit_component_permissions_path(current_participatory_space, component)) ||
|
51
|
+
is_active_link?(decidim_admin_conferences.component_share_tokens_path(current_participatory_space, component)) ||
|
51
52
|
participatory_space_active_link?(component),
|
52
53
|
if: component.manifest.admin_engine && user_role_config.component_is_accessible?(component.manifest_name)
|
53
54
|
end
|
@@ -100,8 +101,8 @@ module Decidim
|
|
100
101
|
end
|
101
102
|
end
|
102
103
|
|
103
|
-
def self.
|
104
|
-
Decidim.menu :
|
104
|
+
def self.register_conference_admin_menu!
|
105
|
+
Decidim.menu :conference_admin_menu do |menu|
|
105
106
|
menu.add_item :edit_conference,
|
106
107
|
I18n.t("info", scope: "decidim.admin.menu.conferences_submenu"),
|
107
108
|
decidim_admin_conferences.edit_conference_path(current_participatory_space),
|
@@ -118,12 +119,6 @@ module Decidim
|
|
118
119
|
["decidim/conferences/admin/components", %w(index new edit)]),
|
119
120
|
submenu: { target_menu: :admin_conferences_components_menu }
|
120
121
|
|
121
|
-
menu.add_item :categories,
|
122
|
-
I18n.t("categories", scope: "decidim.admin.menu.conferences_submenu"),
|
123
|
-
decidim_admin_conferences.categories_path(current_participatory_space),
|
124
|
-
icon_name: "price-tag-3-line",
|
125
|
-
if: allowed_to?(:read, :category, conference: current_participatory_space)
|
126
|
-
|
127
122
|
menu.add_item :attachments,
|
128
123
|
I18n.t("attachments", scope: "decidim.admin.menu.conferences_submenu"),
|
129
124
|
decidim_admin_conferences.conference_attachments_path(current_participatory_space),
|
@@ -172,6 +167,25 @@ module Decidim
|
|
172
167
|
decidim_admin_conferences.moderations_path(current_participatory_space),
|
173
168
|
icon_name: "flag-line",
|
174
169
|
if: allowed_to?(:read, :moderation, conference: current_participatory_space)
|
170
|
+
|
171
|
+
menu.add_item :conference_share_tokens,
|
172
|
+
I18n.t("menu.share_tokens", scope: "decidim.admin"),
|
173
|
+
decidim_admin_conferences.conference_share_tokens_path(current_participatory_space),
|
174
|
+
active: is_active_link?(decidim_admin_conferences.conference_share_tokens_path(current_participatory_space)),
|
175
|
+
icon_name: "share-line",
|
176
|
+
if: allowed_to?(:read, :share_tokens, current_participatory_space:)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.register_conferences_admin_menu!
|
181
|
+
Decidim.menu :admin_conferences_menu do |menu|
|
182
|
+
menu.add_item :conferences,
|
183
|
+
I18n.t("menu.conferences", scope: "decidim.admin"),
|
184
|
+
decidim_admin_conferences.conferences_path,
|
185
|
+
position: 1,
|
186
|
+
active: is_active_link?(decidim_admin_conferences.conferences_path),
|
187
|
+
icon_name: "government-line",
|
188
|
+
if: allowed_to?(:read, :conference_list)
|
175
189
|
end
|
176
190
|
end
|
177
191
|
|
@@ -182,7 +196,7 @@ module Decidim
|
|
182
196
|
decidim_admin_conferences.conferences_path,
|
183
197
|
icon_name: "live-line",
|
184
198
|
position: 2.8,
|
185
|
-
active: :inclusive,
|
199
|
+
active: is_active_link?(decidim_admin_conferences.conferences_path, :inclusive),
|
186
200
|
if: allowed_to?(:enter, :space_area, space_name: :conferences)
|
187
201
|
end
|
188
202
|
end
|