decidim-core 0.0.8.1 → 0.1.0
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/assets/config/decidim_core_manifest.js +0 -1
- data/app/assets/javascripts/decidim/form_filter.component.js.es6 +12 -2
- data/app/assets/stylesheets/decidim/_decidim.scss +1 -2
- data/app/assets/stylesheets/decidim/extras/_embed.scss +21 -0
- data/app/assets/stylesheets/decidim/modules/_cards.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_icons.scss +1 -1
- data/app/commands/decidim/create_registration.rb +1 -1
- data/app/commands/decidim/invite_user.rb +7 -8
- data/app/controllers/concerns/decidim/filter_resource.rb +2 -3
- data/app/controllers/concerns/decidim/payload_info.rb +1 -1
- data/app/controllers/decidim/authorizations_controller.rb +0 -4
- data/app/controllers/decidim/pages_controller.rb +8 -11
- data/app/controllers/decidim/participatory_process_groups_controller.rb +1 -1
- data/app/controllers/decidim/participatory_process_widgets_controller.rb +4 -0
- data/app/controllers/decidim/widgets_controller.rb +7 -3
- data/app/forms/decidim/registration_form.rb +4 -4
- data/app/helpers/decidim/layout_helper.rb +1 -1
- data/app/helpers/decidim/map_helper.rb +21 -21
- data/app/helpers/decidim/resource_helper.rb +4 -4
- data/app/helpers/decidim/widget_urls_helper.rb +2 -2
- data/app/mailers/decidim/export_mailer.rb +29 -0
- data/app/middleware/decidim/current_organization.rb +1 -1
- data/app/models/decidim/feature.rb +5 -0
- data/app/models/decidim/organization.rb +1 -1
- data/app/models/decidim/participatory_process.rb +1 -1
- data/app/models/decidim/user.rb +1 -1
- data/app/presenters/decidim/home_stats_presenter.rb +74 -0
- data/app/queries/decidim/stats_users_count.rb +24 -0
- data/app/services/decidim/public_processes.rb +4 -2
- data/app/services/decidim/resource_search.rb +1 -1
- data/app/services/decidim/static_map_generator.rb +1 -3
- data/app/uploaders/decidim/image_uploader.rb +1 -1
- data/app/views/decidim/export_mailer/export.html.erb +1 -0
- data/app/views/decidim/participatory_process_widgets/show.html.erb +16 -27
- data/app/views/decidim/participatory_processes/show.html.erb +7 -7
- data/app/views/decidim/widgets/show.js.erb +27 -17
- data/app/views/layouts/decidim/widget.html.erb +55 -3
- data/app/views/pages/home/_statistics.html.erb +2 -10
- data/config/i18n-tasks.yml +1 -0
- data/config/initializers/devise.rb +11 -4
- data/config/locales/ca.yml +14 -3
- data/config/locales/en.yml +14 -3
- data/config/locales/es.yml +13 -2
- data/config/locales/eu.yml +0 -2
- data/config/locales/fi.yml +0 -2
- data/config/locales/fr.yml +386 -1
- data/config/locales/nl.yml +1 -3
- data/db/seeds.rb +1 -1
- data/lib/decidim/core.rb +10 -2
- data/lib/decidim/core/api/decidim_type.rb +4 -0
- data/lib/decidim/core/api/translated_field_type.rb +2 -2
- data/lib/decidim/core/engine.rb +13 -0
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +16 -18
- data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +2 -2
- data/lib/decidim/core/test/shared_examples/reports_examples.rb +9 -9
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/exporters.rb +9 -0
- data/lib/decidim/exporters/csv.rb +54 -0
- data/lib/decidim/exporters/export_data.rb +22 -0
- data/lib/decidim/exporters/exporter.rb +28 -0
- data/lib/decidim/exporters/json.rb +22 -0
- data/lib/decidim/feature_manifest.rb +18 -0
- data/lib/decidim/file_zipper.rb +28 -0
- data/lib/decidim/form_builder.rb +27 -14
- data/lib/decidim/has_reference.rb +1 -1
- data/lib/decidim/i18n_exceptions.rb +3 -2
- data/lib/decidim/query_extensions.rb +1 -1
- data/lib/decidim/reportable.rb +1 -1
- data/lib/decidim/resource_manifest.rb +0 -7
- data/lib/decidim/stats_registry.rb +110 -0
- data/vendor/assets/javascripts/form_datepicker.js.es6 +3 -1
- metadata +53 -29
- data/app/assets/stylesheets/decidim/widget.scss.erb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abd55b4bc86a454e483127b15d235ed2a056e718
|
4
|
+
data.tar.gz: 4d29c9e66aea8a4c43110cda9b6487310d5c8429
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2e6c3415e64aa2e6430062cfca573d1aef0e28dc42d04ff7dec6332e7018b20672d9e76c1efd95974c5d6f1f362655515c3fa96d5d813364e178b0dc1f259cf
|
7
|
+
data.tar.gz: df609842f94d94b53b37c5611988c853f710453bc5e2a98b46bd370c39879a867f9764c5ee3adf1ecbff4614030a20d7e22ce614fa19eafdc3d64962cb8d6158
|
@@ -9,6 +9,7 @@
|
|
9
9
|
class FormFilterComponent {
|
10
10
|
constructor($form) {
|
11
11
|
this.$form = $form;
|
12
|
+
this.id = this.$form.attr('id') || this._getUID();
|
12
13
|
this.mounted = false;
|
13
14
|
|
14
15
|
this._onFormChange = this._onFormChange.bind(this);
|
@@ -24,7 +25,7 @@
|
|
24
25
|
if (this.mounted) {
|
25
26
|
this.mounted = false;
|
26
27
|
this.$form.off('change', 'input, select', this._onFormChange);
|
27
|
-
exports.Decidim.History.unregisterCallback(`filters-${this
|
28
|
+
exports.Decidim.History.unregisterCallback(`filters-${this.id}`)
|
28
29
|
}
|
29
30
|
}
|
30
31
|
|
@@ -37,7 +38,7 @@
|
|
37
38
|
if (this.$form.length > 0 && !this.mounted) {
|
38
39
|
this.mounted = true;
|
39
40
|
this.$form.on('change', 'input, select', this._onFormChange);
|
40
|
-
exports.Decidim.History.registerCallback(`filters-${this
|
41
|
+
exports.Decidim.History.registerCallback(`filters-${this.id}`, () => {
|
41
42
|
this._onPopState();
|
42
43
|
});
|
43
44
|
}
|
@@ -187,6 +188,15 @@
|
|
187
188
|
|
188
189
|
exports.Decidim.History.pushState(newUrl);
|
189
190
|
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Generates a unique identifier for the form.
|
194
|
+
* @private
|
195
|
+
* @returns {String} - Returns a unique identifier
|
196
|
+
*/
|
197
|
+
_getUID() {
|
198
|
+
return `filter-form-${new Date().setUTCMilliseconds()}-${Math.floor(Math.random() * 10000000)}`;
|
199
|
+
}
|
190
200
|
}
|
191
201
|
|
192
202
|
exports.Decidim = exports.Decidim || {};
|
@@ -9,3 +9,24 @@
|
|
9
9
|
overflow-y: auto;
|
10
10
|
}
|
11
11
|
}
|
12
|
+
|
13
|
+
$widget-padding: 8px;
|
14
|
+
|
15
|
+
body.widget {
|
16
|
+
background: #fff;
|
17
|
+
padding: $widget-padding;
|
18
|
+
margin: 0;
|
19
|
+
|
20
|
+
.participatory-process{
|
21
|
+
margin-bottom: $widget-padding;
|
22
|
+
}
|
23
|
+
|
24
|
+
.card {
|
25
|
+
margin: 0;
|
26
|
+
}
|
27
|
+
|
28
|
+
.organization {
|
29
|
+
margin-top: $widget-padding;
|
30
|
+
text-align: right;
|
31
|
+
}
|
32
|
+
}
|
@@ -36,14 +36,13 @@ module Decidim
|
|
36
36
|
|
37
37
|
def invite_user
|
38
38
|
@user = Decidim::User.create(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
})
|
39
|
+
name: form.name,
|
40
|
+
email: form.email.downcase,
|
41
|
+
organization: form.organization,
|
42
|
+
roles: form.roles,
|
43
|
+
comments_notifications: true,
|
44
|
+
replies_notifications: true
|
45
|
+
)
|
47
46
|
@user.invite!(
|
48
47
|
form.invited_by,
|
49
48
|
invitation_instructions: form.invitation_instructions
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# rubocop:disable Metrics/BlockLength
|
3
2
|
require "active_support/concern"
|
4
3
|
|
5
4
|
module Decidim
|
@@ -16,11 +15,11 @@ module Decidim
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def method_missing(method_name, *_arguments)
|
19
|
-
@filter.present? && @filter.
|
18
|
+
@filter.present? && @filter.has_key?(method_name) ? @filter[method_name] : super
|
20
19
|
end
|
21
20
|
|
22
21
|
def respond_to_missing?(method_name, include_private = false)
|
23
|
-
@filter.present? && @filter.
|
22
|
+
@filter.present? && @filter.has_key?(method_name) || super
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
payload[:referer] = request.referer.to_s
|
17
17
|
payload[:request_id] = request.uuid
|
18
18
|
payload[:user_agent] = request.user_agent
|
19
|
-
payload[:xhr] = request.xhr? ?
|
19
|
+
payload[:xhr] = request.xhr? ? "true" : "false"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -11,7 +11,7 @@ module Decidim
|
|
11
11
|
|
12
12
|
authorize_resource :public_pages, class: false
|
13
13
|
delegate :page, to: :page_finder
|
14
|
-
helper_method :page, :promoted_participatory_processes, :highlighted_participatory_processes, :
|
14
|
+
helper_method :page, :promoted_participatory_processes, :highlighted_participatory_processes, :stats
|
15
15
|
|
16
16
|
def index
|
17
17
|
@pages = current_organization.static_pages.all.to_a.sort do |a, b|
|
@@ -23,21 +23,18 @@ module Decidim
|
|
23
23
|
@page_finder ||= Decidim::PageFinder.new(params[:id], current_organization)
|
24
24
|
end
|
25
25
|
|
26
|
-
def users
|
27
|
-
@users ||= Decidim::User.where(organization: current_organization)
|
28
|
-
end
|
29
|
-
|
30
|
-
# This should be deleted once the statistics are done properly.
|
31
|
-
def participatory_processes
|
32
|
-
@processes ||= OrganizationParticipatoryProcesses.new(current_organization) | PublicParticipatoryProcesses.new
|
33
|
-
end
|
34
|
-
|
35
26
|
def promoted_participatory_processes
|
36
|
-
@promoted_processes ||=
|
27
|
+
@promoted_processes ||= OrganizationParticipatoryProcesses.new(current_organization) | PublicParticipatoryProcesses.new | PromotedParticipatoryProcesses.new
|
37
28
|
end
|
38
29
|
|
39
30
|
def highlighted_participatory_processes
|
40
31
|
@promoted_processes ||= OrganizationParticipatoryProcesses.new(current_organization) | HighlightedParticipatoryProcesses.new
|
41
32
|
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def stats
|
37
|
+
@stats ||= HomeStatsPresenter.new(organization: current_organization)
|
38
|
+
end
|
42
39
|
end
|
43
40
|
end
|
@@ -14,7 +14,7 @@ module Decidim
|
|
14
14
|
def participatory_processes
|
15
15
|
@participatory_processes ||= group.participatory_processes.published
|
16
16
|
end
|
17
|
-
|
17
|
+
alias collection participatory_processes
|
18
18
|
|
19
19
|
def group
|
20
20
|
Decidim::ParticipatoryProcessGroup.find(params[:id])
|
@@ -10,6 +10,10 @@ module Decidim
|
|
10
10
|
@model ||= ParticipatoryProcess.find(params[:participatory_process_id])
|
11
11
|
end
|
12
12
|
|
13
|
+
def current_participatory_process
|
14
|
+
model
|
15
|
+
end
|
16
|
+
|
13
17
|
def iframe_url
|
14
18
|
@iframe_url ||= participatory_process_participatory_process_widget_url(model)
|
15
19
|
end
|
@@ -3,12 +3,12 @@
|
|
3
3
|
module Decidim
|
4
4
|
class WidgetsController < Decidim::ApplicationController
|
5
5
|
skip_authorization_check only: :show
|
6
|
-
|
6
|
+
skip_before_action :verify_authenticity_token
|
7
7
|
after_action :allow_iframe, only: :show
|
8
8
|
|
9
|
-
layout
|
9
|
+
layout "decidim/widget"
|
10
10
|
|
11
|
-
helper_method :iframe_url
|
11
|
+
helper_method :model, :iframe_url, :current_participatory_process
|
12
12
|
|
13
13
|
def show
|
14
14
|
respond_to do |format|
|
@@ -19,6 +19,10 @@ module Decidim
|
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
+
def current_participatory_process
|
23
|
+
@current_participatory_process ||= model.feature.participatory_process
|
24
|
+
end
|
25
|
+
|
22
26
|
def iframe_url
|
23
27
|
raise NotImplementedError
|
24
28
|
end
|
@@ -23,13 +23,13 @@ module Decidim
|
|
23
23
|
validates :password, presence: true, confirmation: true, length: { in: Decidim::User.password_length }
|
24
24
|
validates :tos_agreement, allow_nil: false, acceptance: true
|
25
25
|
|
26
|
-
validates :user_group_name, presence: true, if: :
|
27
|
-
validates :user_group_document_number, presence: true, if: :
|
28
|
-
validates :user_group_phone, presence: true, if: :
|
26
|
+
validates :user_group_name, presence: true, if: :user_group?
|
27
|
+
validates :user_group_document_number, presence: true, if: :user_group?
|
28
|
+
validates :user_group_phone, presence: true, if: :user_group?
|
29
29
|
|
30
30
|
validate :email_unique_in_organization
|
31
31
|
|
32
|
-
def
|
32
|
+
def user_group?
|
33
33
|
sign_up_as == "user_group"
|
34
34
|
end
|
35
35
|
|
@@ -44,7 +44,7 @@ module Decidim
|
|
44
44
|
html_properties["class"] = (["icon--#{name}"] + _icon_classes(options)).join(" ")
|
45
45
|
|
46
46
|
content_tag :svg, html_properties do
|
47
|
-
content_tag :use, nil, "xlink:href" => "#{
|
47
|
+
content_tag :use, nil, "xlink:href" => "#{asset_path("decidim/icons.svg")}#icon-#{name}"
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -9,32 +9,32 @@ module Decidim
|
|
9
9
|
# options - An optional hash of options (default: { zoom: 17 })
|
10
10
|
# * zoom: A number to represent the zoom value of the map
|
11
11
|
def static_map_link(resource, options = {})
|
12
|
-
|
13
|
-
zoom = options[:zoom] || 17
|
14
|
-
latitude = resource.latitude
|
15
|
-
longitude = resource.longitude
|
12
|
+
return unless resource.geocoded?
|
16
13
|
|
17
|
-
|
14
|
+
zoom = options[:zoom] || 17
|
15
|
+
latitude = resource.latitude
|
16
|
+
longitude = resource.longitude
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
map_url = "https://www.openstreetmap.org/?mlat=#{latitude}&mlon=#{longitude}#map=#{zoom}/#{latitude}/#{longitude}"
|
19
|
+
|
20
|
+
link_to map_url, target: "_blank" do
|
21
|
+
image_tag decidim.static_map_path(sgid: resource.to_sgid.to_s)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def dynamic_map_for(markers_data
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
25
|
+
def dynamic_map_for(markers_data)
|
26
|
+
return unless Decidim.geocoder.present?
|
27
|
+
|
28
|
+
map_html_options = {
|
29
|
+
class: "google-map",
|
30
|
+
id: "map",
|
31
|
+
"data-markers-data" => markers_data.to_json,
|
32
|
+
"data-here-app-id" => Decidim.geocoder[:here_app_id],
|
33
|
+
"data-here-app-code" => Decidim.geocoder[:here_app_code]
|
34
|
+
}
|
35
|
+
content = capture { yield }
|
36
|
+
content_tag :div, class: "row column" do
|
37
|
+
content_tag(:div, "", map_html_options) + content
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -65,8 +65,8 @@ module Decidim
|
|
65
65
|
def linked_classes_for(klass)
|
66
66
|
return [] unless klass.respond_to?(:linked_classes_for)
|
67
67
|
|
68
|
-
klass.linked_classes_for(current_feature).map do |
|
69
|
-
[
|
68
|
+
klass.linked_classes_for(current_feature).map do |k|
|
69
|
+
[k.underscore, t(k.demodulize.downcase, scope: "decidim.filters.linked_classes")]
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -91,7 +91,7 @@ module Decidim
|
|
91
91
|
# Returns a String.
|
92
92
|
def _decidim_resource_route(resource, route_type, options)
|
93
93
|
manifest = resource.class.resource_manifest
|
94
|
-
engine =
|
94
|
+
engine = manifest.feature_manifest.engine
|
95
95
|
|
96
96
|
url_params = {
|
97
97
|
id: resource.id,
|
@@ -99,7 +99,7 @@ module Decidim
|
|
99
99
|
participatory_process_id: resource.feature.participatory_process.id
|
100
100
|
}
|
101
101
|
|
102
|
-
engine.send("#{manifest.route_name}_#{route_type}", url_params.merge(options))
|
102
|
+
engine.routes.url_helpers.send("#{manifest.route_name}_#{route_type}", url_params.merge(options))
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
module Decidim
|
3
3
|
module WidgetUrlsHelper
|
4
4
|
def embed_modal_for(url)
|
5
|
-
js_embed_code =
|
6
|
-
embed_code =
|
5
|
+
js_embed_code = String.new(content_tag(:script, "", src: url))
|
6
|
+
embed_code = String.new(content_tag(:noscript, content_tag(:iframe, "", src: url.gsub(".js", ".html"), frameborder: 0, scrolling: "vertical")))
|
7
7
|
render partial: "decidim/shared/embed_modal", locals: { js_embed_code: js_embed_code, embed_code: embed_code }
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Decidim
|
3
|
+
# This mailer sends a notification email containing the export as an
|
4
|
+
# attachment.
|
5
|
+
class ExportMailer < ApplicationMailer
|
6
|
+
# Public: Sends a notification email with the result of an export in a
|
7
|
+
# zipped file.
|
8
|
+
#
|
9
|
+
# user - The user to be notified.
|
10
|
+
# name - The name of the export.
|
11
|
+
# export_data - The data containing the result of the export.
|
12
|
+
#
|
13
|
+
# Returns nothing.
|
14
|
+
def export(user, name, export_data)
|
15
|
+
@user = user
|
16
|
+
@organization = user.organization
|
17
|
+
|
18
|
+
original_file_name = "#{name}.#{export_data.extension}"
|
19
|
+
|
20
|
+
attachments["#{name}.zip"] = FileZipper.new(
|
21
|
+
original_file_name, export_data.read
|
22
|
+
).zip
|
23
|
+
|
24
|
+
with_user(user) do
|
25
|
+
mail(to: "#{user.name} <#{user.email}>", subject: I18n.t("decidim.export_mailer.subject", name: original_file_name))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -24,7 +24,7 @@ module Decidim
|
|
24
24
|
|
25
25
|
location = new_location_for(env, organization.host)
|
26
26
|
|
27
|
-
[301, { "Location" => location,
|
27
|
+
[301, { "Location" => location, "Content-Type" => "text/html", "Content-Length" => "0" }, []]
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -81,6 +81,11 @@ module Decidim
|
|
81
81
|
step_settings.fetch(active_step.id.to_s)
|
82
82
|
end
|
83
83
|
|
84
|
+
# Public: Returns the value of the registered primary stat.
|
85
|
+
def primary_stat
|
86
|
+
@primary_stat ||= manifest.stats.filter(primary: true).with_context([self]).map { |name, value| [name, value] }.first&.last
|
87
|
+
end
|
88
|
+
|
84
89
|
private
|
85
90
|
|
86
91
|
def serialize_settings(schema, value)
|