decidim-decidim_awesome 0.5.1 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -14
- data/Rakefile +6 -0
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -0
- data/app/assets/config/decidim_decidim_awesome_manifest.js +1 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/form_exit_warn.js.es6 +30 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +225 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +82 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +20 -20
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +15 -13
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +29 -13
- data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +2 -4
- data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +39 -6
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +34 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +40 -0
- data/app/commands/decidim/decidim_awesome/create_editor_image.rb +5 -3
- data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +29 -1
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +29 -2
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +0 -2
- data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +1 -1
- data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +8 -1
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +11 -0
- data/app/forms/decidim/decidim_awesome/editor_image_form.rb +2 -0
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +4 -0
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +37 -1
- data/app/models/decidim/decidim_awesome/editor_image.rb +4 -3
- data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +9 -0
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +49 -7
- data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +28 -0
- data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/iframe_component/iframe/show.html.erb +6 -1
- data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +46 -20
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +5 -0
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +1 -1
- data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +3 -0
- data/app/views/v0.22/layouts/decidim/_head.html.erb +1 -0
- data/app/views/{v0.21 → v0.23}/layouts/decidim/_head.html.erb +5 -0
- data/app/views/{v0.21 → v0.23}/layouts/decidim/admin/_header.html.erb +3 -0
- data/config/locales/ca.yml +53 -7
- data/config/locales/cs.yml +47 -1
- data/config/locales/en.yml +32 -2
- data/config/locales/es.yml +84 -38
- data/config/locales/eu.yml +171 -0
- data/config/locales/fr.yml +47 -1
- data/config/locales/sv.yml +47 -1
- data/lib/decidim/decidim_awesome.rb +12 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +2 -0
- data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -3
- data/lib/decidim/decidim_awesome/checksums.yml +6 -4
- data/lib/decidim/decidim_awesome/config.rb +13 -12
- data/lib/decidim/decidim_awesome/iframe_component/component.rb +3 -3
- data/lib/decidim/decidim_awesome/map_component/component.rb +6 -0
- data/lib/decidim/decidim_awesome/test/factories.rb +1 -1
- data/lib/decidim/decidim_awesome/test/layouts/decidim/_head.html.erb +2 -0
- data/lib/decidim/decidim_awesome/test/layouts/decidim/admin/_header.html.erb +3 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +71 -0
- data/lib/decidim/decidim_awesome/version.rb +2 -3
- data/vendor/assets/javascripts/jsrender.min.js +4 -0
- metadata +29 -18
- data/app/helpers/decidim/decidim_awesome/application_helper.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca4e9a5883518e03b29844b430fe92343558ca88394a4e03334ebb387cf133dc
|
4
|
+
data.tar.gz: 2dbdc12ff4446debcf62641c8dc4fa788fc5a07011060216874d3811f526d4f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb94d6bb293ebf2ac77767d18721f7f59f674a6fcfa89b5d8c3a12b7a2c56f3c49629767e878ff0ef7c9f7dffb31b13c1a90c7d82e5ffea2893aa1d59b57b548
|
7
|
+
data.tar.gz: 1af64bdf1c90aa1bcfb296777726df9fe7ffe6e1b472cd057e2595376b9eac47e96bd3c3abc4a6ebc2aba20537ecaac4c6047f8d2d0039ed436b33bdfbac2f6f
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
Usability and UX tweaks for Decidim.
|
8
8
|
|
9
|
-
This plugin allows the administrators to expand the possibilities of Decidim beyond some existing limitations.
|
9
|
+
This plugin allows the administrators to expand the possibilities of Decidim beyond some existing limitations.
|
10
10
|
All tweaks are provided in a optional fashion with granular permissions that let the administrator to choose exactly where to apply those mods. Some tweaks can be applied to any assembly, other in an specific participatory process or even in type of component only.
|
11
11
|
|
12
12
|
**This in beta status, we do not accept any responsibility for breaking anything. Feedback is appreciated though.**
|
@@ -16,7 +16,7 @@ All tweaks are provided in a optional fashion with granular permissions that let
|
|
16
16
|
At Platoniq, we like to explore and combine open tools for enriching democracy in many levels. And also for organizations or companies, not only governments.
|
17
17
|
Currently we are working very closely with the team behind [Decidim](https://decidim.org) because we believe that it is a great software.
|
18
18
|
|
19
|
-
However in Platoniq we have this slogan: "Democracy is fun if you take it seriously" (feel free to ask for T-shirts 😉).
|
19
|
+
However in Platoniq we have this slogan: "Democracy is fun if you take it seriously" (feel free to ask for T-shirts 😉).
|
20
20
|
And, let's face it, sometimes we feel that Decidim lacks a bit of the "fun" part so we created this.
|
21
21
|
Because Decidim is awesome and so is this!
|
22
22
|
|
@@ -89,7 +89,7 @@ This feature allows to customize each organization css without affecting the oth
|
|
89
89
|
4. Modify that file as you like, you can use any SASS function available (such as `@import`)
|
90
90
|
5. Restart your server, enjoy!
|
91
91
|
|
92
|
-
See an example here:
|
92
|
+
See an example here:
|
93
93
|
https://github.com/Platoniq/decidim-demo/tree/master/app/assets/themes
|
94
94
|
|
95
95
|
NOTE: Files presents in the `app/assets/themes` folder are added automatically into the precompile list of Rails by this plugin.
|
@@ -106,14 +106,20 @@ With this feature you can have a support chat in Decidim. It is linked to a [Tel
|
|
106
106
|
|
107
107
|
![Intergram screenshot](examples/intergram.png)
|
108
108
|
|
109
|
+
#### 10. Custom CSS applied only according scopes restrictions
|
110
|
+
|
111
|
+
For instance, with this feature you can create directly from the admin a CSS snipped that is only applied globally, in a particular assembly or even a single proposal!
|
112
|
+
|
113
|
+
![CSS screenshot](examples/custom_styles.png)
|
114
|
+
|
109
115
|
|
110
116
|
#### To be continued...
|
111
117
|
|
112
|
-
Some things in the road-map:
|
118
|
+
Some things in the road-map:
|
113
119
|
|
114
120
|
1. Improve the conversation in comments by allowing images
|
115
|
-
1.
|
116
|
-
1.
|
121
|
+
1. Allow to create non-private surveys where the responding user is known by admins
|
122
|
+
1. Manipulate menus (reorder, change texts, add new items)
|
117
123
|
1. Propose something! or even better send a PR!
|
118
124
|
|
119
125
|
## Installation
|
@@ -121,7 +127,7 @@ Some things in the road-map:
|
|
121
127
|
Add this line to your application's Gemfile:
|
122
128
|
|
123
129
|
```ruby
|
124
|
-
gem "decidim-decidim_awesome", "~> 0.
|
130
|
+
gem "decidim-decidim_awesome", "~> 0.6.4"
|
125
131
|
```
|
126
132
|
|
127
133
|
And then execute:
|
@@ -135,13 +141,13 @@ bundle exec rails db:migrate
|
|
135
141
|
Depending on your Decidim version, choose the corresponding Awesome version to ensure compatibility:
|
136
142
|
|
137
143
|
| Awesome version | Compatible Decidim versions |
|
138
|
-
|
144
|
+
|---|---|
|
139
145
|
| 0.5.x | 0.21.x, 0.22.x |
|
140
|
-
|
146
|
+
| 0.6.x | 0.22.x, 0.23.x |
|
141
147
|
|
142
148
|
## Configuration
|
143
149
|
|
144
|
-
Each tweak can be enabled or disabled by default. It also can be deactivated so
|
150
|
+
Each tweak can be enabled or disabled by default. It also can be deactivated so
|
145
151
|
admins do not even see it.
|
146
152
|
|
147
153
|
In order to personalize default values, create an initializer such as:
|
@@ -244,15 +250,23 @@ DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_
|
|
244
250
|
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rspec
|
245
251
|
```
|
246
252
|
|
247
|
-
However, this project also make use of the gem [Appraisals](https://github.com/thoughtbot/appraisal) in order to test
|
253
|
+
However, this project also make use of the gem [Appraisals](https://github.com/thoughtbot/appraisal) in order to test against several versions of Decidim. The idea is to support same supported versions of Decidim.
|
254
|
+
|
255
|
+
You can run run all tests against all Decidim versions by using:
|
248
256
|
|
249
|
-
You can run run all tests againts all Decidim versions by using:
|
250
257
|
```bash
|
251
258
|
bundle exec appraisal install
|
252
|
-
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_app
|
259
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec appraisal rake test_app
|
253
260
|
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec appraisal rspec
|
254
261
|
```
|
255
262
|
|
263
|
+
To test a specific apprasail configured version do the following:
|
264
|
+
|
265
|
+
```
|
266
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec appraisal decidim-0.23 rake test_app
|
267
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec appraisal decidim-0.23 rspec
|
268
|
+
```
|
269
|
+
|
256
270
|
Note that the database user has to have rights to create and drop a database in
|
257
271
|
order to create the dummy test app database.
|
258
272
|
|
@@ -276,13 +290,15 @@ the code coverage report.
|
|
276
290
|
|
277
291
|
### Appraisals commands
|
278
292
|
|
293
|
+
The [Appraisals](Appraisals) file contains the supported versions. In i each version defines the changes respect to the main `Gemfile`.
|
294
|
+
|
279
295
|
Appraisal uses custom gems for testing in the folder `gemfiles`, these gemfiles are generated from the file `Appraisals`. To update definitions do:
|
280
296
|
|
281
297
|
```
|
282
298
|
bundle exec appraisal install
|
283
299
|
```
|
284
300
|
|
285
|
-
To update the Appraisal definitions
|
301
|
+
The former command will take care of updating all configured version. To update the Appraisal definitions manually (not usually necessary) do the following:
|
286
302
|
|
287
303
|
```
|
288
304
|
cd gemfiles
|
data/Rakefile
CHANGED
@@ -20,6 +20,11 @@ def copy_themes
|
|
20
20
|
FileUtils.cp_r "lib/decidim/decidim_awesome/test/themes", "spec/decidim_dummy_app/app/assets/themes", verbose: true
|
21
21
|
end
|
22
22
|
|
23
|
+
def copy_headers
|
24
|
+
FileUtils.mkdir_p "spec/decidim_dummy_app/app/views/v0.11", verbose: true
|
25
|
+
FileUtils.cp_r "lib/decidim/decidim_awesome/test/layouts", "spec/decidim_dummy_app/app/views/v0.11/layouts", verbose: true
|
26
|
+
end
|
27
|
+
|
23
28
|
desc "copy test theme files"
|
24
29
|
task :copy_themes do
|
25
30
|
copy_themes
|
@@ -30,6 +35,7 @@ task test_app: "decidim:generate_external_test_app" do
|
|
30
35
|
ENV["RAILS_ENV"] = "test"
|
31
36
|
install_module("spec/decidim_dummy_app")
|
32
37
|
copy_themes
|
38
|
+
copy_headers
|
33
39
|
end
|
34
40
|
|
35
41
|
desc "Generates a development app."
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// = require_self
|
2
|
+
|
3
|
+
$(() => {
|
4
|
+
const $form = $("form.awesome-edit-config");
|
5
|
+
if ($form.length > 0) {
|
6
|
+
$form.find("input, textarea, select").on("change", () => {
|
7
|
+
$form.data("changed", true);
|
8
|
+
});
|
9
|
+
|
10
|
+
const safePath = $form.data("safe-path").split("?")[0];
|
11
|
+
$(document).on("click", "a", (event) => {
|
12
|
+
window.exitUrl = event.currentTarget.href;
|
13
|
+
});
|
14
|
+
$(document).on("submit", "form", (event) => {
|
15
|
+
window.exitUrl = event.currentTarget.action;
|
16
|
+
});
|
17
|
+
|
18
|
+
window.addEventListener("beforeunload", (event) => {
|
19
|
+
const exitUrl = window.exitUrl;
|
20
|
+
const hasChanged = $form.data("changed");
|
21
|
+
window.exitUrl = null;
|
22
|
+
|
23
|
+
if (!hasChanged || (exitUrl && exitUrl.includes(safePath))) {
|
24
|
+
return null;
|
25
|
+
}
|
26
|
+
|
27
|
+
event.returnValue = true;
|
28
|
+
});
|
29
|
+
}
|
30
|
+
});
|
@@ -0,0 +1,225 @@
|
|
1
|
+
// = require jsrender.min
|
2
|
+
// = require decidim/map
|
3
|
+
// = require leaflet.featuregroup.subgroup
|
4
|
+
// = require decidim/decidim_awesome/awesome_map/categories
|
5
|
+
// = require decidim/decidim_awesome/awesome_map/legacy_proposals
|
6
|
+
// = require decidim/decidim_awesome/awesome_map/meetings
|
7
|
+
// = require_self
|
8
|
+
|
9
|
+
((exports) => {
|
10
|
+
const { fetchProposals, fetchMeetings, getCategory } = exports.AwesomeMap;
|
11
|
+
|
12
|
+
const collapsedMenu = $("#map").data("collapsed");
|
13
|
+
const show = {
|
14
|
+
withdrawn: $("#map").data("show-withdrawn"),
|
15
|
+
accepted: $("#map").data("show-accepted"),
|
16
|
+
evaluating: $("#map").data("show-evaluating"),
|
17
|
+
notAnswered: $("#map").data("show-not-answered"),
|
18
|
+
rejected: $("#map").data("show-rejected")
|
19
|
+
};
|
20
|
+
const components = $("#map").data("components");
|
21
|
+
const popupMeetingTemplateId = "marker-meeting-popup";
|
22
|
+
const popupProposalTemplateId = "legacy-marker-proposal-popup";
|
23
|
+
|
24
|
+
const cluster = L.markerClusterGroup();
|
25
|
+
const amendments = [];
|
26
|
+
|
27
|
+
const layers = {};
|
28
|
+
|
29
|
+
const control = L.control.layers(null, null, {
|
30
|
+
position: 'topleft',
|
31
|
+
sortLayers: false,
|
32
|
+
collapsed: collapsedMenu,
|
33
|
+
// hideSingleBase: true
|
34
|
+
});
|
35
|
+
const allMarkers = [];
|
36
|
+
|
37
|
+
const drawMarker = (element, marker, component) => {
|
38
|
+
let tmpl = component.type === "proposals" ? popupProposalTemplateId : popupMeetingTemplateId,
|
39
|
+
node = document.createElement("div");
|
40
|
+
|
41
|
+
$($.templates(`#${tmpl}`).render(element)).appendTo(node);
|
42
|
+
|
43
|
+
marker.bindPopup(node, {
|
44
|
+
maxwidth: 640,
|
45
|
+
minWidth: 500,
|
46
|
+
keepInView: true,
|
47
|
+
className: "map-info"
|
48
|
+
}).openPopup();
|
49
|
+
|
50
|
+
allMarkers.push({
|
51
|
+
marker: marker,
|
52
|
+
component: component,
|
53
|
+
element: element
|
54
|
+
});
|
55
|
+
|
56
|
+
// Check if it has amendments, add it to a list
|
57
|
+
if(element.amendments && element.amendments.length) {
|
58
|
+
element.amendments.forEach((amendment) => {
|
59
|
+
amendments.push(amendment.emendation.id);
|
60
|
+
});
|
61
|
+
}
|
62
|
+
// Add to category layer
|
63
|
+
let cat = getCategory(element.category);
|
64
|
+
if(layers[cat.id]) {
|
65
|
+
marker.addTo(layers[cat.id].group);
|
66
|
+
// show category if hidden
|
67
|
+
const $label = $(`.awesome_map-category_${cat.id}`).closest("label");
|
68
|
+
const $parent = $(`.awesome_map-category_${cat.parent}`).closest("label");
|
69
|
+
$label.show();
|
70
|
+
// update number of items
|
71
|
+
$label.attr("title", parseInt($label.attr("title") || 0) + 1);
|
72
|
+
// show parent if apply
|
73
|
+
$parent.show();
|
74
|
+
$parent.attr("title", parseInt($parent.attr("title") || 0) + 1);
|
75
|
+
// update component stats
|
76
|
+
const $component = $(`#awesome_map-component-${component.id}`);
|
77
|
+
$component.attr("title", parseInt($component.attr("title") || 0) + 1);
|
78
|
+
}
|
79
|
+
|
80
|
+
return marker;
|
81
|
+
};
|
82
|
+
|
83
|
+
const loadElements = (map) => {
|
84
|
+
// legends
|
85
|
+
control.addTo(map);
|
86
|
+
cluster.addTo(map);
|
87
|
+
|
88
|
+
// Load markers
|
89
|
+
components.forEach((component) => {
|
90
|
+
if(component.type == "proposals") {
|
91
|
+
// add control layer for proposals
|
92
|
+
layers.proposals = {
|
93
|
+
label: `<span id="awesome_map-component-${component.id}" title="0">${component.name || window.DecidimAwesome.texts.proposals}</span>`,
|
94
|
+
group: L.featureGroup.subGroup(cluster)
|
95
|
+
};
|
96
|
+
control.addOverlay(layers.proposals.group, layers.proposals.label);
|
97
|
+
layers.proposals.group.addTo(map);
|
98
|
+
|
99
|
+
// add control layer for amendments if any
|
100
|
+
if(component.amendments) {
|
101
|
+
layers.amendments = {
|
102
|
+
label: `<span id="awesome_map-component-${component.d}" title="0">${window.DecidimAwesome.texts.amendments}</span>`,
|
103
|
+
group: L.featureGroup.subGroup(cluster)
|
104
|
+
}
|
105
|
+
control.addOverlay(layers.amendments.group, layers.amendments.label);
|
106
|
+
layers.amendments.group.addTo(map);
|
107
|
+
}
|
108
|
+
|
109
|
+
fetchProposals(component, '', (element, marker) => {
|
110
|
+
if(show[element.state || 'notAnswered']) {
|
111
|
+
drawMarker(element, marker, component).addTo(layers.proposals.group)
|
112
|
+
}
|
113
|
+
}, () => {
|
114
|
+
// finall call
|
115
|
+
map.fitBounds(cluster.getBounds(), { padding: [50, 50] });
|
116
|
+
allMarkers.forEach((item) => {
|
117
|
+
// add marker to amendments layers if it's an amendment
|
118
|
+
if(amendments.find((a) => a == item.element.id)) {
|
119
|
+
item.marker.removeFrom(layers.proposals.group);
|
120
|
+
item.marker.addTo(layers.amendments.group);
|
121
|
+
}
|
122
|
+
});
|
123
|
+
});
|
124
|
+
}
|
125
|
+
|
126
|
+
if(component.type == "meetings") {
|
127
|
+
// add control layer for meetings
|
128
|
+
layers.meetings = {
|
129
|
+
label: `<span id="awesome_map-component-${component.id}" title="0">${component.name || window.DecidimAwesome.texts.meetings}</span>`,
|
130
|
+
group: L.featureGroup.subGroup(cluster)
|
131
|
+
};
|
132
|
+
control.addOverlay(layers.meetings.group, layers.meetings.label);
|
133
|
+
layers.meetings.group.addTo(map);
|
134
|
+
|
135
|
+
fetchMeetings(component, '', (element, marker) => {
|
136
|
+
drawMarker(element, marker, component).addTo(layers.meetings.group);
|
137
|
+
}, () => {
|
138
|
+
map.fitBounds(cluster.getBounds(), { padding: [50, 50] });
|
139
|
+
});
|
140
|
+
}
|
141
|
+
});
|
142
|
+
|
143
|
+
|
144
|
+
// add categories control layers
|
145
|
+
if(window.AwesomeMap.categories.length) {
|
146
|
+
let lastLayer = layers[Object.keys(layers)[Object.keys(layers).length - 1]];
|
147
|
+
// Add Categories "title"
|
148
|
+
if(lastLayer) {
|
149
|
+
lastLayer.label = `${lastLayer.label}<hr><b>${window.DecidimAwesome.texts.categories}</b>`;
|
150
|
+
control.removeLayer(lastLayer.group);
|
151
|
+
control.addOverlay(lastLayer.group, lastLayer.label);
|
152
|
+
}
|
153
|
+
|
154
|
+
window.AwesomeMap.categories.forEach((category) => {
|
155
|
+
// add control layer for this category
|
156
|
+
layers[category.id] = {
|
157
|
+
label: `<i class="awesome_map-category_${category.id}"></i> ${category.name}`,
|
158
|
+
group: L.featureGroup.subGroup(cluster)
|
159
|
+
};
|
160
|
+
layers[category.id].group.addTo(map);
|
161
|
+
control.addOverlay(layers[category.id].group, layers[category.id].label);
|
162
|
+
// hide layer by default, it will be activated if there's any marker in it
|
163
|
+
setTimeout(() => {
|
164
|
+
$(`.awesome_map-category_${category.id}`).closest("label").hide();
|
165
|
+
});
|
166
|
+
});
|
167
|
+
|
168
|
+
// watch events for subcategories syncronitzation
|
169
|
+
const getCatFromClass = (name) => {
|
170
|
+
let id = name.match(/awesome_map-category_(\d+)/)
|
171
|
+
if(!id) return;
|
172
|
+
const cat = getCategory(id[1]);
|
173
|
+
if(!cat || !cat.name) return;
|
174
|
+
|
175
|
+
return cat;
|
176
|
+
};
|
177
|
+
|
178
|
+
const indeterminateInput = (id) => {
|
179
|
+
$('[class^="awesome_map-category_"]').parent().prev().prop("indeterminate", false);
|
180
|
+
if(id) {
|
181
|
+
let $input = $(`.awesome_map-category_${id}`).parent().prev();
|
182
|
+
if(!$input.prop("checked")) {
|
183
|
+
$input.prop("indeterminate", true);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
};
|
187
|
+
|
188
|
+
map.on('overlayadd', (e) => {
|
189
|
+
const cat = getCatFromClass(e.name);
|
190
|
+
if(!cat) return;
|
191
|
+
// if it's a children, put the parent to indeterminate
|
192
|
+
indeterminateInput(cat.parent);
|
193
|
+
});
|
194
|
+
|
195
|
+
// on remove a parent category, remove all children
|
196
|
+
map.on('overlayremove', (e) => {
|
197
|
+
const cat = getCatFromClass(e.name);
|
198
|
+
if(!cat) return;
|
199
|
+
cat.children().forEach((c) => {
|
200
|
+
let $el = $(`.awesome_map-category_${c.id}`);
|
201
|
+
if($el.parent().prev().prop("checked")) {
|
202
|
+
$el.click();
|
203
|
+
}
|
204
|
+
});
|
205
|
+
});
|
206
|
+
|
207
|
+
}
|
208
|
+
|
209
|
+
};
|
210
|
+
|
211
|
+
// currentMap might not be loaded yet so let's delay a bit
|
212
|
+
// TODO: improve this
|
213
|
+
const waitMap = () => {
|
214
|
+
if(exports.Decidim && exports.Decidim.currentMap) {
|
215
|
+
loadElements(exports.Decidim.currentMap);
|
216
|
+
} else {
|
217
|
+
setTimeout(() => {
|
218
|
+
waitMap();
|
219
|
+
}, 100);
|
220
|
+
}
|
221
|
+
};
|
222
|
+
|
223
|
+
waitMap();
|
224
|
+
|
225
|
+
})(window);
|
@@ -0,0 +1,82 @@
|
|
1
|
+
// = require decidim/decidim_awesome/awesome_map/api_fetcher
|
2
|
+
// = require decidim/decidim_awesome/awesome_map/categories
|
3
|
+
|
4
|
+
((exports) => {
|
5
|
+
const { getCategory } = exports.AwesomeMap;
|
6
|
+
const query = `query ($id: ID!, $after: String!) {
|
7
|
+
component(id: $id) {
|
8
|
+
id
|
9
|
+
__typename
|
10
|
+
... on Proposals {
|
11
|
+
proposals(first: 50, after: $after){
|
12
|
+
pageInfo {
|
13
|
+
hasNextPage
|
14
|
+
endCursor
|
15
|
+
}
|
16
|
+
edges {
|
17
|
+
node {
|
18
|
+
id
|
19
|
+
state
|
20
|
+
title
|
21
|
+
body
|
22
|
+
address
|
23
|
+
coordinates {
|
24
|
+
latitude
|
25
|
+
longitude
|
26
|
+
}
|
27
|
+
amendments {
|
28
|
+
emendation {
|
29
|
+
id
|
30
|
+
}
|
31
|
+
}
|
32
|
+
category {
|
33
|
+
id
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}`;
|
41
|
+
|
42
|
+
const ProposalIcon = L.DivIcon.SVGIcon.DecidimIcon;
|
43
|
+
|
44
|
+
const createMarker = (element, callback) => {
|
45
|
+
const marker = L.marker([element.coordinates.latitude, element.coordinates.longitude], {
|
46
|
+
icon: new ProposalIcon({
|
47
|
+
fillColor: getCategory(element.category).color
|
48
|
+
})
|
49
|
+
});
|
50
|
+
|
51
|
+
element.body = element.body.replace(/\n/g, "<br>");
|
52
|
+
callback(element, marker);
|
53
|
+
};
|
54
|
+
|
55
|
+
const fetchProposals = (component, after, callback, finalCall = () => {}) => {
|
56
|
+
const variables = {
|
57
|
+
"id": component.id,
|
58
|
+
"after": after
|
59
|
+
};
|
60
|
+
const api = new ApiFetcher(query, variables);
|
61
|
+
api.fetchAll((result) => {
|
62
|
+
if(result) {
|
63
|
+
result.component.proposals.edges.forEach((element) => {
|
64
|
+
if(!element.node) return;
|
65
|
+
|
66
|
+
if(element.node.coordinates) {
|
67
|
+
element.node.link = component.url + '/proposals/' + element.node.id;
|
68
|
+
createMarker(element.node, callback);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
if (result.component.proposals.pageInfo.hasNextPage) {
|
72
|
+
fetchProposals(component, result.component.proposals.pageInfo.endCursor, callback, finalCall);
|
73
|
+
} else {
|
74
|
+
finalCall();
|
75
|
+
}
|
76
|
+
}
|
77
|
+
});
|
78
|
+
};
|
79
|
+
|
80
|
+
exports.AwesomeMap = exports.AwesomeMap || {};
|
81
|
+
exports.AwesomeMap.fetchProposals = fetchProposals;
|
82
|
+
})(window);
|