rails_admin 3.3.1 → 4.0.0.beta

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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -3
  3. data/README.md +11 -11
  4. data/Rakefile +3 -11
  5. data/app/assets/builds/rails_admin.css +10 -0
  6. data/app/assets/builds/rails_admin.js +34 -0
  7. data/app/controllers/rails_admin/main_controller.rb +3 -14
  8. data/app/helpers/rails_admin/application_helper.rb +3 -15
  9. data/app/helpers/rails_admin/form_builder.rb +6 -6
  10. data/app/views/layouts/rails_admin/_head.html.erb +10 -27
  11. data/app/views/layouts/rails_admin/_head_custom.html.erb +3 -0
  12. data/app/views/layouts/rails_admin/_secondary_navigation.html.erb +1 -1
  13. data/app/views/rails_admin/main/_dashboard_history.html.erb +1 -1
  14. data/app/views/rails_admin/main/_delete_notice.html.erb +3 -3
  15. data/app/views/rails_admin/main/_form_boolean.html.erb +9 -13
  16. data/app/views/rails_admin/main/_submit_buttons.html.erb +4 -4
  17. data/app/views/rails_admin/main/bulk_delete.html.erb +2 -2
  18. data/app/views/rails_admin/main/dashboard.html.erb +3 -3
  19. data/app/views/rails_admin/main/delete.html.erb +2 -2
  20. data/app/views/rails_admin/main/export.html.erb +2 -2
  21. data/app/views/rails_admin/main/history.html.erb +2 -2
  22. data/app/views/rails_admin/main/index.html.erb +3 -3
  23. data/config/initializers/active_record_extensions.rb +1 -4
  24. data/lib/generators/rails_admin/install_generator.rb +37 -92
  25. data/lib/generators/rails_admin/templates/rails_admin.scss.erb +1 -1
  26. data/lib/rails_admin/abstract_model.rb +69 -191
  27. data/lib/rails_admin/adapters/active_record/property.rb +7 -0
  28. data/lib/rails_admin/adapters/active_record/reflection.rb +87 -0
  29. data/lib/rails_admin/adapters/active_record/repository.rb +216 -0
  30. data/lib/rails_admin/adapters/active_record/statement_builder.rb +148 -0
  31. data/lib/rails_admin/adapters/active_record/where_builder.rb +40 -0
  32. data/lib/rails_admin/adapters/active_record.rb +7 -360
  33. data/lib/rails_admin/adapters/mongoid/extension.rb +16 -6
  34. data/lib/rails_admin/adapters/mongoid/property.rb +7 -0
  35. data/lib/rails_admin/adapters/mongoid/reflection.rb +58 -0
  36. data/lib/rails_admin/adapters/mongoid/repository.rb +237 -0
  37. data/lib/rails_admin/adapters/mongoid/statement_builder.rb +93 -0
  38. data/lib/rails_admin/adapters/mongoid.rb +7 -305
  39. data/lib/rails_admin/adapters/reflection.rb +105 -0
  40. data/lib/rails_admin/adapters/repository.rb +169 -0
  41. data/lib/rails_admin/adapters/statement_builder.rb +109 -0
  42. data/lib/rails_admin/adapters.rb +94 -0
  43. data/lib/rails_admin/config/actions/base.rb +8 -0
  44. data/lib/rails_admin/config/actions/bulk_delete.rb +4 -4
  45. data/lib/rails_admin/config/actions/dashboard.rb +1 -1
  46. data/lib/rails_admin/config/actions/edit.rb +3 -2
  47. data/lib/rails_admin/config/actions/export.rb +1 -2
  48. data/lib/rails_admin/config/actions/index.rb +3 -3
  49. data/lib/rails_admin/config/actions/new.rb +3 -2
  50. data/lib/rails_admin/config/actions/show.rb +1 -1
  51. data/lib/rails_admin/config/configurable.rb +3 -2
  52. data/lib/rails_admin/config/fields/association.rb +9 -8
  53. data/lib/rails_admin/config/fields/base.rb +55 -37
  54. data/lib/rails_admin/config/fields/collection_association.rb +2 -2
  55. data/lib/rails_admin/config/fields/factories/carrierwave.rb +35 -20
  56. data/lib/rails_admin/config/fields/factories/dragonfly.rb +30 -18
  57. data/lib/rails_admin/config/fields/factories/enum.rb +14 -8
  58. data/lib/rails_admin/config/fields/factories/paperclip.rb +29 -19
  59. data/lib/rails_admin/config/fields/factories/shrine.rb +19 -8
  60. data/lib/rails_admin/config/fields/singular_association.rb +6 -1
  61. data/lib/rails_admin/config/fields/types/active_record_enum.rb +3 -7
  62. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +8 -4
  63. data/lib/rails_admin/config/fields/types/bson_object_id.rb +1 -1
  64. data/lib/rails_admin/config/fields/types/datetime.rb +0 -4
  65. data/lib/rails_admin/config/fields/types/dragonfly.rb +1 -1
  66. data/lib/rails_admin/config/fields/types/enum.rb +11 -2
  67. data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +0 -2
  68. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +4 -4
  69. data/lib/rails_admin/config/fields/types/time.rb +1 -1
  70. data/lib/rails_admin/config/model.rb +27 -5
  71. data/lib/rails_admin/config/sections/list.rb +0 -8
  72. data/lib/rails_admin/config.rb +7 -21
  73. data/lib/rails_admin/criteria/path.rb +66 -0
  74. data/lib/rails_admin/criteria/period.rb +67 -0
  75. data/lib/rails_admin/engine.rb +11 -15
  76. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -3
  77. data/lib/rails_admin/extensions/url_for_extension.rb +8 -0
  78. data/lib/rails_admin/support/asset_source.rb +42 -0
  79. data/lib/rails_admin/support/composite_keys_serializer.rb +28 -2
  80. data/lib/rails_admin/support/csv_converter.rb +3 -10
  81. data/lib/rails_admin/version.rb +8 -7
  82. data/lib/rails_admin.rb +7 -1
  83. data/lib/tasks/assets.rake +23 -0
  84. data/package.json +12 -7
  85. data/src/rails_admin/base.js +18 -15
  86. data/src/rails_admin/filter-box.js +7 -4
  87. data/src/rails_admin/filtering-multiselect.js +1 -1
  88. data/src/rails_admin/filtering-select.js +8 -8
  89. data/src/rails_admin/flatpickr.js +14 -0
  90. data/src/rails_admin/remote-form.js +74 -48
  91. data/src/rails_admin/styles/base/theming.scss +48 -25
  92. data/src/rails_admin/styles/base.scss +25 -1
  93. data/src/rails_admin/styles/filtering-select.scss +23 -62
  94. data/src/rails_admin/ui.js +1 -1
  95. data/src/rails_admin/vendor/jquery_nested_form.js +4 -4
  96. data/src/rails_admin/widgets.js +44 -11
  97. metadata +30 -124
  98. data/app/assets/javascripts/rails_admin/application.js.erb +0 -30
  99. data/app/assets/javascripts/rails_admin/custom/ui.js +0 -1
  100. data/app/assets/stylesheets/rails_admin/application.scss.erb +0 -35
  101. data/app/assets/stylesheets/rails_admin/custom/mixins.scss +0 -11
  102. data/app/assets/stylesheets/rails_admin/custom/theming.scss +0 -13
  103. data/app/assets/stylesheets/rails_admin/custom/variables.scss +0 -15
  104. data/lib/generators/rails_admin/importmap_formatter.rb +0 -29
  105. data/lib/generators/rails_admin/templates/rails_admin.vite.js +0 -2
  106. data/lib/generators/rails_admin/templates/rails_admin.webpacker.js +0 -2
  107. data/lib/rails_admin/adapters/active_record/object_extension.rb +0 -13
  108. data/lib/rails_admin/adapters/mongoid/object_extension.rb +0 -29
  109. data/lib/rails_admin/support/es_module_processor.rb +0 -23
  110. data/lib/rails_admin/support/serialization_schema.rb +0 -72
  111. data/vendor/assets/fonts/rails_admin/fa-solid-900.ttf +0 -0
  112. data/vendor/assets/javascripts/rails_admin/bootstrap.js +0 -5046
  113. data/vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js +0 -11246
  114. data/vendor/assets/javascripts/rails_admin/jquery-ui/data.js +0 -41
  115. data/vendor/assets/javascripts/rails_admin/jquery-ui/effect.js +0 -1637
  116. data/vendor/assets/javascripts/rails_admin/jquery-ui/ie.js +0 -17
  117. data/vendor/assets/javascripts/rails_admin/jquery-ui/keycode.js +0 -47
  118. data/vendor/assets/javascripts/rails_admin/jquery-ui/position.js +0 -500
  119. data/vendor/assets/javascripts/rails_admin/jquery-ui/safe-active-element.js +0 -42
  120. data/vendor/assets/javascripts/rails_admin/jquery-ui/scroll-parent.js +0 -47
  121. data/vendor/assets/javascripts/rails_admin/jquery-ui/unique-id.js +0 -51
  122. data/vendor/assets/javascripts/rails_admin/jquery-ui/version.js +0 -17
  123. data/vendor/assets/javascripts/rails_admin/jquery-ui/widget.js +0 -735
  124. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/autocomplete.js +0 -689
  125. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/menu.js +0 -680
  126. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/mouse.js +0 -230
  127. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/sortable.js +0 -1561
  128. data/vendor/assets/javascripts/rails_admin/jquery3.js +0 -10881
  129. data/vendor/assets/javascripts/rails_admin/popper.js +0 -1974
  130. data/vendor/assets/stylesheets/rails_admin/bootstrap/_accordion.scss +0 -118
  131. data/vendor/assets/stylesheets/rails_admin/bootstrap/_alert.scss +0 -57
  132. data/vendor/assets/stylesheets/rails_admin/bootstrap/_badge.scss +0 -29
  133. data/vendor/assets/stylesheets/rails_admin/bootstrap/_breadcrumb.scss +0 -28
  134. data/vendor/assets/stylesheets/rails_admin/bootstrap/_button-group.scss +0 -139
  135. data/vendor/assets/stylesheets/rails_admin/bootstrap/_buttons.scss +0 -111
  136. data/vendor/assets/stylesheets/rails_admin/bootstrap/_card.scss +0 -216
  137. data/vendor/assets/stylesheets/rails_admin/bootstrap/_carousel.scss +0 -229
  138. data/vendor/assets/stylesheets/rails_admin/bootstrap/_close.scss +0 -40
  139. data/vendor/assets/stylesheets/rails_admin/bootstrap/_containers.scss +0 -41
  140. data/vendor/assets/stylesheets/rails_admin/bootstrap/_dropdown.scss +0 -240
  141. data/vendor/assets/stylesheets/rails_admin/bootstrap/_forms.scss +0 -9
  142. data/vendor/assets/stylesheets/rails_admin/bootstrap/_functions.scss +0 -302
  143. data/vendor/assets/stylesheets/rails_admin/bootstrap/_grid.scss +0 -33
  144. data/vendor/assets/stylesheets/rails_admin/bootstrap/_helpers.scss +0 -9
  145. data/vendor/assets/stylesheets/rails_admin/bootstrap/_images.scss +0 -42
  146. data/vendor/assets/stylesheets/rails_admin/bootstrap/_list-group.scss +0 -174
  147. data/vendor/assets/stylesheets/rails_admin/bootstrap/_mixins.scss +0 -43
  148. data/vendor/assets/stylesheets/rails_admin/bootstrap/_modal.scss +0 -209
  149. data/vendor/assets/stylesheets/rails_admin/bootstrap/_nav.scss +0 -139
  150. data/vendor/assets/stylesheets/rails_admin/bootstrap/_navbar.scss +0 -335
  151. data/vendor/assets/stylesheets/rails_admin/bootstrap/_offcanvas.scss +0 -83
  152. data/vendor/assets/stylesheets/rails_admin/bootstrap/_pagination.scss +0 -64
  153. data/vendor/assets/stylesheets/rails_admin/bootstrap/_placeholders.scss +0 -51
  154. data/vendor/assets/stylesheets/rails_admin/bootstrap/_popover.scss +0 -158
  155. data/vendor/assets/stylesheets/rails_admin/bootstrap/_progress.scss +0 -48
  156. data/vendor/assets/stylesheets/rails_admin/bootstrap/_reboot.scss +0 -625
  157. data/vendor/assets/stylesheets/rails_admin/bootstrap/_root.scss +0 -54
  158. data/vendor/assets/stylesheets/rails_admin/bootstrap/_spinners.scss +0 -69
  159. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tables.scss +0 -155
  160. data/vendor/assets/stylesheets/rails_admin/bootstrap/_toasts.scss +0 -51
  161. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss +0 -115
  162. data/vendor/assets/stylesheets/rails_admin/bootstrap/_transitions.scss +0 -27
  163. data/vendor/assets/stylesheets/rails_admin/bootstrap/_type.scss +0 -104
  164. data/vendor/assets/stylesheets/rails_admin/bootstrap/_utilities.scss +0 -630
  165. data/vendor/assets/stylesheets/rails_admin/bootstrap/_variables.scss +0 -1641
  166. data/vendor/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss +0 -53
  167. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_floating-labels.scss +0 -63
  168. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-check.scss +0 -152
  169. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-control.scss +0 -219
  170. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-range.scss +0 -91
  171. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-select.scss +0 -72
  172. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-text.scss +0 -11
  173. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_input-group.scss +0 -121
  174. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_labels.scss +0 -36
  175. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_validation.scss +0 -12
  176. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_clearfix.scss +0 -3
  177. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_colored-links.scss +0 -12
  178. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_position.scss +0 -30
  179. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_ratio.scss +0 -26
  180. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stacks.scss +0 -15
  181. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stretched-link.scss +0 -15
  182. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_text-truncation.scss +0 -7
  183. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_visually-hidden.scss +0 -8
  184. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_vr.scss +0 -8
  185. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_alert.scss +0 -11
  186. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_backdrop.scss +0 -14
  187. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss +0 -78
  188. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_box-shadow.scss +0 -18
  189. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_breakpoints.scss +0 -127
  190. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss +0 -133
  191. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_caret.scss +0 -64
  192. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss +0 -9
  193. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_color-scheme.scss +0 -7
  194. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_container.scss +0 -9
  195. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_deprecate.scss +0 -10
  196. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss +0 -144
  197. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss +0 -47
  198. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss +0 -151
  199. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss +0 -16
  200. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss +0 -24
  201. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_lists.scss +0 -7
  202. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss +0 -31
  203. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-text.scss +0 -17
  204. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss +0 -6
  205. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_table-variants.scss +0 -21
  206. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_text-truncate.scss +0 -8
  207. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_transition.scss +0 -26
  208. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_utilities.scss +0 -89
  209. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_visually-hidden.scss +0 -29
  210. data/vendor/assets/stylesheets/rails_admin/bootstrap/utilities/_api.scss +0 -47
  211. data/vendor/assets/stylesheets/rails_admin/bootstrap/vendor/_rfs.scss +0 -354
  212. data/vendor/assets/stylesheets/rails_admin/flatpickr.css +0 -791
  213. data/vendor/assets/stylesheets/rails_admin/font-awesome.scss +0 -6351
@@ -1,6 +1,6 @@
1
1
  import jQuery from "jquery";
2
2
  import "jquery-ui/ui/widget.js";
3
- import I18n from "./i18n";
3
+ import I18n from "./i18n.js";
4
4
 
5
5
  (function ($) {
6
6
  $.widget("ra.filteringMultiselect", $.ra.abstractSelect, {
@@ -1,7 +1,7 @@
1
1
  import jQuery from "jquery";
2
2
  import "jquery-ui/ui/widget.js";
3
3
  import "jquery-ui/ui/widgets/autocomplete.js";
4
- import I18n from "./i18n";
4
+ import I18n from "./i18n.js";
5
5
 
6
6
  (function ($) {
7
7
  "use strict";
@@ -30,7 +30,7 @@ import I18n from "./i18n";
30
30
  // to be generated.
31
31
  if (this.filtering_select.length > 0) {
32
32
  this.input = this.filtering_select.children("input");
33
- this.button = this.filtering_select.children(".input-group-btn");
33
+ this.button = this.filtering_select.children(".btn");
34
34
  } else {
35
35
  this.element.hide();
36
36
  this.filtering_select = this._inputGroup(this.element.attr("id"));
@@ -106,7 +106,7 @@ import I18n from "./i18n";
106
106
  var self = this;
107
107
  var requestIndex = 0;
108
108
 
109
- if ($.isArray(source)) {
109
+ if (Array.isArray(source)) {
110
110
  return function (request, response) {
111
111
  response(self._getResultSet(request, source, false));
112
112
  };
@@ -152,11 +152,9 @@ import I18n from "./i18n";
152
152
  },
153
153
 
154
154
  _buttonField: function () {
155
+ // A direct child of .input-group, so Bootstrap joins it to the input.
155
156
  return $(
156
- '<span class="input-group-btn">' +
157
- '<label class="btn btn-info dropdown-toggle" title="Show All Items" role="button">' +
158
- "</label>" +
159
- "</span>"
157
+ '<label class="btn btn-info dropdown-toggle" title="Show All Items" role="button"></label>'
160
158
  );
161
159
  },
162
160
 
@@ -212,6 +210,8 @@ import I18n from "./i18n";
212
210
  delay: this.options.searchDelay,
213
211
  minLength: this.options.minLength,
214
212
  source: this._getSourceFunction(this.options.source),
213
+ // Render the menu as a Bootstrap dropdown, so it follows the app's theme.
214
+ classes: { "ui-autocomplete": "ui-front dropdown-menu" },
215
215
  select: function (event, ui) {
216
216
  var option = self.element.find(
217
217
  `option[value="${CSS.escape(ui.item.id)}"]`
@@ -289,7 +289,7 @@ import I18n from "./i18n";
289
289
  this.input.data("ui-autocomplete")._renderItem = function (ul, item) {
290
290
  return $("<li></li>")
291
291
  .data("ui-autocomplete-item", item)
292
- .append($("<a></a>").html(item.html || item.id))
292
+ .append($('<a class="dropdown-item"></a>').html(item.html || item.id))
293
293
  .appendTo(ul);
294
294
  };
295
295
  },
@@ -0,0 +1,14 @@
1
+ // flatpickr with every locale registered onto its shared `l10ns` singleton, so the
2
+ // date/time widgets can honour `locale: I18n.locale`. This is the equivalent of the
3
+ // Sprockets manifest's old `flatpickr-with-locales` require. Import this instead of
4
+ // "flatpickr" directly.
5
+ //
6
+ // flatpickr assigns itself to `window.flatpickr` on load, and the l10n bundle
7
+ // self-registers onto that global - so the "flatpickr" import has to come first to
8
+ // win the evaluation-order race. Assigning the locales by hand instead does not
9
+ // work: esbuild's Node interop hands back the wrapped module namespace, which
10
+ // clobbers `l10ns.default` and breaks every picker.
11
+ import flatpickr from "flatpickr";
12
+ import "flatpickr/dist/l10n/index.js";
13
+
14
+ export default flatpickr;
@@ -1,4 +1,3 @@
1
- import Rails from "@rails/ujs";
2
1
  import jQuery from "jquery";
3
2
  import "jquery-ui/ui/widget.js";
4
3
  import * as bootstrap from "bootstrap";
@@ -79,7 +78,13 @@ import * as bootstrap from "bootstrap";
79
78
  cancelButtonText = dialog.find(":submit[name=_continue]").html();
80
79
  dialog.find(".form-actions").remove();
81
80
 
82
- form.attr("data-remote", true).attr("data-type", "json");
81
+ // We submit this form ourselves (see _submitForm) and want the JSON back,
82
+ // not a Turbo navigation - catch both the save button and an Enter keypress.
83
+ form.attr("data-turbo", "false");
84
+ form.off("submit.raRemoteForm").on("submit.raRemoteForm", function (e) {
85
+ e.preventDefault();
86
+ widget._submitForm(form);
87
+ });
83
88
  dialog.find(".modal-header-title").text(form.data("title"));
84
89
  dialog
85
90
  .find(".cancel-action")
@@ -96,63 +101,84 @@ import * as bootstrap from "bootstrap";
96
101
  .find(".save-action")
97
102
  .unbind()
98
103
  .click(function () {
99
- Rails.fire(form[0], "submit");
104
+ form.trigger("submit.raRemoteForm");
100
105
  return false;
101
106
  })
102
107
  .html(saveButtonText);
103
108
 
104
109
  const event = new CustomEvent("rails_admin.dom_ready", { detail: form });
105
110
  document.dispatchEvent(event);
111
+ },
112
+
113
+ _submitForm: function (form) {
114
+ var widget = this;
115
+ var csrf = document.querySelector('meta[name="csrf-token"]');
116
+ // We read the form without submitting it, so let widgets write back first.
117
+ form[0].dispatchEvent(
118
+ new CustomEvent("rails_admin.before_remote_submit")
119
+ );
120
+ jQuery.ajax({
121
+ url: form.attr("action"),
122
+ method: (form.attr("method") || "post").toUpperCase(),
123
+ data: new FormData(form[0]),
124
+ processData: false,
125
+ contentType: false,
126
+ headers: {
127
+ "X-CSRF-Token": csrf ? csrf.content : "",
128
+ // JSON on success, the modal HTML (format.js) on validation errors.
129
+ Accept: "application/json, text/javascript",
130
+ },
131
+ complete: function (xhr) {
132
+ widget._handleFormResponse(xhr);
133
+ },
134
+ });
135
+ },
106
136
 
107
- form.bind("ajax:complete", function (event) {
108
- var data = event.detail[0];
109
- if (data.status == 200) {
110
- var json = $.parseJSON(data.responseText);
111
- var option =
112
- '<option value="' +
113
- json.id +
114
- '" selected>' +
115
- json.label +
116
- "</option>";
117
- var select = widget.element.find("select").filter(":hidden");
137
+ _handleFormResponse: function (xhr) {
138
+ var widget = this,
139
+ dialog = this._getModal();
140
+ if (xhr.status == 200) {
141
+ var json = JSON.parse(xhr.responseText);
142
+ var option =
143
+ '<option value="' +
144
+ json.id +
145
+ '" selected>' +
146
+ json.label +
147
+ "</option>";
148
+ var select = widget.element.find("select").filter(":hidden");
118
149
 
119
- if (widget.element.find(".filtering-select").length) {
120
- // select input
121
- var input = widget.element
122
- .find(".filtering-select")
123
- .children(".ra-filtering-select-input");
124
- input.val(json.label);
125
- if (!select.find("option[value=" + json.id + "]").length) {
126
- // not a replace
127
- select.html(option).val(json.id);
128
- widget.element.find(".update").removeClass("disabled");
129
- }
130
- } else {
131
- // multi-select input
132
- var multiselect = widget.element.find(".ra-multiselect");
133
- if (multiselect.find("option[value=" + json.id + "]").length) {
134
- // replace
135
- select.find("option[value=" + json.id + "]").text(json.label);
136
- multiselect
137
- .find("option[value= " + json.id + "]")
138
- .text(json.label);
139
- } else {
140
- // add
141
- select.append(option);
142
- multiselect
143
- .find("select.ra-multiselect-selection")
144
- .append(option);
145
- }
150
+ if (widget.element.find(".filtering-select").length) {
151
+ // select input
152
+ var input = widget.element
153
+ .find(".filtering-select")
154
+ .children(".ra-filtering-select-input");
155
+ input.val(json.label);
156
+ if (!select.find("option[value=" + json.id + "]").length) {
157
+ // not a replace
158
+ select.html(option).val(json.id);
159
+ widget.element.find(".update").removeClass("disabled");
146
160
  }
147
- widget._trigger("success");
148
- dialog.each(function (index, element) {
149
- bootstrap.Modal.getInstance(element).hide();
150
- });
151
161
  } else {
152
- dialog.find(".modal-body").html(data.responseText);
153
- widget._bindFormEvents();
162
+ // multi-select input
163
+ var multiselect = widget.element.find(".ra-multiselect");
164
+ if (multiselect.find("option[value=" + json.id + "]").length) {
165
+ // replace
166
+ select.find("option[value=" + json.id + "]").text(json.label);
167
+ multiselect.find("option[value= " + json.id + "]").text(json.label);
168
+ } else {
169
+ // add
170
+ select.append(option);
171
+ multiselect.find("select.ra-multiselect-selection").append(option);
172
+ }
154
173
  }
155
- });
174
+ widget._trigger("success");
175
+ dialog.each(function (index, element) {
176
+ bootstrap.Modal.getInstance(element).hide();
177
+ });
178
+ } else {
179
+ dialog.find(".modal-body").html(xhr.responseText);
180
+ widget._bindFormEvents();
181
+ }
156
182
  },
157
183
 
158
184
  _getModal: function () {
@@ -3,9 +3,38 @@
3
3
  Keep it clean, people
4
4
  */
5
5
 
6
- $avatar-size: 30px;
7
-
8
6
  body.rails_admin {
7
+ /*
8
+ Theming custom properties. Override these from the host app (an
9
+ app/views/layouts/rails_admin/_head_custom.html.erb <style> block, or a
10
+ stylesheet targeting `body.rails_admin`) to retheme RailsAdmin without
11
+ rebuilding its CSS. Defaults reproduce the compiled-in Bootstrap theme.
12
+ */
13
+ --ra-avatar-size: 30px;
14
+ --ra-nav-link-active-bg: #{map-get($theme-colors, primary)};
15
+ --ra-nav-link-active-color: #{color-contrast(map-get($theme-colors, primary))};
16
+ --ra-nav-toggle-color: #{$gray-600};
17
+ --ra-nav-toggle-active-color: #{$gray-700};
18
+ --ra-nested-form-border-color: #{map-get($theme-colors, primary)};
19
+ --ra-nested-form-border-color-2: #{lighten(map-get($theme-colors, info), 20%)};
20
+ --ra-nested-form-border-color-3: #{lighten(
21
+ map-get($theme-colors, warning),
22
+ 30%
23
+ )};
24
+ --ra-nested-form-border-color-4: #{lighten(
25
+ map-get($theme-colors, success),
26
+ 40%
27
+ )};
28
+ --ra-table-sort-caret-color: #{$dark};
29
+ --ra-table-sort-active-bg: #{rgba($info, 0.25)};
30
+ --ra-table-sticky-bg: #{if(
31
+ $table-bg == transparent,
32
+ if($body-bg == transparent, #fff, $body-bg),
33
+ $table-bg
34
+ )};
35
+ --ra-table-sort-sticky-bg: #e2eff6;
36
+ --ra-autocomplete-font-size: #{$font-size-base * 1.1};
37
+
9
38
  .thumbnail {
10
39
  display: inline-block;
11
40
  }
@@ -19,10 +48,10 @@ body.rails_admin {
19
48
 
20
49
  img {
21
50
  position: absolute;
22
- top: calc((40px - $avatar-size) / 2);
51
+ top: calc((40px - var(--ra-avatar-size)) / 2);
23
52
 
24
53
  & + span {
25
- margin-left: ($avatar-size + 5px);
54
+ margin-left: calc(var(--ra-avatar-size) + 5px);
26
55
  }
27
56
  }
28
57
  }
@@ -36,24 +65,24 @@ body.rails_admin {
36
65
  margin-top: calc(#{$grid-gutter-width} / 2);
37
66
  padding: 3px calc(#{$grid-gutter-width} / 2);
38
67
  font-weight: bold;
39
- color: $gray-600;
68
+ color: var(--ra-nav-toggle-color);
40
69
  }
41
70
 
42
71
  .btn-toggle[aria-expanded="true"] {
43
- color: $gray-700;
72
+ color: var(--ra-nav-toggle-active-color);
44
73
  }
45
74
 
46
75
  .btn-toggle-nav > li > a {
47
76
  padding: calc(#{$navbar-padding-y} / 2) calc(#{$grid-gutter-width} / 2);
48
77
 
49
78
  &.active {
50
- background-color: map-get($theme-colors, primary);
51
- color: color-contrast(map-get($theme-colors, primary));
79
+ background-color: var(--ra-nav-link-active-bg);
80
+ color: var(--ra-nav-link-active-color);
52
81
  }
53
82
 
54
83
  &:hover {
55
- background-color: map-get($theme-colors, primary);
56
- color: color-contrast(map-get($theme-colors, primary));
84
+ background-color: var(--ra-nav-link-active-bg);
85
+ color: var(--ra-nav-link-active-color);
57
86
  }
58
87
 
59
88
  &.nav-level-1 {
@@ -80,7 +109,7 @@ body.rails_admin {
80
109
  /* nested forms */
81
110
  .tab-content {
82
111
  .tab-pane {
83
- border-left: 5px solid map-get($theme-colors, primary);
112
+ border-left: 5px solid var(--ra-nested-form-border-color);
84
113
  position: relative;
85
114
 
86
115
  fieldset {
@@ -111,7 +140,7 @@ body.rails_admin {
111
140
 
112
141
  /* double nesting, guys. Easy. */
113
142
  .tab-content .tab-content .tab-pane {
114
- border-color: lighten(map-get($theme-colors, info), 20%);
143
+ border-color: var(--ra-nested-form-border-color-2);
115
144
  margin-left: 10px;
116
145
 
117
146
  .form-group {
@@ -121,7 +150,7 @@ body.rails_admin {
121
150
 
122
151
  /* triple nesting!*/
123
152
  .tab-content .tab-content .tab-content .tab-pane {
124
- border-color: lighten(map-get($theme-colors, warning), 30%);
153
+ border-color: var(--ra-nested-form-border-color-3);
125
154
  margin-left: 20px;
126
155
 
127
156
  .form-group {
@@ -131,7 +160,7 @@ body.rails_admin {
131
160
 
132
161
  /* totally awesome! nesting on 4 levels! */
133
162
  .tab-content .tab-content .tab-content .tab-content .tab-pane {
134
- border-color: lighten(map-get($theme-colors, success), 40%);
163
+ border-color: var(--ra-nested-form-border-color-4);
135
164
  margin-left: 30px;
136
165
 
137
166
  .form-group {
@@ -183,13 +212,13 @@ body.rails_admin {
183
212
  margin-right: -16px;
184
213
  border-width: 0 4px 4px;
185
214
  border-style: solid;
186
- border-color: $dark transparent;
215
+ border-color: var(--ra-table-sort-caret-color) transparent;
187
216
  visibility: hidden;
188
217
  }
189
218
  }
190
219
  .headerSortUp,
191
220
  .headerSortDown {
192
- background-color: rgba($info, 0.25);
221
+ background-color: var(--ra-table-sort-active-bg);
193
222
  text-shadow: 0 1px 1px rgba($light, 0.75);
194
223
  }
195
224
  .header:hover {
@@ -209,7 +238,7 @@ body.rails_admin {
209
238
  border-bottom: none;
210
239
  border-left: 4px solid transparent;
211
240
  border-right: 4px solid transparent;
212
- border-top: 4px solid $dark;
241
+ border-top: 4px solid var(--ra-table-sort-caret-color);
213
242
  visibility: visible;
214
243
  @include box-shadow(none);
215
244
  opacity: 60;
@@ -299,21 +328,15 @@ body.rails_admin {
299
328
  }
300
329
 
301
330
  // Remove transparency on sticky cells.
302
- $table-bg-default: if(
303
- $table-bg == transparent,
304
- if($body-bg == transparent, #fff, $body-bg),
305
- $table-bg
306
- ) !default;
307
331
  .table-striped > tbody > tr > td,
308
332
  .table-striped > thead > tr > th {
309
- background-color: $table-bg-default;
333
+ background-color: var(--ra-table-sticky-bg);
310
334
  }
311
- $table-bg-header-sort: #e2eff6 !default;
312
335
  .table .sticky,
313
336
  .table .last {
314
337
  &.headerSortUp,
315
338
  &.headerSortDown {
316
- background-color: $table-bg-header-sort;
339
+ background-color: var(--ra-table-sort-sticky-bg);
317
340
  }
318
341
  }
319
342
  }
@@ -12,7 +12,31 @@
12
12
  /*** Font-awesome ***/
13
13
 
14
14
  $fa-font-path: "~@fortawesome/fontawesome-free/webfonts" !default;
15
- @import "@fortawesome/fontawesome-free/scss/solid";
15
+ @import "@fortawesome/fontawesome-free/scss/functions";
16
+ @import "@fortawesome/fontawesome-free/scss/variables";
17
+
18
+ // Font Awesome's scss/solid, inlined so we can ship the woff2 face without the
19
+ // .ttf fallback (388 KB of dead weight - every browser that can run RailsAdmin
20
+ // supports woff2). Keep in sync with node_modules/@fortawesome/fontawesome-free/scss/solid.scss.
21
+ :root,
22
+ :host {
23
+ --#{$fa-css-prefix}-style-family-classic: "#{$fa-style-family}";
24
+ --#{$fa-css-prefix}-font-solid: normal 900 1em/1 "#{$fa-style-family}";
25
+ }
26
+
27
+ @font-face {
28
+ font-family: "Font Awesome 6 Free";
29
+ font-style: normal;
30
+ font-weight: 900;
31
+ font-display: $fa-font-display;
32
+ src: url("#{$fa-font-path}/fa-solid-900.woff2") format("woff2");
33
+ }
34
+
35
+ .fas,
36
+ .#{$fa-css-prefix}-solid {
37
+ font-weight: 900;
38
+ }
39
+
16
40
  @import "@fortawesome/fontawesome-free/scss/fontawesome";
17
41
 
18
42
  /*** Bootstrap ***/
@@ -1,68 +1,29 @@
1
- .ui-widget {
2
- font-family: Arial, sans-serif;
3
- font-size: 1.1em;
4
- }
5
- .ui-widget .ui-widget {
6
- font-size: 1em;
7
- }
8
- .ui-widget input,
9
- .ui-widget select,
10
- .ui-widget textarea,
11
- .ui-widget button {
12
- font-family: Arial, sans-serif;
13
- font-size: 1em;
14
- }
15
- .ui-widget-content {
16
- border: 1px solid #b6b6b6;
17
- background: #ffffff;
18
- color: #4f4f4f;
19
- }
20
- .ui-widget-content a {
21
- color: #4f4f4f;
22
- }
23
-
24
- .ui-menu {
25
- list-style: none;
26
- padding: 2px;
27
- margin: 0;
28
- display: block;
29
- float: left;
30
- }
31
- .ui-menu .ui-menu {
32
- margin-top: -3px;
33
- }
34
- .ui-menu .ui-menu-item {
35
- margin: 0;
36
- padding: 0;
37
- zoom: 1;
38
- float: left;
39
- clear: left;
40
- width: 100%;
41
- }
42
- .ui-menu .ui-menu-item a {
43
- text-decoration: none;
44
- display: block;
45
- padding: 0.2em 0.4em;
46
- line-height: 1.5;
47
- zoom: 1;
48
- }
49
- .ui-menu .ui-menu-item a.ui-state-hover,
50
- .ui-menu .ui-menu-item a.ui-state-active {
51
- font-weight: normal;
52
- margin: -1px;
53
- background: #5f83b9;
54
- color: #ffffff;
55
- text-shadow: 0px 1px 1px #234386;
56
- border-color: #466086;
57
- border-radius: 0;
58
- }
59
-
1
+ /*
2
+ The jQuery UI autocomplete menu. filtering-select.js renders it with Bootstrap's
3
+ .dropdown-menu / .dropdown-item classes, so only what Bootstrap does not cover
4
+ belongs here.
5
+ */
60
6
  .ui-autocomplete {
61
- position: absolute;
62
7
  cursor: default;
8
+
9
+ /* A touch larger than the surrounding form, as the pre-Bootstrap menu was. */
10
+ --bs-dropdown-font-size: var(--ra-autocomplete-font-size);
11
+
12
+ /* Above .modal (1055), so the menu is usable in the nested-form modal. */
63
13
  z-index: 1056 !important;
64
- border-radius: 0;
65
- box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
14
+
15
+ /* Bootstrap only emits this with $enable-shadows; the menu floats over the form. */
16
+ box-shadow: var(--bs-dropdown-box-shadow);
17
+
18
+ /*
19
+ jQuery UI marks the focused item - by keyboard or by pointer - as
20
+ .ui-state-active rather than leaving it to :hover, so it takes the styling
21
+ Bootstrap gives .dropdown-item.active.
22
+ */
23
+ .dropdown-item.ui-state-active {
24
+ color: var(--bs-dropdown-link-active-color);
25
+ background-color: var(--bs-dropdown-link-active-bg);
26
+ }
66
27
  }
67
28
 
68
29
  .ui-helper-hidden-accessible {
@@ -1,6 +1,6 @@
1
1
  import jQuery from "jquery";
2
2
  import "jquery-ui/ui/effect.js";
3
- import I18n from "./i18n";
3
+ import I18n from "./i18n.js";
4
4
 
5
5
  (function ($) {
6
6
  $(document).on("click", "#list input.toggle", function () {
@@ -48,7 +48,7 @@ import jQuery from 'jquery';
48
48
  // Make a unique ID for the new child
49
49
  var regexp = new RegExp('new_' + assoc, 'g');
50
50
  var new_id = this.newId();
51
- content = $.trim(content.replace(regexp, new_id));
51
+ content = content.replace(regexp, new_id).trim();
52
52
 
53
53
  var field = this.insertFields(content, assoc, link);
54
54
  // bubble up event upto document (through form)
@@ -71,13 +71,13 @@ import jQuery from 'jquery';
71
71
  removeFields: function(e) {
72
72
  var $link = $(e.currentTarget),
73
73
  assoc = $link.data('association'); // Name of child to be removed
74
-
74
+
75
75
  var hiddenField = $link.prev('input[type=hidden]');
76
76
  hiddenField.val('1');
77
-
77
+
78
78
  var field = $link.closest('.fields');
79
79
  field.hide();
80
-
80
+
81
81
  field
82
82
  .trigger({ type: 'nested:fieldRemoved', field: field })
83
83
  .trigger({ type: 'nested:fieldRemoved:' + assoc, field: field });