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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -14
  3. data/Rakefile +6 -0
  4. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -0
  5. data/app/assets/config/decidim_decidim_awesome_manifest.js +1 -0
  6. data/app/assets/javascripts/decidim/decidim_awesome/admin/form_exit_warn.js.es6 +30 -0
  7. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +225 -0
  8. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +82 -0
  9. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +20 -20
  10. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +15 -13
  11. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +29 -13
  12. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +2 -4
  13. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +39 -6
  14. data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +34 -0
  15. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +40 -0
  16. data/app/commands/decidim/decidim_awesome/create_editor_image.rb +5 -3
  17. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +29 -1
  18. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +29 -2
  19. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +0 -2
  20. data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +1 -1
  21. data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +8 -1
  22. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +11 -0
  23. data/app/forms/decidim/decidim_awesome/editor_image_form.rb +2 -0
  24. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +4 -0
  25. data/app/helpers/decidim/decidim_awesome/map_helper.rb +37 -1
  26. data/app/models/decidim/decidim_awesome/editor_image.rb +4 -3
  27. data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +9 -0
  28. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +49 -7
  29. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +28 -0
  30. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -1
  31. data/app/views/decidim/decidim_awesome/iframe_component/iframe/show.html.erb +6 -1
  32. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +46 -20
  33. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +5 -0
  34. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +1 -1
  35. data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +3 -0
  36. data/app/views/v0.22/layouts/decidim/_head.html.erb +1 -0
  37. data/app/views/{v0.21 → v0.23}/layouts/decidim/_head.html.erb +5 -0
  38. data/app/views/{v0.21 → v0.23}/layouts/decidim/admin/_header.html.erb +3 -0
  39. data/config/locales/ca.yml +53 -7
  40. data/config/locales/cs.yml +47 -1
  41. data/config/locales/en.yml +32 -2
  42. data/config/locales/es.yml +84 -38
  43. data/config/locales/eu.yml +171 -0
  44. data/config/locales/fr.yml +47 -1
  45. data/config/locales/sv.yml +47 -1
  46. data/lib/decidim/decidim_awesome.rb +12 -0
  47. data/lib/decidim/decidim_awesome/admin_engine.rb +2 -0
  48. data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -3
  49. data/lib/decidim/decidim_awesome/checksums.yml +6 -4
  50. data/lib/decidim/decidim_awesome/config.rb +13 -12
  51. data/lib/decidim/decidim_awesome/iframe_component/component.rb +3 -3
  52. data/lib/decidim/decidim_awesome/map_component/component.rb +6 -0
  53. data/lib/decidim/decidim_awesome/test/factories.rb +1 -1
  54. data/lib/decidim/decidim_awesome/test/layouts/decidim/_head.html.erb +2 -0
  55. data/lib/decidim/decidim_awesome/test/layouts/decidim/admin/_header.html.erb +3 -0
  56. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +71 -0
  57. data/lib/decidim/decidim_awesome/version.rb +2 -3
  58. data/vendor/assets/javascripts/jsrender.min.js +4 -0
  59. metadata +29 -18
  60. 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: 3d9259114807c3c7f0dca652e83f99013ca524a6c68cdb4ece408de7efdaa6f8
4
- data.tar.gz: '0937b4bf68c2240a022d99e0b15f2bb05407134d3a71c05ee6d325500af06843'
3
+ metadata.gz: ca4e9a5883518e03b29844b430fe92343558ca88394a4e03334ebb387cf133dc
4
+ data.tar.gz: 2dbdc12ff4446debcf62641c8dc4fa788fc5a07011060216874d3811f526d4f5
5
5
  SHA512:
6
- metadata.gz: 45c576b8359928d771d58f3b67a64ee4189ce36e7b252a08170abdd2b2eaccaf18754640cf7c9f591b0669b5b7335dc944330778e47c027e70b8d5833bdd21c5
7
- data.tar.gz: b993edbf892739c8379baeba8e745117895cb09cf453345976cf9be6909e333a3855af3ff365f0a2677f8012e2944893884996fa8a9dd97bd8709898c5ddbe08
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. Direct export of surveys in PDF
116
- 1. Allow to create surveys where the responding user is known
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.5.1"
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 againts several versions of Decidim. The idea is to suport same supported versions of Decidim.
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 maually do the following:
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."
@@ -1 +1,2 @@
1
1
  // = link decidim/decidim_awesome/admin.js
2
+ // = link decidim/decidim_awesome/admin/form_exit_warn.js
@@ -1,2 +1,3 @@
1
1
  // = link decidim/decidim_awesome/application.js
2
+ // = link decidim/decidim_awesome/awesome_map/legacy_map.js
2
3
  // = link decidim/decidim_awesome/awesome_map/map.js
@@ -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);