rails_admin 3.0.0 → 3.1.2

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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +4 -2
  4. data/Rakefile +2 -0
  5. data/app/assets/javascripts/rails_admin/{application.js → application.js.erb} +8 -0
  6. data/app/assets/stylesheets/rails_admin/{application.scss → application.scss.erb} +4 -0
  7. data/app/controllers/rails_admin/application_controller.rb +2 -0
  8. data/app/controllers/rails_admin/main_controller.rb +9 -14
  9. data/app/helpers/rails_admin/application_helper.rb +37 -9
  10. data/app/helpers/rails_admin/form_builder.rb +10 -0
  11. data/app/helpers/rails_admin/main_helper.rb +7 -15
  12. data/app/views/layouts/rails_admin/_head.html.erb +12 -3
  13. data/app/views/layouts/rails_admin/_secondary_navigation.html.erb +3 -1
  14. data/app/views/layouts/rails_admin/_sidebar_navigation.html.erb +1 -1
  15. data/app/views/layouts/rails_admin/application.html.erb +4 -1
  16. data/app/views/rails_admin/main/_dashboard_history.html.erb +1 -1
  17. data/app/views/rails_admin/main/_form_action_text.html.erb +2 -1
  18. data/app/views/rails_admin/main/_form_file_upload.html.erb +1 -1
  19. data/app/views/rails_admin/main/_form_filtering_multiselect.html.erb +2 -2
  20. data/app/views/rails_admin/main/_form_filtering_select.html.erb +1 -1
  21. data/app/views/rails_admin/main/_form_multiple_file_upload.html.erb +1 -1
  22. data/app/views/rails_admin/main/dashboard.html.erb +2 -2
  23. data/app/views/rails_admin/main/history.html.erb +1 -1
  24. data/app/views/rails_admin/main/index.html.erb +7 -19
  25. data/config/initializers/active_record_extensions.rb +26 -3
  26. data/config/initializers/mongoid_extensions.rb +2 -0
  27. data/config/locales/rails_admin.en.yml +3 -2
  28. data/config/routes.rb +2 -0
  29. data/lib/generators/rails_admin/importmap_formatter.rb +28 -0
  30. data/lib/generators/rails_admin/install_generator.rb +71 -9
  31. data/lib/generators/rails_admin/templates/rails_admin.js +1 -0
  32. data/lib/generators/rails_admin/templates/rails_admin.scss.erb +1 -0
  33. data/lib/generators/rails_admin/templates/rails_admin.webpacker.js +2 -0
  34. data/lib/generators/rails_admin/utils.rb +2 -0
  35. data/lib/rails_admin/abstract_model.rb +9 -2
  36. data/lib/rails_admin/adapters/active_record/association.rb +11 -1
  37. data/lib/rails_admin/adapters/active_record/object_extension.rb +2 -0
  38. data/lib/rails_admin/adapters/active_record/property.rb +2 -0
  39. data/lib/rails_admin/adapters/active_record.rb +25 -2
  40. data/lib/rails_admin/adapters/composite_primary_keys/association.rb +45 -0
  41. data/lib/rails_admin/adapters/composite_primary_keys.rb +40 -0
  42. data/lib/rails_admin/adapters/mongoid/association.rb +14 -4
  43. data/lib/rails_admin/adapters/mongoid/bson.rb +2 -0
  44. data/lib/rails_admin/adapters/mongoid/extension.rb +3 -3
  45. data/lib/rails_admin/adapters/mongoid/object_extension.rb +2 -0
  46. data/lib/rails_admin/adapters/mongoid/property.rb +2 -0
  47. data/lib/rails_admin/adapters/mongoid.rb +4 -2
  48. data/lib/rails_admin/config/actions/base.rb +2 -0
  49. data/lib/rails_admin/config/actions/bulk_delete.rb +2 -0
  50. data/lib/rails_admin/config/actions/dashboard.rb +2 -0
  51. data/lib/rails_admin/config/actions/delete.rb +2 -0
  52. data/lib/rails_admin/config/actions/edit.rb +2 -0
  53. data/lib/rails_admin/config/actions/export.rb +2 -0
  54. data/lib/rails_admin/config/actions/history_index.rb +2 -0
  55. data/lib/rails_admin/config/actions/history_show.rb +2 -0
  56. data/lib/rails_admin/config/actions/index.rb +2 -0
  57. data/lib/rails_admin/config/actions/new.rb +2 -0
  58. data/lib/rails_admin/config/actions/show.rb +2 -0
  59. data/lib/rails_admin/config/actions/show_in_app.rb +2 -0
  60. data/lib/rails_admin/config/actions.rb +2 -0
  61. data/lib/rails_admin/config/configurable.rb +2 -0
  62. data/lib/rails_admin/config/const_load_suppressor.rb +78 -0
  63. data/lib/rails_admin/config/fields/association.rb +2 -0
  64. data/lib/rails_admin/config/fields/base.rb +44 -14
  65. data/lib/rails_admin/config/fields/factories/action_text.rb +2 -0
  66. data/lib/rails_admin/config/fields/factories/active_storage.rb +2 -0
  67. data/lib/rails_admin/config/fields/factories/association.rb +6 -5
  68. data/lib/rails_admin/config/fields/factories/carrierwave.rb +2 -0
  69. data/lib/rails_admin/config/fields/factories/devise.rb +2 -0
  70. data/lib/rails_admin/config/fields/factories/dragonfly.rb +2 -0
  71. data/lib/rails_admin/config/fields/factories/enum.rb +2 -0
  72. data/lib/rails_admin/config/fields/factories/paperclip.rb +2 -0
  73. data/lib/rails_admin/config/fields/factories/password.rb +2 -0
  74. data/lib/rails_admin/config/fields/factories/shrine.rb +2 -0
  75. data/lib/rails_admin/config/fields/group.rb +2 -0
  76. data/lib/rails_admin/config/fields/types/action_text.rb +6 -0
  77. data/lib/rails_admin/config/fields/types/active_record_enum.rb +2 -0
  78. data/lib/rails_admin/config/fields/types/active_storage.rb +14 -0
  79. data/lib/rails_admin/config/fields/types/all.rb +3 -0
  80. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +7 -5
  81. data/lib/rails_admin/config/fields/types/boolean.rb +7 -1
  82. data/lib/rails_admin/config/fields/types/bson_object_id.rb +2 -0
  83. data/lib/rails_admin/config/fields/types/carrierwave.rb +2 -0
  84. data/lib/rails_admin/config/fields/types/citext.rb +2 -0
  85. data/lib/rails_admin/config/fields/types/ck_editor.rb +2 -0
  86. data/lib/rails_admin/config/fields/types/code_mirror.rb +2 -0
  87. data/lib/rails_admin/config/fields/types/color.rb +2 -0
  88. data/lib/rails_admin/config/fields/types/composite_keys_belongs_to_association.rb +31 -0
  89. data/lib/rails_admin/config/fields/types/date.rb +2 -0
  90. data/lib/rails_admin/config/fields/types/datetime.rb +12 -0
  91. data/lib/rails_admin/config/fields/types/decimal.rb +2 -0
  92. data/lib/rails_admin/config/fields/types/dragonfly.rb +2 -0
  93. data/lib/rails_admin/config/fields/types/enum.rb +15 -2
  94. data/lib/rails_admin/config/fields/types/file_upload.rb +2 -0
  95. data/lib/rails_admin/config/fields/types/float.rb +2 -0
  96. data/lib/rails_admin/config/fields/types/froala.rb +2 -0
  97. data/lib/rails_admin/config/fields/types/has_and_belongs_to_many_association.rb +2 -0
  98. data/lib/rails_admin/config/fields/types/has_many_association.rb +2 -0
  99. data/lib/rails_admin/config/fields/types/has_one_association.rb +7 -1
  100. data/lib/rails_admin/config/fields/types/hidden.rb +2 -0
  101. data/lib/rails_admin/config/fields/types/inet.rb +2 -0
  102. data/lib/rails_admin/config/fields/types/integer.rb +2 -0
  103. data/lib/rails_admin/config/fields/types/json.rb +2 -0
  104. data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +22 -0
  105. data/lib/rails_admin/config/fields/types/multiple_carrierwave.rb +2 -0
  106. data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +2 -0
  107. data/lib/rails_admin/config/fields/types/numeric.rb +6 -0
  108. data/lib/rails_admin/config/fields/types/paperclip.rb +2 -0
  109. data/lib/rails_admin/config/fields/types/password.rb +2 -0
  110. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +2 -0
  111. data/lib/rails_admin/config/fields/types/serialized.rb +2 -0
  112. data/lib/rails_admin/config/fields/types/shrine.rb +2 -0
  113. data/lib/rails_admin/config/fields/types/simple_mde.rb +2 -0
  114. data/lib/rails_admin/config/fields/types/string.rb +2 -0
  115. data/lib/rails_admin/config/fields/types/string_like.rb +6 -0
  116. data/lib/rails_admin/config/fields/types/text.rb +2 -0
  117. data/lib/rails_admin/config/fields/types/time.rb +6 -0
  118. data/lib/rails_admin/config/fields/types/timestamp.rb +2 -0
  119. data/lib/rails_admin/config/fields/types/uuid.rb +2 -0
  120. data/lib/rails_admin/config/fields/types/wysihtml5.rb +2 -0
  121. data/lib/rails_admin/config/fields/types.rb +2 -0
  122. data/lib/rails_admin/config/fields.rb +3 -1
  123. data/lib/rails_admin/config/groupable.rb +2 -0
  124. data/lib/rails_admin/config/has_description.rb +2 -0
  125. data/lib/rails_admin/config/has_fields.rb +3 -1
  126. data/lib/rails_admin/config/has_groups.rb +2 -0
  127. data/lib/rails_admin/config/hideable.rb +2 -0
  128. data/lib/rails_admin/config/inspectable.rb +2 -0
  129. data/lib/rails_admin/config/lazy_model.rb +74 -0
  130. data/lib/rails_admin/config/model.rb +5 -1
  131. data/lib/rails_admin/config/proxyable/proxy.rb +2 -0
  132. data/lib/rails_admin/config/proxyable.rb +2 -0
  133. data/lib/rails_admin/config/sections/base.rb +2 -0
  134. data/lib/rails_admin/config/sections/create.rb +2 -0
  135. data/lib/rails_admin/config/sections/edit.rb +2 -0
  136. data/lib/rails_admin/config/sections/export.rb +2 -0
  137. data/lib/rails_admin/config/sections/list.rb +6 -0
  138. data/lib/rails_admin/config/sections/modal.rb +2 -0
  139. data/lib/rails_admin/config/sections/nested.rb +2 -0
  140. data/lib/rails_admin/config/sections/show.rb +2 -0
  141. data/lib/rails_admin/config/sections/update.rb +2 -0
  142. data/lib/rails_admin/config/sections.rb +2 -0
  143. data/lib/rails_admin/config.rb +30 -42
  144. data/lib/rails_admin/engine.rb +19 -17
  145. data/lib/rails_admin/extension.rb +2 -0
  146. data/lib/rails_admin/extensions/cancancan/authorization_adapter.rb +21 -4
  147. data/lib/rails_admin/extensions/cancancan.rb +2 -0
  148. data/lib/rails_admin/extensions/controller_extension.rb +2 -0
  149. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +49 -27
  150. data/lib/rails_admin/extensions/paper_trail.rb +2 -0
  151. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -0
  152. data/lib/rails_admin/extensions/pundit.rb +2 -0
  153. data/lib/rails_admin/support/csv_converter.rb +2 -2
  154. data/lib/rails_admin/support/datetime.rb +3 -1
  155. data/lib/rails_admin/support/es_module_processor.rb +23 -0
  156. data/lib/rails_admin/support/hash_helper.rb +2 -0
  157. data/lib/rails_admin/version.rb +4 -2
  158. data/lib/rails_admin.rb +7 -2
  159. data/lib/tasks/rails_admin.rake +2 -0
  160. data/package.json +2 -2
  161. data/src/rails_admin/base.js +14 -3
  162. data/src/rails_admin/filter-box.js +166 -210
  163. data/src/rails_admin/filtering-multiselect.js +5 -10
  164. data/src/rails_admin/filtering-select.js +16 -7
  165. data/src/rails_admin/i18n.js +3 -1
  166. data/src/rails_admin/jquery.js +3 -0
  167. data/src/rails_admin/nested-form-hooks.js +6 -4
  168. data/src/rails_admin/remote-form.js +5 -5
  169. data/src/rails_admin/styles/base/theming.scss +25 -8
  170. data/src/rails_admin/styles/base.scss +5 -5
  171. data/src/rails_admin/styles/widgets.scss +1 -1
  172. data/src/rails_admin/ui.js +52 -19
  173. data/src/rails_admin/widgets.js +7 -2
  174. data/vendor/assets/fonts/rails_admin/fa-solid-900.ttf +0 -0
  175. data/vendor/assets/fonts/rails_admin/fa-solid-900.woff2 +0 -0
  176. data/vendor/assets/javascripts/rails_admin/jquery3.js +118 -109
  177. data/vendor/assets/stylesheets/rails_admin/font-awesome.scss +4531 -2782
  178. metadata +16 -14
  179. data/lib/generators/rails_admin/templates/rails_admin.js.erb +0 -2
  180. data/lib/generators/rails_admin/templates/rails_admin.scss +0 -1
  181. data/lib/generators/rails_admin/templates/webpack.config.js +0 -29
  182. data/lib/rails_admin/support/esmodule_preprocessor.rb +0 -33
  183. data/vendor/assets/fonts/rails_admin/fa-solid-900.eot +0 -0
  184. data/vendor/assets/fonts/rails_admin/fa-solid-900.svg +0 -5034
  185. data/vendor/assets/fonts/rails_admin/fa-solid-900.woff +0 -0
  186. data/vendor/assets/images/rails_admin/bootstrap/glyphicons-halflings-white.png +0 -0
  187. data/vendor/assets/images/rails_admin/bootstrap/glyphicons-halflings.png +0 -0
@@ -7,98 +7,54 @@ import flatpickr from "flatpickr";
7
7
 
8
8
  $.filters = filters = {
9
9
  append: function (options) {
10
- options = options || {};
11
10
  var field_label = options["label"];
12
11
  var field_name = options["name"];
13
12
  var field_type = options["type"];
14
- var field_value = options["value"];
13
+ var field_value = options["value"] || "";
15
14
  var field_operator = options["operator"];
16
- var select_options = options["select_options"];
17
- var required = options["required"];
15
+ var operators = options["operators"];
18
16
  var index = options["index"];
19
17
  var value_name = "f[" + field_name + "][" + index + "][v]";
20
18
  var operator_name = "f[" + field_name + "][" + index + "][o]";
21
19
  var control = null;
22
20
  var additional_control = null;
23
21
 
22
+ if (operators.length > 0) {
23
+ control = $(
24
+ '<select class="form-control form-select form-select-sm"></select>'
25
+ ).prop("name", operator_name);
26
+
27
+ operators.forEach((operator) => {
28
+ var element = this.build_operator(operator, options);
29
+ if (!element) {
30
+ return;
31
+ }
32
+ if (element.prop("value") === field_operator) {
33
+ element.prop("selected", true);
34
+ }
35
+ control.append(element);
36
+ });
37
+
38
+ if (control.find("[data-additional-fieldset]").length > 0) {
39
+ control.addClass("switch-additional-fieldsets");
40
+ }
41
+ }
42
+
24
43
  switch (field_type) {
25
44
  case "boolean":
26
- control = $('<select class="form-control form-control-sm"></select>')
27
- .prop("name", value_name)
28
- .append('<option value="_discard">...</option>')
29
- .append(
30
- $('<option value="true"></option>')
31
- .prop("selected", field_value == "true")
32
- .text(I18n.t("true"))
33
- )
34
- .append(
35
- $('<option value="false"></option>')
36
- .prop("selected", field_value == "false")
37
- .text(I18n.t("false"))
38
- );
39
- if (!required) {
40
- control.append([
41
- '<option disabled="disabled">---------</option>',
42
- $('<option value="_present"></option>')
43
- .prop("selected", field_value == "_present")
44
- .text(I18n.t("is_present")),
45
- $('<option value="_blank"></option>')
46
- .prop("selected", field_value == "_blank")
47
- .text(I18n.t("is_blank")),
48
- ]);
49
- }
45
+ control &&
46
+ control
47
+ .prop("name", value_name)
48
+ .find("option")
49
+ .each(function () {
50
+ if ($(this).attr("value") === field_value)
51
+ $(this).attr("selected", true);
52
+ });
50
53
  break;
51
54
  case "date":
52
55
  case "datetime":
53
56
  case "timestamp":
54
57
  case "time":
55
- control =
56
- control ||
57
- $(
58
- '<select class="switch-additional-fieldsets form-control form-control-sm"></select>'
59
- )
60
- .prop("name", operator_name)
61
- .append(
62
- $(
63
- '<option data-additional-fieldset="default" value="default"></option>'
64
- )
65
- .prop("selected", field_operator == "default")
66
- .text(I18n.t(field_type == "time" ? "time" : "date"))
67
- )
68
- .append(
69
- $(
70
- '<option data-additional-fieldset="between" value="between"></option>'
71
- )
72
- .prop("selected", field_operator == "between")
73
- .text(I18n.t("between_and_"))
74
- );
75
- if (field_type != "time") {
76
- control.append([
77
- $('<option value="today"></option>')
78
- .prop("selected", field_operator == "today")
79
- .text(I18n.t("today")),
80
- $('<option value="yesterday"></option>')
81
- .prop("selected", field_operator == "yesterday")
82
- .text(I18n.t("yesterday")),
83
- $('<option value="this_week"></option>')
84
- .prop("selected", field_operator == "this_week")
85
- .text(I18n.t("this_week")),
86
- $('<option value="last_week"></option>')
87
- .prop("selected", field_operator == "last_week")
88
- .text(I18n.t("last_week")),
89
- ]);
90
- }
91
- if (!required) {
92
- control.append([
93
- '<option disabled="disabled">---------</option>',
94
- $('<option value="_not_null"></option>')
95
- .prop("selected", field_operator == "_not_null")
96
- .text(I18n.t("is_present")),
97
- $('<option value="_null"></option>')
98
- .prop("selected", field_operator == "_null")
99
- .text(I18n.t("is_blank")),
100
- ]);
101
- }
102
58
  additional_control = $.map(
103
59
  [undefined, "-∞", "∞"],
104
60
  function (placeholder, index) {
@@ -126,101 +82,34 @@ import flatpickr from "flatpickr";
126
82
  );
127
83
  break;
128
84
  case "enum":
129
- var multiple_values = field_value instanceof Array ? true : false;
130
- control = $(
131
- '<select class="select-single form-control form-control-sm"></select>'
132
- )
133
- .css("display", multiple_values ? "none" : "inline-block")
134
- .prop("name", multiple_values ? undefined : value_name)
135
- .data("name", value_name)
136
- .append('<option value="_discard">...</option>')
137
- .append(
138
- required
139
- ? []
140
- : [
141
- $('<option value="_present"></option>')
142
- .prop("selected", field_value == "_present")
143
- .text(I18n.t("is_present")),
144
- $('<option value="_blank"></option>')
145
- .prop("selected", field_value == "_blank")
146
- .text(I18n.t("is_blank")),
147
- '<option disabled="disabled">---------</option>',
148
- ]
149
- )
150
- .append(select_options)
151
- .add(
152
- $(
153
- '<select multiple="multiple" class="select-multiple form-control form-control-sm"></select>'
154
- )
155
- .css("display", multiple_values ? "inline-block" : "none")
156
- .prop("name", multiple_values ? value_name + "[]" : undefined)
157
- .data("name", value_name + "[]")
158
- .append(select_options)
159
- )
160
- .add(
161
- $('<a href="#" class="switch-select"></a>').append(
162
- $("<i></i>").addClass(
163
- "fas fa-" + (multiple_values ? "minus" : "plus")
85
+ if (control) {
86
+ var multiple = field_value instanceof Array;
87
+ control = control
88
+ .prop("name", multiple ? value_name + "[]" : value_name)
89
+ .prop("multiple", multiple)
90
+ .add(
91
+ $('<a href="#" class="switch-select"></a>').append(
92
+ $("<i></i>").addClass(
93
+ "fas fa-" + (multiple ? "minus" : "plus")
94
+ )
164
95
  )
96
+ );
97
+ control.find("option").each(function () {
98
+ const value = $(this).attr("value");
99
+ if (
100
+ multiple ? field_value.includes(value) : value === field_value
165
101
  )
166
- );
102
+ $(this).attr("selected", true);
103
+ });
104
+ if (multiple)
105
+ control.find("option[value^=_],option[disabled]").hide();
106
+ }
167
107
  break;
168
108
  case "citext":
169
109
  case "string":
170
110
  case "text":
171
111
  case "belongs_to_association":
172
- control = $(
173
- '<select class="switch-additional-fieldsets form-control form-control-sm"></select>'
174
- )
175
- .prop("value", field_operator)
176
- .prop("name", operator_name)
177
- .append('<option value="_discard">...</option>')
178
- .append(
179
- $(
180
- '<option data-additional-fieldset="additional-fieldset" value="like"></option>'
181
- )
182
- .prop("selected", field_operator == "like")
183
- .text(I18n.t("contains"))
184
- )
185
- .append(
186
- $(
187
- '<option data-additional-fieldset="additional-fieldset" value="not_like"></option>'
188
- )
189
- .prop("selected", field_operator == "not_like")
190
- .text(I18n.t("does_not_contain"))
191
- )
192
- .append(
193
- $(
194
- '<option data-additional-fieldset="additional-fieldset" value="is"></option>'
195
- )
196
- .prop("selected", field_operator == "is")
197
- .text(I18n.t("is_exactly"))
198
- )
199
- .append(
200
- $(
201
- '<option data-additional-fieldset="additional-fieldset" value="starts_with"></option>'
202
- )
203
- .prop("selected", field_operator == "starts_with")
204
- .text(I18n.t("starts_with"))
205
- )
206
- .append(
207
- $(
208
- '<option data-additional-fieldset="additional-fieldset" value="ends_with"></option>'
209
- )
210
- .prop("selected", field_operator == "ends_with")
211
- .text(I18n.t("ends_with"))
212
- );
213
- if (!required) {
214
- control.append([
215
- '<option disabled="disabled">---------</option>',
216
- $('<option value="_present"></option>')
217
- .prop("selected", field_operator == "_present")
218
- .text(I18n.t("is_present")),
219
- $('<option value="_blank"></option>')
220
- .prop("selected", field_operator == "_blank")
221
- .text(I18n.t("is_blank")),
222
- ]);
223
- }
112
+ case "has_one_association":
224
113
  additional_control = $(
225
114
  '<input class="additional-fieldset form-control form-control-sm" type="text" />'
226
115
  )
@@ -236,35 +125,6 @@ import flatpickr from "flatpickr";
236
125
  case "integer":
237
126
  case "decimal":
238
127
  case "float":
239
- control = $(
240
- '<select class="switch-additional-fieldsets form-control form-control-sm"></select>'
241
- )
242
- .prop("name", operator_name)
243
- .append(
244
- $(
245
- '<option data-additional-fieldset="default" value="default"></option>'
246
- )
247
- .prop("selected", field_operator == "default")
248
- .text(I18n.t("number"))
249
- )
250
- .append(
251
- $(
252
- '<option data-additional-fieldset="between" value="between"></option>'
253
- )
254
- .prop("selected", field_operator == "between")
255
- .text(I18n.t("between_and_"))
256
- );
257
- if (!required) {
258
- control.append([
259
- '<option disabled="disabled">---------</option>',
260
- $('<option value="_not_null"></option>')
261
- .prop("selected", field_operator == "_not_null")
262
- .text(I18n.t("is_present")),
263
- $('<option value="_null"></option>')
264
- .prop("selected", field_operator == "_null")
265
- .text(I18n.t("is_blank")),
266
- ]);
267
- }
268
128
  additional_control = $(
269
129
  '<input class="additional-fieldset default form-control form-control-sm" type="text" />'
270
130
  )
@@ -312,7 +172,7 @@ import flatpickr from "flatpickr";
312
172
  }
313
173
 
314
174
  var filterContainerId = field_name + "-" + index + "-filter-container";
315
- $("p#" + filterContainerId).remove();
175
+ $("#" + filterContainerId).remove();
316
176
 
317
177
  var $content = $("<div>")
318
178
  .attr("id", filterContainerId)
@@ -347,21 +207,114 @@ import flatpickr from "flatpickr";
347
207
 
348
208
  $("hr.filters_box:hidden").show("slow");
349
209
  },
210
+ build_operator: function (operator, options) {
211
+ if (operator instanceof Object) {
212
+ var element = $("<option></option>");
213
+ element.text(operator.label);
214
+ delete operator.label;
215
+ for (const key in operator) {
216
+ element.attr(key, operator[key]);
217
+ }
218
+ return element;
219
+ }
220
+ switch (operator) {
221
+ case "_discard":
222
+ return $('<option value="_discard">...</option>');
223
+ case "_separator":
224
+ return $('<option disabled="disabled">---------</option>');
225
+ case "_present":
226
+ return $('<option value="_present"></option>').text(
227
+ I18n.t("is_present")
228
+ );
229
+ case "_blank":
230
+ return $('<option value="_blank"></option>').text(I18n.t("is_blank"));
231
+ case "_not_null":
232
+ return $('<option value="_not_null"></option>').text(
233
+ I18n.t("is_present")
234
+ );
235
+ case "_null":
236
+ return $('<option value="_null"></option>').text(I18n.t("is_blank"));
237
+
238
+ case "true":
239
+ return $('<option value="true"></option>').text(I18n.t("true"));
240
+ case "false":
241
+ return $('<option value="false"></option>').text(I18n.t("false"));
242
+
243
+ case "today":
244
+ return $('<option value="today"></option>').text(I18n.t("today"));
245
+ case "yesterday":
246
+ return $('<option value="yesterday"></option>').text(
247
+ I18n.t("yesterday")
248
+ );
249
+ case "this_week":
250
+ return $('<option value="this_week"></option>').text(
251
+ I18n.t("this_week")
252
+ );
253
+ case "last_week":
254
+ return $('<option value="last_week"></option>').text(
255
+ I18n.t("last_week")
256
+ );
257
+
258
+ case "like":
259
+ return $(
260
+ '<option data-additional-fieldset="additional-fieldset" value="like"></option>'
261
+ ).text(I18n.t("contains"));
262
+ case "not_like":
263
+ return $(
264
+ '<option data-additional-fieldset="additional-fieldset" value="not_like"></option>'
265
+ ).text(I18n.t("does_not_contain"));
266
+ case "is":
267
+ return $(
268
+ '<option data-additional-fieldset="additional-fieldset" value="is"></option>'
269
+ ).text(I18n.t("is_exactly"));
270
+ case "starts_with":
271
+ return $(
272
+ '<option data-additional-fieldset="additional-fieldset" value="starts_with"></option>'
273
+ ).text(I18n.t("starts_with"));
274
+ case "ends_with":
275
+ return $(
276
+ '<option data-additional-fieldset="additional-fieldset" value="ends_with"></option>'
277
+ ).text(I18n.t("ends_with"));
278
+
279
+ case "default":
280
+ var label;
281
+ switch (options.type) {
282
+ case "date":
283
+ case "datetime":
284
+ case "timestamp":
285
+ label = I18n.t("date");
286
+ break;
287
+ case "time":
288
+ label = I18n.t("time");
289
+ break;
290
+ case "integer":
291
+ case "decimal":
292
+ case "float":
293
+ label = I18n.t("number");
294
+ break;
295
+ }
296
+ return $(
297
+ '<option data-additional-fieldset="default" value="default"></option>'
298
+ ).text(label);
299
+ case "between":
300
+ return $(
301
+ '<option data-additional-fieldset="between" value="between"></option>'
302
+ ).text(I18n.t("between_and_"));
303
+
304
+ default:
305
+ return null;
306
+ }
307
+ },
350
308
  };
351
309
 
352
310
  $(document).on("click", "#filters a", function (e) {
353
311
  e.preventDefault();
354
- $.filters.append({
355
- label: $(this).data("field-label"),
356
- name: $(this).data("field-name"),
357
- type: $(this).data("field-type"),
358
- value: $(this).data("field-value"),
359
- operator: $(this).data("field-operator"),
360
- select_options: $(this).data("field-options"),
361
- required: $(this).data("field-required"),
362
- index: $.now().toString().slice(6, 11),
363
- datetimepicker_options: $(this).data("field-datetimepicker-options"),
364
- });
312
+ $.filters.append(
313
+ $.extend(
314
+ { index: $.now().toString().slice(6, 11) },
315
+ $(this).data("options")
316
+ )
317
+ );
365
318
  });
366
319
 
367
320
  $(document).on("click", "#filters_box .delete", function (e) {
@@ -374,12 +327,15 @@ import flatpickr from "flatpickr";
374
327
 
375
328
  $(document).on("click", "#filters_box .switch-select", function (e) {
376
329
  e.preventDefault();
377
- var selected_select = $(this).siblings("select:visible");
378
- var not_selected_select = $(this).siblings("select:hidden");
379
- not_selected_select
380
- .attr("name", not_selected_select.data("name"))
381
- .show("slow");
382
- selected_select.attr("name", null).hide("slow");
330
+ var select = $(this).siblings("select");
331
+ select.attr("multiple", !select.attr("multiple"));
332
+ select.attr(
333
+ "name",
334
+ select.attr("multiple")
335
+ ? select.attr("name") + "[]"
336
+ : select.attr("name").replace(/\[\]$/, "")
337
+ );
338
+ select.find("option[value^=_],option[disabled]").toggle();
383
339
  $(this).find("i").toggleClass("fa-plus fa-minus");
384
340
  });
385
341
 
@@ -1,7 +1,6 @@
1
1
  import jQuery from "jquery";
2
- import "jquery-ui/ui/widget";
2
+ import "jquery-ui/ui/widget.js";
3
3
  import I18n from "./i18n";
4
-
5
4
  (function ($) {
6
5
  $.widget("ra.filteringMultiselect", {
7
6
  _cache: {},
@@ -112,15 +111,11 @@ import I18n from "./i18n";
112
111
  }
113
112
  if (this.options.sortable) {
114
113
  this.up = $(
115
- '<a href="#" class="fas fa-chevron-circle-up ra-multiselect-item-up">' +
116
- this.options.regional.up +
117
- "</a>"
118
- );
114
+ '<a href="#" class="fas fa-chevron-circle-up ra-multiselect-item-up"></a>'
115
+ ).attr("title", this.options.regional.up);
119
116
  this.down = $(
120
- '<a href="#" class="fas fa-chevron-circle-down ra-multiselect-item-down">' +
121
- this.options.regional.down +
122
- "</a>"
123
- );
117
+ '<a href="#" class="fas fa-chevron-circle-down ra-multiselect-item-down"></a>'
118
+ ).attr("title", this.options.regional.down);
124
119
  columns.center.append(this.up).append(this.down);
125
120
  }
126
121
 
@@ -1,6 +1,6 @@
1
1
  import jQuery from "jquery";
2
- import "jquery-ui/ui/widget";
3
- import "jquery-ui/ui/widgets/autocomplete";
2
+ import "jquery-ui/ui/widget.js";
3
+ import "jquery-ui/ui/widgets/autocomplete.js";
4
4
  import I18n from "./i18n";
5
5
 
6
6
  (function ($) {
@@ -216,11 +216,20 @@ import I18n from "./i18n";
216
216
  minLength: this.options.minLength,
217
217
  source: this._getSourceFunction(this.options.source),
218
218
  select: function (event, ui) {
219
- var option = $("<option>")
220
- .attr("value", ui.item.id)
221
- .attr("selected", "selected")
222
- .text(ui.item.value);
223
- self.element.html(option).trigger("change", ui.item.id);
219
+ var option = self.element.find(
220
+ `option[value="${CSS.escape(ui.item.id)}"]`
221
+ );
222
+ self.element.find("option[selected]").attr("selected", false);
223
+ if (option.length > 0) {
224
+ option.attr("selected", "selected");
225
+ } else {
226
+ option = $("<option>")
227
+ .attr("value", ui.item.id)
228
+ .attr("selected", true)
229
+ .text(ui.item.value);
230
+ self.element.append(option);
231
+ }
232
+ self.element.trigger("change", ui.item.id);
224
233
  self._trigger("selected", event, {
225
234
  item: option,
226
235
  });
@@ -1,4 +1,4 @@
1
- export default {
1
+ var I18n = {
2
2
  locale: null,
3
3
  translations: null,
4
4
  init(locale, translations) {
@@ -14,3 +14,5 @@ export default {
14
14
  return this.translations[key] || humanize;
15
15
  },
16
16
  };
17
+
18
+ export { I18n as default };
@@ -0,0 +1,3 @@
1
+ import jQuery from "jquery";
2
+
3
+ window.$ = window.jQuery = jQuery;
@@ -1,5 +1,5 @@
1
1
  import jQuery from "jquery";
2
- import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
2
+ import * as bootstrap from "bootstrap";
3
3
 
4
4
  (function ($) {
5
5
  $(document).ready(function () {
@@ -44,9 +44,9 @@ import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
44
44
  bootstrap.Tab.getOrCreateInstance(element).show();
45
45
  });
46
46
  if (!one_to_one) {
47
- nav.filter(":hidden").show("slow");
47
+ new bootstrap.Collapse(nav[0], { toggle: false }).show();
48
48
  }
49
- content.filter(":hidden").show("slow");
49
+ new bootstrap.Collapse(content[0], { toggle: false }).show();
50
50
  toggler
51
51
  .addClass("active")
52
52
  .removeClass("disabled")
@@ -87,7 +87,9 @@ import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
87
87
  });
88
88
  current_li.remove();
89
89
  if (nav.children().length === 0) {
90
- nav.filter(":visible").hide("slow");
90
+ new bootstrap.Collapse(controls.siblings(".tab-content")[0], {
91
+ toggle: false,
92
+ }).hide();
91
93
  toggler
92
94
  .removeClass("active")
93
95
  .addClass("disabled")
@@ -1,7 +1,7 @@
1
1
  import Rails from "@rails/ujs";
2
2
  import jQuery from "jquery";
3
- import "jquery-ui/ui/widget";
4
- import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
3
+ import "jquery-ui/ui/widget.js";
4
+ import * as bootstrap from "bootstrap";
5
5
 
6
6
  (function ($) {
7
7
  $.widget("ra.remoteForm", {
@@ -105,9 +105,8 @@ import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
105
105
  document.dispatchEvent(event);
106
106
 
107
107
  form.bind("ajax:complete", function (event) {
108
- var data = event.detail[0],
109
- status = event.detail[1];
110
- if (status == "OK") {
108
+ var data = event.detail[0];
109
+ if (data.status == 200) {
111
110
  var json = $.parseJSON(data.responseText);
112
111
  var option =
113
112
  '<option value="' +
@@ -184,6 +183,7 @@ import * as bootstrap from "bootstrap/dist/js/bootstrap.esm";
184
183
  new bootstrap.Modal(widget.dialog[0], {
185
184
  keyboard: true,
186
185
  backdrop: true,
186
+ focus: false,
187
187
  show: true,
188
188
  }).show();
189
189
  }
@@ -19,7 +19,7 @@ body.rails_admin {
19
19
 
20
20
  img {
21
21
  position: absolute;
22
- top: ((40px - $avatar-size) / 2);
22
+ top: calc((40px - $avatar-size) / 2);
23
23
 
24
24
  & + span {
25
25
  margin-left: ($avatar-size + 5px);
@@ -29,18 +29,32 @@ body.rails_admin {
29
29
  }
30
30
 
31
31
  /* Sidebar navigation */
32
- .btn-toggle-nav {
32
+ .sidebar.btn-toggle-nav {
33
33
  padding: 0;
34
34
 
35
- .dropdown-header {
36
- padding: ($grid-gutter-width / 2) ($grid-gutter-width / 2) 3px;
35
+ .btn-toggle {
36
+ margin-top: calc(#{$grid-gutter-width} / 2);
37
+ padding: 3px calc(#{$grid-gutter-width} / 2);
37
38
  font-weight: bold;
39
+ color: $gray-600;
40
+ }
41
+
42
+ .btn-toggle[aria-expanded="true"] {
38
43
  color: $gray-700;
39
- text-transform: uppercase;
40
44
  }
41
45
 
42
- > li > a {
43
- padding: ($navbar-padding-y / 2) ($grid-gutter-width / 2);
46
+ .btn-toggle-nav > li > a {
47
+ padding: calc(#{$navbar-padding-y} / 2) calc(#{$grid-gutter-width} / 2);
48
+
49
+ &.active {
50
+ background-color: map-get($theme-colors, primary);
51
+ color: color-contrast(map-get($theme-colors, primary));
52
+ }
53
+
54
+ &:hover {
55
+ background-color: map-get($theme-colors, primary);
56
+ color: color-contrast(map-get($theme-colors, primary));
57
+ }
44
58
 
45
59
  &.nav-level-1 {
46
60
  padding-left: $grid-gutter-width;
@@ -303,11 +317,14 @@ body.rails_admin {
303
317
  }
304
318
  }
305
319
  }
320
+ .pagination .page-item {
321
+ white-space: nowrap;
322
+ }
306
323
  }
307
324
 
308
325
  @media screen and (min-width: map-get($grid-breakpoints, "sm")) {
309
326
  body.rails_admin {
310
- .btn-toggle-nav {
327
+ .sidebar.btn-toggle-nav {
311
328
  position: fixed;
312
329
  top: $nav-link-height + $navbar-padding-y * 2;
313
330
  bottom: 0;