decidim-participatory_documents 0.2.0 → 0.2.1
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/.github/workflows/lint.yml +2 -2
- data/.github/workflows/test.yml +8 -5
- data/.ruby-version +1 -1
- data/.simplecov +15 -9
- data/Gemfile.lock +186 -184
- data/README.md +32 -28
- data/app/commands/decidim/participatory_documents/create_suggestion.rb +3 -1
- data/app/controllers/concerns/decidim/participatory_documents/needs_pdf_document.rb +8 -1
- data/app/controllers/decidim/participatory_documents/admin/documents_controller.rb +5 -3
- data/app/controllers/decidim/participatory_documents/admin/suggestions_controller.rb +21 -1
- data/app/controllers/decidim/participatory_documents/admin/valuation_assignments_controller.rb +5 -1
- data/app/controllers/decidim/participatory_documents/document_suggestions_controller.rb +14 -0
- data/app/controllers/decidim/participatory_documents/section_suggestions_controller.rb +4 -0
- data/app/forms/decidim/participatory_documents/admin/document_form.rb +2 -1
- data/app/jobs/decidim/participatory_documents/export_my_suggestions_job.rb +16 -0
- data/app/models/decidim/participatory_documents/suggestion.rb +12 -0
- data/app/packs/entrypoints/decidim_participatory_documents.scss +8 -0
- data/app/packs/entrypoints/decidim_participatory_documents_editor.js +1 -3
- data/app/packs/entrypoints/decidim_participatory_documents_viewer_off.js +6 -0
- data/app/packs/images/export_suggestions.svg +1 -0
- data/app/packs/src/decidim/participatory_documents/pdf/pdf_modal_manager.js +4 -1
- data/app/packs/src/decidim/participatory_documents/pdf/suggestion_form.js +1 -1
- data/app/packs/src/decidim/participatory_documents/pdf.js +46 -0
- data/app/packs/src/decidim/participatory_documents/pdf_off.js +39 -0
- data/app/packs/stylesheets/decidim/participatory_documents/pdf/admin_modals.scss +9 -5
- data/app/packs/stylesheets/decidim/participatory_documents/pdf/admin_tweaks.scss +0 -21
- data/app/packs/stylesheets/decidim/participatory_documents/{decidim_admin_classes.scss → pdf/decidim_admin_styles.scss} +0 -3
- data/app/packs/stylesheets/decidim/participatory_documents/pdf/modals.scss +49 -0
- data/app/packs/stylesheets/decidim/participatory_documents/pdf/tweaks.scss +76 -7
- data/app/permissions/decidim/participatory_documents/admin/permissions.rb +30 -15
- data/app/permissions/decidim/participatory_documents/permissions.rb +2 -0
- data/app/serializers/decidim/participatory_documents/my_suggestion_serializer.rb +22 -0
- data/app/serializers/decidim/participatory_documents/suggestion_serializer.rb +1 -1
- data/app/uploaders/decidim/participatory_documents/pdf_document_uploader.rb +4 -0
- data/app/views/decidim/participatory_documents/admin/documents/_editor_modal.html.erb +1 -1
- data/app/views/decidim/participatory_documents/admin/documents/pdf_viewer.html.erb +1 -1
- data/app/views/decidim/participatory_documents/admin/sections/_form.html.erb +0 -3
- data/app/views/decidim/participatory_documents/admin/suggestions/_suggestion.html.erb +1 -1
- data/app/views/decidim/participatory_documents/documents/_export_modal.html.erb +25 -0
- data/app/views/decidim/participatory_documents/documents/_pdfjs_base.html.erb +5 -2
- data/app/views/decidim/participatory_documents/documents/pdf_viewer.html.erb +40 -33
- data/config/assets.rb +1 -0
- data/config/locales/ca.yml +259 -0
- data/config/locales/de.yml +259 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/es.yml +259 -0
- data/lib/decidim/participatory_documents/component.rb +6 -4
- data/lib/decidim/participatory_documents/engine.rb +5 -1
- data/lib/decidim/participatory_documents/version.rb +2 -2
- data/lib/decidim/participatory_documents.rb +5 -3
- metadata +12 -3
data/README.md
CHANGED
@@ -8,12 +8,17 @@
|
|
8
8
|
|
9
9
|
This module allows to upload PDF (and possibilty other formats) and define areas on top of it that will become spaces for suggestions, improvements and other participative activities.
|
10
10
|
|
11
|
-
> NOTE: in development, not ready for production.
|
12
|
-
|
13
11
|
## Installation
|
14
12
|
|
15
13
|
Add this line to your application's Gemfile:
|
16
14
|
|
15
|
+
```ruby
|
16
|
+
gem 'decidim-participatory_documents
|
17
|
+
```
|
18
|
+
|
19
|
+
Or, if you want to stay up to date with the latest changes use this line instead:
|
20
|
+
|
21
|
+
|
17
22
|
```ruby
|
18
23
|
gem 'decidim-participatory_documents', git: "https://github.com/openpoke/decidim-module-participatory-documents"
|
19
24
|
```
|
@@ -23,45 +28,44 @@ And then execute:
|
|
23
28
|
```
|
24
29
|
bundle
|
25
30
|
bundle exec rails decidim_participatory_documents:install:migrations
|
31
|
+
bundle exec rails decidim_participatory_documents:install_pdf_js
|
32
|
+
bundle exec rails db:migrate
|
26
33
|
```
|
27
34
|
|
35
|
+
Depending on your Decidim version, you can choose the corresponding version to ensure compatibility:
|
36
|
+
|
37
|
+
| Version | Compatible Decidim versions |
|
38
|
+
|---|---|
|
39
|
+
| 0.2.x | 0.27.x |
|
40
|
+
|
41
|
+
|
28
42
|
## Usage
|
29
43
|
|
30
44
|
TODO...
|
31
45
|
|
32
46
|
|
33
|
-
|
34
|
-
the application. Defaults to the configured in the module:
|
35
|
-
```ruby
|
36
|
-
# lib/decidim/participatory_documents.rb
|
37
|
-
|
38
|
-
module Decidim
|
39
|
-
# This namespace holds the logic of the `decidim-participatory_documents` module.
|
40
|
-
module ParticipatoryDocuments
|
41
|
-
include ActiveSupport::Configurable
|
42
|
-
|
43
|
-
# Public: The minimum length of a suggestion to be considered valid.
|
44
|
-
config_accessor :min_suggestion_length do
|
45
|
-
5
|
46
|
-
end
|
47
|
-
|
48
|
-
# Public: The maximum length of a suggestion to be considered valid.
|
49
|
-
config_accessor :max_suggestion_length do
|
50
|
-
500
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
```
|
47
|
+
## Configuration
|
55
48
|
|
56
|
-
|
57
|
-
|
49
|
+
By default, the module is configured to read the configuration from ENV variables.
|
50
|
+
|
51
|
+
Currently, the following ENV variables are supported:
|
58
52
|
|
53
|
+
| ENV variable | Description | Default value |
|
54
|
+
| ------------ | ----------- |-------|
|
55
|
+
| MAX_EXPORT_TEXT_LENGTH | If a positive number, it will truncate the exported suggestions before sending them by email | `0` |
|
56
|
+
| MIN_SUGGESTION_LENGTH | Minimum characters in a suggestion to be valid (this setting can be configured in each component as well by the admins) | `5` |
|
57
|
+
| MAX_SUGGESTION_LENGTH | Maximum characters in a suggestion to be valid (this setting can be configured in each component as well by the admins) | `1000` |
|
58
|
+
|
59
|
+
It is also possible to configure the module using the `decidim-participatory_documents` initializer:
|
60
|
+
|
61
|
+
```ruby
|
59
62
|
Decidim::ParticipatoryDocuments.configure do |config|
|
63
|
+
config.max_export_text_length = 0
|
64
|
+
config.min_suggestion_length = 5
|
65
|
+
config.max_suggestion_length = 1000
|
60
66
|
end
|
61
67
|
```
|
62
68
|
|
63
|
-
And, of course, having these values in your `config/secrets.yml` file.
|
64
|
-
|
65
69
|
## Contributing
|
66
70
|
|
67
71
|
Bug reports and pull requests are welcome on GitHub at https://github.com/openpoke/decidim-module-participatory-documents.
|
@@ -29,10 +29,12 @@ module Decidim
|
|
29
29
|
attr_reader :form, :suggestion, :suggestable
|
30
30
|
|
31
31
|
def create_suggestion
|
32
|
+
sanitized_body = Decidim::ContentProcessor.sanitize(form.body)
|
33
|
+
|
32
34
|
@suggestion = Decidim.traceability.create!(
|
33
35
|
Decidim::ParticipatoryDocuments::Suggestion,
|
34
36
|
form.current_user,
|
35
|
-
{ body: { I18n.locale =>
|
37
|
+
{ body: { I18n.locale => sanitized_body },
|
36
38
|
suggestable: suggestable,
|
37
39
|
author: form.current_user },
|
38
40
|
visibility: "public-only"
|
@@ -7,7 +7,7 @@ module Decidim
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
included do
|
10
|
-
helper_method :document, :box_color_as_rgba, :pdf_custom_style
|
10
|
+
helper_method :document, :box_color_as_rgba, :pdf_custom_style, :all_suggestions
|
11
11
|
|
12
12
|
protected
|
13
13
|
|
@@ -22,6 +22,13 @@ module Decidim
|
|
22
22
|
@document ||= Decidim::ParticipatoryDocuments::Document.find_by(component: current_component)
|
23
23
|
end
|
24
24
|
|
25
|
+
def all_suggestions
|
26
|
+
@all_suggestions ||= begin
|
27
|
+
manifest = document.component.manifest.export_manifests.find { |man| man.name == :suggestions }
|
28
|
+
manifest.collection.call(document.component, current_user, :my_suggestions)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
25
32
|
def box_color_as_rgba(document, opacity: nil)
|
26
33
|
opacity ||= document.box_opacity
|
27
34
|
return "rgba(30, 152, 215, 0.12);" unless document.box_color.present? && opacity.present?
|
@@ -6,6 +6,7 @@ module Decidim
|
|
6
6
|
# This controller allows admins to manage documents in a participatory process.
|
7
7
|
class DocumentsController < Admin::ApplicationController
|
8
8
|
include Decidim::ApplicationHelper
|
9
|
+
include Decidim::ComponentPathHelper
|
9
10
|
include NeedsAdminSnippets
|
10
11
|
|
11
12
|
helper Decidim::LayoutHelper
|
@@ -13,7 +14,6 @@ module Decidim
|
|
13
14
|
|
14
15
|
before_action except: [:index, :new, :create] do
|
15
16
|
redirect_to(documents_path) if document.blank?
|
16
|
-
redirect_to(edit_document_path(document)) unless document.file.attached?
|
17
17
|
end
|
18
18
|
|
19
19
|
def index
|
@@ -32,7 +32,9 @@ module Decidim
|
|
32
32
|
CreateDocument.call(@form) do
|
33
33
|
on(:ok) do |document|
|
34
34
|
flash[:notice] = I18n.t("documents.create.success", scope: "decidim.participatory_documents.admin")
|
35
|
-
|
35
|
+
|
36
|
+
redirect_to(edit_pdf_documents_path(id: document.id)) && return if document.file.attached?
|
37
|
+
redirect_to(manage_component_path(document.component)) && return unless document.file.attached?
|
36
38
|
end
|
37
39
|
|
38
40
|
on(:invalid) do
|
@@ -69,7 +71,7 @@ module Decidim
|
|
69
71
|
end
|
70
72
|
|
71
73
|
def pdf_viewer
|
72
|
-
@form = form(SectionForm).
|
74
|
+
@form = form(SectionForm).instance
|
73
75
|
render layout: false
|
74
76
|
end
|
75
77
|
|
@@ -14,6 +14,8 @@ module Decidim
|
|
14
14
|
helper_method :suggestions, :suggestion, :notes_form, :find_valuators_for_select, :suggestion_ids, :suggestion_find
|
15
15
|
|
16
16
|
def show
|
17
|
+
enforce_permission_to :show, :suggestion, suggestion: suggestion
|
18
|
+
|
17
19
|
@form = form(Decidim::ParticipatoryDocuments::Admin::AnswerSuggestionForm).from_model(suggestion)
|
18
20
|
end
|
19
21
|
|
@@ -133,11 +135,29 @@ module Decidim
|
|
133
135
|
end
|
134
136
|
|
135
137
|
def base_query
|
138
|
+
valuator_roles_exist? ? suggestions_for_valuator : all_document_suggestions
|
139
|
+
end
|
140
|
+
|
141
|
+
def all_document_suggestions
|
136
142
|
Suggestion.where(suggestable: document).or(Suggestion.where(suggestable: document.sections))
|
137
143
|
end
|
138
144
|
|
145
|
+
def suggestions_for_valuator
|
146
|
+
valuator_suggestions_ids = Decidim::ParticipatoryDocuments::ValuationAssignment
|
147
|
+
.where(valuator_role: valuator_roles).pluck(:decidim_participatory_documents_suggestion_id)
|
148
|
+
Suggestion.where(id: valuator_suggestions_ids)
|
149
|
+
end
|
150
|
+
|
151
|
+
def valuator_roles
|
152
|
+
current_participatory_space.user_roles(:valuator).where(user: current_user)
|
153
|
+
end
|
154
|
+
|
155
|
+
def valuator_roles_exist?
|
156
|
+
valuator_roles.exists?
|
157
|
+
end
|
158
|
+
|
139
159
|
def suggestion
|
140
|
-
base_query.
|
160
|
+
base_query.find_by(id: params[:id])
|
141
161
|
end
|
142
162
|
|
143
163
|
# Internal: A method to cache to queries to find the valuators for the
|
data/app/controllers/decidim/participatory_documents/admin/valuation_assignments_controller.rb
CHANGED
@@ -30,7 +30,11 @@ module Decidim
|
|
30
30
|
Admin::UnassignSuggestionsFromValuator.call(@form) do
|
31
31
|
on(:ok) do |_proposal|
|
32
32
|
flash.keep[:notice] = I18n.t("valuation_assignments.delete.success", scope: "decidim.participatory_documents.admin")
|
33
|
-
|
33
|
+
if current_user == @form.valuator_user
|
34
|
+
redirect_to EngineRouter.admin_proxy(current_component).root_path
|
35
|
+
else
|
36
|
+
redirect_back fallback_location: EngineRouter.admin_proxy(current_component).root_path
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
36
40
|
on(:invalid) do
|
@@ -10,10 +10,14 @@ module Decidim
|
|
10
10
|
layout false
|
11
11
|
|
12
12
|
def index
|
13
|
+
enforce_permission_to :create, :suggestion
|
14
|
+
|
13
15
|
@form = form(Decidim::ParticipatoryDocuments::SuggestionForm).instance
|
14
16
|
end
|
15
17
|
|
16
18
|
def create
|
19
|
+
enforce_permission_to :create, :suggestion
|
20
|
+
|
17
21
|
@form = form(Decidim::ParticipatoryDocuments::SuggestionForm).from_params(params)
|
18
22
|
|
19
23
|
CreateSuggestion.call(@form, section) do
|
@@ -26,6 +30,16 @@ module Decidim
|
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
33
|
+
def export
|
34
|
+
enforce_permission_to :create, :suggestion
|
35
|
+
|
36
|
+
return render json: { message: t(".empty") }, status: :unprocessable_entity unless all_suggestions.any?
|
37
|
+
|
38
|
+
ExportMySuggestionsJob.perform_later(current_user, document, "Excel")
|
39
|
+
|
40
|
+
render json: { message: t(".success", count: all_suggestions&.count, email: current_user&.email) }
|
41
|
+
end
|
42
|
+
|
29
43
|
private
|
30
44
|
|
31
45
|
def suggestions
|
@@ -10,10 +10,14 @@ module Decidim
|
|
10
10
|
layout false
|
11
11
|
|
12
12
|
def index
|
13
|
+
enforce_permission_to :create, :suggestion
|
14
|
+
|
13
15
|
@form = form(Decidim::ParticipatoryDocuments::SuggestionForm).instance
|
14
16
|
end
|
15
17
|
|
16
18
|
def create
|
19
|
+
enforce_permission_to :create, :suggestion
|
20
|
+
|
17
21
|
@form = form(Decidim::ParticipatoryDocuments::SuggestionForm).from_params(params)
|
18
22
|
|
19
23
|
CreateSuggestion.call(@form, section) do
|
@@ -15,9 +15,10 @@ module Decidim
|
|
15
15
|
attribute :box_color, String, default: "#1e98d7"
|
16
16
|
attribute :box_opacity, Integer, default: 12
|
17
17
|
|
18
|
-
attribute :file
|
18
|
+
attribute :file, Decidim::Attributes::Blob
|
19
19
|
attribute :remove_file, Boolean, default: false
|
20
20
|
|
21
|
+
validates :file, file_content_type: { allow: ["application/pdf"] }
|
21
22
|
# ensure color and opacity are present
|
22
23
|
def map_model(doc)
|
23
24
|
self.box_color = doc.box_color.presence || "#1e98d7"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ParticipatoryDocuments
|
5
|
+
class ExportMySuggestionsJob < Decidim::ExportJob
|
6
|
+
def perform(user, document, format)
|
7
|
+
export_manifest = document.component.manifest.export_manifests.find { |manifest| manifest.name == :suggestions }
|
8
|
+
collection = export_manifest.collection.call(document.component, user, :my_suggestions)
|
9
|
+
|
10
|
+
export_data = Decidim::Exporters.find_exporter(format).new(collection, MySuggestionSerializer).export
|
11
|
+
|
12
|
+
ExportMailer.export(user, :suggestions, export_data).deliver_now
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -29,6 +29,8 @@ module Decidim
|
|
29
29
|
scope :missing_answer, -> { where(answered_at: nil) }
|
30
30
|
scope :not_published, -> { where(answer_is_published: false) }
|
31
31
|
|
32
|
+
validate :validate_file_type, if: :attached?
|
33
|
+
|
32
34
|
POSSIBLE_STATES = %w(not_answered evaluating accepted rejected withdrawn).freeze
|
33
35
|
|
34
36
|
POSSIBLE_STATES.each do |possible|
|
@@ -162,6 +164,16 @@ module Decidim
|
|
162
164
|
def self.export_serializer
|
163
165
|
Decidim::ParticipatoryDocuments::SuggestionSerializer
|
164
166
|
end
|
167
|
+
|
168
|
+
def validate_file_type
|
169
|
+
allowed_extensions = organization.file_upload_settings["allowed_file_extensions"]["default"]
|
170
|
+
allowed_content_types = organization.file_upload_settings["allowed_content_types"]["default"]
|
171
|
+
|
172
|
+
file_extension = File.extname(file.blob.filename.to_s)[1..]
|
173
|
+
file_content_type = file.blob.content_type
|
174
|
+
|
175
|
+
errors.add(:file, :invalid) if allowed_extensions.exclude?(file_extension) || allowed_content_types.exclude?(file_content_type)
|
176
|
+
end
|
165
177
|
end
|
166
178
|
end
|
167
179
|
end
|
@@ -2,10 +2,18 @@
|
|
2
2
|
@import "stylesheets/decidim/variables";
|
3
3
|
@import "stylesheets/decidim/utils/mixins";
|
4
4
|
|
5
|
+
#loginModal-label {
|
6
|
+
outline: none;
|
7
|
+
}
|
8
|
+
|
5
9
|
.pdf-viewer-container {
|
6
10
|
height: calc(100vh - 30rem);
|
7
11
|
min-height: 50em;
|
8
12
|
padding: 0;
|
13
|
+
|
14
|
+
@media(max-width: 680px) {
|
15
|
+
margin-left: -1.6rem;
|
16
|
+
}
|
9
17
|
}
|
10
18
|
|
11
19
|
pdf-iframe {
|
@@ -1,10 +1,8 @@
|
|
1
1
|
import "../src/decidim/participatory_documents/pdf_admin.js"
|
2
|
-
|
3
|
-
import "entrypoints/decidim_participatory_documents_editor.scss";
|
4
|
-
|
5
2
|
import $ from "jquery"; // eslint-disable-line id-length
|
6
3
|
import "foundation-sites";
|
7
4
|
|
5
|
+
import "entrypoints/decidim_participatory_documents_editor.scss";
|
8
6
|
|
9
7
|
const csrfToken = document.getElementsByName("csrf-token");
|
10
8
|
$.ajaxSetup({
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 106.08"><defs><style>.cls-1{fill-rule:evenodd;}</style></defs><title>chat-download</title><path class="cls-1" d="M71.54,54.18A30.15,30.15,0,0,1,94.8,45.43V9a1.54,1.54,0,0,0-.47-1.1,1.59,1.59,0,0,0-1.1-.48H9A1.64,1.64,0,0,0,7.41,9V75.47a1.58,1.58,0,0,0,.47,1.11l.1.1A1.64,1.64,0,0,0,9,77H23.66a3.71,3.71,0,0,1,3.71,3.71v13L43.65,78.09a3.68,3.68,0,0,1,2.56-1H62.78a30,30,0,0,1,8.76-22.88Zm30.67-7.3A30.07,30.07,0,1,1,71.54,96.71a30.48,30.48,0,0,1-7.43-12.25H47.68L26.44,104.83a3.76,3.76,0,0,1-2.78,1.25,3.71,3.71,0,0,1-3.7-3.71V84.46H9a9,9,0,0,1-6.06-2.39l-.28-.26A9,9,0,0,1,0,75.47V9A9,9,0,0,1,9,0H93.23a9,9,0,0,1,9,9V46.88ZM25.42,33.31a3.71,3.71,0,0,1,0-7.41H76.79a3.71,3.71,0,1,1,0,7.41Zm0,21.93a3.71,3.71,0,0,1,0-7.41H59.81a3.71,3.71,0,1,1,0,7.41Zm80.2,18.59a2.56,2.56,0,0,1,2.17,1c1.14,1.72-.42,3.41-1.5,4.59-3.07,3.37-10,9.46-11.52,11.24a2.5,2.5,0,0,1-3.93,0C89.28,88.86,82,82.39,79.05,79.12c-1-1.14-2.27-2.69-1.21-4.27a2.57,2.57,0,0,1,2.17-1h5.46V64.05A3.08,3.08,0,0,1,88.55,61H97.1a3.08,3.08,0,0,1,3.08,3.07v9.78Z"/></svg>
|
@@ -8,6 +8,7 @@ export default class PdfModalManager {
|
|
8
8
|
this.csrfToken = options.csrfToken;
|
9
9
|
// UI
|
10
10
|
this.modalLayout = document.getElementById("decidim");
|
11
|
+
this.modalLayout.addEventListener("click", this._closeHandler.bind(this));
|
11
12
|
// events
|
12
13
|
this.onSave = () => {};
|
13
14
|
this.onDestroy = () => {};
|
@@ -29,6 +30,7 @@ export default class PdfModalManager {
|
|
29
30
|
}
|
30
31
|
|
31
32
|
displayModal(box) {
|
33
|
+
const modal = document.getElementById("editor-modal");
|
32
34
|
const uiSave = document.getElementById("editor-modal-save");
|
33
35
|
const uiClose = document.getElementById("editor-modal-close");
|
34
36
|
const uiTitle = document.getElementById("editor-modal-title");
|
@@ -38,6 +40,7 @@ export default class PdfModalManager {
|
|
38
40
|
this.modalLayout.classList.add("show");
|
39
41
|
$(this.modalLayout).foundation();
|
40
42
|
|
43
|
+
modal.addEventListener("click", (evt) => evt.stopPropagation(), { once: true });
|
41
44
|
uiClose.addEventListener("click", this._closeHandler.bind(this), { once: true });
|
42
45
|
uiRemove.addEventListener("click", (evt) => this._removeHandler(box, evt), { once: true });
|
43
46
|
uiSave.addEventListener("click", (evt) => this._saveHandler(box, evt), { once: true });
|
@@ -61,7 +64,7 @@ export default class PdfModalManager {
|
|
61
64
|
if (response.ok) {
|
62
65
|
return response.json();
|
63
66
|
}
|
64
|
-
throw new Error(
|
67
|
+
throw new Error(response.statusText);
|
65
68
|
}).
|
66
69
|
then((resp) => {
|
67
70
|
box.setInfo();
|
@@ -15,12 +15,58 @@ window.InitDocumentManagers = (options) => {
|
|
15
15
|
window.currentSuggestionForm.open();
|
16
16
|
}
|
17
17
|
});
|
18
|
+
|
19
|
+
const decidim = document.getElementById("decidim");
|
20
|
+
options.exportModal.addEventListener("click", (evt) => {
|
21
|
+
evt.stopPropagation();
|
22
|
+
});
|
23
|
+
options.exportButton.addEventListener("click", (evt) => {
|
24
|
+
evt.stopPropagation();
|
25
|
+
const uiClose = decidim.querySelector(".close-button");
|
26
|
+
uiClose.addEventListener("click", () => decidim.classList.remove("show"), { once: true });
|
27
|
+
decidim.addEventListener("click", () => decidim.classList.remove("show"), { once: true });
|
28
|
+
|
29
|
+
decidim.classList.add("show");
|
30
|
+
});
|
31
|
+
options.exportModal.querySelector(".export-button").addEventListener("click", (evt) => {
|
32
|
+
evt.stopPropagation();
|
33
|
+
fetch(evt.target.dataset.url, {
|
34
|
+
method: "POST",
|
35
|
+
headers: {
|
36
|
+
"Content-Type": "application/json",
|
37
|
+
"Accept": "application/json",
|
38
|
+
"X-CSRF-Token": document.getElementsByName("csrf-token").item(0).content
|
39
|
+
},
|
40
|
+
credentials: "include"
|
41
|
+
}).
|
42
|
+
then((response) => {
|
43
|
+
if (response.ok) {
|
44
|
+
return response.json();
|
45
|
+
}
|
46
|
+
return response.json().then((json) => {
|
47
|
+
throw new Error(json.message)
|
48
|
+
});
|
49
|
+
}).
|
50
|
+
then((resp) => {
|
51
|
+
// console.log("response ok", resp);
|
52
|
+
options.exportModal.querySelector(".content").innerHTML = `<div class="callout success">${resp.message}</div>`;
|
53
|
+
}).
|
54
|
+
catch((message) => {
|
55
|
+
options.exportModal.querySelector(".content").innerHTML = `<div class="callout alert">${message}</div>`;
|
56
|
+
// console.error("Error exporting", message);
|
57
|
+
});
|
58
|
+
});
|
18
59
|
};
|
19
60
|
|
20
61
|
// Call this on an annotation layer to initialize the polygon viewer (public side)
|
21
62
|
window.InitPolygonViewer = (layer, boxes, options) => {
|
22
63
|
let viewer = new PolygonViewer(layer, boxes, { i18n: options.i18n});
|
23
64
|
|
65
|
+
// prevent hiding the layout due onBoxBlur
|
66
|
+
options.participationLayout.addEventListener("click", (evt) => {
|
67
|
+
evt.stopPropagation();
|
68
|
+
});
|
69
|
+
|
24
70
|
viewer.onBoxClick = (box, evt) => {
|
25
71
|
console.log("click on box", box, evt);
|
26
72
|
window.currentSuggestionForm = new SuggestionForm(options.participationLayout, options.documentPath, box.section);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/* eslint-disable no-alert */
|
2
|
+
|
3
|
+
import PolygonViewer from "src/decidim/participatory_documents/pdf/polygon_viewer";
|
4
|
+
import "src/decidim/participatory_documents/pdf_notifications";
|
5
|
+
import "src/decidim/participatory_documents/global";
|
6
|
+
|
7
|
+
const openLogin = (evt) => {
|
8
|
+
evt.stopPropagation();
|
9
|
+
if (!window.parent) {
|
10
|
+
// This shouldn't appear because is in a iframe, but just in case (or for developing)
|
11
|
+
alert("Login required");
|
12
|
+
}
|
13
|
+
|
14
|
+
// add the rediret_to otherwise is going to be the iframe url and the user will lose the context
|
15
|
+
const loginForm = window.parent.document.getElementById("login_new_user");
|
16
|
+
let parts = loginForm.action.split("?")
|
17
|
+
let params = new URLSearchParams(parts[1]);
|
18
|
+
params.append("redirect_url", window.parent.location.href);
|
19
|
+
loginForm.action = `${parts[0]}?${params.toString()}`;
|
20
|
+
|
21
|
+
window.parent.$("#loginModal").foundation("open")
|
22
|
+
};
|
23
|
+
|
24
|
+
window.InitDocumentManagers = (options) => {
|
25
|
+
options.globalSuggestionsButton.addEventListener("click", openLogin);
|
26
|
+
|
27
|
+
options.exportButton.addEventListener("click", openLogin);
|
28
|
+
};
|
29
|
+
|
30
|
+
// Call this on an annotation layer to initialize the polygon viewer (public side)
|
31
|
+
window.InitPolygonViewer = (layer, boxes, options) => {
|
32
|
+
let viewer = new PolygonViewer(layer, boxes, { i18n: options.i18n});
|
33
|
+
|
34
|
+
viewer.onBoxClick = (box, evt) => {
|
35
|
+
openLogin(evt);
|
36
|
+
}
|
37
|
+
|
38
|
+
return viewer;
|
39
|
+
};
|
@@ -4,10 +4,8 @@
|
|
4
4
|
@import "stylesheets/decidim/utils/fontface";
|
5
5
|
@import "stylesheets/decidim/admin/utils/settings";
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
background-color: rgba(var(--primary-rgb), .6);
|
10
|
-
}
|
7
|
+
.reveal-overlay {
|
8
|
+
z-index: 100000;
|
11
9
|
}
|
12
10
|
|
13
11
|
#decidim {
|
@@ -25,7 +23,7 @@
|
|
25
23
|
line-height: $global-lineheight;
|
26
24
|
color: $body-font-color;
|
27
25
|
|
28
|
-
@include meta.load-css("stylesheets/decidim/participatory_documents/
|
26
|
+
@include meta.load-css("stylesheets/decidim/participatory_documents/pdf/decidim_admin_styles.scss");
|
29
27
|
|
30
28
|
&.show {
|
31
29
|
display: block;
|
@@ -39,3 +37,9 @@
|
|
39
37
|
}
|
40
38
|
}
|
41
39
|
}
|
40
|
+
|
41
|
+
@keyframes blinker {
|
42
|
+
50% {
|
43
|
+
background-color: rgba(var(--primary-rgb), .6);
|
44
|
+
}
|
45
|
+
}
|
@@ -20,25 +20,4 @@
|
|
20
20
|
vertical-align: middle;
|
21
21
|
}
|
22
22
|
}
|
23
|
-
|
24
|
-
@media(max-width: 900px) {
|
25
|
-
margin-top: 12px;
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
#fullscreenButton {
|
30
|
-
@media(max-width: 900px) {
|
31
|
-
width: 28px;
|
32
|
-
height: 28px;
|
33
|
-
margin-right: 0;
|
34
|
-
padding-right: 0;
|
35
|
-
overflow: hidden;
|
36
|
-
font-size: 0;
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
#scaleSelectContainer {
|
41
|
-
@media(max-width: 900px) {
|
42
|
-
display: none;
|
43
|
-
}
|
44
23
|
}
|
@@ -1,9 +1,6 @@
|
|
1
1
|
@import "stylesheets/decidim/admin/variables";
|
2
2
|
@import "stylesheets/decidim/utils/fontface";
|
3
3
|
@import "stylesheets/decidim/admin/utils/settings";
|
4
|
-
|
5
|
-
// @import "stylesheets/decidim/admin/utils/helpers";
|
6
|
-
// @import "stylesheets/decidim/admin/utils/keyframes";
|
7
4
|
@import "foundation-sites/scss/foundation";
|
8
5
|
@import "stylesheets/foundation-overrides/components/button-group";
|
9
6
|
|
@@ -5,12 +5,45 @@
|
|
5
5
|
@import "foundation-sites/scss/foundation";
|
6
6
|
@import "stylesheets/decidim/modules/icons";
|
7
7
|
@import "stylesheets/decidim/modules/margins";
|
8
|
+
@import "stylesheets/decidim/modules/callout";
|
8
9
|
@import "stylesheets/decidim/utils/helpers";
|
9
10
|
|
10
11
|
@include foundation-everything();
|
11
12
|
|
12
13
|
@import "stylesheets/decidim/modules/comments";
|
13
14
|
|
15
|
+
.reveal-overlay {
|
16
|
+
z-index: 100000;
|
17
|
+
}
|
18
|
+
|
19
|
+
#decidim {
|
20
|
+
position: fixed;
|
21
|
+
top: 0;
|
22
|
+
left: 0;
|
23
|
+
width: 100%;
|
24
|
+
height: 100%;
|
25
|
+
z-index: 100000;
|
26
|
+
display: none;
|
27
|
+
margin: 0;
|
28
|
+
padding: 0;
|
29
|
+
font-family: $body-font-family;
|
30
|
+
font-weight: $global-weight-normal;
|
31
|
+
line-height: $global-lineheight;
|
32
|
+
color: $body-font-color;
|
33
|
+
|
34
|
+
&.show {
|
35
|
+
display: block;
|
36
|
+
|
37
|
+
.reveal-overlay {
|
38
|
+
display: block;
|
39
|
+
|
40
|
+
.reveal {
|
41
|
+
display: block;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
14
47
|
#participation-modal {
|
15
48
|
width: 0;
|
16
49
|
height: 0;
|
@@ -56,6 +89,14 @@
|
|
56
89
|
|
57
90
|
&.active {
|
58
91
|
width: 50vw;
|
92
|
+
|
93
|
+
@media(max-width: 900px) {
|
94
|
+
width: 75vw;
|
95
|
+
}
|
96
|
+
|
97
|
+
@media(max-width: 680px) {
|
98
|
+
width: 100vw;
|
99
|
+
}
|
59
100
|
}
|
60
101
|
}
|
61
102
|
|
@@ -107,6 +148,14 @@
|
|
107
148
|
display: flex;
|
108
149
|
align-items: center;
|
109
150
|
justify-content: space-between;
|
151
|
+
|
152
|
+
strong {
|
153
|
+
margin-left: 1rem;
|
154
|
+
|
155
|
+
&:first-child {
|
156
|
+
margin-left: 0;
|
157
|
+
}
|
158
|
+
}
|
110
159
|
}
|
111
160
|
|
112
161
|
.author__info {
|