activeadmin_addons 1.9.0 → 2.0.0.beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -17
  3. data/app/inputs/active_admin/inputs/select_input.rb +5 -1
  4. data/app/inputs/nested_level_input.rb +2 -1
  5. data/app/inputs/search_select_input.rb +1 -1
  6. data/app/inputs/tags_input.rb +1 -1
  7. data/app/javascript/activeadmin_addons/addons/slim-select-interactive-tag.js +78 -0
  8. data/app/javascript/activeadmin_addons/addons/toggle_bool.js +1 -1
  9. data/app/javascript/activeadmin_addons/all.js +2 -7
  10. data/app/javascript/activeadmin_addons/config.js +8 -5
  11. data/app/javascript/activeadmin_addons/inputs/color-picker.js +1 -1
  12. data/app/javascript/activeadmin_addons/inputs/date-time-picker.js +1 -1
  13. data/app/javascript/activeadmin_addons/inputs/slim-select-nested.js +93 -0
  14. data/app/javascript/activeadmin_addons/inputs/slim-select-search.js +37 -0
  15. data/app/javascript/activeadmin_addons/inputs/slim-select-selected-list.js +103 -0
  16. data/app/javascript/activeadmin_addons/inputs/slim-select-simple-tags.js +22 -0
  17. data/app/javascript/activeadmin_addons/inputs/slim-select-tags.js +67 -0
  18. data/app/javascript/activeadmin_addons/inputs/slim-select-utils.js +70 -0
  19. data/app/javascript/activeadmin_addons/inputs/slim-select.js +75 -0
  20. data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/all.scss +5 -11
  21. data/app/javascript/activeadmin_addons/stylesheets/imports/slimselect.css +1 -0
  22. data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/selected-list.scss +0 -1
  23. data/app/javascript/activeadmin_addons/stylesheets/inputs/slim-select.scss +9 -0
  24. data/lib/activeadmin_addons/addons/image_builder.rb +21 -3
  25. data/lib/activeadmin_addons/addons/markdown_builder.rb +38 -0
  26. data/lib/activeadmin_addons/addons/tag_builder.rb +6 -21
  27. data/lib/activeadmin_addons/engine.rb +0 -5
  28. data/lib/activeadmin_addons/support/enum_utils.rb +19 -0
  29. data/lib/activeadmin_addons/support/input_helpers/select_helpers.rb +1 -1
  30. data/lib/activeadmin_addons/support/select_filter_input_extension.rb +19 -0
  31. data/lib/activeadmin_addons/version.rb +1 -1
  32. data/lib/activeadmin_addons.rb +1 -1
  33. data/lib/generators/activeadmin_addons/install/install_generator.rb +2 -1
  34. data/lib/generators/activeadmin_addons/install/templates/initializer.rb +1 -1
  35. data/lib/generators/activeadmin_addons/webpacker/webpacker_generator.rb +1 -1
  36. metadata +83 -181
  37. data/app/assets/images/fileicons/file_extension_3gp.png +0 -0
  38. data/app/assets/images/fileicons/file_extension_7z.png +0 -0
  39. data/app/assets/images/fileicons/file_extension_ace.png +0 -0
  40. data/app/assets/images/fileicons/file_extension_ai.png +0 -0
  41. data/app/assets/images/fileicons/file_extension_aif.png +0 -0
  42. data/app/assets/images/fileicons/file_extension_aiff.png +0 -0
  43. data/app/assets/images/fileicons/file_extension_amr.png +0 -0
  44. data/app/assets/images/fileicons/file_extension_asf.png +0 -0
  45. data/app/assets/images/fileicons/file_extension_asx.png +0 -0
  46. data/app/assets/images/fileicons/file_extension_bat.png +0 -0
  47. data/app/assets/images/fileicons/file_extension_bin.png +0 -0
  48. data/app/assets/images/fileicons/file_extension_bmp.png +0 -0
  49. data/app/assets/images/fileicons/file_extension_bup.png +0 -0
  50. data/app/assets/images/fileicons/file_extension_cab.png +0 -0
  51. data/app/assets/images/fileicons/file_extension_cbr.png +0 -0
  52. data/app/assets/images/fileicons/file_extension_cda.png +0 -0
  53. data/app/assets/images/fileicons/file_extension_cdl.png +0 -0
  54. data/app/assets/images/fileicons/file_extension_cdr.png +0 -0
  55. data/app/assets/images/fileicons/file_extension_chm.png +0 -0
  56. data/app/assets/images/fileicons/file_extension_dat.png +0 -0
  57. data/app/assets/images/fileicons/file_extension_divx.png +0 -0
  58. data/app/assets/images/fileicons/file_extension_dll.png +0 -0
  59. data/app/assets/images/fileicons/file_extension_dmg.png +0 -0
  60. data/app/assets/images/fileicons/file_extension_doc.png +0 -0
  61. data/app/assets/images/fileicons/file_extension_docx.png +0 -0
  62. data/app/assets/images/fileicons/file_extension_dss.png +0 -0
  63. data/app/assets/images/fileicons/file_extension_dvf.png +0 -0
  64. data/app/assets/images/fileicons/file_extension_dwg.png +0 -0
  65. data/app/assets/images/fileicons/file_extension_eml.png +0 -0
  66. data/app/assets/images/fileicons/file_extension_eps.png +0 -0
  67. data/app/assets/images/fileicons/file_extension_exe.png +0 -0
  68. data/app/assets/images/fileicons/file_extension_fla.png +0 -0
  69. data/app/assets/images/fileicons/file_extension_flv.png +0 -0
  70. data/app/assets/images/fileicons/file_extension_gif.png +0 -0
  71. data/app/assets/images/fileicons/file_extension_gz.png +0 -0
  72. data/app/assets/images/fileicons/file_extension_hqx.png +0 -0
  73. data/app/assets/images/fileicons/file_extension_htm.png +0 -0
  74. data/app/assets/images/fileicons/file_extension_html.png +0 -0
  75. data/app/assets/images/fileicons/file_extension_ifo.png +0 -0
  76. data/app/assets/images/fileicons/file_extension_indd.png +0 -0
  77. data/app/assets/images/fileicons/file_extension_iso.png +0 -0
  78. data/app/assets/images/fileicons/file_extension_jar.png +0 -0
  79. data/app/assets/images/fileicons/file_extension_jpeg.png +0 -0
  80. data/app/assets/images/fileicons/file_extension_jpg.png +0 -0
  81. data/app/assets/images/fileicons/file_extension_lnk.png +0 -0
  82. data/app/assets/images/fileicons/file_extension_log.png +0 -0
  83. data/app/assets/images/fileicons/file_extension_m4a.png +0 -0
  84. data/app/assets/images/fileicons/file_extension_m4b.png +0 -0
  85. data/app/assets/images/fileicons/file_extension_m4p.png +0 -0
  86. data/app/assets/images/fileicons/file_extension_m4v.png +0 -0
  87. data/app/assets/images/fileicons/file_extension_mcd.png +0 -0
  88. data/app/assets/images/fileicons/file_extension_mdb.png +0 -0
  89. data/app/assets/images/fileicons/file_extension_mid.png +0 -0
  90. data/app/assets/images/fileicons/file_extension_mov.png +0 -0
  91. data/app/assets/images/fileicons/file_extension_mp2.png +0 -0
  92. data/app/assets/images/fileicons/file_extension_mp3.png +0 -0
  93. data/app/assets/images/fileicons/file_extension_mp4.png +0 -0
  94. data/app/assets/images/fileicons/file_extension_mpeg.png +0 -0
  95. data/app/assets/images/fileicons/file_extension_mpg.png +0 -0
  96. data/app/assets/images/fileicons/file_extension_msi.png +0 -0
  97. data/app/assets/images/fileicons/file_extension_mswmm.png +0 -0
  98. data/app/assets/images/fileicons/file_extension_ogg.png +0 -0
  99. data/app/assets/images/fileicons/file_extension_pdf.png +0 -0
  100. data/app/assets/images/fileicons/file_extension_png.png +0 -0
  101. data/app/assets/images/fileicons/file_extension_pps.png +0 -0
  102. data/app/assets/images/fileicons/file_extension_ppt.png +0 -0
  103. data/app/assets/images/fileicons/file_extension_pptx.png +0 -0
  104. data/app/assets/images/fileicons/file_extension_ps.png +0 -0
  105. data/app/assets/images/fileicons/file_extension_psd.png +0 -0
  106. data/app/assets/images/fileicons/file_extension_pst.png +0 -0
  107. data/app/assets/images/fileicons/file_extension_ptb.png +0 -0
  108. data/app/assets/images/fileicons/file_extension_pub.png +0 -0
  109. data/app/assets/images/fileicons/file_extension_qbb.png +0 -0
  110. data/app/assets/images/fileicons/file_extension_qbw.png +0 -0
  111. data/app/assets/images/fileicons/file_extension_qxd.png +0 -0
  112. data/app/assets/images/fileicons/file_extension_ram.png +0 -0
  113. data/app/assets/images/fileicons/file_extension_rar.png +0 -0
  114. data/app/assets/images/fileicons/file_extension_rm.png +0 -0
  115. data/app/assets/images/fileicons/file_extension_rmvb.png +0 -0
  116. data/app/assets/images/fileicons/file_extension_rtf.png +0 -0
  117. data/app/assets/images/fileicons/file_extension_sea.png +0 -0
  118. data/app/assets/images/fileicons/file_extension_ses.png +0 -0
  119. data/app/assets/images/fileicons/file_extension_sit.png +0 -0
  120. data/app/assets/images/fileicons/file_extension_sitx.png +0 -0
  121. data/app/assets/images/fileicons/file_extension_ss.png +0 -0
  122. data/app/assets/images/fileicons/file_extension_swf.png +0 -0
  123. data/app/assets/images/fileicons/file_extension_tgz.png +0 -0
  124. data/app/assets/images/fileicons/file_extension_thm.png +0 -0
  125. data/app/assets/images/fileicons/file_extension_tif.png +0 -0
  126. data/app/assets/images/fileicons/file_extension_tmp.png +0 -0
  127. data/app/assets/images/fileicons/file_extension_torrent.png +0 -0
  128. data/app/assets/images/fileicons/file_extension_ttf.png +0 -0
  129. data/app/assets/images/fileicons/file_extension_txt.png +0 -0
  130. data/app/assets/images/fileicons/file_extension_unknown.png +0 -0
  131. data/app/assets/images/fileicons/file_extension_vcd.png +0 -0
  132. data/app/assets/images/fileicons/file_extension_vob.png +0 -0
  133. data/app/assets/images/fileicons/file_extension_wav.png +0 -0
  134. data/app/assets/images/fileicons/file_extension_wma.png +0 -0
  135. data/app/assets/images/fileicons/file_extension_wmv.png +0 -0
  136. data/app/assets/images/fileicons/file_extension_wps.png +0 -0
  137. data/app/assets/images/fileicons/file_extension_xls.png +0 -0
  138. data/app/assets/images/fileicons/file_extension_xlsx.png +0 -0
  139. data/app/assets/images/fileicons/file_extension_xpi.png +0 -0
  140. data/app/assets/images/fileicons/file_extension_zip.png +0 -0
  141. data/app/assets/images/material/icons/keyboard_arrow_down.svg +0 -4
  142. data/app/assets/images/material/icons/keyboard_arrow_left.svg +0 -4
  143. data/app/assets/images/material/icons/keyboard_arrow_right.svg +0 -4
  144. data/app/assets/images/material/icons/keyboard_arrow_up.svg +0 -4
  145. data/app/assets/images/material/icons/today.svg +0 -4
  146. data/app/assets/javascripts/activeadmin_addons/all.js +0 -753
  147. data/app/assets/stylesheets/activeadmin_addons/addons/material-datepicker.scss +0 -173
  148. data/app/assets/stylesheets/activeadmin_addons/addons/material-toggle_bool.scss +0 -52
  149. data/app/assets/stylesheets/activeadmin_addons/inputs/select2.scss +0 -3
  150. data/app/assets/stylesheets/activeadmin_addons/material.scss +0 -53
  151. data/app/javascript/activeadmin_addons/addons/interactive_select_tag.js +0 -95
  152. data/app/javascript/activeadmin_addons/inputs/nested-select.js +0 -170
  153. data/app/javascript/activeadmin_addons/inputs/search-select.js +0 -76
  154. data/app/javascript/activeadmin_addons/inputs/select2.js +0 -52
  155. data/app/javascript/activeadmin_addons/inputs/selected-list.js +0 -107
  156. data/app/javascript/activeadmin_addons/inputs/tags.js +0 -76
  157. data/lib/activeadmin_addons/addons/attachment_builder.rb +0 -60
  158. data/lib/activeadmin_addons/support/enumerize_formtastic_support.rb +0 -18
  159. data/lib/generators/activeadmin_addons/assets/assets_generator.rb +0 -53
  160. data/vendor/assets/select2/select2.css +0 -481
  161. data/vendor/assets/select2/select2.full.js +0 -6820
  162. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/addons/interactive_select_tag.scss +0 -0
  163. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/addons/toggle_bool.scss +0 -0
  164. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/imports/jquery-datepicker.scss +0 -0
  165. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/color-picker.scss +0 -0
  166. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/date-time-picker-filter.scss +0 -0
  167. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/date-time-picker.scss +0 -0
  168. /data/app/{assets/stylesheets/activeadmin_addons → javascript/activeadmin_addons/stylesheets}/inputs/numeric-range-filter.scss +0 -0
  169. /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: 31434452186d9b02e7d7272b27d06d1e4831b1c4c6de9c068e973cf5311da476
4
- data.tar.gz: 0a43f7f1d45b50c01eeb4b4f7a56f5ff9bcb4329a24adb4f77fc1d1ca28fa0e7
3
+ metadata.gz: aed38304ff68795198eb34b4fb634a5f8e55143b4f159b04698d0852d32e36ef
4
+ data.tar.gz: 6c4637ae03b38a74d1d06831fea506de8d13a996002d1770a0d5d80372242906
5
5
  SHA512:
6
- metadata.gz: 10db20adc03c85569ab16debe8edffd16115b348baf7779e79544fa42a265058cc60d3d24ac77dea5e85591297a6daeb2ede226141cb7dbb4e34d0776966462a
7
- data.tar.gz: b911e25eeb0801b2bbe7857c012f4c93fa71a2bf77d574d552461e39cdedfcdd698673ed625a4034c749852f2d1b47e1387a7b7c0a4f754cdb3311c753beab6a
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 "rake tests"
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
- super.merge(data: { tags: @options[:tags].present? })
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,6 +15,7 @@ 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
20
  load_data_attr(:predicate, default: "contains")
20
21
  load_data_attr(:filters)
@@ -23,7 +24,7 @@ class NestedLevelInput < ActiveAdminAddons::InputBase
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, default: "80%")
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")
@@ -19,7 +19,7 @@ class SearchSelectInput < ActiveAdminAddons::InputBase
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, default: "80%")
22
+ load_data_attr(:width)
23
23
  load_data_attr(
24
24
  :order,
25
25
  value: @options[:order_by],
@@ -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, default: "80%")
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
+ });
@@ -36,4 +36,4 @@ var initializer = function() {
36
36
  };
37
37
 
38
38
  $(initializer);
39
- $(document).on('turbolinks:load', initializer);
39
+ $(document).on('turbolinks:load turbo:load', initializer);
@@ -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/select2';
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/interactive_select_tag';
9
+ import './addons/slim-select-interactive-tag';
@@ -1,10 +1,13 @@
1
- var initializer = function() {
1
+ const loadEvents = ['turbo:load', 'turbolinks:load', 'DOMContentLoaded'];
2
+
3
+ function initializer() {
2
4
  window.ActiveadminAddons = {
3
5
  config: {
4
- defaultSelect: $('body').data('default-select'),
6
+ defaultSelect: document.querySelector('body').dataset.defaultSelect,
5
7
  },
6
8
  };
7
- };
9
+ }
8
10
 
9
- $(initializer);
10
- $(document).on('turbolinks:load', initializer);
11
+ loadEvents.forEach((event) => {
12
+ document.addEventListener(event, initializer);
13
+ });
@@ -13,4 +13,4 @@ var initializer = function() {
13
13
  };
14
14
 
15
15
  $(initializer);
16
- $(document).on('turbolinks:load', initializer);
16
+ $(document).on('turbolinks:load turbo:load', initializer);
@@ -25,4 +25,4 @@ var initializer = function() {
25
25
  };
26
26
 
27
27
  $(initializer);
28
- $(document).on('turbolinks:load', initializer);
28
+ $(document).on('turbolinks:load turbo:load', initializer);
@@ -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
+ }