decidim-decidim_awesome 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +1 -0
  4. data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +15 -0
  5. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/hashtags.js.es6 +48 -0
  6. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +106 -0
  7. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +12 -19
  8. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +3 -2
  9. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +166 -170
  10. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/markers.js.es6 +56 -0
  11. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +4 -3
  12. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +17 -4
  13. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +48 -0
  14. data/app/assets/stylesheets/decidim/decidim_awesome/admin.scss +7 -4
  15. data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +16 -0
  16. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/leaflet.scss.erb +9 -0
  17. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +95 -0
  18. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_editor.scss +1 -1
  19. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +4 -1
  20. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -2
  21. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +11 -0
  22. data/app/helpers/decidim/decidim_awesome/map_helper.rb +9 -3
  23. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +1 -0
  24. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -2
  25. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +9 -6
  26. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +4 -1
  27. data/config/locales/ca.yml +13 -0
  28. data/config/locales/cs.yml +13 -0
  29. data/config/locales/en.yml +14 -0
  30. data/config/locales/es.yml +13 -0
  31. data/config/locales/eu.yml +13 -0
  32. data/config/locales/fr.yml +154 -141
  33. data/config/locales/nl.yml +148 -135
  34. data/config/locales/sv.yml +47 -34
  35. data/lib/decidim/decidim_awesome/map_component/component.rb +7 -1
  36. data/lib/decidim/decidim_awesome/version.rb +1 -1
  37. data/vendor/assets/javascripts/codemirror.js +9801 -0
  38. data/vendor/assets/javascripts/jquery.truncate.js +105 -0
  39. data/vendor/assets/javascripts/keymap/sublime.js +720 -0
  40. data/vendor/assets/javascripts/mode/css/css.js +864 -0
  41. data/vendor/assets/stylesheets/codemirror.css +350 -0
  42. data/vendor/assets/stylesheets/inscrybmde.min.scss +180 -0
  43. metadata +28 -3
  44. data/vendor/assets/stylesheets/inscrybmde.min.css +0 -8
@@ -0,0 +1,56 @@
1
+ // = require jsrender.min
2
+ // = require decidim/decidim_awesome/awesome_map/layers
3
+ // = require decidim/decidim_awesome/awesome_map/categories
4
+
5
+ ((exports) => {
6
+ const { getCategory, layers } = exports.AwesomeMap;
7
+
8
+ const popupMeetingTemplateId = "marker-meeting-popup";
9
+ const popupProposalTemplateId = "marker-proposal-popup";
10
+ const allMarkers = [];
11
+
12
+ const drawMarker = (element, marker, component) => {
13
+ let tmpl = component.type === "proposals" ? popupProposalTemplateId : popupMeetingTemplateId,
14
+ node = document.createElement("div");
15
+
16
+ $($.templates(`#${tmpl}`).render(element)).appendTo(node);
17
+
18
+ marker.bindPopup(node, {
19
+ maxwidth: 640,
20
+ minWidth: 500,
21
+ keepInView: true,
22
+ className: "map-info"
23
+ }).openPopup();
24
+
25
+ allMarkers.push({
26
+ marker: marker,
27
+ component: component,
28
+ element: element
29
+ });
30
+
31
+ // Add to category layer
32
+ let cat = getCategory(element.category);
33
+ if(layers[cat.id]) {
34
+ $('#awesome_map-categories-control').show();
35
+ marker.addTo(layers[cat.id].group);
36
+ // show category if hidden
37
+ const $label = $(`label.awesome_map-category-${cat.id}`);
38
+ const $parent = $(`label.awesome_map-category-${cat.parent}`);
39
+ $label.show();
40
+ // update number of items
41
+ $label.attr("title", (parseInt($label.attr("title") || 0) + 1) + " " + window.DecidimAwesome.texts.items);
42
+ // show parent if apply
43
+ $parent.show();
44
+ $parent.attr("title", (parseInt($parent.attr("title") || 0) + 1) + " " + window.DecidimAwesome.texts.items);
45
+ }
46
+
47
+ // update component stats
48
+ const $component = $(`#awesome_map-component_${component.id}`);
49
+ $component.attr("title", parseInt($component.attr("title") || 0) + 1);
50
+
51
+ return marker;
52
+ };
53
+
54
+ exports.AwesomeMap.allMarkers = allMarkers;
55
+ exports.AwesomeMap.drawMarker = drawMarker;
56
+ })(window);
@@ -1,8 +1,9 @@
1
1
  // = require decidim/decidim_awesome/awesome_map/api_fetcher
2
2
  // = require decidim/decidim_awesome/awesome_map/categories
3
+ // = require decidim/decidim_awesome/awesome_map/utilities
3
4
 
4
5
  ((exports) => {
5
- const { getCategory } = exports.AwesomeMap;
6
+ const { getCategory, truncate } = exports.AwesomeMap;
6
7
  const query = `query ($id: ID!, $after: String!) {
7
8
  component(id: $id) {
8
9
  id
@@ -59,7 +60,7 @@
59
60
  const MeetingIcon = L.DivIcon.SVGIcon.extend({
60
61
  options: {
61
62
  fillColor: "#ef604d",
62
- iconSize: {x: 300, y:150},
63
+ iconSize: { x: 300, y: 150 },
63
64
  opacity: 0
64
65
  },
65
66
  _createPathDescription: function() {
@@ -93,7 +94,7 @@
93
94
  });
94
95
 
95
96
  element.title.translation = ApiFetcher.findTranslation(element.title.translations);
96
- element.description.translation = ApiFetcher.findTranslation(element.description.translations).replace(/\n/g, "<br>");;
97
+ element.description.translation = truncate(ApiFetcher.findTranslation(element.description.translations)).replace(/\n/g, "<br>");
97
98
  element.location.translation = ApiFetcher.findTranslation(element.location.translations);
98
99
  element.locationHints.translation = ApiFetcher.findTranslation(element.locationHints.translations);
99
100
  callback(element, marker);
@@ -1,8 +1,10 @@
1
1
  // = require decidim/decidim_awesome/awesome_map/api_fetcher
2
2
  // = require decidim/decidim_awesome/awesome_map/categories
3
+ // = require decidim/decidim_awesome/awesome_map/hashtags
4
+ // = require decidim/decidim_awesome/awesome_map/utilities
3
5
 
4
6
  ((exports) => {
5
- const { getCategory } = exports.AwesomeMap;
7
+ const { getCategory, truncate, collectHashtags, removeHashtags, appendHtmlHashtags } = exports.AwesomeMap;
6
8
  const query = `query ($id: ID!, $after: String!) {
7
9
  component(id: $id) {
8
10
  id
@@ -14,7 +16,7 @@
14
16
  endCursor
15
17
  }
16
18
  edges {
17
- node {
19
+ node {
18
20
  id
19
21
  state
20
22
  title {
@@ -49,6 +51,7 @@
49
51
  }
50
52
  }`;
51
53
 
54
+ let amendments = [];
52
55
  const ProposalIcon = L.DivIcon.SVGIcon.DecidimIcon;
53
56
 
54
57
  const createMarker = (element, callback) => {
@@ -59,7 +62,9 @@
59
62
  });
60
63
 
61
64
  element.title.translation = ApiFetcher.findTranslation(element.title.translations);
62
- element.body.translation = ApiFetcher.findTranslation(element.body.translations).replace(/\n/g, "<br>");
65
+ const body = ApiFetcher.findTranslation(element.body.translations);
66
+ element.hashtags = collectHashtags(body);
67
+ element.body.translation = appendHtmlHashtags(truncate(removeHashtags(body)).replace(/\n/g, "<br>"), element.hashtags);
63
68
 
64
69
  callback(element, marker);
65
70
  };
@@ -74,11 +79,18 @@
74
79
  if(result) {
75
80
  result.component.proposals.edges.forEach((element) => {
76
81
  if(!element.node) return;
77
-
82
+
78
83
  if(element.node.coordinates) {
79
84
  element.node.link = component.url + '/proposals/' + element.node.id;
80
85
  createMarker(element.node, callback);
81
86
  }
87
+
88
+ // Check if it has amendments, add it to a list
89
+ if(element.node.amendments && element.node.amendments.length) {
90
+ element.node.amendments.forEach((amendment) => {
91
+ amendments.push(amendment.emendation.id);
92
+ });
93
+ }
82
94
  });
83
95
  if (result.component.proposals.pageInfo.hasNextPage) {
84
96
  fetchProposals(component, result.component.proposals.pageInfo.endCursor, callback, finalCall);
@@ -91,4 +103,5 @@
91
103
 
92
104
  exports.AwesomeMap = exports.AwesomeMap || {};
93
105
  exports.AwesomeMap.fetchProposals = fetchProposals;
106
+ exports.AwesomeMap.amendments = amendments;
94
107
  })(window);
@@ -0,0 +1,48 @@
1
+ //= require jquery.truncate
2
+
3
+ ((exports) => {
4
+ const sanitizeCenter = (string) => {
5
+ const parts = string.split(",")
6
+ if (parts.length >= 2) {
7
+ const lat = parseFloat(parts[0]);
8
+ const lng = parseFloat(parts[1]);
9
+ if(lat && lng) {
10
+ return [lat, lng];
11
+ }
12
+ }
13
+ return null
14
+ };
15
+
16
+ const options = {
17
+ length: $("#awesome-map").data("truncate") || 255,
18
+ center: sanitizeCenter($("#awesome-map").data("map-center")),
19
+ zoom: $("#awesome-map").data("map-zoom"),
20
+ menu: {
21
+ amendments: $("#awesome-map").data("menu-amendments"),
22
+ meetings: $("#awesome-map").data("menu-meetings"),
23
+ hashtags: $("#awesome-map").data("menu-hashtags")
24
+ }
25
+ };
26
+
27
+ const truncate = (string) => {
28
+ return $.truncate(string, options);
29
+ };
30
+
31
+ const show = {
32
+ withdrawn: $("#awesome-map").data("show-withdrawn"),
33
+ accepted: $("#awesome-map").data("show-accepted"),
34
+ evaluating: $("#awesome-map").data("show-evaluating"),
35
+ notAnswered: $("#awesome-map").data("show-not-answered"),
36
+ rejected: $("#awesome-map").data("show-rejected")
37
+ };
38
+
39
+ const collapsedMenu = $("#awesome-map").data("collapsed");
40
+ const components = $("#awesome-map").data("components");
41
+
42
+ exports.AwesomeMap = exports.AwesomeMap || {};
43
+ exports.AwesomeMap.truncate = truncate;
44
+ exports.AwesomeMap.options = options;
45
+ exports.AwesomeMap.show = show;
46
+ exports.AwesomeMap.collapsedMenu = collapsedMenu;
47
+ exports.AwesomeMap.components = components;
48
+ })(window);
@@ -1,4 +1,5 @@
1
1
  //= require github.min
2
+ //= require codemirror
2
3
  //= require inscrybmde.min
3
4
  //= require_self
4
5
 
@@ -6,6 +7,7 @@
6
7
  @import "decidim/utils/settings";
7
8
  @import "decidim/utils/mixins";
8
9
  @import "./admin/constraints";
10
+ @import "./admin/codemirror";
9
11
  @import "./editors/quill_editor";
10
12
  @import "./editors/markdown_editor";
11
13
 
@@ -17,7 +19,7 @@
17
19
  font-size: .8em;
18
20
  }
19
21
 
20
- .decidim_awesome {
22
+ .decidim_awesome{
21
23
  &.modal{
22
24
  .spinner{
23
25
  @include spinner(25px, #aaa, var(--secondary), 800ms);
@@ -33,17 +35,18 @@
33
35
  }
34
36
  }
35
37
 
36
- &-form {
38
+ &-form{
37
39
  margin-bottom: 2em;
38
40
  border-bottom: 1px solid #999;
39
41
  padding-bottom: 1.5em;
40
42
  }
41
- &-form:last-child {
43
+
44
+ &-form:last-child{
42
45
  border-bottom: none;
43
46
  padding-bottom: 0;
44
47
  }
45
48
  }
46
49
 
47
- tbody tr.menu_hack-addition {
50
+ tbody tr.menu_hack-addition{
48
51
  background: rgb(255, 248, 222);
49
52
  }
@@ -0,0 +1,16 @@
1
+ .awesome-edit-config{
2
+ .scoped-style{
3
+ .form-error {
4
+ margin: 0;
5
+ }
6
+ >.CodeMirror{
7
+ border-top: .5em solid #f6f6f6;
8
+ border-right: .5em solid #f6f6f6;
9
+ min-height: 6em;
10
+ height: auto;
11
+ max-height: 40em;
12
+ resize: vertical;
13
+ overflow: vertical !important;
14
+ }
15
+ }
16
+ }
@@ -7,3 +7,12 @@
7
7
  .leaflet-default-icon-path {
8
8
  background-image: url(<%= asset_path "marker-icon.png" %>);
9
9
  }
10
+ .leaflet-container {
11
+ font: inherit;
12
+
13
+ #bodyContent .description {
14
+ img, iframe {
15
+ max-height: 5em;
16
+ }
17
+ }
18
+ }
@@ -63,4 +63,99 @@
63
63
  border: 2px solid #bbb;
64
64
  border-radius: 4px;
65
65
  }
66
+
67
+ .awesome_map-title-control{
68
+ display: block;
69
+ cursor: pointer;
70
+
71
+ &::after{
72
+ content: '';
73
+ width: 0;
74
+ height: 0;
75
+ border-left: 5px solid transparent;
76
+ border-right: 5px solid transparent;
77
+ border-top: 5px solid black;
78
+ border-bottom: 0;
79
+ display: inline-block;
80
+ margin: 0 0 2px 5px;
81
+ }
82
+ }
83
+
84
+ .active{
85
+ .awesome_map-title-control::after{
86
+ border-top: 0;
87
+ border-bottom: 5px solid black;
88
+ }
89
+ }
90
+
91
+ #awesome_map-{
92
+ &categories-control{
93
+ display: none;
94
+
95
+ label{
96
+ margin-left: .5rem;
97
+ display: none;
98
+
99
+ i{
100
+ display: inline-block;
101
+ width: .8rem;
102
+ height: .8rem;
103
+ border-radius: 50%;
104
+ background-color: var(-- primary);
105
+ }
106
+
107
+ &.subcategory{
108
+ padding-left: 1em;
109
+ }
110
+ }
111
+
112
+ .categories-container{
113
+ display: none;
114
+ }
115
+
116
+ &.active{
117
+ .categories-container{
118
+ display: block;
119
+ }
120
+ }
121
+ }
122
+
123
+ &hashtags-control{
124
+ display: none;
125
+
126
+ label{
127
+ display: inline-block;
128
+ line-height: 1;
129
+ background-color: #f0f0f0;
130
+ border-radius: 5px;
131
+ margin: .5rem;
132
+ padding: .5rem;
133
+
134
+ span{
135
+ margin: 0 .5rem 2px 0;
136
+ }
137
+
138
+ input{
139
+ vertical-align: top;
140
+ }
141
+ }
142
+
143
+ .awesome_map-toggle_all_tags{
144
+ margin: .5rem 1rem;
145
+ font-size: .875rem;
146
+ }
147
+
148
+ .hashtags-container,
149
+ .awesome_map-toggle_all_tags{
150
+ display: none;
151
+ }
152
+
153
+ &.active{
154
+ .hashtags-container,
155
+ .awesome_map-toggle_all_tags{
156
+ display: block;
157
+ }
158
+ }
159
+ }
160
+ }
66
161
  }
@@ -1,6 +1,6 @@
1
1
  // editor tweaks
2
2
  //
3
- .CodeMirror{
3
+ .editor .CodeMirror{
4
4
  color: #333;
5
5
  font-weight: normal;
6
6
  line-height: 1.45;
@@ -18,7 +18,10 @@ module Decidim
18
18
  #
19
19
  # Returns nothing.
20
20
  def call
21
- return broadcast(:invalid) if form.invalid?
21
+ if form.invalid?
22
+ message = form.errors[:scoped_styles].join("; ") if @form.errors[:scoped_styles].any?
23
+ return broadcast(:invalid, message, form.errors)
24
+ end
22
25
 
23
26
  begin
24
27
  form.attributes.each do |key, val|
@@ -28,9 +28,9 @@ module Decidim
28
28
  redirect_to decidim_admin_decidim_awesome.config_path
29
29
  end
30
30
 
31
- on(:invalid) do |message|
31
+ on(:invalid) do |message, err|
32
32
  flash.now[:alert] = I18n.t("config.update.error", error: message, scope: "decidim.decidim_awesome.admin")
33
- render :show
33
+ render :show, locals: { errors: err.presence }
34
34
  end
35
35
  end
36
36
  end
@@ -20,11 +20,22 @@ module Decidim
20
20
  # collect all keys anything not specified in the params (UpdateConfig command ignores it)
21
21
  attr_accessor :valid_keys
22
22
 
23
+ validate :css_syntax, if: ->(form) { form.scoped_styles.present? }
24
+
23
25
  def self.from_params(params, additional_params = {})
24
26
  instance = super(params, additional_params)
25
27
  instance.valid_keys = params.keys.map(&:to_sym) || []
26
28
  instance
27
29
  end
30
+
31
+ def css_syntax
32
+ scoped_styles.each do |key, code|
33
+ SassC::Engine.new(code).render
34
+ rescue SassC::SyntaxError => e
35
+ errors.add(:scoped_styles, I18n.t("config.form.errors.incorrect_css", key: key, scope: "decidim.decidim_awesome.admin"))
36
+ errors.add(key.to_sym, e.message)
37
+ end
38
+ end
28
39
  end
29
40
  end
30
41
  end
@@ -24,11 +24,17 @@ module Decidim
24
24
  }
25
25
  end.to_json,
26
26
  "data-collapsed" => current_component.settings.collapse,
27
+ "data-truncate" => current_component.settings.truncate,
28
+ "data-map-center" => current_component.settings.map_center,
29
+ "data-map-zoom" => current_component.settings.map_zoom,
30
+ "data-menu-amendments" => current_component.settings.menu_amendments,
31
+ "data-menu-meetings" => current_component.settings.menu_meetings,
32
+ "data-menu-hashtags" => current_component.settings.menu_hashtags,
27
33
  "data-show-not-answered" => current_component.current_settings.show_not_answered,
28
34
  "data-show-accepted" => current_component.current_settings.show_accepted,
29
35
  "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
36
+ "data-show-evaluating" => current_component.current_settings.show_evaluating,
37
+ "data-show-rejected" => current_component.current_settings.show_rejected
32
38
  }
33
39
  content_tag(:div, map, map_html_options)
34
40
  end
@@ -54,7 +60,7 @@ module Decidim
54
60
  "data-show-accepted" => current_component.current_settings.show_accepted,
55
61
  "data-show-withdrawn" => current_component.current_settings.show_withdrawn,
56
62
  "data-show-evaluating" => current_component.current_settings.show_evaluating,
57
- # "data-show-rejected" => current_component.current_settings.show_rejected,
63
+ "data-show-rejected" => current_component.current_settings.show_rejected,
58
64
  "data-markers-data" => [].to_json
59
65
  }
60
66