activeadmin_addons 1.10.1 → 2.0.0.beta.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -17
- data/app/inputs/active_admin/inputs/select_input.rb +5 -1
- data/app/inputs/nested_level_input.rb +3 -2
- data/app/inputs/search_select_input.rb +2 -2
- data/app/inputs/selected_list_input.rb +1 -1
- data/app/inputs/tags_input.rb +1 -1
- data/app/javascript/activeadmin_addons/addons/slim-select-interactive-tag.js +78 -0
- data/app/javascript/activeadmin_addons/all.js +2 -7
- data/app/javascript/activeadmin_addons/config.js +8 -5
- data/app/javascript/activeadmin_addons/inputs/slim-select-nested.js +93 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select-search.js +37 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select-selected-list.js +103 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select-simple-tags.js +22 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select-tags.js +67 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select-utils.js +70 -0
- data/app/javascript/activeadmin_addons/inputs/slim-select.js +75 -0
- data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/all.scss +5 -11
- data/app/javascript/activeadmin_addons/stylesheets/imports/slimselect.css +1 -0
- data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/selected-list.scss +0 -1
- data/app/javascript/activeadmin_addons/stylesheets/inputs/slim-select.scss +9 -0
- data/lib/activeadmin_addons/addons/image_builder.rb +2 -9
- data/lib/activeadmin_addons/addons/tag_builder.rb +3 -22
- data/lib/activeadmin_addons/engine.rb +0 -5
- data/lib/activeadmin_addons/support/input_helpers/select_helpers.rb +1 -1
- data/lib/activeadmin_addons/version.rb +1 -1
- data/lib/activeadmin_addons.rb +1 -1
- data/lib/generators/activeadmin_addons/install/install_generator.rb +2 -1
- data/lib/generators/activeadmin_addons/install/templates/initializer.rb +1 -1
- data/lib/generators/activeadmin_addons/webpacker/webpacker_generator.rb +1 -1
- metadata +49 -220
- data/app/assets/images/fileicons/file_extension_3gp.png +0 -0
- data/app/assets/images/fileicons/file_extension_7z.png +0 -0
- data/app/assets/images/fileicons/file_extension_ace.png +0 -0
- data/app/assets/images/fileicons/file_extension_ai.png +0 -0
- data/app/assets/images/fileicons/file_extension_aif.png +0 -0
- data/app/assets/images/fileicons/file_extension_aiff.png +0 -0
- data/app/assets/images/fileicons/file_extension_amr.png +0 -0
- data/app/assets/images/fileicons/file_extension_asf.png +0 -0
- data/app/assets/images/fileicons/file_extension_asx.png +0 -0
- data/app/assets/images/fileicons/file_extension_bat.png +0 -0
- data/app/assets/images/fileicons/file_extension_bin.png +0 -0
- data/app/assets/images/fileicons/file_extension_bmp.png +0 -0
- data/app/assets/images/fileicons/file_extension_bup.png +0 -0
- data/app/assets/images/fileicons/file_extension_cab.png +0 -0
- data/app/assets/images/fileicons/file_extension_cbr.png +0 -0
- data/app/assets/images/fileicons/file_extension_cda.png +0 -0
- data/app/assets/images/fileicons/file_extension_cdl.png +0 -0
- data/app/assets/images/fileicons/file_extension_cdr.png +0 -0
- data/app/assets/images/fileicons/file_extension_chm.png +0 -0
- data/app/assets/images/fileicons/file_extension_dat.png +0 -0
- data/app/assets/images/fileicons/file_extension_divx.png +0 -0
- data/app/assets/images/fileicons/file_extension_dll.png +0 -0
- data/app/assets/images/fileicons/file_extension_dmg.png +0 -0
- data/app/assets/images/fileicons/file_extension_doc.png +0 -0
- data/app/assets/images/fileicons/file_extension_docx.png +0 -0
- data/app/assets/images/fileicons/file_extension_dss.png +0 -0
- data/app/assets/images/fileicons/file_extension_dvf.png +0 -0
- data/app/assets/images/fileicons/file_extension_dwg.png +0 -0
- data/app/assets/images/fileicons/file_extension_eml.png +0 -0
- data/app/assets/images/fileicons/file_extension_eps.png +0 -0
- data/app/assets/images/fileicons/file_extension_exe.png +0 -0
- data/app/assets/images/fileicons/file_extension_fla.png +0 -0
- data/app/assets/images/fileicons/file_extension_flv.png +0 -0
- data/app/assets/images/fileicons/file_extension_gif.png +0 -0
- data/app/assets/images/fileicons/file_extension_gz.png +0 -0
- data/app/assets/images/fileicons/file_extension_hqx.png +0 -0
- data/app/assets/images/fileicons/file_extension_htm.png +0 -0
- data/app/assets/images/fileicons/file_extension_html.png +0 -0
- data/app/assets/images/fileicons/file_extension_ifo.png +0 -0
- data/app/assets/images/fileicons/file_extension_indd.png +0 -0
- data/app/assets/images/fileicons/file_extension_iso.png +0 -0
- data/app/assets/images/fileicons/file_extension_jar.png +0 -0
- data/app/assets/images/fileicons/file_extension_jpeg.png +0 -0
- data/app/assets/images/fileicons/file_extension_jpg.png +0 -0
- data/app/assets/images/fileicons/file_extension_lnk.png +0 -0
- data/app/assets/images/fileicons/file_extension_log.png +0 -0
- data/app/assets/images/fileicons/file_extension_m4a.png +0 -0
- data/app/assets/images/fileicons/file_extension_m4b.png +0 -0
- data/app/assets/images/fileicons/file_extension_m4p.png +0 -0
- data/app/assets/images/fileicons/file_extension_m4v.png +0 -0
- data/app/assets/images/fileicons/file_extension_mcd.png +0 -0
- data/app/assets/images/fileicons/file_extension_mdb.png +0 -0
- data/app/assets/images/fileicons/file_extension_mid.png +0 -0
- data/app/assets/images/fileicons/file_extension_mov.png +0 -0
- data/app/assets/images/fileicons/file_extension_mp2.png +0 -0
- data/app/assets/images/fileicons/file_extension_mp3.png +0 -0
- data/app/assets/images/fileicons/file_extension_mp4.png +0 -0
- data/app/assets/images/fileicons/file_extension_mpeg.png +0 -0
- data/app/assets/images/fileicons/file_extension_mpg.png +0 -0
- data/app/assets/images/fileicons/file_extension_msi.png +0 -0
- data/app/assets/images/fileicons/file_extension_mswmm.png +0 -0
- data/app/assets/images/fileicons/file_extension_ogg.png +0 -0
- data/app/assets/images/fileicons/file_extension_pdf.png +0 -0
- data/app/assets/images/fileicons/file_extension_png.png +0 -0
- data/app/assets/images/fileicons/file_extension_pps.png +0 -0
- data/app/assets/images/fileicons/file_extension_ppt.png +0 -0
- data/app/assets/images/fileicons/file_extension_pptx.png +0 -0
- data/app/assets/images/fileicons/file_extension_ps.png +0 -0
- data/app/assets/images/fileicons/file_extension_psd.png +0 -0
- data/app/assets/images/fileicons/file_extension_pst.png +0 -0
- data/app/assets/images/fileicons/file_extension_ptb.png +0 -0
- data/app/assets/images/fileicons/file_extension_pub.png +0 -0
- data/app/assets/images/fileicons/file_extension_qbb.png +0 -0
- data/app/assets/images/fileicons/file_extension_qbw.png +0 -0
- data/app/assets/images/fileicons/file_extension_qxd.png +0 -0
- data/app/assets/images/fileicons/file_extension_ram.png +0 -0
- data/app/assets/images/fileicons/file_extension_rar.png +0 -0
- data/app/assets/images/fileicons/file_extension_rm.png +0 -0
- data/app/assets/images/fileicons/file_extension_rmvb.png +0 -0
- data/app/assets/images/fileicons/file_extension_rtf.png +0 -0
- data/app/assets/images/fileicons/file_extension_sea.png +0 -0
- data/app/assets/images/fileicons/file_extension_ses.png +0 -0
- data/app/assets/images/fileicons/file_extension_sit.png +0 -0
- data/app/assets/images/fileicons/file_extension_sitx.png +0 -0
- data/app/assets/images/fileicons/file_extension_ss.png +0 -0
- data/app/assets/images/fileicons/file_extension_swf.png +0 -0
- data/app/assets/images/fileicons/file_extension_tgz.png +0 -0
- data/app/assets/images/fileicons/file_extension_thm.png +0 -0
- data/app/assets/images/fileicons/file_extension_tif.png +0 -0
- data/app/assets/images/fileicons/file_extension_tmp.png +0 -0
- data/app/assets/images/fileicons/file_extension_torrent.png +0 -0
- data/app/assets/images/fileicons/file_extension_ttf.png +0 -0
- data/app/assets/images/fileicons/file_extension_txt.png +0 -0
- data/app/assets/images/fileicons/file_extension_unknown.png +0 -0
- data/app/assets/images/fileicons/file_extension_vcd.png +0 -0
- data/app/assets/images/fileicons/file_extension_vob.png +0 -0
- data/app/assets/images/fileicons/file_extension_wav.png +0 -0
- data/app/assets/images/fileicons/file_extension_wma.png +0 -0
- data/app/assets/images/fileicons/file_extension_wmv.png +0 -0
- data/app/assets/images/fileicons/file_extension_wps.png +0 -0
- data/app/assets/images/fileicons/file_extension_xls.png +0 -0
- data/app/assets/images/fileicons/file_extension_xlsx.png +0 -0
- data/app/assets/images/fileicons/file_extension_xpi.png +0 -0
- data/app/assets/images/fileicons/file_extension_zip.png +0 -0
- data/app/assets/images/material/icons/keyboard_arrow_down.svg +0 -4
- data/app/assets/images/material/icons/keyboard_arrow_left.svg +0 -4
- data/app/assets/images/material/icons/keyboard_arrow_right.svg +0 -4
- data/app/assets/images/material/icons/keyboard_arrow_up.svg +0 -4
- data/app/assets/images/material/icons/today.svg +0 -4
- data/app/assets/javascripts/activeadmin_addons/all.js +0 -753
- data/app/assets/stylesheets/activeadmin_addons/addons/material-datepicker.scss +0 -173
- data/app/assets/stylesheets/activeadmin_addons/addons/material-toggle_bool.scss +0 -52
- data/app/assets/stylesheets/activeadmin_addons/inputs/select2.scss +0 -3
- data/app/assets/stylesheets/activeadmin_addons/material.scss +0 -53
- data/app/javascript/activeadmin_addons/addons/interactive_select_tag.js +0 -95
- data/app/javascript/activeadmin_addons/inputs/nested-select.js +0 -170
- data/app/javascript/activeadmin_addons/inputs/search-select.js +0 -76
- data/app/javascript/activeadmin_addons/inputs/select2.js +0 -52
- data/app/javascript/activeadmin_addons/inputs/selected-list.js +0 -107
- data/app/javascript/activeadmin_addons/inputs/tags.js +0 -76
- data/lib/activeadmin_addons/addons/attachment_builder.rb +0 -60
- data/lib/activeadmin_addons/support/enumerize_formtastic_support.rb +0 -18
- data/lib/generators/activeadmin_addons/assets/assets_generator.rb +0 -53
- data/vendor/assets/select2/select2.css +0 -481
- data/vendor/assets/select2/select2.full.js +0 -6820
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/addons/interactive_select_tag.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/addons/toggle_bool.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/imports/jquery-datepicker.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/color-picker.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/date-time-picker-filter.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/date-time-picker.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/numeric-range-filter.scss +0 -0
- /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/vendor/palette-color-picker.scss +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aed38304ff68795198eb34b4fb634a5f8e55143b4f159b04698d0852d32e36ef
|
4
|
+
data.tar.gz: 6c4637ae03b38a74d1d06831fea506de8d13a996002d1770a0d5d80372242906
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c955ceb1fedfefd561237ba63e433b0013be0debad0750b70932e82141ae41c323c970041317720caed90cdff1820bda25d667cf00c4110d63fe6ebfcfbc3a1
|
7
|
+
data.tar.gz: d9522cb0cab4b42be862e0451efbba5156a5b85cde8a8dfddd359b613c21638b216eff53b5a4e899e9b4b4d6fbae614dc238d0c72b4a35266350743e70214b6a
|
data/Rakefile
CHANGED
@@ -18,29 +18,13 @@ task :prepare_assets do
|
|
18
18
|
system "rm -rf spec/dummy/public/packs"
|
19
19
|
system "rm -rf spec/dummy/public/packs-test"
|
20
20
|
system "yarn install"
|
21
|
-
system "yarn build"
|
22
21
|
system "(cd spec/dummy && yarn install)"
|
23
22
|
end
|
24
23
|
|
25
24
|
task :tests do
|
26
25
|
system "rspec ./spec/lib"
|
27
|
-
end
|
28
|
-
|
29
|
-
task :sprockets_tests do
|
30
|
-
system "rake prepare_assets"
|
31
|
-
system "export SPROCKETS=true; rspec ./spec/features"
|
32
|
-
end
|
33
|
-
|
34
|
-
task :webpack_tests do
|
35
|
-
system "rake prepare_assets"
|
36
|
-
system "export SPROCKETS=false; rspec ./spec/features"
|
37
|
-
end
|
38
|
-
|
39
|
-
task :all_tests do
|
40
26
|
system "rake prepare_assets"
|
41
|
-
system "
|
42
|
-
system "export SPROCKETS=true; rspec ./spec/features"
|
43
|
-
system "export SPROCKETS=false; rspec ./spec/features"
|
27
|
+
system "rspec ./spec/features"
|
44
28
|
end
|
45
29
|
|
46
30
|
Bundler::GemHelper.install_tasks
|
@@ -1,6 +1,10 @@
|
|
1
1
|
class ActiveAdmin::Inputs::SelectInput < Formtastic::Inputs::SelectInput
|
2
2
|
def input_html_options
|
3
|
-
|
3
|
+
if @options[:tags].present?
|
4
|
+
super.deep_merge(class: 'simple-tags-input')
|
5
|
+
else
|
6
|
+
super
|
7
|
+
end
|
4
8
|
end
|
5
9
|
|
6
10
|
def raw_collection
|
@@ -15,15 +15,16 @@ class NestedLevelInput < ActiveAdminAddons::InputBase
|
|
15
15
|
|
16
16
|
def load_control_attributes
|
17
17
|
load_class(@options[:class])
|
18
|
+
load_data_attr(:association, value: association_name)
|
18
19
|
load_data_attr(:fields, default: ["name"], formatter: :to_json)
|
19
|
-
load_data_attr(:predicate, default: "
|
20
|
+
load_data_attr(:predicate, default: "contains")
|
20
21
|
load_data_attr(:filters)
|
21
22
|
load_data_attr(:model, value: model_name)
|
22
23
|
load_data_attr(:display_name, default: "name")
|
23
24
|
load_data_attr(:minimum_input_length, default: 1)
|
24
25
|
load_data_attr(:url, default: url_from_method)
|
25
26
|
load_data_attr(:response_root, default: tableize_method)
|
26
|
-
load_data_attr(:width
|
27
|
+
load_data_attr(:width)
|
27
28
|
load_data_attr(:order,
|
28
29
|
value: @options[:order_by],
|
29
30
|
default: get_data_attr_value(:fields).first.to_s + "_desc")
|
@@ -14,12 +14,12 @@ class SearchSelectInput < ActiveAdminAddons::InputBase
|
|
14
14
|
def load_control_attributes
|
15
15
|
load_class(@options[:class])
|
16
16
|
load_data_attr(:fields, default: ["name"], formatter: :to_json)
|
17
|
-
load_data_attr(:predicate, default: "
|
17
|
+
load_data_attr(:predicate, default: "contains")
|
18
18
|
load_data_attr(:url, default: url_from_method)
|
19
19
|
load_data_attr(:response_root, default: tableize_method)
|
20
20
|
load_data_attr(:display_name, default: "name")
|
21
21
|
load_data_attr(:minimum_input_length, default: 1)
|
22
|
-
load_data_attr(:width
|
22
|
+
load_data_attr(:width)
|
23
23
|
load_data_attr(
|
24
24
|
:order,
|
25
25
|
value: @options[:order_by],
|
@@ -11,7 +11,7 @@ class SelectedListInput < ActiveAdminAddons::InputBase
|
|
11
11
|
load_data_attr(:url, default: url_from_method)
|
12
12
|
load_data_attr(:response_root, default: tableize_method)
|
13
13
|
load_data_attr(:fields, default: ["name"], formatter: :to_json)
|
14
|
-
load_data_attr(:predicate, default: "
|
14
|
+
load_data_attr(:predicate, default: "contains")
|
15
15
|
load_data_attr(:display_name, default: "name")
|
16
16
|
load_data_attr(:minimum_input_length, default: 1)
|
17
17
|
load_data_attr(:width, default: "100%")
|
data/app/inputs/tags_input.rb
CHANGED
@@ -12,7 +12,7 @@ class TagsInput < ActiveAdminAddons::InputBase
|
|
12
12
|
def load_control_attributes
|
13
13
|
load_data_attr(:model, value: model_name)
|
14
14
|
load_data_attr(:method, value: method)
|
15
|
-
load_data_attr(:width
|
15
|
+
load_data_attr(:width)
|
16
16
|
|
17
17
|
if active_record_select?
|
18
18
|
load_data_attr(:relation, value: true)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import SlimSelect from 'slim-select';
|
2
|
+
|
3
|
+
function updateTag(url, data) {
|
4
|
+
return fetch(url, {
|
5
|
+
method: 'PATCH',
|
6
|
+
headers: {
|
7
|
+
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
8
|
+
'Accept': 'application/json',
|
9
|
+
'Content-Type': 'application/json',
|
10
|
+
},
|
11
|
+
body: JSON.stringify(data),
|
12
|
+
});
|
13
|
+
}
|
14
|
+
|
15
|
+
function setupSelect(el) {
|
16
|
+
if (el.slim) {
|
17
|
+
el.slim.destroy();
|
18
|
+
}
|
19
|
+
|
20
|
+
return new SlimSelect({
|
21
|
+
select: el,
|
22
|
+
events: {
|
23
|
+
// eslint-disable-next-line max-statements
|
24
|
+
afterClose: () => {
|
25
|
+
const containerEl = el.closest('.tag-select-container');
|
26
|
+
const selectContainer = containerEl.querySelector('.interactive-tag-select');
|
27
|
+
const tagContainer = containerEl.querySelector('.interactive-tag');
|
28
|
+
const model = tagContainer.dataset.model;
|
29
|
+
const objectId = tagContainer.dataset.objectId;
|
30
|
+
const field = tagContainer.dataset.field;
|
31
|
+
|
32
|
+
if (el.value === tagContainer.dataset.value) {
|
33
|
+
selectContainer.classList.add('select-container-hidden');
|
34
|
+
containerEl.querySelector('.interactive-tag').classList.remove('interactive-tag-hidden');
|
35
|
+
} else {
|
36
|
+
const data = { id: objectId };
|
37
|
+
data[model] = {};
|
38
|
+
data[model][field] = el.value;
|
39
|
+
updateTag(tagContainer.dataset.url, data)
|
40
|
+
.then(() => {
|
41
|
+
const statusTag = tagContainer.querySelector('.status_tag');
|
42
|
+
statusTag.innerText = el.selectedOptions[0].text;
|
43
|
+
statusTag.classList.remove(tagContainer.dataset.value);
|
44
|
+
statusTag.classList.add(el.value);
|
45
|
+
tagContainer.dataset.value = el.value;
|
46
|
+
selectContainer.dataset.value = el.value;
|
47
|
+
})
|
48
|
+
.catch(() => {
|
49
|
+
const errorMsg = 'Error: Update Unsuccessful';
|
50
|
+
console.log(errorMsg);
|
51
|
+
})
|
52
|
+
.finally(() => {
|
53
|
+
selectContainer.classList.add('select-container-hidden');
|
54
|
+
containerEl.querySelector('.interactive-tag').classList.remove('interactive-tag-hidden');
|
55
|
+
});
|
56
|
+
}
|
57
|
+
},
|
58
|
+
},
|
59
|
+
});
|
60
|
+
}
|
61
|
+
|
62
|
+
function setupInteractiveTag(containerEl) {
|
63
|
+
const selectContainer = containerEl.querySelector('.interactive-tag-select');
|
64
|
+
const slimSelect = setupSelect(selectContainer.querySelector('select'));
|
65
|
+
const tag = containerEl.querySelector('.interactive-tag');
|
66
|
+
|
67
|
+
tag.addEventListener('click', () => {
|
68
|
+
selectContainer.classList.remove('select-container-hidden');
|
69
|
+
tag.classList.add('interactive-tag-hidden');
|
70
|
+
window.setTimeout(() => {
|
71
|
+
slimSelect.open();
|
72
|
+
}, 0);
|
73
|
+
});
|
74
|
+
}
|
75
|
+
|
76
|
+
window.addEventListener('load', () => {
|
77
|
+
document.querySelectorAll('.tag-select-container').forEach(setupInteractiveTag);
|
78
|
+
});
|
@@ -1,14 +1,9 @@
|
|
1
|
-
import 'select2';
|
2
1
|
import 'jquery-datetimepicker';
|
3
2
|
import './vendor/jquery_palette_color_picker/palette-color-picker';
|
4
3
|
|
5
4
|
import './config';
|
6
|
-
import './inputs/
|
7
|
-
import './inputs/search-select';
|
8
|
-
import './inputs/nested-select';
|
9
|
-
import './inputs/tags';
|
10
|
-
import './inputs/selected-list';
|
5
|
+
import './inputs/slim-select';
|
11
6
|
import './inputs/date-time-picker';
|
12
7
|
import './inputs/color-picker';
|
13
8
|
import './addons/toggle_bool';
|
14
|
-
import './addons/
|
9
|
+
import './addons/slim-select-interactive-tag';
|
@@ -1,10 +1,13 @@
|
|
1
|
-
|
1
|
+
const loadEvents = ['turbo:load', 'turbolinks:load', 'DOMContentLoaded'];
|
2
|
+
|
3
|
+
function initializer() {
|
2
4
|
window.ActiveadminAddons = {
|
3
5
|
config: {
|
4
|
-
defaultSelect:
|
6
|
+
defaultSelect: document.querySelector('body').dataset.defaultSelect,
|
5
7
|
},
|
6
8
|
};
|
7
|
-
}
|
9
|
+
}
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
loadEvents.forEach((event) => {
|
12
|
+
document.addEventListener(event, initializer);
|
13
|
+
});
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import { ransackSearch } from './slim-select-utils';
|
2
|
+
|
3
|
+
const classes = ['nested-level-input'];
|
4
|
+
|
5
|
+
function ajaxSearch(search, currentData, args) {
|
6
|
+
args.fields.forEach((field) => {
|
7
|
+
if (field === 'id') {
|
8
|
+
args.textQuery[`${field}_eq`] = search;
|
9
|
+
} else {
|
10
|
+
args.textQuery[`${field}_${args.predicate}`] = search;
|
11
|
+
}
|
12
|
+
});
|
13
|
+
|
14
|
+
if (!!args.parent) {
|
15
|
+
args.query.q[`${args.parent}_eq`] = args.parentId;
|
16
|
+
}
|
17
|
+
|
18
|
+
args.query.q = { ...args.query.q, ...args.filters };
|
19
|
+
|
20
|
+
return ransackSearch(search, currentData, args);
|
21
|
+
}
|
22
|
+
|
23
|
+
function collectionSearch(search, args, collection) {
|
24
|
+
if (search.length < args.minimumInputLength) {
|
25
|
+
return Promise.reject('Search term too short');
|
26
|
+
}
|
27
|
+
|
28
|
+
const data = JSON.parse(collection).map(
|
29
|
+
(item) => ({ value: String(item.id), text: item.text }),
|
30
|
+
).filter(
|
31
|
+
(item) => String(item.text).toLowerCase().includes(search.toLowerCase()));
|
32
|
+
|
33
|
+
return Promise.resolve(data);
|
34
|
+
}
|
35
|
+
|
36
|
+
function settings(el) {
|
37
|
+
return {
|
38
|
+
settings: {
|
39
|
+
allowDeselect: true,
|
40
|
+
},
|
41
|
+
events: {
|
42
|
+
beforeOpen: () => {
|
43
|
+
if (Number(el.dataset.minimumInputLength) === 0) {
|
44
|
+
el.slim.search('');
|
45
|
+
}
|
46
|
+
},
|
47
|
+
afterChange: () => {
|
48
|
+
const { model, association } = el.dataset;
|
49
|
+
const child = el.closest('.nested_level')
|
50
|
+
.parentNode
|
51
|
+
.querySelector(`.nested_level [data-model=${model}][data-parent=${association}_id]`);
|
52
|
+
|
53
|
+
if (child) {
|
54
|
+
child.slim.setSelected();
|
55
|
+
child.slim.setData([]);
|
56
|
+
if (child.slim.events.afterChange) {
|
57
|
+
child.slim.events.afterChange();
|
58
|
+
}
|
59
|
+
child.dispatchEvent(new Event('change'));
|
60
|
+
child.dataset.parentId = el.value;
|
61
|
+
}
|
62
|
+
},
|
63
|
+
search(search, currentData) {
|
64
|
+
const args = {
|
65
|
+
url: el.dataset.url,
|
66
|
+
fields: el.dataset.fields && JSON.parse(el.dataset.fields) || {},
|
67
|
+
predicate: el.dataset.predicate,
|
68
|
+
filters: el.dataset.filters && JSON.parse(el.dataset.filters) || {},
|
69
|
+
displayName: el.dataset.displayName,
|
70
|
+
parent: el.dataset.parent,
|
71
|
+
parentId: el.dataset.parentId,
|
72
|
+
responseRoot: el.dataset.responseRoot,
|
73
|
+
minimumInputLength: el.dataset.minimumInputLength,
|
74
|
+
order: el.dataset.order,
|
75
|
+
textQuery: { m: 'or' },
|
76
|
+
query: { q: {} },
|
77
|
+
};
|
78
|
+
|
79
|
+
if (el.dataset.collection) {
|
80
|
+
return collectionSearch(search, args, el.dataset.collection);
|
81
|
+
}
|
82
|
+
|
83
|
+
return ajaxSearch(search, currentData, args);
|
84
|
+
},
|
85
|
+
},
|
86
|
+
};
|
87
|
+
}
|
88
|
+
|
89
|
+
export {
|
90
|
+
settings,
|
91
|
+
classes,
|
92
|
+
};
|
93
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { ransackSearch } from './slim-select-utils';
|
2
|
+
|
3
|
+
const classes = ['search-select-input', 'search-select-filter-input', 'ajax-filter-input'];
|
4
|
+
|
5
|
+
function settings(el) {
|
6
|
+
const url = el.dataset.url;
|
7
|
+
const fields = JSON.parse(el.dataset.fields);
|
8
|
+
const predicate = el.dataset.predicate;
|
9
|
+
const displayName = el.dataset.displayName;
|
10
|
+
const responseRoot = el.dataset.responseRoot;
|
11
|
+
const minimumInputLength = el.dataset.minimumInputLength;
|
12
|
+
const order = el.dataset.order;
|
13
|
+
|
14
|
+
const args = { url, fields, predicate, displayName, responseRoot, minimumInputLength, order };
|
15
|
+
|
16
|
+
return {
|
17
|
+
events: {
|
18
|
+
search: (search, currentData) => {
|
19
|
+
args.textQuery = { m: 'or' };
|
20
|
+
args.fields.forEach((field) => {
|
21
|
+
if (field === 'id') {
|
22
|
+
args.textQuery[`${field}_eq`] = search;
|
23
|
+
} else {
|
24
|
+
args.textQuery[`${field}_${args.predicate}`] = search;
|
25
|
+
}
|
26
|
+
});
|
27
|
+
|
28
|
+
return ransackSearch(search, currentData, args);
|
29
|
+
},
|
30
|
+
},
|
31
|
+
};
|
32
|
+
}
|
33
|
+
|
34
|
+
export {
|
35
|
+
settings,
|
36
|
+
classes,
|
37
|
+
};
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import { ransackSearch } from './slim-select-utils';
|
2
|
+
|
3
|
+
const classes = ['selected-list-input'];
|
4
|
+
|
5
|
+
// eslint-disable-next-line max-statements
|
6
|
+
function settings(el) {
|
7
|
+
const url = el.dataset.url;
|
8
|
+
const fields = JSON.parse(el.dataset.fields);
|
9
|
+
const predicate = el.dataset.predicate;
|
10
|
+
const displayName = el.dataset.displayName;
|
11
|
+
const method = el.dataset.method;
|
12
|
+
const model = el.dataset.model;
|
13
|
+
const prefix = `${model}_${method}`;
|
14
|
+
const responseRoot = el.dataset.responseRoot;
|
15
|
+
const minimumInputLength = el.dataset.minimumInputLength;
|
16
|
+
const order = el.dataset.order;
|
17
|
+
|
18
|
+
const args = { url, fields, predicate, displayName, responseRoot, minimumInputLength, order };
|
19
|
+
|
20
|
+
return {
|
21
|
+
settings: {
|
22
|
+
allowDeselect: false,
|
23
|
+
},
|
24
|
+
events: {
|
25
|
+
// eslint-disable-next-line max-statements
|
26
|
+
afterChange: (newVal) => {
|
27
|
+
if (!newVal || newVal[0] && !newVal[0].value) return;
|
28
|
+
|
29
|
+
const selectedItemsContainer = document.querySelector(`[id='${prefix}_selected_values']`);
|
30
|
+
const itemName = `${model}[${method}][]`;
|
31
|
+
|
32
|
+
// eslint-disable-next-line max-statements
|
33
|
+
newVal.forEach((data) => {
|
34
|
+
const itemId = `${prefix}_${data.value}`;
|
35
|
+
if (!!document.querySelector(`#${itemId}`)) {
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
|
39
|
+
const item = document.createElement('div');
|
40
|
+
item.id = itemId;
|
41
|
+
item.textContent = data.text;
|
42
|
+
item.classList.add('selected-item');
|
43
|
+
|
44
|
+
const hiddenInput = document.createElement('input');
|
45
|
+
hiddenInput.name = itemName;
|
46
|
+
hiddenInput.type = 'hidden';
|
47
|
+
hiddenInput.value = data.value;
|
48
|
+
|
49
|
+
item.appendChild(hiddenInput);
|
50
|
+
selectedItemsContainer.appendChild(item);
|
51
|
+
});
|
52
|
+
el.slim.setSelected();
|
53
|
+
},
|
54
|
+
search: (search, currentData) => {
|
55
|
+
args.textQuery = { m: 'or' };
|
56
|
+
args.fields.forEach((field) => {
|
57
|
+
args.textQuery[`${field}_${predicate}`] = search;
|
58
|
+
});
|
59
|
+
|
60
|
+
return ransackSearch(search, currentData, args);
|
61
|
+
},
|
62
|
+
},
|
63
|
+
};
|
64
|
+
}
|
65
|
+
|
66
|
+
function setupSelectedList(containerEl) {
|
67
|
+
containerEl.addEventListener('click', (event) => {
|
68
|
+
const item = event.target;
|
69
|
+
if (item.classList.contains('selected-item')) {
|
70
|
+
item.remove();
|
71
|
+
}
|
72
|
+
});
|
73
|
+
}
|
74
|
+
|
75
|
+
function setupSelectedLists(node) {
|
76
|
+
node.querySelectorAll('.selected-list-container').forEach(setupSelectedList);
|
77
|
+
}
|
78
|
+
|
79
|
+
function mutationObserver() {
|
80
|
+
return new MutationObserver((mutations) => {
|
81
|
+
mutations.forEach((mutation) => {
|
82
|
+
if (mutation.type === 'childList') {
|
83
|
+
mutation.addedNodes.forEach((node) => {
|
84
|
+
if (node instanceof Element) {
|
85
|
+
setupSelectedLists(node);
|
86
|
+
}
|
87
|
+
});
|
88
|
+
}
|
89
|
+
});
|
90
|
+
});
|
91
|
+
}
|
92
|
+
|
93
|
+
function init() {
|
94
|
+
setupSelectedLists(document);
|
95
|
+
mutationObserver();
|
96
|
+
}
|
97
|
+
|
98
|
+
export {
|
99
|
+
settings,
|
100
|
+
classes,
|
101
|
+
init,
|
102
|
+
};
|
103
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
const classes = ['simple-tags-input'];
|
2
|
+
|
3
|
+
function init(el) {
|
4
|
+
el.multiple = true;
|
5
|
+
if (!el.value) {
|
6
|
+
el.value = null;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
function settings() {
|
11
|
+
return {
|
12
|
+
events: {
|
13
|
+
addable: (value) => value,
|
14
|
+
},
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
export {
|
19
|
+
classes,
|
20
|
+
init,
|
21
|
+
settings,
|
22
|
+
};
|
@@ -0,0 +1,67 @@
|
|
1
|
+
const classes = ['tags-input'];
|
2
|
+
|
3
|
+
// eslint-disable-next-line max-statements
|
4
|
+
function settings(el) {
|
5
|
+
const model = el.dataset.model;
|
6
|
+
const method = el.dataset.method;
|
7
|
+
const prefix = `${model}_${method}`;
|
8
|
+
const isRelation = el.dataset.relation === 'true';
|
9
|
+
const collection = el.dataset.collection ? JSON.parse(el.dataset.collection) : null;
|
10
|
+
|
11
|
+
const parsedCollection = collection && collection.map((item) => {
|
12
|
+
const { id, ...rest } = item;
|
13
|
+
|
14
|
+
return { ...rest, value: id, selected: !!item.selected };
|
15
|
+
});
|
16
|
+
|
17
|
+
function fillHiddenInput(values) {
|
18
|
+
const hiddenInput = document.querySelector(`#${prefix}`);
|
19
|
+
hiddenInput.value = values.map(val => val.value).join();
|
20
|
+
}
|
21
|
+
|
22
|
+
const events = {
|
23
|
+
afterChange: (newVal) => {
|
24
|
+
if (isRelation) {
|
25
|
+
const selectedItemsContainer = document.querySelector(`#${prefix}_selected_values`);
|
26
|
+
const itemName = `${model}[${method}][]`;
|
27
|
+
selectedItemsContainer.innerHTML = '';
|
28
|
+
|
29
|
+
newVal.forEach((data) => {
|
30
|
+
const itemId = `${prefix}_${data.value}`;
|
31
|
+
if (document.querySelectorAll(`#${itemId}`).length > 0) {
|
32
|
+
return;
|
33
|
+
}
|
34
|
+
|
35
|
+
const hiddenInput = document.createElement('input');
|
36
|
+
hiddenInput.id = itemId;
|
37
|
+
hiddenInput.name = itemName;
|
38
|
+
hiddenInput.value = data.value;
|
39
|
+
hiddenInput.type = 'hidden';
|
40
|
+
|
41
|
+
selectedItemsContainer.appendChild(hiddenInput);
|
42
|
+
});
|
43
|
+
} else {
|
44
|
+
fillHiddenInput(newVal);
|
45
|
+
}
|
46
|
+
},
|
47
|
+
};
|
48
|
+
|
49
|
+
if (!isRelation) {
|
50
|
+
events.addable = (value) => value;
|
51
|
+
}
|
52
|
+
|
53
|
+
return {
|
54
|
+
data: parsedCollection,
|
55
|
+
events,
|
56
|
+
};
|
57
|
+
}
|
58
|
+
|
59
|
+
function init(el) {
|
60
|
+
el.multiple = true;
|
61
|
+
}
|
62
|
+
|
63
|
+
export {
|
64
|
+
settings,
|
65
|
+
classes,
|
66
|
+
init,
|
67
|
+
};
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import merge from 'lodash.merge';
|
2
|
+
|
3
|
+
function parseObjectToQuery(obj, prefix) {
|
4
|
+
let queryArray = [];
|
5
|
+
Object.keys(obj).forEach(key => {
|
6
|
+
const value = obj[key];
|
7
|
+
const prefixedKey = prefix ? `${prefix}[${key}]` : key;
|
8
|
+
if (Array.isArray(value)) {
|
9
|
+
value.forEach((v, i) => {
|
10
|
+
queryArray = [...queryArray, parseObjectToQuery(v, `${prefixedKey}[${i}]`)];
|
11
|
+
});
|
12
|
+
} else if (typeof value === 'object') {
|
13
|
+
queryArray = [...queryArray, parseObjectToQuery(value, prefixedKey)];
|
14
|
+
} else {
|
15
|
+
queryArray.push(`${prefixedKey}=${encodeURIComponent(value)}`);
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
return queryArray.join('&');
|
20
|
+
}
|
21
|
+
|
22
|
+
export function ransackSearch(search, currentData, settings) {
|
23
|
+
return new Promise((resolve, reject) => {
|
24
|
+
if (search.length < settings.minimumInputLength) {
|
25
|
+
reject(`Please enter ${settings.minimumInputLength} or more characters`);
|
26
|
+
}
|
27
|
+
|
28
|
+
const defaultQuery = {
|
29
|
+
order: settings.order,
|
30
|
+
q: {
|
31
|
+
groupings: [settings.textQuery],
|
32
|
+
combinator: 'and',
|
33
|
+
},
|
34
|
+
};
|
35
|
+
|
36
|
+
const finalQuery = merge({}, defaultQuery, settings.query);
|
37
|
+
const csrfTokenEl = document.querySelector('meta[name="csrf-token"]');
|
38
|
+
const csrfToken = csrfTokenEl ? csrfTokenEl.getAttribute('content') : null;
|
39
|
+
|
40
|
+
const queryString = parseObjectToQuery(finalQuery);
|
41
|
+
fetch(`${settings.url}?${queryString}`, {
|
42
|
+
method: 'GET',
|
43
|
+
headers: {
|
44
|
+
'X-CSRF-TOKEN': csrfToken,
|
45
|
+
'Accept': 'application/json',
|
46
|
+
'Content-Type': 'application/json',
|
47
|
+
},
|
48
|
+
})
|
49
|
+
.then((response) => response.json())
|
50
|
+
.then((res) => {
|
51
|
+
let data = res;
|
52
|
+
if (data.constructor === Object) {
|
53
|
+
data = data[settings.responseRoot];
|
54
|
+
}
|
55
|
+
|
56
|
+
const options = data.map(resource => {
|
57
|
+
if (!resource[settings.displayName]) {
|
58
|
+
resource[settings.displayName] = `No display name for id #${resource.id.toString()}`;
|
59
|
+
}
|
60
|
+
|
61
|
+
return {
|
62
|
+
value: resource.id,
|
63
|
+
text: resource[settings.displayName],
|
64
|
+
};
|
65
|
+
});
|
66
|
+
|
67
|
+
resolve(options);
|
68
|
+
});
|
69
|
+
});
|
70
|
+
}
|