decidim-core 0.19.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +19 -0
- data/app/assets/javascripts/decidim.js.es6 +2 -1
- data/app/assets/javascripts/decidim/input_hashtags.js.es6 +1 -1
- data/app/assets/javascripts/decidim/input_mentions.js.es6 +112 -50
- data/app/assets/stylesheets/decidim/modules/_signup.scss +57 -0
- data/app/cells/decidim/coauthorships_cell.rb +2 -6
- data/app/cells/decidim/diff_cell.rb +3 -7
- data/app/controllers/decidim/application_controller.rb +0 -8
- data/app/controllers/decidim/devise/unlocks_controller.rb +25 -0
- data/app/controllers/decidim/searches_controller.rb +0 -1
- data/app/jobs/decidim/export_participatory_space_job.rb +20 -0
- data/app/models/decidim/category.rb +2 -0
- data/app/models/decidim/component.rb +2 -0
- data/app/models/decidim/user.rb +9 -2
- data/app/models/decidim/user_group.rb +7 -0
- data/app/presenters/decidim/attachment_presenter.rb +21 -0
- data/app/resolvers/decidim/core/user_resolver.rb +61 -0
- data/app/scrubbers/decidim/user_input_scrubber.rb +2 -2
- data/app/serializers/decidim/exporters/participatory_space_components_serializer.rb +46 -0
- data/{lib → app/serializers}/decidim/exporters/serializer.rb +0 -0
- data/app/serializers/decidim/importers/importer.rb +25 -0
- data/app/serializers/decidim/importers/participatory_space_components_importer.rb +67 -0
- data/app/services/decidim/open_data_exporter.rb +1 -1
- data/app/uploaders/decidim/banner_image_uploader.rb +0 -1
- data/app/views/decidim/devise/invitations/edit.html.erb +4 -2
- data/app/views/decidim/devise/registrations/new.html.erb +2 -2
- data/app/views/decidim/devise/unlocks/new.html.erb +33 -0
- data/app/views/decidim/searches/_filters.html.erb +3 -19
- data/app/views/decidim/searches/_resources_filter_block.html.erb +20 -0
- data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/layouts/decidim/_main_footer.html.erb +26 -0
- data/app/views/layouts/decidim/_mini_footer.html.erb +21 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +7 -50
- data/config/initializers/devise.rb +6 -6
- data/config/locales/en.yml +0 -10
- data/config/routes.rb +1 -0
- data/db/migrate/20191028135718_add_lockable_to_users.rb +10 -0
- data/db/migrate/20191118120529_add_weight_to_categories.rb +7 -0
- data/db/migrate/20191212102051_remove_continuity_badges.rb +13 -0
- data/db/seeds.rb +18 -0
- data/lib/decidim/acts_as_author.rb +21 -0
- data/lib/decidim/component_manifest.rb +45 -4
- data/lib/decidim/core.rb +1 -0
- data/lib/decidim/core/engine.rb +0 -4
- data/lib/decidim/core/test.rb +3 -0
- data/lib/decidim/core/test/factories.rb +5 -0
- data/lib/decidim/core/test/shared_examples/acts_as_author_examples.rb +12 -0
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +41 -2
- data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +145 -0
- data/lib/decidim/core/test/shared_examples/searchable_resources_shared_context.rb +12 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/exporters.rb +0 -1
- data/lib/decidim/exporters/export_manifest.rb +72 -0
- data/lib/decidim/faker/localized.rb +10 -0
- data/lib/decidim/form_builder.rb +2 -3
- data/lib/decidim/participatory_space_manifest.rb +33 -0
- data/lib/decidim/participatory_space_resourceable.rb +8 -0
- data/lib/decidim/query_extensions.rb +16 -0
- data/lib/decidim/resourceable.rb +1 -1
- data/lib/decidim/searchable.rb +19 -1
- data/vendor/assets/javascripts/tribute.js +1683 -1621
- metadata +29 -13
- data/app/assets/images/decidim/gamification/badges/continuity.svg +0 -73
- data/app/models/decidim/continuity_badge_status.rb +0 -9
- data/app/services/decidim/continuity_badge_tracker.rb +0 -64
- data/lib/decidim/components/export_manifest.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd45e8b19642518cb5cdc256a688f47b2befb549b73c3edf9445120aca24e3ff
|
4
|
+
data.tar.gz: 883849819fefaf6d0b74d0b33d22698c9c87ec596bfd64a1dcc5a7237b4df914
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d19e5e70f36cd10e18b26bfde95d1feab778c9b100c5ba79a3fdb35c3259e6868c51b51a91746c3cec8199d6fa66659729fb8887947430c5b0a9434692c4fa72
|
7
|
+
data.tar.gz: 5e2cf574f4b32a3e83fb0b92c616dba9b14bd96462f06dbcca3a3a0e5b57aa98c422b98e98d9c887af9692ad420ad2addee87a8d714c55808069312651b8c927
|
data/README.md
CHANGED
@@ -20,6 +20,10 @@ And then execute:
|
|
20
20
|
bundle
|
21
21
|
```
|
22
22
|
|
23
|
+
## Users
|
24
|
+
|
25
|
+
User authentication is set up with [`Devise`](https://github.com/plataformatec/devise) with its modules, see the [`Decidim::User`](https://github.com/decidim/decidim/blob/master/decidim-core/app/models/decidim/user.rb) model configuration and its setup [initializer](https://github.com/decidim/decidim/blob/master/decidim-core/config/initializers/devise.rb).
|
26
|
+
|
23
27
|
## Amendments
|
24
28
|
|
25
29
|
Core implements an Amendment feature that can be activated in the components. As of now, it's only implemented in the proposal component.
|
@@ -47,8 +51,23 @@ This module also includes the following models to Decidim's Global Search:
|
|
47
51
|
- `Searchable` module: A concern with the features needed when you want a model to be searchable.
|
48
52
|
- `SearchableResource` class: The ActiveRecord that finally includes PgSearch and maps the indexed documents into a model.
|
49
53
|
|
54
|
+
### Adding an artifact to Global Search
|
55
|
+
|
50
56
|
Models that want to be indexed must include `Searchable` and declare `Searchable.searchable_fields`.
|
51
57
|
|
58
|
+
They should be registered as resources. In their manifest, in the `register_resource` section, the artifact should be declared searchable.
|
59
|
+
This can be done in an initializer (like user does), in a participatory_space manifest, or in a component manifest. i.e.:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
initializer "decidim.core.register_resources" do
|
63
|
+
Decidim.register_resource(:user) do |resource|
|
64
|
+
resource.model_class_name = "Decidim::User"
|
65
|
+
resource.card = "decidim/user_profile"
|
66
|
+
resource.searchable = true
|
67
|
+
end
|
68
|
+
...
|
69
|
+
```
|
70
|
+
|
52
71
|
## Metrics docs
|
53
72
|
|
54
73
|
Core adds an implementation to show APP metrics within some pages. You can see specific documentation at [Metrics](https://github.com/decidim/decidim/tree/master/docs/advanced/metrics.md)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// = require decidim/core/bundle.js
|
2
|
-
// = require
|
2
|
+
// = require jquery3
|
3
3
|
// = require rails-ujs
|
4
4
|
// = require decidim/foundation
|
5
5
|
// = require modernizr
|
@@ -18,6 +18,7 @@
|
|
18
18
|
// = require decidim/editor
|
19
19
|
// = require decidim/input_tags
|
20
20
|
// = require decidim/input_hashtags
|
21
|
+
// = require decidim/input_mentions
|
21
22
|
// = require decidim/ajax_modals
|
22
23
|
// = require decidim/conferences
|
23
24
|
// = require decidim/tooltip_keep_on_hover
|
@@ -25,7 +25,7 @@ $(() => {
|
|
25
25
|
|
26
26
|
/* eslint no-use-before-define: ["error", { "variables": false }]*/
|
27
27
|
let remoteSearch = function(text, cb) {
|
28
|
-
$.post("/api", {query: `{hashtags(name
|
28
|
+
$.post("/api", {query: `{hashtags(name:"${text}") {name}}`}).
|
29
29
|
|
30
30
|
then((response) => {
|
31
31
|
let data = response.data.hashtags || {};
|
@@ -3,46 +3,73 @@
|
|
3
3
|
$(() => {
|
4
4
|
const $mentionContainer = $(".js-mentions");
|
5
5
|
const nodatafound = $mentionContainer.attr("data-noresults");
|
6
|
-
const sources = [];
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
// "tag": "barrera",
|
13
|
-
// "name": "Collins Franklin",
|
14
|
-
// },
|
15
|
-
// {
|
16
|
-
// "tag": "woods",
|
17
|
-
// "name": "Nadine Buck",
|
18
|
-
// }]
|
7
|
+
let noMatchTemplate = null
|
8
|
+
if (nodatafound) {
|
9
|
+
noMatchTemplate = () => `<li>${nodatafound}</li>`;
|
10
|
+
}
|
19
11
|
|
20
12
|
// Listener for the event triggered by quilljs
|
21
13
|
let cursor = "";
|
22
|
-
$mentionContainer.on("quill-position",
|
23
|
-
|
14
|
+
$mentionContainer.on("quill-position", (event) => {
|
15
|
+
if (event.detail !== null) {
|
16
|
+
// When replacing the text content after selecting a hashtag, we only need
|
17
|
+
// to know the hashtag's start position as that is the point which we want
|
18
|
+
// to replace.
|
19
|
+
let quill = event.target.__quill;
|
20
|
+
if (quill.getText(event.detail.index - 1, 1) === "@") {
|
21
|
+
cursor = event.detail.index;
|
22
|
+
}
|
23
|
+
}
|
24
24
|
});
|
25
25
|
|
26
|
+
/* eslint no-use-before-define: ["error", { "variables": false }]*/
|
27
|
+
let remoteSearch = function(text, cb) {
|
28
|
+
$.post("/api", {query: `{users(wildcard:"${text}") {nickname,name}}`}).
|
29
|
+
|
30
|
+
then((response) => {
|
31
|
+
let data = response.data.users || {};
|
32
|
+
cb(data)
|
33
|
+
}).fail(function() {
|
34
|
+
cb([])
|
35
|
+
}).always(() => {
|
36
|
+
// This function runs Tribute every single time you type something
|
37
|
+
// So we must evalute DOM properties after each
|
38
|
+
const $parent = $(tribute.current.element).parent();
|
39
|
+
$parent.addClass("is-active");
|
40
|
+
|
41
|
+
// We need to move the container to the wrapper selected
|
42
|
+
const $tribute = $parent.find(".tribute-container");
|
43
|
+
// Remove the inline styles, relative to absolute positioning
|
44
|
+
$tribute.removeAttr("style");
|
45
|
+
})
|
46
|
+
};
|
47
|
+
|
26
48
|
// tribute.js docs - http://github.com/zurb/tribute
|
27
49
|
/* global Tribute*/
|
28
50
|
let tribute = new Tribute({
|
29
|
-
|
30
|
-
|
51
|
+
trigger: "@",
|
52
|
+
values: function (text, cb) {
|
53
|
+
remoteSearch(text, (users) => cb(users));
|
54
|
+
},
|
55
|
+
positionMenu: true,
|
31
56
|
menuContainer: null,
|
32
|
-
|
33
|
-
|
34
|
-
|
57
|
+
menuItemLimit: 5,
|
58
|
+
fillAttr: "nickname",
|
59
|
+
noMatchTemplate: noMatchTemplate,
|
60
|
+
lookup: (item) => item.nickname + item.name,
|
35
61
|
selectTemplate: function(item) {
|
36
62
|
if (typeof item === "undefined") {
|
37
63
|
return null;
|
38
64
|
}
|
39
65
|
if (this.range.isContentEditable(this.current.element)) {
|
40
66
|
// Check quill.js
|
41
|
-
if ($(this.current.element).hasClass("editor
|
42
|
-
let
|
43
|
-
quill
|
67
|
+
if ($(this.current.element).hasClass("ql-editor")) {
|
68
|
+
let editorContainer = $(this.current.element).parent().get(0);
|
69
|
+
let quill = editorContainer.__quill;
|
70
|
+
quill.insertText(cursor - 1, `${item.original.nickname} `, Quill.sources.API);
|
44
71
|
// cursor position + nickname length + "@" sign + space
|
45
|
-
let position = cursor + item.original.
|
72
|
+
let position = cursor + item.original.nickname.length + 2
|
46
73
|
|
47
74
|
let next = 0;
|
48
75
|
if (quill.getLength() > position) {
|
@@ -57,43 +84,78 @@ $(() => {
|
|
57
84
|
|
58
85
|
return ""
|
59
86
|
}
|
60
|
-
return `<span contenteditable="false"
|
87
|
+
return `<span contenteditable="false">${item.original.nickname}</span>`;
|
61
88
|
}
|
62
|
-
return
|
89
|
+
return item.original.nickname;
|
63
90
|
},
|
64
91
|
menuItemTemplate: function(item) {
|
65
|
-
let tpl = `<strong>${item.original.
|
92
|
+
let tpl = `<strong>${item.original.nickname}</strong> <small>${item.original.name}</small>`;
|
66
93
|
return tpl;
|
67
94
|
}
|
68
95
|
});
|
69
96
|
|
70
|
-
|
97
|
+
let setupEvents = function($element) {
|
98
|
+
// DOM manipulation
|
99
|
+
$element.on("focusin", (event) => {
|
100
|
+
// Set the parent container relative to the current element
|
101
|
+
tribute.menuContainer = event.target.parentNode;
|
102
|
+
});
|
103
|
+
$element.on("focusout", (event) => {
|
104
|
+
let $parent = $(event.target).parent();
|
71
105
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
let $parent = $(event.target).parent();
|
106
|
+
if ($parent.hasClass("is-active")) {
|
107
|
+
$parent.removeClass("is-active");
|
108
|
+
}
|
109
|
+
});
|
110
|
+
$element.on("input", (event) => {
|
111
|
+
let $parent = $(event.target).parent();
|
79
112
|
|
80
|
-
|
81
|
-
|
113
|
+
if (tribute.isActive) {
|
114
|
+
// We need to move the container to the wrapper selected
|
115
|
+
let $tribute = $(".tribute-container");
|
116
|
+
$tribute.appendTo($parent);
|
117
|
+
// // Remove the inline styles, relative to absolute positioning
|
118
|
+
$tribute.removeAttr("style");
|
119
|
+
// Parent adaptation
|
120
|
+
$parent.addClass("is-active");
|
121
|
+
} else {
|
122
|
+
$parent.removeClass("is-active");
|
123
|
+
}
|
124
|
+
});
|
125
|
+
|
126
|
+
};
|
127
|
+
|
128
|
+
setupEvents($mentionContainer);
|
129
|
+
|
130
|
+
// This allows external libraries (like React) to use the component
|
131
|
+
// by simply firing and event targeting the element where to attach Tribute
|
132
|
+
$(document).on("attach-mentions-element", (event, element) => {
|
133
|
+
if (!element) {
|
134
|
+
return;
|
82
135
|
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
// We need to move the container to the wrapper selected
|
89
|
-
let $tribute = $(".tribute-container");
|
90
|
-
$tribute.appendTo($parent);
|
91
|
-
// Remove the inline styles, relative to absolute positioning
|
92
|
-
$tribute.removeAttr("style");
|
93
|
-
// Parent adaptation
|
94
|
-
$parent.addClass("is-active");
|
95
|
-
} else {
|
96
|
-
$parent.removeClass("is-active");
|
136
|
+
tribute.attach(element);
|
137
|
+
// Due a bug in Tribute, re-add menu to DOM if it has been removed
|
138
|
+
// See https://github.com/zurb/tribute/issues/140
|
139
|
+
if (tribute.menu && !document.body.contains(tribute.menu)) {
|
140
|
+
tribute.range.getDocument().body.appendChild(tribute.menu);
|
97
141
|
}
|
142
|
+
setupEvents($(element));
|
98
143
|
});
|
144
|
+
|
145
|
+
// tribute.attach($mentionContainer);
|
146
|
+
// Tribute needs to be attached to the `.ql-editor` element as said at:
|
147
|
+
// https://github.com/quilljs/quill/issues/1816
|
148
|
+
//
|
149
|
+
// For this reason we need to wait a bit for quill to initialize itself.
|
150
|
+
setTimeout(function() {
|
151
|
+
$mentionContainer.each((index, item) => {
|
152
|
+
let $qlEditor = $(".ql-editor", item);
|
153
|
+
if ($qlEditor.length > 0) {
|
154
|
+
tribute.attach($qlEditor);
|
155
|
+
} else {
|
156
|
+
tribute.attach(item);
|
157
|
+
}
|
158
|
+
});
|
159
|
+
}, 1000);
|
99
160
|
});
|
161
|
+
|
@@ -58,3 +58,60 @@
|
|
58
58
|
text-align: center;
|
59
59
|
}
|
60
60
|
}
|
61
|
+
|
62
|
+
.user-nickname{
|
63
|
+
label .row{
|
64
|
+
div:first-of-type{
|
65
|
+
// this is the prefix div
|
66
|
+
@extend .input-group-label;
|
67
|
+
|
68
|
+
border-#{$global-right}: 0;
|
69
|
+
width: 8%;
|
70
|
+
height: 3rem;
|
71
|
+
border-top-left-radius: $input-radius;
|
72
|
+
border-bottom-left-radius: $input-radius;
|
73
|
+
|
74
|
+
.prefix{
|
75
|
+
display: inline-block;
|
76
|
+
height: 2.9rem;
|
77
|
+
padding-top: .8rem;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
div:last-of-type{
|
82
|
+
// this is the input div
|
83
|
+
@extend .input-group-field;
|
84
|
+
|
85
|
+
width: 92%;
|
86
|
+
height: 3rem;
|
87
|
+
|
88
|
+
input{
|
89
|
+
border-top-left-radius: 0;
|
90
|
+
border-bottom-left-radius: 0;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
label.is-invalid-label .row{
|
96
|
+
margin-bottom: $form-spacing;
|
97
|
+
|
98
|
+
div:first-of-type{
|
99
|
+
// this is the prefix div
|
100
|
+
background-color: mix($input-background-invalid, $light-gray, 8%);
|
101
|
+
border-color: $input-error-color;
|
102
|
+
}
|
103
|
+
|
104
|
+
div:last-of-type{
|
105
|
+
// this is the input div
|
106
|
+
height: 4.2rem;
|
107
|
+
|
108
|
+
.form-error.is-visible{
|
109
|
+
margin-left: -8%;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
.help-text{
|
115
|
+
margin-top: 1rem;
|
116
|
+
}
|
117
|
+
}
|
@@ -53,12 +53,8 @@ module Decidim
|
|
53
53
|
def presenter_for_author(authorable)
|
54
54
|
if official?
|
55
55
|
"#{model.class.parent}::OfficialAuthorPresenter".constantize.new
|
56
|
-
|
57
|
-
|
58
|
-
elsif authorable.author.is_a?(Decidim::User)
|
59
|
-
Decidim::UserPresenter.new(authorable.author)
|
60
|
-
elsif authorable.author.is_a?(Decidim::Meeting)
|
61
|
-
Decidim::MeetingPresenter.new(authorable.author)
|
56
|
+
else
|
57
|
+
authorable.user_group&.presenter || authorable.author.presenter
|
62
58
|
end
|
63
59
|
end
|
64
60
|
|
@@ -51,11 +51,9 @@ module Decidim
|
|
51
51
|
#
|
52
52
|
# Returns an HTML-safe string.
|
53
53
|
def output_unified_diff(data)
|
54
|
-
return unless data && data[:new_value].present?
|
55
|
-
|
56
54
|
Diffy::Diff.new(
|
57
55
|
data[:old_value].to_s,
|
58
|
-
data[:new_value],
|
56
|
+
data[:new_value].to_s,
|
59
57
|
allow_empty_diff: false,
|
60
58
|
include_plus_and_minus_in_html: true
|
61
59
|
).to_s(:html).html_safe
|
@@ -67,11 +65,9 @@ module Decidim
|
|
67
65
|
#
|
68
66
|
# Returns an HTML-safe string.
|
69
67
|
def output_split_diff(data, direction)
|
70
|
-
return unless direction && data && data[:new_value].present?
|
71
|
-
|
72
68
|
Diffy::SplitDiff.new(
|
73
|
-
data[:old_value],
|
74
|
-
data[:new_value],
|
69
|
+
data[:old_value].to_s,
|
70
|
+
data[:new_value].to_s,
|
75
71
|
allow_empty_diff: false,
|
76
72
|
format: :html,
|
77
73
|
include_plus_and_minus_in_html: true
|
@@ -42,8 +42,6 @@ module Decidim
|
|
42
42
|
|
43
43
|
skip_before_action :disable_http_caching, unless: :user_signed_in?
|
44
44
|
|
45
|
-
before_action :track_continuity_badge
|
46
|
-
|
47
45
|
private
|
48
46
|
|
49
47
|
# Stores the url where the user will be redirected after login.
|
@@ -90,11 +88,5 @@ module Decidim
|
|
90
88
|
def add_vary_header
|
91
89
|
response.headers["Vary"] = "Accept"
|
92
90
|
end
|
93
|
-
|
94
|
-
def track_continuity_badge
|
95
|
-
return unless current_user
|
96
|
-
|
97
|
-
Decidim::ContinuityBadgeTracker.new(current_user).track!(Time.zone.today)
|
98
|
-
end
|
99
91
|
end
|
100
92
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Devise
|
5
|
+
# Custom Devise UnlocksController to avoid namespace problems.
|
6
|
+
class UnlocksController < ::Devise::UnlocksController
|
7
|
+
include Decidim::DeviseControllers
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Since we're using a single Devise installation for multiple
|
12
|
+
# organizations, and user emails can be repeated across organizations,
|
13
|
+
# we need to identify the user by both the email and the organization.
|
14
|
+
# Setting the organization ID here will be used by Devise internally to
|
15
|
+
# find the correct user.
|
16
|
+
#
|
17
|
+
# Note that in order for this to work we need to define the `reset_password_keys`
|
18
|
+
# Devise attribute in the `Decidim::User` model to include the
|
19
|
+
# `decidim_organization_id` attribute.
|
20
|
+
def resource_params
|
21
|
+
super.merge(decidim_organization_id: current_organization.id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -13,7 +13,6 @@ module Decidim
|
|
13
13
|
def index
|
14
14
|
Search.call(term, current_organization, filters, page_params) do
|
15
15
|
on(:ok) do |results|
|
16
|
-
# results.page(params[:page]).per(params[:per_page])
|
17
16
|
results_count = results.sum { |results_by_type| results_by_type.last[:count] }
|
18
17
|
expose(sections: results, results_count: results_count)
|
19
18
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
class ExportParticipatorySpaceJob < ApplicationJob
|
5
|
+
queue_as :default
|
6
|
+
|
7
|
+
def perform(user, participatory_space, name, format)
|
8
|
+
export_manifest = participatory_space.manifest.export_manifests.find do |manifest|
|
9
|
+
manifest.name == name.to_sym
|
10
|
+
end
|
11
|
+
|
12
|
+
collection = export_manifest.collection.call(participatory_space)
|
13
|
+
serializer = export_manifest.serializer
|
14
|
+
|
15
|
+
export_data = Decidim::Exporters.find_exporter(format).new(collection, serializer).export
|
16
|
+
|
17
|
+
Decidim::ExportMailer.export(user, name, export_data).deliver_now
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|