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.
- checksums.yaml +4 -4
- data/README.md +32 -9
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -2
- data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
- data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
- data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +2 -3
- data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
- data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +3 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +52 -56
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +2 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +1 -1
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +33 -24
- data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +14 -2
- data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +18 -4
- data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +5 -1
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +0 -1
- data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +15 -4
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +12 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +0 -1
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
- data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
- data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
- data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +1 -0
- data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +31 -18
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
- data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +39 -0
- data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
- data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +67 -16
- data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
- data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
- data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
- data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
- data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
- data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -7
- data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
- data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
- data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +0 -2
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
- data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +4 -0
- data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
- data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
- data/app/views/v0.23/layouts/decidim/_head.html.erb +1 -1
- data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +1 -1
- data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
- data/app/views/v0.24/layouts/decidim/_head.html.erb +2 -2
- data/app/views/v0.24/layouts/decidim/admin/_header.html.erb +2 -2
- data/config/locales/ca.yml +62 -3
- data/config/locales/cs.yml +62 -3
- data/config/locales/en.yml +90 -11
- data/config/locales/es.yml +61 -2
- data/config/locales/eu.yml +63 -4
- data/config/locales/fr.yml +62 -3
- data/config/locales/it.yml +284 -0
- data/config/locales/ja.yml +284 -0
- data/config/locales/nl.yml +62 -3
- data/config/locales/sv.yml +62 -3
- data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
- data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
- data/lib/decidim/decidim_awesome/checksums.yml +17 -4
- data/lib/decidim/decidim_awesome/config.rb +53 -6
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
- data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
- data/lib/decidim/decidim_awesome/engine.rb +62 -6
- data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
- data/lib/decidim/decidim_awesome/version.rb +1 -1
- data/lib/decidim/decidim_awesome.rb +41 -8
- data/vendor/assets/javascripts/delta.min.js +405 -0
- data/vendor/assets/javascripts/delta.min.js.map +1 -0
- data/vendor/assets/javascripts/europa.min.js +4 -0
- data/vendor/assets/javascripts/form-builder.min.js +19 -0
- data/vendor/assets/javascripts/form-render.min.js +19 -0
- data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
- data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
- data/vendor/assets/javascripts/select2.js +6147 -0
- data/vendor/assets/langs/en-US.lang +110 -0
- data/vendor/assets/stylesheets/inscrybmde.min.scss +14 -0
- data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
- data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
- data/vendor/assets/stylesheets/select2.css +515 -0
- metadata +68 -27
- data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -3
- data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
- data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
- data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -58
- data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
- 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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
40
|
-
const
|
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: $
|
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"
|
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: $
|
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
|
@@ -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
|
-
.
|
3
|
-
|
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:
|
8
|
-
border-right:
|
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
|
}
|