decidim-decidim_awesome 0.7.0 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +32 -9
  3. data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
  4. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -2
  5. data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
  6. data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
  7. data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
  8. data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
  9. data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
  10. data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +2 -3
  11. data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
  12. data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
  13. data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
  14. data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
  15. data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
  16. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +3 -2
  17. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
  18. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +52 -56
  19. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +2 -2
  20. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +1 -1
  21. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +33 -24
  22. data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +14 -2
  23. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +18 -4
  24. data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
  25. data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
  26. data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
  27. data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +5 -1
  28. data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +0 -1
  29. data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
  30. data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
  31. data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +15 -4
  32. data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
  33. data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
  34. data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
  35. data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +12 -0
  36. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
  37. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +0 -1
  38. data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
  39. data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
  40. data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
  41. data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
  42. data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
  43. data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
  44. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
  45. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
  46. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
  47. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
  48. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
  49. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
  50. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
  51. data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
  52. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +1 -0
  53. data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
  54. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +31 -18
  55. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
  56. data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
  57. data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
  58. data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
  59. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +39 -0
  60. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
  61. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
  62. data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
  63. data/app/helpers/decidim/decidim_awesome/map_helper.rb +67 -16
  64. data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
  65. data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
  66. data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
  67. data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
  68. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
  69. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +1 -1
  70. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
  71. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
  72. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
  73. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
  74. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
  75. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
  76. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -7
  77. data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
  78. data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
  79. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +0 -2
  80. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
  81. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  82. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
  83. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
  84. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +4 -0
  85. data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
  86. data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
  87. data/app/views/v0.23/layouts/decidim/_head.html.erb +1 -1
  88. data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +1 -1
  89. data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
  90. data/app/views/v0.24/layouts/decidim/_head.html.erb +2 -2
  91. data/app/views/v0.24/layouts/decidim/admin/_header.html.erb +2 -2
  92. data/config/locales/ca.yml +62 -3
  93. data/config/locales/cs.yml +62 -3
  94. data/config/locales/en.yml +90 -11
  95. data/config/locales/es.yml +61 -2
  96. data/config/locales/eu.yml +63 -4
  97. data/config/locales/fr.yml +62 -3
  98. data/config/locales/it.yml +284 -0
  99. data/config/locales/ja.yml +284 -0
  100. data/config/locales/nl.yml +62 -3
  101. data/config/locales/sv.yml +62 -3
  102. data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
  103. data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
  104. data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
  105. data/lib/decidim/decidim_awesome/checksums.yml +17 -4
  106. data/lib/decidim/decidim_awesome/config.rb +53 -6
  107. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
  108. data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
  109. data/lib/decidim/decidim_awesome/engine.rb +62 -6
  110. data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
  111. data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
  112. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
  113. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
  114. data/lib/decidim/decidim_awesome/version.rb +1 -1
  115. data/lib/decidim/decidim_awesome.rb +41 -8
  116. data/vendor/assets/javascripts/delta.min.js +405 -0
  117. data/vendor/assets/javascripts/delta.min.js.map +1 -0
  118. data/vendor/assets/javascripts/europa.min.js +4 -0
  119. data/vendor/assets/javascripts/form-builder.min.js +19 -0
  120. data/vendor/assets/javascripts/form-render.min.js +19 -0
  121. data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
  122. data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
  123. data/vendor/assets/javascripts/select2.js +6147 -0
  124. data/vendor/assets/langs/en-US.lang +110 -0
  125. data/vendor/assets/stylesheets/inscrybmde.min.scss +14 -0
  126. data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
  127. data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
  128. data/vendor/assets/stylesheets/select2.css +515 -0
  129. metadata +68 -27
  130. data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
  131. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -3
  132. data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
  133. data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
  134. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
  135. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -58
  136. data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
  137. data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
@@ -80,7 +80,7 @@
80
80
  result.component.proposals.edges.forEach((element) => {
81
81
  if(!element.node) return;
82
82
 
83
- if(element.node.coordinates) {
83
+ if(element.node.coordinates && element.node.coordinates.latitude && element.node.coordinates.longitude) {
84
84
  element.node.link = component.url + '/proposals/' + element.node.id;
85
85
  createMarker(element.node, callback);
86
86
  }
@@ -1,48 +1,57 @@
1
1
  //= require jquery.truncate
2
2
 
3
3
  ((exports) => {
4
+ const $ = exports.$; // eslint-disable-line
5
+
4
6
  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];
7
+ if(string) {
8
+ const parts = string.split(",")
9
+ if (parts.length >= 2) {
10
+ const lat = parseFloat(parts[0]);
11
+ const lng = parseFloat(parts[1]);
12
+ if(lat && lng) {
13
+ return [lat, lng];
14
+ }
11
15
  }
12
16
  }
13
17
  return null
14
18
  };
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")
19
+ const options = () => {
20
+ return {
21
+ length: $("#awesome-map").data("truncate") || 255,
22
+ center: sanitizeCenter($("#awesome-map").data("map-center")),
23
+ zoom: $("#awesome-map").data("map-zoom"),
24
+ menu: {
25
+ amendments: $("#awesome-map").data("menu-amendments"),
26
+ meetings: $("#awesome-map").data("menu-meetings"),
27
+ hashtags: $("#awesome-map").data("menu-hashtags")
28
+ }
24
29
  }
25
30
  };
26
31
 
27
32
  const truncate = (string) => {
28
- return $.truncate(string, options);
33
+ return $.truncate(string, options());
29
34
  };
30
35
 
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")
36
+ const show = () => {
37
+ return {
38
+ withdrawn: $("#awesome-map").data("show-withdrawn"),
39
+ accepted: $("#awesome-map").data("show-accepted"),
40
+ evaluating: $("#awesome-map").data("show-evaluating"),
41
+ notAnswered: $("#awesome-map").data("show-not-answered"),
42
+ rejected: $("#awesome-map").data("show-rejected")
43
+ }
37
44
  };
38
45
 
39
- const collapsedMenu = $("#awesome-map").data("collapsed");
40
- const components = $("#awesome-map").data("components");
46
+ const hideControls = () => $("#awesome-map").data("hide-controls");
47
+ const collapsedMenu = () => $("#awesome-map").data("collapsed");
48
+ const components = () => $("#awesome-map").data("components");
41
49
 
42
50
  exports.AwesomeMap = exports.AwesomeMap || {};
43
51
  exports.AwesomeMap.truncate = truncate;
44
52
  exports.AwesomeMap.options = options;
45
53
  exports.AwesomeMap.show = show;
46
54
  exports.AwesomeMap.collapsedMenu = collapsedMenu;
55
+ exports.AwesomeMap.hideControls = hideControls;
47
56
  exports.AwesomeMap.components = components;
48
57
  })(window);
@@ -4,6 +4,7 @@
4
4
  // = require inline-attachment.js
5
5
  // = require codemirror-4.inline-attachment.js
6
6
  // = require jquery.inline-attachment.js
7
+ // = require europa.min.js
7
8
  // = require_self
8
9
 
9
10
  ((exports) => {
@@ -117,17 +118,23 @@
117
118
  };
118
119
 
119
120
  const createMarkdownEditor = (container) => {
120
- $(container).hide();
121
121
  const t = window.DecidimAwesome.texts["drag_and_drop_image"];
122
122
  const token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
123
123
  const $input = $(container).siblings('input[type="hidden"]');
124
+ const $faker = $('<input type="hidden" name="faker-inscrybmde">');
125
+ const $form = $(container).closest('form');
126
+ const europa = new Europa();
127
+ $faker.val(europa.convert($input.val()));
128
+ $faker.insertBefore($(container));
129
+ $(container).hide();
124
130
  const inscrybmde = new InscrybMDE({
125
- element: $input[0],
131
+ element: $faker[0],
126
132
  spellChecker: false,
127
133
  renderingConfig: {
128
134
  codeSyntaxHighlighting: true
129
135
  }
130
136
  });
137
+ $faker[0].InscrybMDE = inscrybmde;
131
138
 
132
139
  // Allow image upload
133
140
  if(window.DecidimAwesome.allow_images_in_markdown_editor) {
@@ -139,6 +146,11 @@
139
146
  extraHeaders: { "X-CSRF-Token": token }
140
147
  });
141
148
  }
149
+
150
+ // convert to html on submit
151
+ $form.on("submit", () => {
152
+ $input.val(inscrybmde.markdown(inscrybmde.value()));
153
+ });
142
154
  };
143
155
 
144
156
  const quillEditor = () => {
@@ -4,6 +4,8 @@
4
4
  // = require inline-attachment.js
5
5
  // = require codemirror-4.inline-attachment.js
6
6
  // = require jquery.inline-attachment.js
7
+ // = require europa.min.js
8
+ // = require decidim/editor/linebreak_module.js
7
9
  // = require_self
8
10
 
9
11
  ((exports) => {
@@ -109,7 +111,7 @@
109
111
  });
110
112
  container.dispatchEvent(event);
111
113
 
112
- if (text === "\n") {
114
+ if (text === "\n" || text === "\n\n") {
113
115
  $input.val("");
114
116
  } else {
115
117
  $input.val(quill.root.innerHTML);
@@ -118,7 +120,7 @@
118
120
 
119
121
  if(addImage) {
120
122
  const t = window.DecidimAwesome.texts["drag_and_drop_image"];
121
- $(container).after(`<p class="help-text" style="margin-top:-1.5rem;">${t}</p>`);
123
+ $(container).after(`<p class="help-text">${t}</p>`);
122
124
  }
123
125
 
124
126
  // After editor is ready, linebreak_module deletes two extraneous new lines
@@ -128,17 +130,23 @@
128
130
  };
129
131
 
130
132
  const createMarkdownEditor = (container) => {
131
- $(container).hide();
132
133
  const t = window.DecidimAwesome.texts["drag_and_drop_image"];
133
134
  const token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
134
135
  const $input = $(container).siblings('input[type="hidden"]');
136
+ const $faker = $('<input type="hidden" name="faker-inscrybmde">');
137
+ const $form = $(container).closest('form');
138
+ const europa = new Europa();
139
+ $faker.val(europa.convert($input.val()));
140
+ $faker.insertBefore($(container));
141
+ $(container).hide();
135
142
  const inscrybmde = new InscrybMDE({
136
- element: $input[0],
143
+ element: $faker[0],
137
144
  spellChecker: false,
138
145
  renderingConfig: {
139
146
  codeSyntaxHighlighting: true
140
147
  }
141
148
  });
149
+ $faker[0].InscrybMDE = inscrybmde;
142
150
 
143
151
  // Allow image upload
144
152
  if(window.DecidimAwesome.allow_images_in_markdown_editor) {
@@ -150,6 +158,12 @@
150
158
  extraHeaders: { "X-CSRF-Token": token }
151
159
  });
152
160
  }
161
+
162
+ // convert to html on submit
163
+ $form.on("submit", () => {
164
+ // e.preventDefault();
165
+ $input.val(inscrybmde.markdown(inscrybmde.value()));
166
+ });
153
167
  };
154
168
 
155
169
  const quillEditor = () => {
@@ -0,0 +1,24 @@
1
+ // = require_self
2
+
3
+ /**
4
+ * When switching tabs in i18n fields, autofocus on the markdown if exists
5
+ */
6
+ $(() => {
7
+ // Event launched by foundation
8
+ $("[data-tabs]").on("change.zf.tabs", (event) => {
9
+ const $container = $(event.target).closest(".label--tabs").next(".tabs-content").find(".tabs-panel.is-active");
10
+ // fix inscrybemde if present
11
+ let $input = $container.find('[name="faker-inscrybmde"]');
12
+ if ($input.length > 0) {
13
+ $input[0].InscrybMDE.codemirror.refresh();
14
+ }
15
+ // fix custom fields if present
16
+ $input = $container.find(".proposal_custom_field:first");
17
+ if($input.length > 0) {
18
+ // saves current data to the hidden field for the lang
19
+ DecidimAwesome.FormRenderBuilder.storeData();
20
+ // init the current language
21
+ DecidimAwesome.FormRenderBuilder.init($input);
22
+ }
23
+ });
24
+ });
@@ -0,0 +1,211 @@
1
+ // = require form-render.min
2
+ // = require decidim/decidim_awesome/forms/rich_text_plugin
3
+
4
+ class CustomFieldsBuilder { // eslint-disable-line no-unused-vars
5
+ constructor(container_selector) {
6
+ this.container_selector = container_selector || ".proposal_custom_field:last";
7
+ this.lang = this.getLang($("html").attr("lang"));
8
+ }
9
+
10
+ getLang(lang) {
11
+ const langs = {
12
+ // ar: 'ar-SA', // Not in decidim yet
13
+ 'ar': 'ar-TN',
14
+ 'ca': 'ca-ES',
15
+ 'cs': 'cs-CZ',
16
+ 'da': 'da-DK',
17
+ 'de': 'de-DE',
18
+ 'el': 'el-GR',
19
+ 'en': 'en-US',
20
+ 'es': 'es-ES',
21
+ 'fa': 'fa-IR',
22
+ 'fi': 'fi-FI',
23
+ 'fr': 'fr-FR',
24
+ 'he': 'he-IL',
25
+ 'hu': 'hu-HU',
26
+ 'it': 'it-IT',
27
+ 'ja': 'ja-JP',
28
+ 'my': 'my-MM',
29
+ 'nb': 'nb-NO',
30
+ 'nl': 'nl-NL',
31
+ 'pl': 'pl-PL',
32
+ 'pt': 'pt-BR',
33
+ 'qz': 'qz-MM',
34
+ 'ro': 'ro-RO',
35
+ 'ru': 'ru-RU',
36
+ 'sl': 'sl-SI',
37
+ 'th': 'th-TH',
38
+ 'tr': 'tr-TR',
39
+ 'uk': 'uk-UA',
40
+ 'vi': 'vi-VN',
41
+ 'zh-TW': 'zh-TW',
42
+ 'zh': 'zh-CN'
43
+ };
44
+ if(langs[lang]) {
45
+ return langs[lang];
46
+ }
47
+ if(langs[lang.substr(0, 2)]) {
48
+ return langs[lang.substr(0, 2)];
49
+ }
50
+ return 'en-US';
51
+ }
52
+
53
+ /*
54
+ * Creates an XML document with a subset of html-compatible dl/dd/dt elements
55
+ * to store the custom fields answers
56
+ */
57
+ dataToXML(data) {
58
+ const doc = $.parseXML("<xml/>");
59
+ const xml = doc.getElementsByTagName("xml")[0];
60
+ const dl = doc.createElement("dl");
61
+ let key, dt, dd, div, val, text, label, l;
62
+ xml.appendChild(dl);
63
+ $(dl).attr("class", "decidim_awesome-custom_fields");
64
+ $(dl).attr("data-generator", "decidim_awesome");
65
+ $(dl).attr("data-version", window.DecidimAwesome.version);
66
+ for (key in data) {
67
+ // console.log("get the data!", key, data[key]);
68
+ // Richtext plugin does not saves userdata, so we get it from the hidden input
69
+ if(data[key].type == "textarea" && data[key].subtype == "richtext") {
70
+ data[key].userData = [$(`#${data[key].name}-input`).val()];
71
+ }
72
+ if (data[key].userData && data[key].userData.length) {
73
+ dt = doc.createElement("dt");
74
+ $(dt).text(data[key].label);
75
+ $(dt).attr("name", data[key].name);
76
+ dd = doc.createElement("dd");
77
+ // console.log("data for", key, data[key].name, data[key])
78
+ for(val in data[key].userData) {
79
+ div = doc.createElement("div");
80
+ label = data[key].userData[val];
81
+ text = null;
82
+ if(data[key].values) {
83
+ l = data[key].values.find((v) => v["value"] == data[key].userData[val]);
84
+ if(l) {
85
+ text = label;
86
+ label = l.label;
87
+ }
88
+ } else if(data[key].type == "date" && label) {
89
+ l = new Date(label).toLocaleDateString();
90
+ if(l) {
91
+ text = label;
92
+ label = l;
93
+ }
94
+ }
95
+ // console.log("userData", text, "label", label, 'key', key, 'data', data)
96
+ if(data[key].type == "textarea" && data[key].subtype == "richtext") {
97
+ $(div).html(label);
98
+ } else {
99
+ $(div).text(label);
100
+ }
101
+ if(text) {
102
+ $(div).attr("alt", text);
103
+ }
104
+ dd.appendChild(div);
105
+ }
106
+ $(dd).attr("id", data[key].name);
107
+ $(dd).attr("name", data[key].type);
108
+ dl.appendChild(dt);
109
+ dl.appendChild(dd);
110
+ }
111
+ }
112
+ return xml.outerHTML;
113
+ }
114
+
115
+ fixBuggyFields() {
116
+ if(!this.$container) {
117
+ return false;
118
+ }
119
+ /**
120
+ * Hack to fix required checkboxes being reset
121
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/82
122
+ */
123
+ this.$container.find('.formbuilder-checkbox-group').each((_key, group) => {
124
+ const inputs = $('.formbuilder-checkbox input', group);
125
+ const data = this.spec.find((a) => a.type=="checkbox-group");
126
+ let values = data.userData;
127
+ if(!inputs.length || !data || !values) {
128
+ return;
129
+ }
130
+
131
+ inputs.each((_key, input) => {
132
+ let index = values.indexOf(input.value);
133
+ if(index >= 0) {
134
+ values.splice(index, 1)
135
+ // setting checked=true do not makes the browser aware that the form is valid if the field is required
136
+ if(!input.checked)
137
+ $(input).click();
138
+ } else {
139
+ if(input.checked)
140
+ $(input).click();
141
+ }
142
+ });
143
+
144
+ // Fill "other" option
145
+ const other_option = $('.other-option', inputs.parent())[0];
146
+ const other_val = $('.other-val', inputs.parent())[0];
147
+ const other_text = values.join(" ");
148
+
149
+ if (other_option) {
150
+ if (other_text) {
151
+ other_option.checked = true;
152
+ other_option.value = other_text;
153
+ other_val.value = other_text;
154
+ } else {
155
+ other_option.checked = false;
156
+ other_option.value = '';
157
+ other_val.value = '';
158
+ }
159
+ }
160
+ });
161
+ /**
162
+ * Hack to fix required radio buttons "other" value
163
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/133
164
+ */
165
+ this.$container.find('.formbuilder-radio input.other-val').on('input', (input) => {
166
+ const $input = $(input.currentTarget);
167
+ const $group = $input.closest('.formbuilder-radio-group');
168
+ $group.find("input").each((_key, radio) => {
169
+ const name = $(radio).attr('name');
170
+ if(name && name.endsWith('[]')) {
171
+ $(radio).attr('name', name.slice(0, -2));
172
+ }
173
+ });
174
+ });
175
+ }
176
+
177
+ // Saves xml to the hidden input
178
+ storeData() {
179
+ if(!this.$container) {
180
+ return false;
181
+ }
182
+ const $form = this.$container.closest("form");
183
+ const $body = $form.find('input[name="' + this.$element.data("name") +'"]');
184
+ if($body.length && this.instance) {
185
+ this.spec = this.instance.userData;
186
+ $body.val(this.dataToXML(this.spec));
187
+ this.$element.data("spec", this.spec);
188
+ }
189
+ // console.log("storeData", this.spec, "xml", $body.val());
190
+ }
191
+
192
+ init($element) {
193
+ this.$element = $element;
194
+ this.spec = $element.data("spec");
195
+ if(!this.$container) {
196
+ this.$container = $(this.container_selector);
197
+ }
198
+ // console.log("init", $element, "data", data)
199
+ // TODO: save current data to the hidden field
200
+ // always use the last field (in case of multilang tabs we only render one form due a limitation of the library to handle several instances)
201
+ this.instance = this.$container.formRender({
202
+ i18n: {
203
+ locale: this.lang,
204
+ location: 'https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/'
205
+ },
206
+ formData: this.spec,
207
+ render: true
208
+ });
209
+ this.fixBuggyFields();
210
+ }
211
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ *
3
+ * NOTE: For some reason, this seems to throw an error while transpiling
4
+ * For this reason a rich_text_plugin.js is provided using the online transpiler https://babeljs.io/repl
5
+ * Hopefully, this situation will change when webpacker is updated in the v0.25 of Decidim
6
+ *
7
+ * Decidim rich text editor control plugin
8
+ * Renders standard Decidim WYSIWYG editor
9
+ *
10
+ * Registers Decidim Richtext as a subtype for the textarea control
11
+ */
12
+
13
+ // configure the class for runtime loading
14
+ if (!window.fbControls) window.fbControls = []
15
+ window.fbControls.push(function(controlClass, allControlClasses) {
16
+ const controlTextarea = allControlClasses.textarea
17
+ /**
18
+ * DecidimRichtext control class
19
+ *
20
+ * NOTE: I haven't found a way to set the userData value using this plugin
21
+ * For this reason the value of the field must be collected manually
22
+ * from the hidden input name same as the field with the suffix '-input'
23
+ */
24
+ class controlRichtext extends controlTextarea {
25
+ /**
26
+ * Class configuration - return the icons & label related to this control
27
+ * @returndefinition object
28
+ */
29
+ static get definition() {
30
+ return {
31
+ icon: '📝',
32
+ i18n: {
33
+ default: 'Rich Text Editor'
34
+ },
35
+ }
36
+ }
37
+
38
+ /**
39
+ * configure the richtext editor requirements
40
+ */
41
+ configure() {
42
+ window.fbEditors.richtext = {};
43
+ }
44
+
45
+ /**
46
+ * build a div DOM element & convert to a richtext editor
47
+ * @return {DOMElement} DOM Element to be injected into the form.
48
+ */
49
+ build() {
50
+ const { value, userData, ...attrs } = this.config;
51
+
52
+ // hidden input for storing the current HTML value of the div
53
+ this.inputId = this.id + '-input'
54
+ this.input = this.markup('input', null, {
55
+ name: name,
56
+ id: this.inputId,
57
+ type: 'hidden',
58
+ value: (userData && userData[0]) || value
59
+ });
60
+
61
+ const css = this.markup(
62
+ 'style',
63
+ `
64
+ #${attrs.id} { height: auto; padding-left: 0; padding-right: 0; }
65
+ #${attrs.id} div.ql-container { height: ${attrs.rows || 1}rem; }
66
+ #${attrs.id} p.help-text { margin-top: .5rem; }
67
+ `,
68
+ { type: 'text/css' }
69
+ );
70
+ // console.log("build value", value, "userData", userData, "attrs", attrs, attrs.id);
71
+ this.wrapper = this.markup('div', null, attrs);
72
+ return this.markup('div', [css, this.input, this.wrapper], attrs);
73
+ }
74
+
75
+ /**
76
+ * When the element is rendered into the DOM, execute the following code to initialise it
77
+ * @param {Object} evt - event
78
+ */
79
+ onRender(evt) {
80
+ // const value = this.config.value || '';
81
+ if (window.fbEditors.richtext[this.id]) {
82
+ // console.log("todo destroy", window.fbEditors.richtext[this.id]);
83
+ // window.fbEditors.richtext[this.id].richtext('destroy')
84
+ }
85
+
86
+ window.fbEditors.quill[this.id] = {};
87
+ const editor = window.fbEditors.quill[this.id];
88
+ // createQuillEditor does all the job to update the hidden input wrapper
89
+ editor.instance = window.Decidim.createQuillEditor(this.wrapper);
90
+ // editor.data = new Delta();
91
+ // if (value) {
92
+ // editor.instance.setContents(window.JSON.parse(this.parsedHtml(value)));
93
+ // }
94
+ // editor.instance.on('text-change', function(delta) {
95
+ // console.log("text-change", "delta", delta, "editor", editor);
96
+ // // // editor.data = editor.data.compose(delta);
97
+ // });
98
+
99
+ // console.log("render! editor", editor, "this", this, "value", value);
100
+ return evt;
101
+ }
102
+ }
103
+
104
+ // register Decidim richtext as a richtext control
105
+ controlTextarea.register('richtext', controlRichtext, 'textarea');
106
+ })
@@ -1,3 +1,7 @@
1
1
  // = require decidim/decidim_awesome/admin/constraints
2
- // = require decidim/decidim_awesome/admin/codemirror
3
2
  // = require decidim/decidim_awesome/editors/legacy_quill_editor
3
+ // = require decidim/decidim_awesome/admin/legacy_form_builder
4
+ // = require decidim/decidim_awesome/editors/tabs_focus
5
+ // = require decidim/decidim_awesome/admin/codemirror
6
+ // = require decidim/decidim_awesome/admin/user_picker.js
7
+ // = require decidim/decidim_awesome/admin/auto_edit.js
@@ -1,4 +1,3 @@
1
1
  // = require decidim/decidim_awesome/proposals/images
2
2
  // = require decidim/decidim_awesome/editors/legacy_quill_editor
3
- // = require decidim/decidim_awesome/editors/markdown_view
4
3
  // = require decidim/decidim_awesome/forms/autosave
@@ -0,0 +1,21 @@
1
+ // = require decidim/decidim_awesome/forms/custom_fields_builder
2
+ // = require_self
3
+
4
+ window.DecidimAwesome.FormRenderBuilder = window.DecidimAwesome.FormRenderBuilder || new CustomFieldsBuilder();
5
+
6
+ $(() => {
7
+ // use admin multilang specs if exists
8
+ let $el = $("proposal_custom_field:first", ".tabs-title.is-active");
9
+ $el = $el.length ? $el : $(".proposal_custom_field:first");
10
+ DecidimAwesome.FormRenderBuilder.init($el);
11
+
12
+ DecidimAwesome.FormRenderBuilder.$container.closest("form").on("submit", (e) => {
13
+ if(e.target.checkValidity()) {
14
+ // save current editor
15
+ DecidimAwesome.FormRenderBuilder.storeData();
16
+ } else {
17
+ e.preventDefault();
18
+ e.target.reportValidity();
19
+ }
20
+ });
21
+ });
@@ -0,0 +1,15 @@
1
+ input.awesome-auto-edit {
2
+ display: inline-block;
3
+ width: auto;
4
+ margin: 0 2px;
5
+ padding: 1px;
6
+ line-height: 0;
7
+ height: auto;
8
+ }
9
+ span.awesome-auto-edit {
10
+ padding: 0 4px;
11
+ background-color: #f0f0f0;
12
+ border-radius: 5px;
13
+ margin: 0;
14
+ font-weight: 600;
15
+ }
@@ -1,16 +1,27 @@
1
1
  .awesome-edit-config{
2
- .scoped-style{
3
- .form-error {
2
+ .scoped_styles_container,
3
+ .proposal_custom_fields_container{
4
+ .form-error{
4
5
  margin: 0;
5
6
  }
7
+
6
8
  >.CodeMirror{
7
- border-top: .5em solid #f6f6f6;
8
- border-right: .5em solid #f6f6f6;
9
+ border-top-left-radius: 5px;
10
+ border-top-right-radius: 5px;
11
+ border-top: .5em solid #e0e0e0;
12
+ border-right: .5em solid #e0e0e0;
13
+ border-bottom: .5em solid #e0e0e0;
9
14
  min-height: 6em;
10
15
  height: auto;
11
16
  max-height: 40em;
12
17
  resize: vertical;
13
18
  overflow: vertical !important;
19
+
20
+ >.CodeMirror-scroll{
21
+ >.CodeMirror-gutters{
22
+ background: #e0e0e0;
23
+ }
24
+ }
14
25
  }
15
26
  }
16
27
  }
@@ -28,10 +28,22 @@
28
28
  &.component_id{
29
29
  background-color: #ee449c;
30
30
  }
31
+
32
+ &.constraint{
33
+ &-none{
34
+ background-color: #ff3000;
35
+ }
36
+ }
31
37
  }
32
38
 
33
39
  a{
34
40
  margin-left: 1rem;
35
41
  }
42
+
43
+ &.inactive{
44
+ .label:not(.constraint-none){
45
+ filter: saturate(10%);
46
+ }
47
+ }
36
48
  }
37
49
  }