decidim-decidim_awesome 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +14 -4
  4. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +82 -0
  5. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +13 -2
  6. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +15 -13
  7. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +29 -13
  8. data/app/commands/decidim/decidim_awesome/create_editor_image.rb +5 -3
  9. data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +1 -1
  10. data/app/forms/decidim/decidim_awesome/editor_image_form.rb +2 -0
  11. data/app/helpers/decidim/decidim_awesome/map_helper.rb +11 -1
  12. data/app/models/decidim/decidim_awesome/editor_image.rb +4 -3
  13. data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +9 -0
  14. data/app/views/decidim/decidim_awesome/iframe_component/iframe/show.html.erb +6 -1
  15. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +40 -18
  16. data/config/locales/ca.yml +39 -7
  17. data/config/locales/cs.yml +33 -1
  18. data/config/locales/en.yml +9 -2
  19. data/config/locales/es.yml +70 -38
  20. data/config/locales/fr.yml +33 -1
  21. data/config/locales/sv.yml +33 -1
  22. data/lib/decidim/decidim_awesome/iframe_component/component.rb +2 -2
  23. data/lib/decidim/decidim_awesome/map_component/component.rb +6 -0
  24. data/lib/decidim/decidim_awesome/test/factories.rb +1 -1
  25. data/lib/decidim/decidim_awesome/version.rb +1 -1
  26. data/vendor/assets/javascripts/jsrender.min.js +4 -0
  27. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3401b18b924106ad65b4545904014b5c853485f897dc194affaa00665b07fe40
4
- data.tar.gz: 68f73b33b0b31dc4addbd5f3f6dfa68b90ee5cd5ef56fa6f0ed91ee58c96fb73
3
+ metadata.gz: 3eed88558d87e79b6943a0fafa5e482129482f29d60de45cb30dabeb696a726d
4
+ data.tar.gz: 3818b75fbfa54b2517e75c2873f443262afeb684735a348f4e4a110a4979fe30
5
5
  SHA512:
6
- metadata.gz: 770a318ee4b9e08018709b7526cad4365ec373b75b2083d92e851a6f2eeb8eeee0e7ef51ed515a44a247b4129a4c929313434f99927f1eaa398cd25350151ca4
7
- data.tar.gz: 5d3085dab5205c222eb52c57258b9cbdef9dfea5f1fa8a946700b40da53dea3d8514311672a48976def5a59408d52fd429f8864713361bbd68a97f5146e451db
6
+ metadata.gz: 1036da296077cd339bc14428b2c3bdcd8e47ebbc881ede6d96fe0f74c513d78f5e8691aff184754932c7e071d942d1d9c2dbb93bcbf5b32c6d2b1627f4c2bb60
7
+ data.tar.gz: a0b3b5476eef71ab74b45bee55366bcd9c90918daa7e3aa043dd85aaa9adca6518b2984fe46d5d5567f72fadbfc3c72d653c99cea07f13e1f0a8fe220226daaf
data/README.md CHANGED
@@ -121,7 +121,7 @@ Some things in the road-map:
121
121
  Add this line to your application's Gemfile:
122
122
 
123
123
  ```ruby
124
- gem "decidim-decidim_awesome", "~> 0.6.0"
124
+ gem "decidim-decidim_awesome", "~> 0.6.1"
125
125
  ```
126
126
 
127
127
  And then execute:
@@ -1,7 +1,8 @@
1
+ // = require jsrender.min
1
2
  // = require decidim/map
2
3
  // = require leaflet.featuregroup.subgroup
3
4
  // = require decidim/decidim_awesome/awesome_map/categories
4
- // = require decidim/decidim_awesome/awesome_map/proposals
5
+ // = require decidim/decidim_awesome/awesome_map/legacy_proposals
5
6
  // = require decidim/decidim_awesome/awesome_map/meetings
6
7
  // = require_self
7
8
 
@@ -9,9 +10,16 @@
9
10
  const { fetchProposals, fetchMeetings, getCategory } = exports.AwesomeMap;
10
11
 
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
+ };
12
20
  const components = $("#map").data("components");
13
21
  const popupMeetingTemplateId = "marker-meeting-popup";
14
- const popupProposalTemplateId = "marker-proposal-popup";
22
+ const popupProposalTemplateId = "legacy-marker-proposal-popup";
15
23
 
16
24
  const cluster = L.markerClusterGroup();
17
25
  const amendments = [];
@@ -30,7 +38,7 @@
30
38
  let tmpl = component.type === "proposals" ? popupProposalTemplateId : popupMeetingTemplateId,
31
39
  node = document.createElement("div");
32
40
 
33
- $.tmpl($(`#${tmpl}`), element).appendTo(node);
41
+ $($.templates(`#${tmpl}`).render(element)).appendTo(node);
34
42
 
35
43
  marker.bindPopup(node, {
36
44
  maxwidth: 640,
@@ -99,7 +107,9 @@
99
107
  }
100
108
 
101
109
  fetchProposals(component, '', (element, marker) => {
102
- drawMarker(element, marker, component).addTo(layers.proposals.group);
110
+ if(show[element.state || 'notAnswered']) {
111
+ drawMarker(element, marker, component).addTo(layers.proposals.group)
112
+ }
103
113
  }, () => {
104
114
  // finall call
105
115
  map.fitBounds(cluster.getBounds(), { padding: [50, 50] });
@@ -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);
@@ -1,3 +1,4 @@
1
+ // = require jsrender.min
1
2
  // = require leaflet.featuregroup.subgroup
2
3
  // = require decidim/decidim_awesome/awesome_map/categories
3
4
  // = require decidim/decidim_awesome/awesome_map/proposals
@@ -8,6 +9,13 @@
8
9
  const { fetchProposals, fetchMeetings, getCategory } = exports.AwesomeMap;
9
10
 
10
11
  const collapsedMenu = $("#awesome-map").data("collapsed");
12
+ const show = {
13
+ withdrawn: $("#awesome-map").data("show-withdrawn"),
14
+ accepted: $("#awesome-map").data("show-accepted"),
15
+ evaluating: $("#awesome-map").data("show-evaluating"),
16
+ notAnswered: $("#awesome-map").data("show-not-answered"),
17
+ rejected: $("#awesome-map").data("show-rejected")
18
+ };
11
19
  const components = $("#awesome-map").data("components");
12
20
  const popupMeetingTemplateId = "marker-meeting-popup";
13
21
  const popupProposalTemplateId = "marker-proposal-popup";
@@ -29,7 +37,7 @@
29
37
  let tmpl = component.type === "proposals" ? popupProposalTemplateId : popupMeetingTemplateId,
30
38
  node = document.createElement("div");
31
39
 
32
- $.tmpl($(`#${tmpl}`), element).appendTo(node);
40
+ $($.templates(`#${tmpl}`).render(element)).appendTo(node);
33
41
 
34
42
  marker.bindPopup(node, {
35
43
  maxwidth: 640,
@@ -98,7 +106,10 @@
98
106
  }
99
107
 
100
108
  fetchProposals(component, '', (element, marker) => {
101
- drawMarker(element, marker, component).addTo(layers.proposals.group);
109
+ console.log(element.state, show[element.state || 'notAnswered'], show, element);
110
+ if(show[element.state || 'notAnswered']) {
111
+ drawMarker(element, marker, component).addTo(layers.proposals.group)
112
+ }
102
113
  }, () => {
103
114
  // finall call
104
115
  map.fitBounds(cluster.getBounds(), { padding: [50, 50] });
@@ -93,7 +93,7 @@
93
93
  });
94
94
 
95
95
  element.title.translation = ApiFetcher.findTranslation(element.title.translations);
96
- element.description.translation = ApiFetcher.findTranslation(element.description.translations);
96
+ element.description.translation = ApiFetcher.findTranslation(element.description.translations).replace(/\n/g, "<br>");;
97
97
  element.location.translation = ApiFetcher.findTranslation(element.location.translations);
98
98
  element.locationHints.translation = ApiFetcher.findTranslation(element.locationHints.translations);
99
99
  callback(element, marker);
@@ -107,19 +107,21 @@
107
107
  };
108
108
  const api = new ApiFetcher(query, variables);
109
109
  api.fetchAll((result) => {
110
- result.component.meetings.edges.forEach((element) => {
111
- if(!element.node) return;
112
-
113
- if(element.node.coordinates) {
114
- element.node.link = component.url + '/meetings/' + element.node.id;
115
- createMarker(element.node, callback);
116
- }
117
- });
110
+ if(result) {
111
+ result.component.meetings.edges.forEach((element) => {
112
+ if(!element.node) return;
113
+
114
+ if(element.node.coordinates) {
115
+ element.node.link = component.url + '/meetings/' + element.node.id;
116
+ createMarker(element.node, callback);
117
+ }
118
+ });
118
119
 
119
- if (result.component.meetings.pageInfo.hasNextPage) {
120
- fetchMeetings(component, result.component.meetings.pageInfo.endCursor, callback, finalCall);
121
- } else {
122
- finalCall();
120
+ if (result.component.meetings.pageInfo.hasNextPage) {
121
+ fetchMeetings(component, result.component.meetings.pageInfo.endCursor, callback, finalCall);
122
+ } else {
123
+ finalCall();
124
+ }
123
125
  }
124
126
  });
125
127
  };
@@ -16,8 +16,19 @@
16
16
  edges {
17
17
  node {
18
18
  id
19
- title
20
- body
19
+ state
20
+ title {
21
+ translations {
22
+ text
23
+ locale
24
+ }
25
+ }
26
+ body {
27
+ translations {
28
+ text
29
+ locale
30
+ }
31
+ }
21
32
  address
22
33
  coordinates {
23
34
  latitude
@@ -47,6 +58,9 @@
47
58
  })
48
59
  });
49
60
 
61
+ element.title.translation = ApiFetcher.findTranslation(element.title.translations);
62
+ element.body.translation = ApiFetcher.findTranslation(element.body.translations).replace(/\n/g, "<br>");
63
+
50
64
  callback(element, marker);
51
65
  };
52
66
 
@@ -57,18 +71,20 @@
57
71
  };
58
72
  const api = new ApiFetcher(query, variables);
59
73
  api.fetchAll((result) => {
60
- result.component.proposals.edges.forEach((element) => {
61
- if(!element.node) return;
62
-
63
- if(element.node.coordinates) {
64
- element.node.link = component.url + '/proposals/' + element.node.id;
65
- createMarker(element.node, callback);
74
+ if(result) {
75
+ result.component.proposals.edges.forEach((element) => {
76
+ if(!element.node) return;
77
+
78
+ if(element.node.coordinates) {
79
+ element.node.link = component.url + '/proposals/' + element.node.id;
80
+ createMarker(element.node, callback);
81
+ }
82
+ });
83
+ if (result.component.proposals.pageInfo.hasNextPage) {
84
+ fetchProposals(component, result.component.proposals.pageInfo.endCursor, callback, finalCall);
85
+ } else {
86
+ finalCall();
66
87
  }
67
- });
68
- if (result.component.proposals.pageInfo.hasNextPage) {
69
- fetchProposals(component, result.component.proposals.pageInfo.endCursor, callback, finalCall);
70
- } else {
71
- finalCall();
72
88
  }
73
89
  });
74
90
  };
@@ -19,12 +19,14 @@ module Decidim
19
19
  def call
20
20
  return broadcast(:invalid) if form.invalid?
21
21
 
22
- image = EditorImage.create!(
23
- image: form.image,
22
+ image = EditorImage.new(
24
23
  path: form.path,
25
24
  decidim_author_id: form.current_user.id,
26
- organization: form.current_organization
25
+ organization: form.organization,
26
+ image: form.image
27
27
  )
28
+
29
+ image.save!
28
30
  broadcast(:ok, image)
29
31
  end
30
32
 
@@ -42,7 +42,7 @@ module Decidim
42
42
  {
43
43
  image: params[:image],
44
44
  author_id: current_user.id,
45
- path: request.original_fullpath
45
+ path: request.referer
46
46
  }
47
47
  end
48
48
  end
@@ -11,6 +11,8 @@ module Decidim
11
11
 
12
12
  validates :author_id, presence: true
13
13
  validates :image, presence: true
14
+
15
+ alias organization current_organization
14
16
  end
15
17
  end
16
18
  end
@@ -23,7 +23,12 @@ module Decidim
23
23
  amendments: component.manifest.name == :proposals ? Decidim::Proposals::Proposal.where(component: component).only_emendations.count : 0
24
24
  }
25
25
  end.to_json,
26
- "data-collapsed" => current_component.settings.collapse
26
+ "data-collapsed" => current_component.settings.collapse,
27
+ "data-show-not-answered" => current_component.current_settings.show_not_answered,
28
+ "data-show-accepted" => current_component.current_settings.show_accepted,
29
+ "data-show-withdrawn" => current_component.current_settings.show_withdrawn,
30
+ "data-show-evaluating" => current_component.current_settings.show_evaluating
31
+ # "data-show-rejected" => current_component.current_settings.show_rejected
27
32
  }
28
33
  content_tag(:div, map, map_html_options)
29
34
  end
@@ -45,6 +50,11 @@ module Decidim
45
50
  }
46
51
  end.to_json,
47
52
  "data-collapsed" => current_component.settings.collapse,
53
+ "data-show-not-answered" => current_component.current_settings.show_not_answered,
54
+ "data-show-accepted" => current_component.current_settings.show_accepted,
55
+ "data-show-withdrawn" => current_component.current_settings.show_withdrawn,
56
+ "data-show-evaluating" => current_component.current_settings.show_evaluating,
57
+ # "data-show-rejected" => current_component.current_settings.show_rejected,
48
58
  "data-markers-data" => [].to_json
49
59
  }
50
60
 
@@ -11,9 +11,10 @@ module Decidim
11
11
  validates :organization, presence: true
12
12
  validates :author, presence: true
13
13
 
14
- validates :image,
15
- file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
16
- file_content_type: { allow: ["image/jpeg", "image/png"] }
14
+ validates :image, presence: true
15
+ # validates :image,
16
+ # file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
17
+ # file_content_type: { allow: ["image/jpeg", "image/png"] }
17
18
 
18
19
  mount_uploader :image, Decidim::DecidimAwesome::ImageUploader
19
20
 
@@ -10,10 +10,19 @@ module Decidim
10
10
  process resize_to_fit: [nil, 237]
11
11
  end
12
12
 
13
+ # TODO: remove when diching 0.22 support
13
14
  def extension_white_list
14
15
  %w(jpg jpeg png)
15
16
  end
16
17
 
18
+ def extension_whitelist
19
+ %w(jpg jpeg png)
20
+ end
21
+
22
+ def content_type_whitelist
23
+ %w(image/jpeg image/png)
24
+ end
25
+
17
26
  def max_image_height_or_width
18
27
  8000
19
28
  end
@@ -1,7 +1,12 @@
1
+ <%= announcement = render(partial: "decidim/shared/component_announcement") %>
2
+
1
3
  <%= stylesheet_link_tag "decidim/decidim_awesome/awesome_iframe/iframe" %>
2
4
 
3
5
  <style rel="stylesheet" type="text/css">
4
- <%= ".wrapper { padding: 0; }" if remove_margins? %>
6
+ <% if remove_margins? %>
7
+ <%= ".wrapper { padding-left: 0;padding-right: 0;padding-bottom: 0; }" %>
8
+ <%= ".wrapper { padding-top: 0; }" unless announcement.present? %>
9
+ <% end %>
5
10
  </style>
6
11
 
7
12
  <div class="awesome-iframe<%= " row" if viewport_width? %>">
@@ -2,57 +2,79 @@
2
2
 
3
3
  <%= awesome_map_for map_components do %>
4
4
 
5
- <template id="marker-proposal-popup">
5
+ <script id="legacy-marker-proposal-popup" type="text/x-jsrender">
6
6
  <div class="map-info__content">
7
- <h3>${title}</h3>
7
+ <h3>{{>title}}</h3>
8
8
  <div id="bodyContent">
9
- <p>{{html body}}</p>
9
+ <p>{{:body}}</p>
10
10
  <div class="map__date-adress">
11
11
  <div class="address card__extra">
12
- <div class="address__icon">{{html icon}}</div>
12
+ <div class="address__icon">{{:icon}}</div>
13
13
  <div class="address__details">
14
- <span>${address}</span><br>
14
+ <span>{{>address}}</span><br>
15
15
  </div>
16
16
  </div>
17
17
  </div>
18
18
  <div class="map-info__button">
19
- <a href="${link}" class="button button--sc">
19
+ <a href="{{>link}}" class="button button--sc">
20
20
  <%= t(".view_proposal") %>
21
21
  </a>
22
22
  </div>
23
23
  </div>
24
24
  </div>
25
- </template>
25
+ </script>
26
+
27
+ <script id="marker-proposal-popup" type="text/x-jsrender">
28
+ <div class="map-info__content">
29
+ <h3>{{>title.translation}}</h3>
30
+ <div id="bodyContent">
31
+ <p>{{:body.translation}}</p>
32
+ <div class="map__date-adress">
33
+ <div class="address card__extra">
34
+ <div class="address__icon">{{:icon}}</div>
35
+ <div class="address__details">
36
+ <span>{{>address}}</span><br>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <div class="map-info__button">
41
+ <a href="{{>link}}" class="button button--sc">
42
+ <%= t(".view_proposal") %>
43
+ </a>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </script>
26
48
 
27
- <template id="marker-meeting-popup">
49
+ <script id="marker-meeting-popup" type="text/x-jsrender">
28
50
  <div class="map-info__content">
29
- <h3>${title.translation}</h3>
51
+ <h3>{{>title.translation}}</h3>
30
52
  <div id="bodyContent">
31
- <p>{{html description.translation}}</p>
53
+ <p>{{:description.translation}}</p>
32
54
  <div class="map__date-adress">
33
55
  <div class="card__datetime">
34
56
  <div class="card__datetime__date">
35
- ${startTimeDay} <span class="card__datetime__month">${startTimeMonth} ${startTimeYear}</span>
57
+ {{>startTimeDay}} <span class="card__datetime__month">{{>startTimeMonth}} {{>startTimeYear}}</span>
36
58
  </div>
37
- <div class="card__datetime__time">${starTime}</div>
59
+ <div class="card__datetime__time">{{>starTime}}</div>
38
60
  </div>
39
61
  <div class="address card__extra">
40
- <div class="address__icon">{{html icon}}</div>
62
+ <div class="address__icon">{{:icon}}</div>
41
63
  <div class="address__details">
42
- <strong>{{html location.translation}}</strong><br>
43
- <span>${address}</span><br>
44
- <span>{{html locationHints.translation}}</span>
64
+ <strong>{{:location.translation}}</strong><br>
65
+ <span>{{>address}}</span><br>
66
+ <span>{{:locationHints.translation}}</span>
45
67
  </div>
46
68
  </div>
47
69
  </div>
48
70
  <div class="map-info__button">
49
- <a href="${link}" class="button button--sc">
71
+ <a href="{{>link}}" class="button button--sc">
50
72
  <%= t("decidim.meetings.meetings_map.view_meeting") %>
51
73
  </a>
52
74
  </div>
53
75
  </div>
54
76
  </div>
55
- </template>
77
+ </script>
56
78
 
57
79
  <%= stylesheet_link_tag "decidim/decidim_awesome/awesome_map/map" %>
58
80
  <style type="text/css">