decidim-initiatives 0.29.2 → 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/initiatives/content_blocks/highlighted_initiatives_settings_form/show.erb +1 -1
- data/app/commands/decidim/initiatives/create_initiative.rb +16 -4
- data/app/commands/decidim/initiatives/update_initiative.rb +23 -9
- data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +1 -1
- data/app/controllers/decidim/initiatives/admin/application_controller.rb +2 -0
- data/app/controllers/decidim/initiatives/admin/component_share_tokens_controller.rb +18 -0
- data/app/controllers/decidim/initiatives/admin/initiative_share_tokens_controller.rb +18 -0
- data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +8 -8
- data/app/controllers/decidim/initiatives/create_initiative_controller.rb +3 -2
- data/app/controllers/decidim/initiatives/initiative_types_controller.rb +1 -1
- data/app/controllers/decidim/initiatives/initiatives_controller.rb +3 -0
- data/app/forms/decidim/initiatives/admin/initiative_answer_form.rb +1 -1
- data/app/forms/decidim/initiatives/vote_form.rb +1 -1
- data/app/helpers/decidim/initiatives/initiative_helper.rb +1 -39
- data/app/helpers/decidim/initiatives/initiatives_helper.rb +8 -5
- data/app/helpers/decidim/initiatives/scopes_helper.rb +43 -0
- data/app/jobs/decidim/initiatives/export_initiatives_job.rb +5 -1
- data/app/models/decidim/initiative.rb +40 -27
- data/app/models/decidim/initiatives_type_scope.rb +9 -0
- data/app/permissions/decidim/initiatives/admin/permissions.rb +7 -0
- data/app/permissions/decidim/initiatives/permissions.rb +10 -3
- data/app/queries/decidim/initiatives/outdated_validating_initiatives.rb +1 -1
- data/app/queries/decidim/initiatives/support_period_finished_initiatives.rb +2 -2
- data/app/serializers/decidim/initiatives/download_your_data_initiative_serializer.rb +15 -0
- data/app/serializers/decidim/initiatives/initiative_serializer.rb +5 -24
- data/app/serializers/decidim/initiatives/open_data_initiative_serializer.rb +54 -0
- data/app/services/decidim/initiatives/data_encryptor.rb +1 -1
- data/app/services/decidim/initiatives/pdf_signature_example.rb +0 -2
- data/app/views/decidim/initiatives/admin/initiatives/edit.html.erb +1 -2
- data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +7 -0
- data/app/views/decidim/initiatives/committee_requests/new.html.erb +1 -2
- data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +3 -3
- data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +10 -2
- data/app/views/decidim/initiatives/initiatives/_form.html.erb +3 -3
- data/app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb +16 -13
- data/app/views/decidim/initiatives/initiatives/_vote_button.html.erb +9 -3
- data/app/views/decidim/initiatives/initiatives/_vote_cabin.html.erb +0 -1
- data/app/views/decidim/initiatives/initiatives/show.html.erb +7 -8
- data/app/views/layouts/decidim/admin/_manage_initiatives.html.erb +11 -0
- data/app/views/layouts/decidim/admin/initiatives.html.erb +1 -9
- data/config/assets.rb +1 -3
- data/config/locales/ar.yml +7 -8
- data/config/locales/bg.yml +2 -22
- data/config/locales/ca.yml +55 -21
- data/config/locales/cs.yml +55 -21
- data/config/locales/de.yml +55 -21
- data/config/locales/el.yml +2 -9
- data/config/locales/en.yml +53 -19
- data/config/locales/es-MX.yml +55 -21
- data/config/locales/es-PY.yml +55 -21
- data/config/locales/es.yml +55 -21
- data/config/locales/eu.yml +55 -21
- data/config/locales/fi-plain.yml +55 -21
- data/config/locales/fi.yml +55 -21
- data/config/locales/fr-CA.yml +9 -22
- data/config/locales/fr.yml +9 -22
- data/config/locales/ga-IE.yml +0 -3
- data/config/locales/gl.yml +2 -10
- data/config/locales/hu.yml +2 -20
- data/config/locales/id-ID.yml +2 -8
- data/config/locales/is-IS.yml +0 -9
- data/config/locales/it.yml +2 -11
- data/config/locales/ja.yml +55 -21
- data/config/locales/lb.yml +2 -7
- data/config/locales/lt.yml +2 -22
- data/config/locales/lv.yml +2 -9
- data/config/locales/nl.yml +2 -11
- data/config/locales/no.yml +2 -13
- data/config/locales/pl.yml +2 -21
- data/config/locales/pt-BR.yml +2 -27
- data/config/locales/pt.yml +2 -11
- data/config/locales/ro-RO.yml +2 -19
- data/config/locales/ru.yml +0 -9
- data/config/locales/sk.yml +2 -8
- data/config/locales/sl.yml +0 -1
- data/config/locales/sv.yml +12 -21
- data/config/locales/tr-TR.yml +2 -11
- data/config/locales/uk.yml +0 -9
- data/config/locales/zh-CN.yml +2 -10
- data/config/locales/zh-TW.yml +2 -21
- data/db/migrate/20241127104718_add_taxonomy_to_initiatives_type_scope.rb +7 -0
- data/decidim-initiatives.gemspec +1 -3
- data/lib/decidim/api/initiative_api_type.rb +9 -10
- data/lib/decidim/api/initiative_committee_member_type.rb +3 -4
- data/lib/decidim/api/initiative_type.rb +15 -21
- data/lib/decidim/api/initiative_type_interface.rb +1 -5
- data/lib/decidim/exporters/initiative_votes_pdf.rb +163 -0
- data/lib/decidim/initiatives/admin_engine.rb +68 -49
- data/lib/decidim/initiatives/application_form_pdf.rb +181 -0
- data/lib/decidim/initiatives/engine.rb +6 -0
- data/lib/decidim/initiatives/menu.rb +8 -0
- data/lib/decidim/initiatives/participatory_space.rb +8 -1
- data/lib/decidim/initiatives/test/factories.rb +5 -8
- data/lib/decidim/initiatives/version.rb +1 -1
- data/lib/decidim/initiatives.rb +7 -1
- metadata +25 -59
- data/app/cells/decidim/initiatives_votes/vote/show.erb +0 -39
- data/app/cells/decidim/initiatives_votes/vote_cell.rb +0 -58
- data/app/packs/entrypoints/decidim_initiatives_initiatives_votes.js +0 -1
- data/app/packs/entrypoints/decidim_initiatives_initiatives_votes.scss +0 -1
- data/app/packs/entrypoints/decidim_initiatives_print.js +0 -1
- data/app/packs/entrypoints/decidim_initiatives_print.scss +0 -1
- data/app/packs/stylesheets/decidim/initiatives/initiatives-votes.scss +0 -96
- data/app/packs/stylesheets/decidim/initiatives/print-initiative.scss +0 -172
- data/app/views/decidim/initiatives/admin/initiatives/_signatures.html.erb +0 -87
- data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.html.erb +0 -8
- data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb +0 -5
- data/app/views/decidim/initiatives/initiatives/_linked_initiatives.html.erb +0 -0
- data/app/views/decidim/initiatives/initiatives/print.html.erb +0 -161
- data/app/views/layouts/decidim/admin/initiatives_votes.pdf.erb +0 -11
- data/config/initializers/wicked_pdf.rb +0 -22
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Exporters
|
5
|
+
# Inherits from abstract PDF exporter. This class is used to set
|
6
|
+
# the parameters used to create a PDF when exporting Survey Answers.
|
7
|
+
#
|
8
|
+
class InitiativeVotesPDF < PDF
|
9
|
+
def initialize(collection, initiative, serializer = Serializer)
|
10
|
+
@initiative = initiative
|
11
|
+
super(collection, serializer)
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
attr_reader :initiative
|
17
|
+
|
18
|
+
def page_orientation
|
19
|
+
:landscape
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_data!
|
23
|
+
composer.formatted_text([translated_attribute(initiative.title)], style: :initiative_title)
|
24
|
+
|
25
|
+
add_initiative_data
|
26
|
+
add_signature_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def styles
|
30
|
+
{
|
31
|
+
initiative_title: { font: bold_font, text_align: :center, font_size: 12, margin: [0, 0, 10, 0] },
|
32
|
+
initiative_th: { font: bold_font, font_size: 10 },
|
33
|
+
initiative_td: { font:, font_size: 10 },
|
34
|
+
vote_th: { font: bold_font, font_size: 11 },
|
35
|
+
vote_td: { font:, font_size: 10 }
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_initiative_data
|
40
|
+
data_header = [
|
41
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_id", scope: "decidim.admin"), style: :initiative_th),
|
42
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_title", scope: "decidim.admin"), style: :initiative_th),
|
43
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_start_date", scope: "decidim.admin"), style: :initiative_th),
|
44
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_end_date", scope: "decidim.admin"), style: :initiative_th),
|
45
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_signatures_count", scope: "decidim.admin"), style: :initiative_th),
|
46
|
+
layout.text(I18n.t("models.initiatives_votes.fields.initiative_scope", scope: "decidim.admin"), style: :initiative_th)
|
47
|
+
]
|
48
|
+
|
49
|
+
data_row = [
|
50
|
+
layout.text(initiative.reference, style: :initiative_td),
|
51
|
+
layout.text(translated_attribute(initiative.title), style: :initiative_td),
|
52
|
+
layout.text(I18n.l(initiative.signature_start_date, format: :long), style: :initiative_td),
|
53
|
+
layout.text(I18n.l(initiative.signature_end_date, format: :long), style: :initiative_td),
|
54
|
+
layout.text(collection.count.to_s, style: :initiative_td),
|
55
|
+
layout.text(scope(initiative), style: :initiative_td)
|
56
|
+
]
|
57
|
+
|
58
|
+
column_widths = [-1, -1.75, -0.55, -0.55, -1, -1]
|
59
|
+
|
60
|
+
cells = [
|
61
|
+
[layout.table([data_header], column_widths:, cell_style: row_style)],
|
62
|
+
[layout.table([data_row], column_widths:, cell_style: row_style)]
|
63
|
+
]
|
64
|
+
composer.table(cells, cell_style:)
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_signature_data
|
68
|
+
cells = [[layout.table([header], column_widths: signature_column_widths, cell_style: row_style)]]
|
69
|
+
|
70
|
+
collection.map.with_index do |vote, index|
|
71
|
+
cells.push([layout.table(vote_row(vote, index), column_widths: signature_column_widths, cell_style: row_style)])
|
72
|
+
end
|
73
|
+
|
74
|
+
composer.table(cells, margin: [20, 0, 0, 0], cell_style:)
|
75
|
+
end
|
76
|
+
|
77
|
+
def signature_column_widths
|
78
|
+
if collect_user_extra_fields
|
79
|
+
[-0.5, -1, -0.75, -0.75, -0.75, -0.75, -0.75, -0.5, -0.75]
|
80
|
+
else
|
81
|
+
[-0.5, -1, -0.75, -0.75, -0.75]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def vote_row(model, index)
|
86
|
+
cell = [
|
87
|
+
layout.text((index + 1).to_s, style: :vote_td),
|
88
|
+
layout.text(model.author.nickname, style: :vote_td),
|
89
|
+
layout.text(I18n.l(model.created_at, format: "%Y-%m-%d %H:%M:%S %Z"), style: :vote_td),
|
90
|
+
layout.text(truncate(model.hash_id), style: :vote_td)
|
91
|
+
]
|
92
|
+
|
93
|
+
if collect_user_extra_fields
|
94
|
+
metadata ||= model.encrypted_metadata ? encryptor.decrypt(model.encrypted_metadata) : {}
|
95
|
+
|
96
|
+
cell += [
|
97
|
+
layout.text(metadata[:name_and_surname].presence || "", style: :vote_td),
|
98
|
+
layout.text(metadata[:document_number].presence || "", style: :vote_td),
|
99
|
+
layout.text(metadata[:date_of_birth].presence || "", style: :vote_td),
|
100
|
+
layout.text(metadata[:postal_code].presence || "", style: :vote_td)
|
101
|
+
]
|
102
|
+
end
|
103
|
+
|
104
|
+
cell += [
|
105
|
+
layout.text(truncate(model.timestamp.presence || ""), style: :vote_td)
|
106
|
+
]
|
107
|
+
[cell]
|
108
|
+
end
|
109
|
+
|
110
|
+
def scope(model)
|
111
|
+
return I18n.t("decidim.initiatives.unavailable_scope") if model.scope.blank?
|
112
|
+
|
113
|
+
translated_attribute(model.scope.name)
|
114
|
+
end
|
115
|
+
|
116
|
+
def header
|
117
|
+
header = [
|
118
|
+
layout.text(I18n.t("models.initiatives_votes.fields.signature_count", scope: "decidim.admin"), style: :vote_th),
|
119
|
+
layout.text(I18n.t("models.initiatives_votes.fields.nickname", scope: "decidim.admin"), style: :vote_th),
|
120
|
+
layout.text(I18n.t("models.initiatives_votes.fields.date_and_time", scope: "decidim.admin"), style: :vote_th),
|
121
|
+
layout.text(I18n.t("models.initiatives_votes.fields.hash", scope: "decidim.admin"), style: :vote_th)
|
122
|
+
]
|
123
|
+
|
124
|
+
if collect_user_extra_fields
|
125
|
+
header += [
|
126
|
+
layout.text(I18n.t("models.initiatives_votes.fields.name_and_surname", scope: "decidim.admin"), style: :vote_th),
|
127
|
+
layout.text(I18n.t("models.initiatives_votes.fields.document_number", scope: "decidim.admin"), style: :vote_th),
|
128
|
+
layout.text(I18n.t("models.initiatives_votes.fields.date_of_birth", scope: "decidim.admin"), style: :vote_th),
|
129
|
+
layout.text(I18n.t("models.initiatives_votes.fields.postal_code", scope: "decidim.admin"), style: :vote_th)
|
130
|
+
]
|
131
|
+
end
|
132
|
+
|
133
|
+
header += [
|
134
|
+
layout.text(I18n.t("models.initiatives_votes.fields.timestamp", scope: "decidim.admin"), style: :vote_th)
|
135
|
+
]
|
136
|
+
header
|
137
|
+
end
|
138
|
+
|
139
|
+
def collect_user_extra_fields = initiative.type.collect_user_extra_fields
|
140
|
+
|
141
|
+
def cell_style
|
142
|
+
lambda do |cell|
|
143
|
+
cell.style.margin = 0
|
144
|
+
cell.style.padding = 0
|
145
|
+
cell.style.border(width: 1)
|
146
|
+
cell.style.background_color = "cccccc" if cell.row.zero?
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def encryptor
|
151
|
+
@encryptor ||= Decidim::Initiatives::DataEncryptor.new(secret: "personal user metadata")
|
152
|
+
end
|
153
|
+
|
154
|
+
def truncate(text, length = 50)
|
155
|
+
text.truncate(length)
|
156
|
+
end
|
157
|
+
|
158
|
+
def row_style
|
159
|
+
{ margin: 0, padding: [10, 0, 10, 5], border: { width: 0 } }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -15,75 +15,94 @@ module Decidim
|
|
15
15
|
paths["lib/tasks"] = nil
|
16
16
|
|
17
17
|
routes do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
resources :initiatives_settings, only: [:edit, :update], controller: "initiatives_settings"
|
24
|
-
|
25
|
-
resources :initiatives, only: [:index, :edit, :update], param: :slug do
|
26
|
-
member do
|
27
|
-
get :send_to_technical_validation
|
28
|
-
post :publish
|
29
|
-
delete :unpublish
|
30
|
-
delete :discard
|
31
|
-
get :export_votes
|
32
|
-
get :export_pdf_signatures
|
33
|
-
post :accept
|
34
|
-
delete :reject
|
18
|
+
constraints(->(request) { Decidim::Admin::OrganizationDashboardConstraint.new(request).matches? }) do
|
19
|
+
resources :initiatives_types, except: :show do
|
20
|
+
resource :permissions, controller: "initiatives_types_permissions"
|
21
|
+
resources :initiatives_type_scopes, except: [:index, :show]
|
35
22
|
end
|
36
23
|
|
37
|
-
|
38
|
-
get :export
|
39
|
-
end
|
24
|
+
resources :initiatives_settings, only: [:edit, :update], controller: "initiatives_settings"
|
40
25
|
|
41
|
-
resources :
|
42
|
-
|
43
|
-
resources :committee_requests, only: [:index] do
|
26
|
+
resources :initiatives, only: [:index, :edit, :update], param: :slug do
|
44
27
|
member do
|
45
|
-
get :
|
46
|
-
|
28
|
+
get :send_to_technical_validation
|
29
|
+
post :publish
|
30
|
+
delete :unpublish
|
31
|
+
delete :discard
|
32
|
+
get :export_votes
|
33
|
+
get :export_pdf_signatures
|
34
|
+
post :accept
|
35
|
+
delete :reject
|
47
36
|
end
|
48
|
-
end
|
49
37
|
|
50
|
-
|
38
|
+
collection do
|
39
|
+
get :export
|
40
|
+
end
|
51
41
|
|
52
|
-
|
53
|
-
end
|
42
|
+
resources :attachments, controller: "initiative_attachments", except: [:show]
|
54
43
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
put :unpublish
|
61
|
-
get :share
|
44
|
+
resources :committee_requests, only: [:index] do
|
45
|
+
member do
|
46
|
+
get :approve
|
47
|
+
delete :revoke
|
48
|
+
end
|
62
49
|
end
|
63
|
-
|
50
|
+
|
51
|
+
resource :permissions, controller: "initiatives_permissions"
|
52
|
+
|
53
|
+
resource :answer, only: [:edit, :update]
|
64
54
|
end
|
65
55
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
56
|
+
scope "/initiatives/:initiative_slug" do
|
57
|
+
resources :components do
|
58
|
+
collection do
|
59
|
+
put :reorder
|
60
|
+
get :manage_trash, to: "components#manage_trash"
|
61
|
+
end
|
62
|
+
resource :permissions, controller: "component_permissions"
|
63
|
+
member do
|
64
|
+
put :publish
|
65
|
+
put :unpublish
|
66
|
+
get :share
|
67
|
+
put :hide
|
68
|
+
patch :soft_delete
|
69
|
+
patch :restore
|
70
|
+
end
|
71
|
+
resources :component_share_tokens, except: [:show], path: "share_tokens", as: "share_tokens"
|
72
|
+
resources :exports, only: :create
|
71
73
|
end
|
72
|
-
|
74
|
+
|
75
|
+
resources :moderations do
|
76
|
+
member do
|
77
|
+
put :unreport
|
78
|
+
put :hide
|
79
|
+
put :unhide
|
80
|
+
end
|
81
|
+
patch :bulk_action, on: :collection
|
82
|
+
resources :reports, controller: "moderations/reports", only: [:index, :show]
|
83
|
+
end
|
84
|
+
|
85
|
+
resources :initiative_share_tokens, except: [:show], path: "share_tokens"
|
73
86
|
end
|
74
|
-
end
|
75
87
|
|
76
|
-
|
77
|
-
|
78
|
-
|
88
|
+
scope "/initiatives/:initiative_slug/components/:component_id/manage" do
|
89
|
+
Decidim.component_manifests.each do |manifest|
|
90
|
+
next unless manifest.admin_engine
|
79
91
|
|
80
|
-
|
81
|
-
|
92
|
+
constraints CurrentComponent.new(manifest) do
|
93
|
+
mount manifest.admin_engine, at: "/", as: "decidim_admin_initiative_#{manifest.name}"
|
94
|
+
end
|
82
95
|
end
|
83
96
|
end
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
100
|
+
initializer "decidim_initiatives_admin.mount_routes" do |_app|
|
101
|
+
Decidim::Core::Engine.routes do
|
102
|
+
mount Decidim::Initiatives::AdminEngine, at: "/admin", as: "decidim_admin_initiatives"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
87
106
|
initializer "decidim_initiatives_admin.menu" do
|
88
107
|
Decidim::Initiatives::Menu.register_admin_menu_modules!
|
89
108
|
Decidim::Initiatives::Menu.register_admin_initiatives_components_menu!
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hexapdf"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Initiatives
|
7
|
+
class ApplicationFormPDF
|
8
|
+
include Decidim::OrganizationHelper
|
9
|
+
def initialize(initiative)
|
10
|
+
@initiative = initiative
|
11
|
+
end
|
12
|
+
|
13
|
+
def render
|
14
|
+
composer.styles(**styles)
|
15
|
+
|
16
|
+
add_logo
|
17
|
+
add_organization_data_box
|
18
|
+
add_author_box
|
19
|
+
add_promoter_box
|
20
|
+
|
21
|
+
composer.new_page
|
22
|
+
|
23
|
+
add_initiative_metadata_box
|
24
|
+
add_attachments_box
|
25
|
+
add_signature_box
|
26
|
+
add_legal_box
|
27
|
+
|
28
|
+
composer.write_to_string
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :initiative
|
34
|
+
|
35
|
+
delegate :document, to: :composer
|
36
|
+
delegate :layout, to: :document
|
37
|
+
|
38
|
+
def page = document.pages.first
|
39
|
+
|
40
|
+
def page_width = page.box(:media).width
|
41
|
+
|
42
|
+
def page_height = page.box(:media).height
|
43
|
+
|
44
|
+
def styles
|
45
|
+
{
|
46
|
+
h1: { font: bold_font, text_align: :center, font_size: 16, margin: [10, 0, 10, 0] },
|
47
|
+
title: { font: bold_font, text_align: :center, font_size: 12, margin: [10, 0, 10, 0] },
|
48
|
+
text: { font: bold_font, text_align: :left, font_size: 12, margin: [0, 0, 10, 0] },
|
49
|
+
td: { font:, text_align: :left, font_size: 12, margin: [0, 0, 10, 0] }
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_author_box
|
54
|
+
cells = [
|
55
|
+
[{ content: layout.text(I18n.t("author_title", scope: "decidim.initiatives.initiatives.print"), style: :title), col_span: 3 }],
|
56
|
+
[{ content: layout.text(I18n.t("id_number", scope: "decidim.initiatives.initiatives.print"), style: :td), col_span: 3, padding: [5, 5, 20, 5] }],
|
57
|
+
[{ content: layout.text(I18n.t("full_name", scope: "decidim.initiatives.initiatives.print"), style: :td), col_span: 3, padding: [5, 5, 20, 5] }],
|
58
|
+
[{ content: layout.text(I18n.t("address", scope: "decidim.initiatives.initiatives.print"), style: :td), col_span: 3, padding: [5, 5, 20, 5] }],
|
59
|
+
[
|
60
|
+
{ content: layout.text(I18n.t("city", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] },
|
61
|
+
{ content: layout.text(I18n.t("province", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] },
|
62
|
+
{ content: layout.text(I18n.t("postal_code", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] }
|
63
|
+
],
|
64
|
+
[
|
65
|
+
{ content: layout.text(I18n.t("phone_number", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] },
|
66
|
+
{ content: layout.text(I18n.t("email", scope: "decidim.initiatives.initiatives.print"), style: :td), col_span: 2, padding: [5, 5, 20, 5] }
|
67
|
+
]
|
68
|
+
]
|
69
|
+
composer.table(cells, cell_style: { border: { width: 1 } }, style: { margin: [10, 0] })
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_signature_box
|
73
|
+
cells = [
|
74
|
+
layout.text(I18n.t("place_date", scope: "decidim.initiatives.initiatives.print"), style: :title),
|
75
|
+
layout.text(I18n.t("signature", scope: "decidim.initiatives.initiatives.print"), style: :title)
|
76
|
+
]
|
77
|
+
composer.table([cells], cell_style: { border: { width: 0 } }, style: { margin: [10, 0] })
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_attachments_box
|
81
|
+
cells = [
|
82
|
+
[{ content: layout.text(I18n.t("initiative.attachments", scope: "decidim.initiatives.initiatives.print"), style: :title), col_span: 10 }]
|
83
|
+
]
|
84
|
+
|
85
|
+
6.times do
|
86
|
+
cols = [
|
87
|
+
{ content: layout.text(""), padding: 15 },
|
88
|
+
{ content: layout.text(""), padding: 15, col_span: 9 }
|
89
|
+
]
|
90
|
+
cells.push(cols)
|
91
|
+
end
|
92
|
+
|
93
|
+
composer.table(cells, cell_style: { border: { width: 1 } }, style: { margin: [10, 0] })
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_promoter_box
|
97
|
+
cells = [
|
98
|
+
[{ content: layout.text(I18n.t("members_header", scope: "decidim.initiatives.initiatives.print"), style: :title), col_span: 3 }],
|
99
|
+
[
|
100
|
+
{ content: layout.text(I18n.t("full_name", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] },
|
101
|
+
{ content: layout.text(I18n.t("id_number", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] },
|
102
|
+
{ content: layout.text(I18n.t("address", scope: "decidim.initiatives.initiatives.print"), style: :td), padding: [5, 5, 20, 5] }
|
103
|
+
]
|
104
|
+
]
|
105
|
+
|
106
|
+
4.times do
|
107
|
+
cols = []
|
108
|
+
3.times do
|
109
|
+
cols.push({ content: layout.text(""), padding: 15 })
|
110
|
+
end
|
111
|
+
cells.push(cols)
|
112
|
+
end
|
113
|
+
|
114
|
+
composer.table(cells, cell_style: { border: { width: 1 } }, style: { margin: [10, 0] })
|
115
|
+
end
|
116
|
+
|
117
|
+
def add_legal_box
|
118
|
+
composer.text(I18n.t("legal_text", scope: "decidim.initiatives.initiatives.print"), style: {
|
119
|
+
font:, font_size: 10, margin: [100, 0]
|
120
|
+
})
|
121
|
+
end
|
122
|
+
|
123
|
+
def add_initiative_metadata_box
|
124
|
+
composer.text(I18n.t("initiative.type", scope: "decidim.initiatives.initiatives.print"), style: :text)
|
125
|
+
composer.text(translated_attribute(initiative.type.title), style: :td)
|
126
|
+
composer.text(I18n.t("initiative.title", scope: "decidim.initiatives.initiatives.print"), style: :text)
|
127
|
+
composer.text(translated_attribute(initiative.title), style: :td)
|
128
|
+
composer.text(I18n.t("initiative.description", scope: "decidim.initiatives.initiatives.print"), style: :text)
|
129
|
+
composer.text(translated_attribute(initiative.description), style: :td)
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_organization_data_box
|
133
|
+
composer.text(organization_name(initiative.organization), style: :h1)
|
134
|
+
cells = [
|
135
|
+
layout.text(I18n.t("general_title", scope: "decidim.initiatives.initiatives.print"), style: :title)
|
136
|
+
]
|
137
|
+
composer.table([cells], cell_style: { border: { width: 1 } })
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_logo
|
141
|
+
return if initiative.organization.logo.blank?
|
142
|
+
|
143
|
+
attached_image = initiative.organization.attached_uploader(:logo).variant(:thumb)
|
144
|
+
logo = document.images.add(StringIO.new(attached_image.download))
|
145
|
+
height, width = compute_dimensions(attached_image, 160, 80)
|
146
|
+
|
147
|
+
cells = ["", layout.image(logo, width:, height:), ""]
|
148
|
+
composer.table([cells], cell_style: { border: { width: 0 } })
|
149
|
+
end
|
150
|
+
|
151
|
+
def compute_dimensions(attached_image, max_width, max_height)
|
152
|
+
metadata = attached_image.blob.metadata.with_indifferent_access
|
153
|
+
aspect_ratio = metadata[:width] / metadata[:height]
|
154
|
+
|
155
|
+
if metadata[:width] >= metadata[:height]
|
156
|
+
max_height = (max_height / aspect_ratio).round
|
157
|
+
else
|
158
|
+
max_width = (max_width / aspect_ratio).round
|
159
|
+
end
|
160
|
+
|
161
|
+
return max_height, max_width
|
162
|
+
end
|
163
|
+
|
164
|
+
def font
|
165
|
+
@font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-regular.ttf")
|
166
|
+
end
|
167
|
+
|
168
|
+
def bold_font
|
169
|
+
@bold_font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-700.ttf")
|
170
|
+
end
|
171
|
+
|
172
|
+
def load_font(path)
|
173
|
+
document.fonts.add(Decidim::Core::Engine.root.join("app/packs/fonts/decidim/").join(path))
|
174
|
+
end
|
175
|
+
|
176
|
+
def composer
|
177
|
+
@composer ||= ::HexaPDF::Composer.new
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -86,6 +86,12 @@ module Decidim
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
initializer "decidim_initiatives.mount_routes" do
|
90
|
+
Decidim::Core::Engine.routes do
|
91
|
+
mount Decidim::Initiatives::Engine, at: "/", as: "decidim_initiatives"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
89
95
|
initializer "decidim_initiatives.register_icons" do
|
90
96
|
Decidim.icons.register(name: "Decidim::Initiative", icon: "lightbulb-flash-line", description: "Initiative", category: "activity", engine: :initiatives)
|
91
97
|
Decidim.icons.register(name: "apps-line", icon: "apps-line", category: "system", description: "", engine: :initiatives)
|
@@ -66,6 +66,7 @@ module Decidim
|
|
66
66
|
active: is_active_link?(manage_component_path(component)) ||
|
67
67
|
is_active_link?(decidim_admin_initiatives.edit_component_path(current_participatory_space, component)) ||
|
68
68
|
is_active_link?(decidim_admin_initiatives.edit_component_permissions_path(current_participatory_space, component)) ||
|
69
|
+
is_active_link?(decidim_admin_initiatives.component_share_tokens_path(current_participatory_space, component)) ||
|
69
70
|
participatory_space_active_link?(component),
|
70
71
|
if: component.manifest.admin_engine # && user_role_config.component_is_accessible?(component.manifest_name)
|
71
72
|
end
|
@@ -106,6 +107,13 @@ module Decidim
|
|
106
107
|
decidim_admin_initiatives.moderations_path(current_participatory_space),
|
107
108
|
icon_name: "flag-line",
|
108
109
|
if: allowed_to?(:read, :moderation)
|
110
|
+
|
111
|
+
menu.add_item :initiatives_share_tokens,
|
112
|
+
I18n.t("menu.share_tokens", scope: "decidim.admin"),
|
113
|
+
decidim_admin_initiatives.initiative_share_tokens_path(current_participatory_space),
|
114
|
+
active: is_active_link?(decidim_admin_initiatives.initiative_share_tokens_path(current_participatory_space)),
|
115
|
+
icon_name: "share-line",
|
116
|
+
if: allowed_to?(:read, :share_tokens, current_participatory_space:)
|
109
117
|
end
|
110
118
|
end
|
111
119
|
|
@@ -38,12 +38,19 @@ Decidim.register_participatory_space(:initiatives) do |participatory_space|
|
|
38
38
|
participatory_space.model_class_name = "Decidim::Initiative"
|
39
39
|
participatory_space.permissions_class_name = "Decidim::Initiatives::Permissions"
|
40
40
|
|
41
|
+
participatory_space.data_portable_entities = [
|
42
|
+
"Decidim::Initiative"
|
43
|
+
]
|
44
|
+
|
41
45
|
participatory_space.exports :initiatives do |export|
|
42
46
|
export.collection do
|
43
|
-
Decidim::Initiative
|
47
|
+
Decidim::Initiative.public_spaces
|
44
48
|
end
|
45
49
|
|
50
|
+
export.include_in_open_data = true
|
51
|
+
|
46
52
|
export.serializer Decidim::Initiatives::InitiativeSerializer
|
53
|
+
export.open_data_serializer Decidim::Initiatives::OpenDataInitiativeSerializer
|
47
54
|
end
|
48
55
|
|
49
56
|
participatory_space.seeds do
|
@@ -108,6 +108,7 @@ FactoryBot.define do
|
|
108
108
|
end
|
109
109
|
type { create(:initiatives_type, skip_injection:) }
|
110
110
|
scope { create(:scope, organization: type.organization, skip_injection:) }
|
111
|
+
taxonomy { create(:taxonomy, organization: type.organization, skip_injection:) }
|
111
112
|
supports_required { 1000 }
|
112
113
|
|
113
114
|
trait :with_user_extra_fields_collection do
|
@@ -124,8 +125,8 @@ FactoryBot.define do
|
|
124
125
|
description { generate_localized_description(:initiative_description, skip_injection:) }
|
125
126
|
organization
|
126
127
|
author { create(:user, :confirmed, organization:, skip_injection:) }
|
127
|
-
|
128
|
-
|
128
|
+
state { "open" }
|
129
|
+
published_at { Time.current.utc }
|
129
130
|
signature_type { "online" }
|
130
131
|
signature_start_date { Date.current - 1.day }
|
131
132
|
signature_end_date { Date.current + 120.days }
|
@@ -156,12 +157,8 @@ FactoryBot.define do
|
|
156
157
|
signature_end_date { nil }
|
157
158
|
end
|
158
159
|
|
159
|
-
trait :
|
160
|
-
state { "
|
161
|
-
end
|
162
|
-
|
163
|
-
trait :unpublished do
|
164
|
-
published_at { nil }
|
160
|
+
trait :open do
|
161
|
+
state { "open" }
|
165
162
|
end
|
166
163
|
|
167
164
|
trait :accepted do
|
data/lib/decidim/initiatives.rb
CHANGED
@@ -7,8 +7,14 @@ require "decidim/initiatives/admin_engine"
|
|
7
7
|
require "decidim/initiatives/participatory_space"
|
8
8
|
|
9
9
|
module Decidim
|
10
|
+
module Exporters
|
11
|
+
autoload :InitiativeVotesPDF, "decidim/exporters/initiative_votes_pdf"
|
12
|
+
end
|
13
|
+
|
10
14
|
# Base module for the initiatives engine.
|
11
15
|
module Initiatives
|
16
|
+
autoload :ApplicationFormPDF, "decidim/initiatives/application_form_pdf"
|
17
|
+
|
12
18
|
include ActiveSupport::Configurable
|
13
19
|
|
14
20
|
# Public setting that defines whether creation is allowed to any validated
|
@@ -32,7 +38,7 @@ module Decidim
|
|
32
38
|
|
33
39
|
# Components enabled for a new initiative
|
34
40
|
config_accessor :default_components do
|
35
|
-
[:pages, :meetings]
|
41
|
+
[:pages, :meetings, :blogs]
|
36
42
|
end
|
37
43
|
|
38
44
|
# Notifies when the given percentage of supports is reached for an
|