decidim-decidim_awesome 0.6.6 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +93 -36
  3. data/Rakefile +11 -12
  4. data/app/cells/decidim/decidim_awesome/content_blocks/map/error.erb +11 -0
  5. data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +14 -0
  6. data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +65 -0
  7. data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +65 -0
  8. data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
  9. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
  10. data/app/commands/decidim/decidim_awesome/admin/create_custom_redirect.rb +51 -0
  11. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
  12. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
  13. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
  14. data/app/commands/decidim/decidim_awesome/admin/destroy_custom_redirect.rb +47 -0
  15. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
  16. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
  17. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
  18. data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
  19. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +5 -1
  20. data/app/commands/decidim/decidim_awesome/admin/update_custom_redirect.rb +49 -0
  21. data/app/commands/decidim/decidim_awesome/create_editor_image.rb +12 -5
  22. data/app/controllers/concerns/decidim/decidim_awesome/not_found_redirect.rb +58 -0
  23. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +15 -22
  24. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +41 -20
  25. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
  26. data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +91 -0
  27. data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +7 -10
  28. data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
  29. data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
  30. data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
  31. data/app/controllers/decidim/decidim_awesome/blank_component_controller.rb +19 -0
  32. data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +2 -3
  33. data/app/controllers/decidim/decidim_awesome/iframe_component/iframe_controller.rb +1 -1
  34. data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +2 -9
  35. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +52 -0
  36. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
  37. data/app/forms/decidim/decidim_awesome/admin/custom_redirect_form.rb +45 -0
  38. data/app/forms/decidim/decidim_awesome/editor_image_form.rb +3 -2
  39. data/app/forms/decidim/decidim_awesome/proposals/proposal_wizard_create_step_form_override.rb +38 -0
  40. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +32 -15
  41. data/app/helpers/decidim/decidim_awesome/admin/system_checker_helpers.rb +36 -0
  42. data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
  43. data/app/helpers/decidim/decidim_awesome/map_helper.rb +76 -57
  44. data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
  45. data/app/jobs/decidim/decidim_awesome/migrate_legacy_images_job.rb +106 -0
  46. data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
  47. data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
  48. data/app/models/decidim/decidim_awesome/editor_image.rb +4 -9
  49. data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
  50. data/app/packs/entrypoints/decidim_admin_decidim_awesome.js +5 -0
  51. data/app/packs/entrypoints/decidim_admin_decidim_awesome.scss +1 -0
  52. data/app/packs/entrypoints/decidim_admin_decidim_awesome_custom_fields.js +2 -0
  53. data/app/packs/entrypoints/decidim_decidim_awesome.js +9 -0
  54. data/app/packs/entrypoints/decidim_decidim_awesome.scss +1 -0
  55. data/app/packs/entrypoints/decidim_decidim_awesome_admin_form_exit_warn.js +1 -0
  56. data/app/packs/entrypoints/decidim_decidim_awesome_custom_fields.js +1 -0
  57. data/app/packs/entrypoints/decidim_decidim_awesome_iframe.scss +1 -0
  58. data/app/packs/entrypoints/decidim_decidim_awesome_map.js +5 -0
  59. data/app/packs/entrypoints/decidim_decidim_awesome_map.scss +1 -0
  60. data/app/{assets → packs}/images/decidim/decidim_awesome/platoniq-logo.png +0 -0
  61. data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +82 -0
  62. data/app/packs/src/decidim/decidim_awesome/admin/check_redirections.js +48 -0
  63. data/app/packs/src/decidim/decidim_awesome/admin/codemirror.js +14 -0
  64. data/app/packs/src/decidim/decidim_awesome/admin/constraints.js +55 -0
  65. data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +77 -0
  66. data/app/{assets/javascripts/decidim/decidim_awesome/admin/form_exit_warn.js.es6 → packs/src/decidim/decidim_awesome/admin/form_exit_warn.js} +0 -2
  67. data/app/packs/src/decidim/decidim_awesome/admin/user_picker.js +24 -0
  68. data/app/packs/src/decidim/decidim_awesome/awesome_admin.js +23 -0
  69. data/app/packs/src/decidim/decidim_awesome/awesome_application.js +17 -0
  70. data/app/{assets/javascripts/decidim/decidim_awesome/awesome_map/api_fetcher.js.es6 → packs/src/decidim/decidim_awesome/awesome_map/api/api_fetcher.js} +1 -15
  71. data/app/packs/src/decidim/decidim_awesome/awesome_map/api/fetcher.js +131 -0
  72. data/app/packs/src/decidim/decidim_awesome/awesome_map/api/meetings_fetcher.js +59 -0
  73. data/app/packs/src/decidim/decidim_awesome/awesome_map/api/proposals_fetcher.js +52 -0
  74. data/app/packs/src/decidim/decidim_awesome/awesome_map/awesome_map.js +130 -0
  75. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +112 -0
  76. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/meetings_controller.js +31 -0
  77. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +88 -0
  78. data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +221 -0
  79. data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +51 -0
  80. data/app/packs/src/decidim/decidim_awesome/editors/editor.js +190 -0
  81. data/app/packs/src/decidim/decidim_awesome/editors/tabs_focus.js +22 -0
  82. data/app/{assets/javascripts/decidim/decidim_awesome/forms/autosave.js.es6 → packs/src/decidim/decidim_awesome/forms/autosave.js} +20 -17
  83. data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +207 -0
  84. data/app/packs/src/decidim/decidim_awesome/forms/rich_text_plugin.js +107 -0
  85. data/app/packs/src/decidim/decidim_awesome/proposals/custom_fields.js +22 -0
  86. data/app/packs/src/decidim/decidim_awesome/proposals/images.js +25 -0
  87. data/{vendor/assets/javascripts → app/packs/src/vendor}/image-resize.min.js +0 -0
  88. data/{vendor/assets/javascripts → app/packs/src/vendor}/image-upload.min.js +0 -0
  89. data/app/packs/src/vendor/jquery.truncate.js +105 -0
  90. data/app/packs/src/vendor/leaflet.featuregroup.subgroup.js +184 -0
  91. data/app/packs/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +16 -0
  92. data/app/packs/stylesheets/decidim/decidim_awesome/admin/check_redirections.scss +28 -0
  93. data/app/packs/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +29 -0
  94. data/app/{assets → packs}/stylesheets/decidim/decidim_awesome/admin/constraints.scss +21 -9
  95. data/app/packs/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +93 -0
  96. data/app/packs/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +41 -0
  97. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_admin.scss +71 -0
  98. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_application.scss +19 -0
  99. data/app/{assets → packs}/stylesheets/decidim/decidim_awesome/awesome_iframe/iframe.scss +3 -3
  100. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +176 -0
  101. data/app/{assets → packs}/stylesheets/decidim/decidim_awesome/editors/markdown_editor.scss +6 -4
  102. data/app/packs/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +58 -0
  103. data/app/{assets → packs}/stylesheets/decidim/decidim_awesome/forms/autosave.scss +2 -2
  104. data/app/packs/stylesheets/vendor/select2-foundation-theme.scss +348 -0
  105. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
  106. data/app/presenters/decidim/decidim_awesome/menu_item_presenter_override.rb +25 -0
  107. data/app/presenters/decidim/decidim_awesome/menu_presenter_override.rb +23 -0
  108. data/app/uploaders/decidim/cw/decidim_awesome/image_uploader.rb +26 -0
  109. data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +4 -21
  110. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +28 -22
  111. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
  112. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +3 -3
  113. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
  114. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +1 -3
  115. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
  116. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
  117. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +11 -12
  118. data/app/views/decidim/decidim_awesome/admin/config/_modal.html.erb +1 -1
  119. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +3 -4
  120. data/app/views/decidim/decidim_awesome/admin/constraints/new.html.erb +1 -1
  121. data/app/views/decidim/decidim_awesome/admin/custom_redirects/_form.html.erb +6 -0
  122. data/app/views/decidim/decidim_awesome/admin/custom_redirects/edit.html.erb +13 -0
  123. data/app/views/decidim/decidim_awesome/admin/custom_redirects/index.html.erb +37 -0
  124. data/app/views/decidim/decidim_awesome/admin/custom_redirects/new.html.erb +13 -0
  125. data/app/views/decidim/decidim_awesome/admin/menu_hacks/edit.html.erb +1 -1
  126. data/app/views/decidim/decidim_awesome/admin/menu_hacks/new.html.erb +1 -1
  127. data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +6 -0
  128. data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
  129. data/app/views/decidim/decidim_awesome/iframe_component/iframe/show.html.erb +1 -1
  130. data/app/views/decidim/decidim_awesome/map_component/map/_api_ready.html.erb +3 -0
  131. data/app/views/decidim/decidim_awesome/map_component/map/_map_template.html.erb +68 -0
  132. data/app/views/decidim/decidim_awesome/map_component/map/{error.erb → error.html.erb} +2 -0
  133. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +3 -96
  134. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
  135. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  136. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
  137. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +34 -16
  138. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +6 -1
  139. data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
  140. data/app/views/v0.25/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
  141. data/app/views/{v0.23 → v0.25}/layouts/decidim/_head.html.erb +12 -10
  142. data/app/views/v0.25/layouts/decidim/admin/_header.html.erb +11 -0
  143. data/app/views/v0.26/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
  144. data/app/views/{v0.22 → v0.26}/layouts/decidim/_head.html.erb +18 -10
  145. data/app/views/v0.26/layouts/decidim/admin/_header.html.erb +11 -0
  146. data/config/assets.rb +46 -0
  147. data/config/i18n-tasks.yml +6 -0
  148. data/config/locales/ca.yml +147 -13
  149. data/config/locales/cs.yml +137 -3
  150. data/config/locales/en.yml +170 -11
  151. data/config/locales/es.yml +136 -2
  152. data/config/locales/eu.yml +1 -161
  153. data/config/locales/fr.yml +276 -142
  154. data/config/locales/it.yml +346 -0
  155. data/config/locales/ja.yml +345 -0
  156. data/config/locales/nl.yml +167 -136
  157. data/config/locales/pt-BR.yml +346 -0
  158. data/config/locales/pt-PT.yml +7 -0
  159. data/config/locales/pt.yml +7 -0
  160. data/config/locales/sv.yml +109 -152
  161. data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
  162. data/lib/decidim/decidim_awesome/admin_engine.rb +19 -12
  163. data/lib/decidim/decidim_awesome/awesome.rb +214 -0
  164. data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -17
  165. data/lib/decidim/decidim_awesome/checksums.yml +23 -16
  166. data/lib/decidim/decidim_awesome/config.rb +55 -9
  167. data/lib/decidim/decidim_awesome/content_parsers/editor_images_parser.rb +39 -0
  168. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
  169. data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
  170. data/lib/decidim/decidim_awesome/engine.rb +42 -14
  171. data/lib/decidim/decidim_awesome/iframe_component/admin_engine.rb +23 -0
  172. data/lib/decidim/decidim_awesome/iframe_component/component.rb +6 -6
  173. data/lib/decidim/decidim_awesome/map_component/admin_engine.rb +23 -0
  174. data/lib/decidim/decidim_awesome/map_component/component.rb +13 -6
  175. data/lib/decidim/decidim_awesome/map_component/engine.rb +34 -0
  176. data/lib/decidim/decidim_awesome/menu_hacker.rb +2 -1
  177. data/lib/decidim/decidim_awesome/system_checker.rb +1 -1
  178. data/lib/decidim/decidim_awesome/test/factories.rb +2 -2
  179. data/lib/decidim/decidim_awesome/test/initializer.rb +25 -0
  180. data/lib/decidim/decidim_awesome/test/layouts/decidim/_head.html.erb +30 -2
  181. data/lib/decidim/decidim_awesome/test/layouts/decidim/admin/_header.html.erb +7 -2
  182. data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
  183. data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +18 -0
  184. data/lib/decidim/decidim_awesome/test/shared_examples/controller_examples.rb +13 -0
  185. data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
  186. data/lib/decidim/decidim_awesome/test/shared_examples/custom_redirects_contexts.rb +47 -0
  187. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
  188. data/lib/decidim/decidim_awesome/test/shared_examples/menu_hack_contexts.rb +0 -17
  189. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +420 -0
  190. data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +202 -0
  191. data/lib/decidim/decidim_awesome/version.rb +2 -2
  192. data/lib/decidim/decidim_awesome.rb +4 -119
  193. data/lib/tasks/decidim_awesome_active_storage_migrations_tasks.rake +37 -0
  194. data/lib/tasks/decidim_awesome_webpacker_tasks.rake +62 -0
  195. metadata +148 -83
  196. data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +0 -3
  197. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +0 -2
  198. data/app/assets/config/decidim_decidim_awesome_manifest.css +0 -5
  199. data/app/assets/config/decidim_decidim_awesome_manifest.js +0 -3
  200. data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
  201. data/app/assets/javascripts/decidim/decidim_awesome/admin/constraints.js.es6 +0 -54
  202. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -2
  203. data/app/assets/javascripts/decidim/decidim_awesome/application.js +0 -4
  204. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/categories.js.es6 +0 -25
  205. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +0 -225
  206. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +0 -82
  207. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +0 -215
  208. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +0 -131
  209. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +0 -94
  210. data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
  211. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +0 -160
  212. data/app/assets/javascripts/decidim/decidim_awesome/proposals/images.js.es6 +0 -25
  213. data/app/assets/stylesheets/decidim/decidim_awesome/admin.scss +0 -49
  214. data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
  215. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/leaflet.scss.erb +0 -9
  216. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +0 -66
  217. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
  218. data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +0 -7
  219. data/app/awesome_overrides/presenters/decidim/menu_presenter_override.rb +0 -39
  220. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -64
  221. data/app/controllers/decidim/decidim_awesome/iframe_component/application_controller.rb +0 -15
  222. data/app/controllers/decidim/decidim_awesome/map_component/application_controller.rb +0 -15
  223. data/app/views/v0.22/layouts/decidim/admin/_header.html.erb +0 -11
  224. data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +0 -12
  225. data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
  226. data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
  227. data/lib/decidim/decidim_awesome/test/themes/css.lvh.me.css +0 -3
  228. data/lib/decidim/decidim_awesome/test/themes/erb.lvh.me.scss.erb +0 -2
  229. data/lib/decidim/decidim_awesome/test/themes/scss.lvh.me.scss +0 -1
  230. data/lib/decidim/decidim_awesome/test/themes/test-theme/body.scss +0 -4
  231. data/vendor/assets/images/layers-2x.png +0 -0
  232. data/vendor/assets/images/layers.png +0 -0
  233. data/vendor/assets/images/marker-icon.png +0 -0
  234. data/vendor/assets/javascripts/codemirror-4.inline-attachment.js +0 -89
  235. data/vendor/assets/javascripts/form-storage.js +0 -824
  236. data/vendor/assets/javascripts/highlight.min.js +0 -44
  237. data/vendor/assets/javascripts/inline-attachment.js +0 -399
  238. data/vendor/assets/javascripts/inscrybmde.min.js +0 -7
  239. data/vendor/assets/javascripts/jquery.inline-attachment.js +0 -66
  240. data/vendor/assets/javascripts/jsrender.min.js +0 -4
  241. data/vendor/assets/javascripts/leaflet.featuregroup.subgroup.js +0 -6
  242. data/vendor/assets/stylesheets/default.min.css +0 -1
  243. data/vendor/assets/stylesheets/foundation.min.css +0 -1
  244. data/vendor/assets/stylesheets/github.min.css +0 -2
  245. data/vendor/assets/stylesheets/inscrybmde.min.css +0 -8
@@ -0,0 +1,190 @@
1
+ /* eslint-disable require-jsdoc */
2
+
3
+ /*
4
+ * Since version 0.25 we follow a different strategy and opt to destroy and override completely the original editor
5
+ * That's because editors are instantiated directly instead of creating a global function to instantiate them
6
+ */
7
+
8
+ import lineBreakButtonHandler from "src/decidim/editor/linebreak_module"
9
+ import InscrybMDE from "inscrybmde"
10
+ import Europa from "europa"
11
+ import "inline-attachment/src/inline-attachment";
12
+ import "inline-attachment/src/codemirror-4.inline-attachment";
13
+ import "inline-attachment/src/jquery.inline-attachment";
14
+ import hljs from "highlight.js";
15
+ import "highlight.js/styles/github.css";
16
+
17
+ // In 0.26 these files come with Decidim in the folder src/decidim/vendor so the awesome one's could be removed
18
+ import "src/vendor/image-resize.min"
19
+ import "src/vendor/image-upload.min"
20
+
21
+ const DecidimAwesome = window.DecidimAwesome || {};
22
+ const quillFormats = ["bold", "italic", "link", "underline", "header", "list", "video", "image", "alt", "break", "width", "style", "code", "blockquote", "indent"];
23
+
24
+ // A tricky way to destroy the quill editor
25
+ export function destroyQuillEditor(container) {
26
+ if (container) {
27
+ const content = $(container).find(".ql-editor").html();
28
+ $(container).html(content);
29
+ $(container).siblings(".ql-toolbar").remove();
30
+ $(container).find("*[class*='ql-']").removeClass((index, class_name) => (class_name.match(/(^|\s)ql-\S+/g) || []).join(" "));
31
+ $(container).removeClass((index, class_name) => (class_name.match(/(^|\s)ql-\S+/g) || []).join(" "));
32
+ if ($(container).next().is("p.help-text")) {
33
+ $(container).next().remove();
34
+ }
35
+ }
36
+ else {
37
+ console.error(`editor [${container}] not exists`);
38
+ }
39
+ }
40
+
41
+ export function createQuillEditor(container) {
42
+ const toolbar = $(container).data("toolbar");
43
+ const disabled = $(container).data("disabled");
44
+
45
+ let quillToolbar = [
46
+ ["bold", "italic", "underline", "linebreak"],
47
+ [{ list: "ordered" }, { list: "bullet" }],
48
+ ["link", "clean"],
49
+ ["code", "blockquote"],
50
+ [{ "indent": "-1"}, { "indent": "+1" }]
51
+ ];
52
+
53
+ let addImage = false;
54
+
55
+ if (toolbar === "full") {
56
+ quillToolbar = [
57
+ [{ header: [2, 3, 4, 5, 6, false] }],
58
+ ...quillToolbar
59
+ ];
60
+ if (DecidimAwesome.allow_images_in_full_editor) {
61
+ quillToolbar.push(["video", "image"]);
62
+ addImage = true;
63
+ } else {
64
+ quillToolbar.push(["video"]);
65
+ }
66
+ } else if (toolbar === "basic") {
67
+ if (DecidimAwesome.allow_images_in_small_editor) {
68
+ quillToolbar.push(["video", "image"]);
69
+ addImage = true;
70
+ } else {
71
+ quillToolbar.push(["video"]);
72
+ }
73
+ } else if (DecidimAwesome.allow_images_in_small_editor) {
74
+ quillToolbar.push(["image"]);
75
+ addImage = true;
76
+ }
77
+
78
+ let modules = {
79
+ linebreak: {},
80
+ toolbar: {
81
+ container: quillToolbar,
82
+ handlers: {
83
+ "linebreak": lineBreakButtonHandler
84
+ }
85
+ }
86
+ };
87
+ const $input = $(container).siblings('input[type="hidden"]');
88
+ container.innerHTML = $input.val() || "";
89
+ const token = $('meta[name="csrf-token"]').attr("content");
90
+ if (addImage) {
91
+ modules.imageResize = {
92
+ modules: ["Resize", "DisplaySize"]
93
+ }
94
+ modules.imageUpload = {
95
+ url: $(container).data("uploadImagesPath") || DecidimAwesome.editor_uploader_path,
96
+ method: "POST",
97
+ name: "image",
98
+ withCredentials: false,
99
+ headers: { "X-CSRF-Token": token },
100
+ callbackOK: (serverResponse, next) => {
101
+ $("div.ql-toolbar").last().removeClass("editor-loading")
102
+ next(serverResponse.url);
103
+ },
104
+ callbackKO: (serverError) => {
105
+ $("div.ql-toolbar").last().removeClass("editor-loading")
106
+ console.error(`Image upload error: ${serverError.message}`);
107
+ },
108
+ checkBeforeSend: (file, next) => {
109
+ $("div.ql-toolbar").last().addClass("editor-loading")
110
+ next(file);
111
+ }
112
+ }
113
+ }
114
+ const quill = new Quill(container, {
115
+ modules: modules,
116
+ formats: quillFormats,
117
+ theme: "snow"
118
+ });
119
+
120
+ if (disabled) {
121
+ quill.disable();
122
+ }
123
+
124
+ quill.on("text-change", () => {
125
+ const text = quill.getText();
126
+
127
+ // Triggers CustomEvent with the cursor position
128
+ // It is required in input_mentions.js
129
+ let event = new CustomEvent("quill-position", {
130
+ detail: quill.getSelection()
131
+ });
132
+ container.dispatchEvent(event);
133
+
134
+ if (text === "\n" || text === "\n\n") {
135
+ $input.val("");
136
+ } else {
137
+ $input.val(quill.root.innerHTML);
138
+ }
139
+ });
140
+ // After editor is ready, linebreak_module deletes two extraneous new lines
141
+ quill.emitter.emit("editor-ready");
142
+
143
+ if (addImage) {
144
+ const text = $(container).data("dragAndDropHelpText") || DecidimAwesome.texts.drag_and_drop_image;
145
+ $(container).after(`<p class="help-text" style="margin-top:-1.5rem;">${text}</p>`);
146
+ }
147
+
148
+ // After editor is ready, linebreak_module deletes two extraneous new lines
149
+ quill.emitter.emit("editor-ready");
150
+
151
+ return quill;
152
+ }
153
+
154
+ export function createMarkdownEditor(container) {
155
+ const t = DecidimAwesome.texts.drag_and_drop_image;
156
+ const token = $('meta[name="csrf-token"]').attr("content");
157
+ const $input = $(container).siblings('input[type="hidden"]');
158
+ const $faker = $('<textarea name="faker-inscrybmde"/>');
159
+ const $form = $(container).closest("form");
160
+ const europa = new Europa();
161
+ $faker.val(europa.convert($input.val()));
162
+ $faker.insertBefore($(container));
163
+ $(container).hide();
164
+ const inscrybmde = new InscrybMDE({
165
+ element: $faker[0],
166
+ spellChecker: false,
167
+ renderingConfig: {
168
+ codeSyntaxHighlighting: true,
169
+ hljs: hljs
170
+ }
171
+ });
172
+ $faker[0].InscrybMDE = inscrybmde;
173
+
174
+ // Allow image upload
175
+ if (DecidimAwesome.allow_images_in_markdown_editor) {
176
+ $(inscrybmde.gui.statusbar).prepend(`<span class="help-text" style="float:left;margin:0;text-align:left;">${t}</span>`);
177
+ inlineAttachment.editors.codemirror4.attach(inscrybmde.codemirror, {
178
+ uploadUrl: DecidimAwesome.editor_uploader_path,
179
+ uploadFieldName: "image",
180
+ jsonFieldName: "url",
181
+ extraHeaders: { "X-CSRF-Token": token }
182
+ });
183
+ }
184
+
185
+ // convert to html on submit
186
+ $form.on("submit", () => {
187
+ // e.preventDefault();
188
+ $input.val(inscrybmde.markdown(inscrybmde.value()));
189
+ });
190
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * When switching tabs in i18n fields, autofocus on the markdown if exists
3
+ */
4
+ $(() => {
5
+ // Event launched by foundation
6
+ $("[data-tabs]").on("change.zf.tabs", (event) => {
7
+ const $container = $(event.target).closest(".label--tabs").next(".tabs-content").find(".tabs-panel.is-active");
8
+ // fix inscrybmde if present
9
+ let $input = $container.find('[name="faker-inscrybmde"]');
10
+ if ($input.length > 0) {
11
+ $input[0].InscrybMDE.codemirror.refresh();
12
+ }
13
+ // fix custom fields if present
14
+ $input = $container.find(".proposal_custom_field:first");
15
+ if ($input.length > 0) {
16
+ // saves current data to the hidden field for the lang
17
+ window.DecidimAwesome.CustomFieldsRenderer.storeData();
18
+ // init the current language
19
+ window.DecidimAwesome.CustomFieldsRenderer.init($input);
20
+ }
21
+ });
22
+ });
@@ -1,5 +1,4 @@
1
- // = require form-storage.js
2
- // = require_self
1
+ import FormStorage from "form-storage"
3
2
 
4
3
  $(() => {
5
4
  window.DecidimAwesome = window.DecidimAwesome || {};
@@ -15,10 +14,10 @@ $(() => {
15
14
 
16
15
  const storeId = `awesome_autosave:${questionnaireId}`;
17
16
  const storeCheckboxesId = `awesome_autosave:checkboxes:${questionnaireId}`;
18
- const $form = $('form.answer-questionnaire');
17
+ const $form = $("form.answer-questionnaire");
19
18
 
20
19
  if (!$form.length) {
21
- if(window.DecidimAwesome.questionnaire_answered) {
20
+ if (window.DecidimAwesome.questionnaire_answered) {
22
21
  // console.log("Questionnaire already answered, remove any data saved");
23
22
  window.localStorage.removeItem(storeId);
24
23
  window.localStorage.removeItem(storeCheckboxesId);
@@ -27,21 +26,25 @@ $(() => {
27
26
  return;
28
27
  }
29
28
 
30
- const store = new FormStorage(`#${$form.attr('id')}`, {
29
+ const store = new FormStorage(`#${$form.attr("id")}`, {
31
30
  name: storeId,
32
31
  ignores: [
33
32
  // '[type="hidden"]',
34
33
  '[name="utf8"]',
35
34
  '[name="authenticity_token"]',
36
- '[disabled]',
35
+ "[disabled]",
37
36
  '[type="checkbox"]' // there are problems with matrix questions
38
- ],
37
+ ]
39
38
  });
40
39
 
41
40
  const showMsg = (msg, error = false, default_time = 700) => {
42
- const time = error ? 5000 : default_time;
43
- const $div = $(`<div class="awesome_autosave-notice${error ? ' error' : ''}">${msg}</div>`)
44
- .appendTo($form);
41
+ const time = error
42
+ ? 5000
43
+ : default_time;
44
+ const $div = $(`<div class="awesome_autosave-notice${error
45
+ ? " error"
46
+ : ""}">${msg}</div>`).
47
+ appendTo($form);
45
48
  setTimeout(() => {
46
49
  $div.fadeOut(500, () => {
47
50
  $div.remove();
@@ -54,7 +57,7 @@ $(() => {
54
57
  return;
55
58
  }
56
59
 
57
- if(window.localStorage.getItem(storeId)) {
60
+ if (window.localStorage.getItem(storeId)) {
58
61
  showMsg(window.DecidimAwesome.texts.autosaved_retrieved, false, 5000);
59
62
  }
60
63
 
@@ -63,14 +66,14 @@ $(() => {
63
66
  // restore checkboxes
64
67
  try {
65
68
  let checkboxes = JSON.parse(window.localStorage.getItem(storeCheckboxesId));
66
- for(let id in checkboxes) {
67
- $("#" + id).prop("checked", checkboxes[id]);
69
+ for (let id in checkboxes) {
70
+ $(`#${id}`).prop("checked", checkboxes[id]);
68
71
  }
69
- } catch(e){
72
+ } catch (e) {
70
73
  console.log("No checkboxes found");
71
74
  }
72
- // fire change items
73
- $form.find('input, textarea, select').change();
75
+ // this trigger the "change" event, it seems that it is too much
76
+ // $form.find('input, textarea, select').change();
74
77
 
75
78
  const save = () => {
76
79
  store.save();
@@ -84,7 +87,7 @@ $(() => {
84
87
  };
85
88
 
86
89
  // save changes when modifications
87
- $form.find('input, textarea, select').on('change', () => {
90
+ $form.find("input, textarea, select").on("change", () => {
88
91
  save();
89
92
  });
90
93
  });
@@ -0,0 +1,207 @@
1
+ require("formBuilder/dist/form-render.min.js")
2
+ import "src/decidim/decidim_awesome/forms/rich_text_plugin"
3
+
4
+ export default class CustomFieldsRenderer { // 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 $dl = $("<dl/>");
59
+ let $dd, $div, $dt, key, l, label, text, val;
60
+ $dl.attr("class", "decidim_awesome-custom_fields");
61
+ $dl.attr("data-generator", "decidim_awesome");
62
+ $dl.attr("data-version", window.DecidimAwesome.version);
63
+ for (key in data) {
64
+ // console.log("get the data!", key, data[key]);
65
+ // Richtext plugin does not saves userdata, so we get it from the hidden input
66
+ if (data[key].type == "textarea" && data[key].subtype == "richtext") {
67
+ data[key].userData = [$(`#${data[key].name}-input`).val()];
68
+ }
69
+ if (data[key].userData && data[key].userData.length) {
70
+ $dt = $("<dt/>");
71
+ $dt.text(data[key].label);
72
+ $dt.attr("name", data[key].name);
73
+ $dd = $("<dd/>");
74
+ // console.log("data for", key, data[key].name, data[key])
75
+ for (val in data[key].userData) {
76
+ $div = $("<div/>");
77
+ label = data[key].userData[val];
78
+ text = null;
79
+ if (data[key].values) {
80
+ l = data[key].values.find((v) => v.value == label);
81
+ if (l) {
82
+ text = label;
83
+ label = l.label;
84
+ }
85
+ } else if (data[key].type == "date" && label) {
86
+ l = new Date(label).toLocaleDateString();
87
+ if (l) {
88
+ text = label;
89
+ label = l;
90
+ }
91
+ }
92
+ // console.log("userData", text, "label", label, 'key', key, 'data', data)
93
+ if (data[key].type == "textarea" && data[key].subtype == "richtext") {
94
+ $div.html(label);
95
+ } else {
96
+ $div.text(label);
97
+ }
98
+ if (text) {
99
+ $div.attr("alt", text);
100
+ }
101
+ $dd.append($div);
102
+ }
103
+ $dd.attr("id", data[key].name);
104
+ $dd.attr("name", data[key].type);
105
+ $dl.append($dt);
106
+ $dl.append($dd);
107
+ }
108
+ }
109
+ return `<xml>${$dl[0].outerHTML}</xml>`;
110
+ }
111
+
112
+ fixBuggyFields() {
113
+ if (!this.$container) {
114
+ return false;
115
+ }
116
+
117
+ /**
118
+ * Hack to fix required checkboxes being reset
119
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/82
120
+ */
121
+ this.$container.find(".formbuilder-checkbox-group").each((_key, group) => {
122
+ const inputs = $(".formbuilder-checkbox input", group);
123
+ const data = this.spec.find((a) => a.type == "checkbox-group");
124
+ let values = data.userData;
125
+ if (!inputs.length || !data || !values) {
126
+ return;
127
+ }
128
+
129
+ inputs.each((_idx, input) => {
130
+ let index = values.indexOf(input.value);
131
+ if (index >= 0) {
132
+ values.splice(index, 1)
133
+ // setting checked=true do not makes the browser aware that the form is valid if the field is required
134
+ if (!input.checked)
135
+ {$(input).click();}
136
+ } else if (input.checked)
137
+ {$(input).click();}
138
+ });
139
+
140
+ // Fill "other" option
141
+ const other_option = $(".other-option", inputs.parent())[0];
142
+ const other_val = $(".other-val", inputs.parent())[0];
143
+ const other_text = values.join(" ");
144
+
145
+ if (other_option) {
146
+ if (other_text) {
147
+ other_option.checked = true;
148
+ other_option.value = other_text;
149
+ other_val.value = other_text;
150
+ } else {
151
+ other_option.checked = false;
152
+ other_option.value = "";
153
+ other_val.value = "";
154
+ }
155
+ }
156
+ });
157
+
158
+ /**
159
+ * Hack to fix required radio buttons "other" value
160
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/133
161
+ */
162
+ this.$container.find(".formbuilder-radio input.other-val").on("input", (input) => {
163
+ const $input = $(input.currentTarget);
164
+ const $group = $input.closest(".formbuilder-radio-group");
165
+ $group.find("input").each((_key, radio) => {
166
+ const name = $(radio).attr("name");
167
+ if (name && name.endsWith("[]")) {
168
+ $(radio).attr("name", name.slice(0, -2));
169
+ }
170
+ });
171
+ });
172
+ }
173
+
174
+ // Saves xml to the hidden input
175
+ storeData() {
176
+ if (!this.$container) {
177
+ return false;
178
+ }
179
+ const $form = this.$container.closest("form");
180
+ const $body = $form.find(`input[name="${this.$element.data("name")}"]`);
181
+ if ($body.length && this.instance) {
182
+ this.spec = this.instance.userData;
183
+ $body.val(this.dataToXML(this.spec));
184
+ this.$element.data("spec", this.spec);
185
+ }
186
+ // console.log("storeData spec", this.spec, "$body", $body,"$form",$form,"this",this);
187
+ }
188
+
189
+ init($element) {
190
+ this.$element = $element;
191
+ this.spec = $element.data("spec");
192
+ if (!this.$container) {
193
+ this.$container = $(this.container_selector);
194
+ }
195
+ // console.log("init", $element, "this", this)
196
+ // 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)
197
+ this.instance = this.$container.formRender({
198
+ i18n: {
199
+ locale: this.lang,
200
+ location: "https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/"
201
+ },
202
+ formData: this.spec,
203
+ render: true
204
+ });
205
+ this.fixBuggyFields();
206
+ }
207
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Decidim rich text editor control plugin
3
+ * Renders standard Decidim WYSIWYG editor
4
+ *
5
+ * Registers Decidim Richtext as a subtype for the textarea control
6
+ */
7
+ import {createQuillEditor} from "src/decidim/decidim_awesome/editors/editor"
8
+
9
+ // configure the class for runtime loading
10
+ if (!window.fbControls) {
11
+ window.fbControls = []
12
+ }
13
+ window.fbControls.push(function(controlClass, allControlClasses) {
14
+ const controlTextarea = allControlClasses.textarea
15
+
16
+ /**
17
+ * DecidimRichtext control class
18
+ *
19
+ * NOTE: I haven't found a way to set the userData value using this plugin
20
+ * For this reason the value of the field must be collected manually
21
+ * from the hidden input name same as the field with the suffix '-input'
22
+ */
23
+ class controlRichtext extends controlTextarea {
24
+
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
+ // console.log("build plugin: this",this)
55
+ this.input = this.markup("input", null, {
56
+ name: name,
57
+ id: this.inputId,
58
+ type: "hidden",
59
+ value: (userData && userData[0]) || value || ""
60
+ });
61
+
62
+ const css = this.markup(
63
+ "style",
64
+ `
65
+ #${attrs.id} { height: auto; min-height: 6rem; padding-left: 0; padding-right: 0; }
66
+ #${attrs.id} div.ql-container { height: ${attrs.rows || 1}rem; }
67
+ #${attrs.id} p.help-text { margin-top: .5rem; }
68
+ `,
69
+ { type: "text/css" }
70
+ );
71
+ // console.log("build value", value, "userData", userData, "attrs", attrs, attrs.id);
72
+ this.wrapper = this.markup("div", null, attrs);
73
+ return this.markup("div", [css, this.input, this.wrapper], attrs);
74
+ }
75
+
76
+ /**
77
+ * When the element is rendered into the DOM, execute the following code to initialise it
78
+ * @param {Object} evt - event
79
+ */
80
+ onRender(evt) {
81
+ // const value = this.config.value || '';
82
+ if (window.fbEditors.richtext[this.id]) {
83
+ // console.log("todo destroy", window.fbEditors.richtext[this.id]);
84
+ // window.fbEditors.richtext[this.id].richtext('destroy')
85
+ }
86
+
87
+ window.fbEditors.quill[this.id] = {};
88
+ const editor = window.fbEditors.quill[this.id];
89
+ // createQuillEditor does all the job to update the hidden input wrapper
90
+ editor.instance = createQuillEditor(this.wrapper);
91
+ // editor.data = new Delta();
92
+ // if (value) {
93
+ // editor.instance.setContents(window.JSON.parse(this.parsedHtml(value)));
94
+ // }
95
+ // editor.instance.on('text-change', function(delta) {
96
+ // console.log("text-change", "delta", delta, "editor", editor);
97
+ // // // editor.data = editor.data.compose(delta);
98
+ // });
99
+
100
+ // console.log("render! editor", editor, "this", this, "value", value);
101
+ return evt;
102
+ }
103
+ }
104
+
105
+ // register Decidim richtext as a richtext control
106
+ controlTextarea.register("richtext", controlRichtext, "textarea");
107
+ })
@@ -0,0 +1,22 @@
1
+ import CustomFieldsRenderer from "src/decidim/decidim_awesome/forms/custom_fields_renderer"
2
+
3
+ window.DecidimAwesome.CustomFieldsRenderer = window.DecidimAwesome.CustomFieldsRenderer || new CustomFieldsRenderer();
4
+
5
+ $(() => {
6
+ // use admin multilang specs if exists
7
+ let $el = $("proposal_custom_field:first", ".tabs-title.is-active");
8
+ $el = $el.length
9
+ ? $el
10
+ : $(".proposal_custom_field:first");
11
+ window.DecidimAwesome.CustomFieldsRenderer.init($el);
12
+
13
+ window.DecidimAwesome.CustomFieldsRenderer.$container.closest("form").on("submit", (e) => {
14
+ if (e.target.checkValidity()) {
15
+ // save current editor
16
+ window.DecidimAwesome.CustomFieldsRenderer.storeData();
17
+ } else {
18
+ e.preventDefault();
19
+ e.target.reportValidity();
20
+ }
21
+ });
22
+ });
@@ -0,0 +1,25 @@
1
+ $(() => {
2
+ window.DecidimAwesome = window.DecidimAwesome || {};
3
+
4
+ const token = $('meta[name="csrf-token"]').attr("content");
5
+ const $textarea = $("textarea#proposal_body");
6
+ const t = window.DecidimAwesome.texts.drag_and_drop_image;
7
+
8
+ if (!$textarea.length) {
9
+ return;
10
+ }
11
+
12
+ if (window.DecidimAwesome.allow_images_in_proposals) {
13
+ // Add the capability to upload images only (they will be presented as links)
14
+
15
+ $textarea.after(`<p class="help-text">${t}</p>`);
16
+ $textarea.inlineattachment({
17
+ uploadUrl: window.DecidimAwesome.editor_uploader_path,
18
+ uploadFieldName: "image",
19
+ jsonFieldName: "url",
20
+ progressText: "[Uploading file...]",
21
+ urlText: "{filename}",
22
+ extraHeaders: { "X-CSRF-Token": token }
23
+ });
24
+ }
25
+ });