decidim-conferences 0.29.1 → 0.30.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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/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 +7 -12
- data/app/forms/decidim/conferences/admin/conference_speaker_form.rb +1 -1
- data/app/forms/decidim/conferences/admin/registration_type_form.rb +1 -1
- data/app/helpers/decidim/conferences/conference_program_helper.rb +4 -2
- data/app/mailers/decidim/conferences/admin/send_conference_diploma_mailer.rb +1 -7
- 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 -4
- 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/media_links/new.html.erb +1 -1
- data/app/views/decidim/conferences/admin/send_conference_diploma_mailer/diploma_user.html.erb +13 -7
- 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/app/views/layouts/decidim/diploma.html.erb +1 -1
- data/config/locales/ar.yml +12 -24
- data/config/locales/bg.yml +0 -24
- data/config/locales/bn-BD.yml +1 -0
- data/config/locales/bs-BA.yml +14 -0
- data/config/locales/ca.yml +74 -14
- data/config/locales/cs.yml +76 -16
- data/config/locales/de.yml +75 -15
- data/config/locales/el.yml +0 -24
- data/config/locales/en.yml +82 -22
- data/config/locales/es-MX.yml +75 -15
- data/config/locales/es-PY.yml +78 -18
- data/config/locales/es.yml +71 -11
- data/config/locales/eu.yml +229 -169
- data/config/locales/fi-plain.yml +76 -16
- data/config/locales/fi.yml +82 -22
- data/config/locales/fr-CA.yml +35 -16
- data/config/locales/fr.yml +35 -16
- data/config/locales/ga-IE.yml +0 -2
- data/config/locales/gl.yml +0 -24
- data/config/locales/hu.yml +0 -24
- data/config/locales/id-ID.yml +0 -24
- data/config/locales/it.yml +0 -24
- data/config/locales/ja.yml +73 -13
- data/config/locales/lb.yml +0 -22
- data/config/locales/lt.yml +0 -24
- data/config/locales/lv.yml +0 -24
- data/config/locales/nl.yml +0 -24
- data/config/locales/no.yml +0 -24
- data/config/locales/pl.yml +0 -24
- data/config/locales/pt-BR.yml +0 -24
- data/config/locales/pt.yml +0 -24
- data/config/locales/ro-RO.yml +13 -15
- data/config/locales/sk.yml +0 -24
- data/config/locales/sv.yml +66 -25
- data/config/locales/tr-TR.yml +0 -24
- data/config/locales/zh-CN.yml +0 -24
- data/config/locales/zh-TW.yml +0 -24
- 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 +2 -7
- 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 +26 -43
- data/app/controllers/decidim/conferences/admin/categories_controller.rb +0 -13
- data/config/initializers/wicked_pdf.rb +0 -23
@@ -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
|
@@ -36,6 +36,19 @@ Decidim.register_participatory_space(:conferences) do |participatory_space|
|
|
36
36
|
context.layout = "layouts/decidim/admin/conference"
|
37
37
|
end
|
38
38
|
|
39
|
+
participatory_space.exports :conferences do |export|
|
40
|
+
export.collection do
|
41
|
+
Decidim::Conference
|
42
|
+
.public_spaces
|
43
|
+
.includes(:taxonomies, :attachment_collections)
|
44
|
+
end
|
45
|
+
|
46
|
+
export.include_in_open_data = true
|
47
|
+
|
48
|
+
export.serializer Decidim::Conferences::ConferenceSerializer
|
49
|
+
export.open_data_serializer Decidim::Conferences::OpenDataConferenceSerializer
|
50
|
+
end
|
51
|
+
|
39
52
|
participatory_space.register_on_destroy_account do |user|
|
40
53
|
Decidim::ConferenceUserRole.where(user:).destroy_all
|
41
54
|
Decidim::ConferenceSpeaker.where(user:).destroy_all
|