activeadmin-rails 1.7.2 → 1.8.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.
- checksums.yaml +4 -4
- data/.babelrc +5 -0
- data/.github/workflows/ci.yaml +3 -18
- data/.github/workflows/daily.yaml +6 -18
- data/.github/workflows/pages.yml +1 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +25 -3
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +2 -1
- data/Rakefile +1 -0
- data/activeadmin-rails.gemspec +2 -5
- data/app/assets/javascripts/active_admin/base.js +507 -0
- data/app/assets/stylesheets/active_admin/_base.scss +4 -1
- data/app/assets/stylesheets/active_admin/_forms.scss +11 -10
- data/app/assets/stylesheets/active_admin/_header.scss +22 -19
- data/app/assets/stylesheets/active_admin/_index.scss +7 -0
- data/app/assets/stylesheets/active_admin/components/_batch_actions.scss +2 -4
- data/app/assets/stylesheets/active_admin/components/_blank_slates.scss +1 -1
- data/app/assets/stylesheets/active_admin/components/_comments.scss +8 -6
- data/app/assets/stylesheets/active_admin/components/_date_picker.scss +4 -4
- data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +20 -15
- data/app/assets/stylesheets/active_admin/components/_flash_messages.scss +3 -3
- data/app/assets/stylesheets/active_admin/components/_pagination.scss +21 -14
- data/app/assets/stylesheets/active_admin/components/_status_tags.scss +3 -1
- data/app/assets/stylesheets/active_admin/components/_table_tools.scss +13 -13
- data/app/assets/stylesheets/active_admin/components/_tables.scss +8 -7
- data/app/assets/stylesheets/active_admin/components/_tabs.scss +10 -7
- data/app/assets/stylesheets/active_admin/mixins/_all.scss +0 -4
- data/app/assets/stylesheets/active_admin/mixins/_buttons.scss +22 -15
- data/app/assets/stylesheets/active_admin/mixins/_gradients.scss +7 -5
- data/app/assets/stylesheets/active_admin/mixins/_sections.scss +4 -4
- data/app/assets/stylesheets/active_admin/mixins/_variables.scss +14 -3
- data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +10 -6
- data/app/assets/stylesheets/active_admin/structure/_footer.scss +8 -1
- data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +19 -8
- data/app/javascript/active_admin/base.js +28 -0
- data/app/{assets/javascripts/active_admin/lib/batch_actions.es6 → javascript/active_admin/initializers/batch-actions.js} +5 -3
- data/app/javascript/active_admin/initializers/checkbox-toggler.js +3 -0
- data/app/javascript/active_admin/initializers/dropdown-menu.js +9 -0
- data/app/javascript/active_admin/initializers/filters.js +10 -0
- data/app/{assets/javascripts/active_admin/lib/has_many.es6 → javascript/active_admin/initializers/has-many.js} +7 -1
- data/app/javascript/active_admin/initializers/per-page.js +13 -0
- data/app/javascript/active_admin/initializers/table-checkbox-toggler.js +3 -0
- data/app/{assets/javascripts/active_admin/lib/checkbox-toggler.es6 → javascript/active_admin/lib/checkbox-toggler.js} +2 -2
- data/app/{assets/javascripts/active_admin/lib/dropdown-menu.es6 → javascript/active_admin/lib/dropdown-menu.js} +2 -9
- data/app/javascript/active_admin/lib/filters.js +39 -0
- data/app/{assets/javascripts/active_admin/lib/modal_dialog.es6 → javascript/active_admin/lib/modal-dialog.js} +5 -3
- data/app/javascript/active_admin/lib/per-page.js +38 -0
- data/app/{assets/javascripts/active_admin/lib/table-checkbox-toggler.es6 → javascript/active_admin/lib/table-checkbox-toggler.js} +4 -2
- data/app/javascript/active_admin/lib/utils.js +40 -0
- data/cucumber.yml +2 -2
- data/docs/9-batch-actions.md +2 -2
- data/features/index/format_as_csv.feature +7 -7
- data/features/index/index_as_table.feature +6 -6
- data/gemfiles/rails_71.gemfile +2 -1
- data/gemfiles/rails_72.gemfile +2 -1
- data/gemfiles/rails_80.gemfile +2 -1
- data/gemfiles/rails_81.gemfile +18 -0
- data/lib/active_admin/application.rb +9 -1
- data/lib/active_admin/engine.rb +8 -5
- data/lib/active_admin/filters/active_filter.rb +1 -2
- data/lib/active_admin/namespace.rb +1 -1
- data/lib/active_admin/namespace_settings.rb +2 -1
- data/lib/active_admin/resource/attributes.rb +1 -1
- data/lib/active_admin/router.rb +4 -4
- data/lib/active_admin/version.rb +1 -1
- data/lib/active_admin.rb +2 -4
- data/lib/generators/active_admin/assets/assets_generator.rb +7 -1
- data/lib/generators/active_admin/assets/templates/active_admin.js.erb +6 -0
- data/lib/generators/active_admin/assets/templates/active_admin.scss +2 -2
- data/package.json +42 -0
- data/rollup.config.js +38 -0
- data/spec/requests/pages/layout_spec.rb +8 -2
- data/spec/requests/stylesheets_spec.rb +10 -3
- data/spec/support/active_admin_integration_spec_helper.rb +0 -3
- data/spec/support/rails_template.rb +29 -13
- data/spec/support/templates/dartsass.rb +4 -0
- data/spec/unit/namespace_spec.rb +0 -13
- data/spec/unit/resource/attributes_spec.rb +1 -1
- data/vendor/assets/stylesheets/active_admin/_normalize.scss +70 -354
- metadata +39 -77
- data/app/assets/javascripts/active_admin/base.es6 +0 -23
- data/app/assets/javascripts/active_admin/initializers/filters.es6 +0 -45
- data/app/assets/javascripts/active_admin/lib/active_admin.es6 +0 -41
- data/app/assets/javascripts/active_admin/lib/per_page.es6 +0 -47
- data/app/assets/stylesheets/active_admin/mixins/_rounded.scss +0 -22
- data/app/assets/stylesheets/active_admin/mixins/_shadows.scss +0 -15
- data/app/assets/stylesheets/active_admin/mixins/_typography.scss +0 -3
- data/app/assets/stylesheets/active_admin/mixins/_utilities.scss +0 -17
- data/gemfiles/rails_60.gemfile +0 -16
- data/gemfiles/rails_61.gemfile +0 -16
- data/gemfiles/rails_61_turbolinks.gemfile +0 -16
- data/gemfiles/rails_70.gemfile +0 -16
- data/gemfiles/rails_70_hotwire.gemfile +0 -16
- data/lib/generators/active_admin/assets/templates/active_admin.js +0 -1
- /data/app/{assets/javascripts/active_admin/ext/jquery-ui.es6 → javascript/active_admin/ext/jquery-ui.js} +0 -0
- /data/app/{assets/javascripts/active_admin/ext/jquery.es6 → javascript/active_admin/ext/jquery.js} +0 -0
- /data/app/{assets/javascripts/active_admin/initializers/datepicker.es6 → javascript/active_admin/initializers/datepicker.js} +0 -0
- /data/app/{assets/javascripts/active_admin/initializers/tabs.es6 → javascript/active_admin/initializers/tabs.js} +0 -0
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
#title_bar {
|
|
2
2
|
@include section-header;
|
|
3
|
-
@include clearfix;
|
|
4
3
|
box-sizing: border-box;
|
|
5
4
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.37);
|
|
6
|
-
display:
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: space-between;
|
|
7
8
|
border-bottom-color: #EEE;
|
|
8
9
|
width: 100%;
|
|
9
10
|
position: relative;
|
|
10
11
|
margin: 0;
|
|
11
12
|
padding: 10px $horizontal-page-margin;
|
|
12
|
-
z-index:
|
|
13
|
+
z-index: 1000;
|
|
13
14
|
|
|
14
15
|
#titlebar_left, #titlebar_right {
|
|
15
|
-
height: 50px;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
min-height: 50px;
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#titlebar_left {
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
align-items: flex-start;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
gap: 3px;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
#titlebar_right {
|
|
@@ -33,8 +41,11 @@
|
|
|
33
41
|
span.action_item {
|
|
34
42
|
& > a, & > .dropdown_menu > a {
|
|
35
43
|
@include light-button;
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
|
|
45
|
+
& {
|
|
46
|
+
padding: 12px 17px 10px;
|
|
47
|
+
margin: 0px;
|
|
48
|
+
}
|
|
38
49
|
}
|
|
39
50
|
}
|
|
40
51
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "jquery"
|
|
2
|
+
import "jquery-ui/ui/widgets/datepicker"
|
|
3
|
+
import "jquery-ui/ui/widgets/dialog"
|
|
4
|
+
import "jquery-ui/ui/widgets/sortable"
|
|
5
|
+
import "jquery-ui/ui/widgets/tabs"
|
|
6
|
+
import "jquery-ui/ui/widget"
|
|
7
|
+
import "jquery-ujs"
|
|
8
|
+
|
|
9
|
+
import "./ext/jquery"
|
|
10
|
+
import "./ext/jquery-ui"
|
|
11
|
+
import "./initializers/batch-actions"
|
|
12
|
+
import "./initializers/checkbox-toggler"
|
|
13
|
+
import "./initializers/datepicker"
|
|
14
|
+
import "./initializers/dropdown-menu"
|
|
15
|
+
import "./initializers/filters"
|
|
16
|
+
import "./initializers/has-many"
|
|
17
|
+
import "./initializers/per-page"
|
|
18
|
+
import "./initializers/table-checkbox-toggler"
|
|
19
|
+
import "./initializers/tabs"
|
|
20
|
+
|
|
21
|
+
import ModalDialog from "./lib/modal-dialog";
|
|
22
|
+
|
|
23
|
+
function modal_dialog(message, inputs, callback) {
|
|
24
|
+
console.warn("ActiveAdmin.modal_dialog is deprecated in favor of ActiveAdmin.ModalDialog, please update usage.");
|
|
25
|
+
return ModalDialog(message, inputs, callback);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { ModalDialog, modal_dialog };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import ModalDialog from "../lib/modal-dialog";
|
|
2
|
+
|
|
1
3
|
const onDOMReady = function() {
|
|
2
4
|
// Detach any previously attached handlers before re-attaching them.
|
|
3
5
|
// This avoids double-registered handlers when Turbolinks is enabled
|
|
4
6
|
$('.batch_actions_selector li a').off('click confirm:complete');
|
|
5
7
|
|
|
6
8
|
//
|
|
7
|
-
// Use
|
|
9
|
+
// Use ModalDialog to prompt user if
|
|
8
10
|
// confirmation is required for current Batch Action
|
|
9
11
|
//
|
|
10
12
|
$('.batch_actions_selector li a').on('click', function(event){
|
|
@@ -12,7 +14,7 @@ const onDOMReady = function() {
|
|
|
12
14
|
event.stopPropagation(); // prevent Rails UJS click event
|
|
13
15
|
event.preventDefault();
|
|
14
16
|
if ((message = $(this).data('confirm'))) {
|
|
15
|
-
|
|
17
|
+
ModalDialog(message, $(this).data('inputs'), inputs => {
|
|
16
18
|
$(this).trigger('confirm:complete', inputs);
|
|
17
19
|
});
|
|
18
20
|
} else {
|
|
@@ -45,7 +47,7 @@ const onDOMReady = function() {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
$(document).on('change', '.paginated_collection :checkbox', function() {
|
|
48
|
-
if ($(".paginated_collection :checkbox:checked").length) {
|
|
50
|
+
if ($(".paginated_collection :checkbox:checked").length && $(".dropdown_menu_list").children().length) {
|
|
49
51
|
$(".batch_actions_selector").each(function() { $(this).aaDropdownMenu("enable"); });
|
|
50
52
|
} else {
|
|
51
53
|
$(".batch_actions_selector").each(function() { $(this).aaDropdownMenu("disable"); });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import DropdownMenu from "../lib/dropdown-menu";
|
|
2
|
+
|
|
3
|
+
$.widget.bridge('aaDropdownMenu', DropdownMenu);
|
|
4
|
+
|
|
5
|
+
const onDOMReady = () => $('.dropdown_menu').aaDropdownMenu();
|
|
6
|
+
|
|
7
|
+
$(document).
|
|
8
|
+
ready(onDOMReady).
|
|
9
|
+
on('page:load turbolinks:load turbo:load', onDOMReady);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Filters from '../lib/filters';
|
|
2
|
+
|
|
3
|
+
(($) => {
|
|
4
|
+
|
|
5
|
+
$(document).
|
|
6
|
+
on('click', '.clear_filters_btn', Filters._clearForm).
|
|
7
|
+
on('submit', '.filter_form', Filters._disableEmptyInputFields).
|
|
8
|
+
on('change', '.filter_form_field.select_and_search select', Filters._setSearchType);
|
|
9
|
+
|
|
10
|
+
})(jQuery);
|
|
@@ -66,7 +66,13 @@ var init_sortable = function() {
|
|
|
66
66
|
elems.sortable({
|
|
67
67
|
items: '> fieldset',
|
|
68
68
|
handle: '> ol > .handle',
|
|
69
|
-
|
|
69
|
+
start: (ev, ui) => {
|
|
70
|
+
ui.item.css({opacity: 0.3});
|
|
71
|
+
},
|
|
72
|
+
stop: function (ev, ui) {
|
|
73
|
+
ui.item.css({opacity: 1.0});
|
|
74
|
+
recompute_positions($(this));
|
|
75
|
+
}
|
|
70
76
|
});
|
|
71
77
|
elems.each(recompute_positions);
|
|
72
78
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import PerPage from "../lib/per-page";
|
|
2
|
+
|
|
3
|
+
(($) => {
|
|
4
|
+
|
|
5
|
+
$(document).
|
|
6
|
+
on('change', '.pagination_per_page > select', function(event) {
|
|
7
|
+
PerPage._jQueryInterface.call($(this), 'update')
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
$.fn['perPage'] = PerPage._jQueryInterface
|
|
11
|
+
$.fn['perPage'].Constructor = PerPage
|
|
12
|
+
|
|
13
|
+
})(jQuery);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class CheckboxToggler {
|
|
2
2
|
constructor(options, container){
|
|
3
3
|
this.options = options;
|
|
4
4
|
this.container = container;
|
|
@@ -46,4 +46,4 @@ ActiveAdmin.CheckboxToggler = class CheckboxToggler {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
export default CheckboxToggler;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
class DropdownMenu {
|
|
3
2
|
constructor(options, element) {
|
|
4
3
|
this.options = options;
|
|
5
4
|
this.element = element;
|
|
@@ -114,10 +113,4 @@ ActiveAdmin.DropdownMenu = class DropdownMenu {
|
|
|
114
113
|
}
|
|
115
114
|
};
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const onDOMReady = () => $('.dropdown_menu').aaDropdownMenu();
|
|
120
|
-
|
|
121
|
-
$(document).
|
|
122
|
-
ready(onDOMReady).
|
|
123
|
-
on('page:load turbolinks:load turbo:load', onDOMReady);
|
|
116
|
+
export default DropdownMenu;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { queryStringToParams, hasTurbolinks, turbolinksVisit, toQueryString } from '../lib/utils';
|
|
2
|
+
|
|
3
|
+
class Filters {
|
|
4
|
+
|
|
5
|
+
static _clearForm(event) {
|
|
6
|
+
const regex = /^(q\[|q%5B|q%5b|page|utf8|commit)/;
|
|
7
|
+
const params = queryStringToParams()
|
|
8
|
+
.filter(({name}) => !name.match(regex));
|
|
9
|
+
|
|
10
|
+
event.preventDefault();
|
|
11
|
+
|
|
12
|
+
if (hasTurbolinks()) {
|
|
13
|
+
turbolinksVisit(params);
|
|
14
|
+
} else {
|
|
15
|
+
window.location.search = toQueryString(params);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static _disableEmptyInputFields(event) {
|
|
20
|
+
const params = $(this)
|
|
21
|
+
.find(':input')
|
|
22
|
+
.filter((i, input) => input.value === '')
|
|
23
|
+
.prop({ disabled: true })
|
|
24
|
+
.end()
|
|
25
|
+
.serializeArray();
|
|
26
|
+
|
|
27
|
+
if (hasTurbolinks()) {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
turbolinksVisit(params);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static _setSearchType() {
|
|
34
|
+
$(this).siblings('input').prop({name: `q[${this.value}]`});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default Filters;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
function ModalDialog(message, inputs, callback){
|
|
2
2
|
let html = `<form id="dialog_confirm" title="${message}"><ul>`;
|
|
3
3
|
for (let name in inputs) {
|
|
4
4
|
var elem, opts, wrapper;
|
|
@@ -20,7 +20,7 @@ ActiveAdmin.modal_dialog = function(message, inputs, callback){
|
|
|
20
20
|
(opts ? ((() => {
|
|
21
21
|
const result = [];
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
opts.forEach(v => {
|
|
24
24
|
const $elem = $(`<${elem}/>`);
|
|
25
25
|
if ($.isArray(v)) {
|
|
26
26
|
$elem.text(v[0]).val(v[1]);
|
|
@@ -28,7 +28,7 @@ ActiveAdmin.modal_dialog = function(message, inputs, callback){
|
|
|
28
28
|
$elem.text(v);
|
|
29
29
|
}
|
|
30
30
|
result.push($elem.wrap('<div>').parent().html());
|
|
31
|
-
}
|
|
31
|
+
});
|
|
32
32
|
|
|
33
33
|
return result;
|
|
34
34
|
})()).join('') : '') +
|
|
@@ -59,3 +59,5 @@ ActiveAdmin.modal_dialog = function(message, inputs, callback){
|
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
|
+
|
|
63
|
+
export default ModalDialog;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { queryStringToParams, hasTurbolinks, turbolinksVisit, toQueryString } from './utils';
|
|
2
|
+
|
|
3
|
+
class PerPage {
|
|
4
|
+
constructor(element) {
|
|
5
|
+
this.element = element;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
update() {
|
|
9
|
+
const params = queryStringToParams()
|
|
10
|
+
.filter(({name}) => name != 'per_page' || name != 'page')
|
|
11
|
+
|
|
12
|
+
params.push({ name: 'per_page', value: this.element.value });
|
|
13
|
+
|
|
14
|
+
if (hasTurbolinks()) {
|
|
15
|
+
turbolinksVisit(params);
|
|
16
|
+
} else {
|
|
17
|
+
window.location.search = toQueryString(params);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static _jQueryInterface(config) {
|
|
22
|
+
return this.each(function () {
|
|
23
|
+
const $this = $(this)
|
|
24
|
+
let data = $this.data('perPage')
|
|
25
|
+
|
|
26
|
+
if (!data) {
|
|
27
|
+
data = new PerPage(this)
|
|
28
|
+
$this.data('perPage', data)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (config === 'update') {
|
|
32
|
+
data[config]()
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default PerPage;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import CheckboxToggler from "./checkbox-toggler";
|
|
2
|
+
|
|
3
|
+
class TableCheckboxToggler extends CheckboxToggler {
|
|
2
4
|
_bind() {
|
|
3
5
|
super._bind(...arguments);
|
|
4
6
|
|
|
@@ -33,4 +35,4 @@ ActiveAdmin.TableCheckboxToggler = class TableCheckboxToggler extends ActiveAdmi
|
|
|
33
35
|
}
|
|
34
36
|
};
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
export default TableCheckboxToggler;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function hasTurbolinks() {
|
|
2
|
+
return (typeof Turbolinks !== 'undefined' && Turbolinks.supported);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function turbolinksVisit(params) {
|
|
6
|
+
const path = [window.location.pathname, '?', toQueryString(params)].join('')
|
|
7
|
+
Turbolinks.visit(path);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function queryString() {
|
|
11
|
+
return (window.location.search || '').replace(/^\?/, '');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function queryStringToParams() {
|
|
15
|
+
const decode = (value) => decodeURIComponent((value || '').replace(/\+/g, '%20'));
|
|
16
|
+
|
|
17
|
+
return queryString()
|
|
18
|
+
.split("&")
|
|
19
|
+
.map(pair => pair.split("="))
|
|
20
|
+
.map(([key, value]) => {
|
|
21
|
+
return { name: decode(key), value: decode(value) }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function toQueryString(params) {
|
|
26
|
+
const encode = (value) => encodeURIComponent(value || '');
|
|
27
|
+
|
|
28
|
+
return params
|
|
29
|
+
.map(({name, value}) => [ encode(name), encode(value) ])
|
|
30
|
+
.map(pair => pair.join('='))
|
|
31
|
+
.join('&')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
hasTurbolinks,
|
|
36
|
+
turbolinksVisit,
|
|
37
|
+
queryString,
|
|
38
|
+
queryStringToParams,
|
|
39
|
+
toQueryString
|
|
40
|
+
};
|
data/cucumber.yml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
std_opts = "--format progress --order random"
|
|
3
3
|
%>
|
|
4
4
|
|
|
5
|
-
default: <%= std_opts %> --require features/support/regular_env.rb features --tags 'not @requires-reloading' --tags 'not @wip'
|
|
6
|
-
class-reloading: CLASS_RELOADING=true <%= std_opts %> --require features/support/reload_env.rb features --tags @requires-reloading
|
|
5
|
+
default: <%= std_opts %> --require features/support/regular_env.rb features --tags 'not @requires-reloading' --tags 'not @wip' --publish-quiet
|
|
6
|
+
class-reloading: CLASS_RELOADING=true <%= std_opts %> --require features/support/reload_env.rb features --tags @requires-reloading --publish-quiet
|
data/docs/9-batch-actions.md
CHANGED
|
@@ -165,13 +165,13 @@ batch_action :doit, form: -> { {user: User.pluck(:name, :id)} } do |ids, inputs|
|
|
|
165
165
|
end
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
Under the covers this is powered by the JS `ActiveAdmin.
|
|
168
|
+
Under the covers this is powered by the JS `ActiveAdmin.ModalDialog` which you
|
|
169
169
|
can use yourself:
|
|
170
170
|
|
|
171
171
|
```coffee
|
|
172
172
|
if $('body.admin_users').length
|
|
173
173
|
$('a[data-prompt]').click ->
|
|
174
|
-
ActiveAdmin.
|
|
174
|
+
ActiveAdmin.ModalDialog $(@).data('prompt'), comment: 'textarea',
|
|
175
175
|
(inputs)=>
|
|
176
176
|
$.post "/admin/users/#{$(@).data 'id'}/change_state",
|
|
177
177
|
comment: inputs.comment, state: $(@).data('state'),
|
|
@@ -13,8 +13,8 @@ Feature: Format as CSV
|
|
|
13
13
|
When I am on the index page for posts
|
|
14
14
|
And I follow "CSV"
|
|
15
15
|
Then I should download a CSV file for "posts" containing:
|
|
16
|
-
| Id |
|
|
17
|
-
| \d+ |
|
|
16
|
+
| Id | Body | Created at | Foo | Position | Published date | Starred | Title | Updated at |
|
|
17
|
+
| \d+ | | (.*) | | | | | Hello World | (.*) |
|
|
18
18
|
|
|
19
19
|
Scenario: Default with alias
|
|
20
20
|
Given a configuration of:
|
|
@@ -25,7 +25,7 @@ Feature: Format as CSV
|
|
|
25
25
|
When I am on the index page for my_articles
|
|
26
26
|
And I follow "CSV"
|
|
27
27
|
Then I should download a CSV file for "my-articles" containing:
|
|
28
|
-
| Id |
|
|
28
|
+
| Id | Body | Created at | Foo | Position | Published date | Starred | Title | Updated at |
|
|
29
29
|
|
|
30
30
|
Scenario: Default with streaming disabled
|
|
31
31
|
Given a configuration of:
|
|
@@ -38,8 +38,8 @@ Feature: Format as CSV
|
|
|
38
38
|
When I am on the index page for posts
|
|
39
39
|
And I follow "CSV"
|
|
40
40
|
Then I should download a CSV file for "posts" containing:
|
|
41
|
-
| Id |
|
|
42
|
-
| \d+ |
|
|
41
|
+
| Id | Body | Created at | Foo | Position | Published date | Starred | Title | Updated at |
|
|
42
|
+
| \d+ | | (.*) | | | | | Hello World | (.*) |
|
|
43
43
|
|
|
44
44
|
Scenario: With CSV format customization
|
|
45
45
|
Given a configuration of:
|
|
@@ -104,8 +104,8 @@ Feature: Format as CSV
|
|
|
104
104
|
When I am on the index page for posts
|
|
105
105
|
And I follow "CSV"
|
|
106
106
|
Then I should download a CSV file with "," separator for "posts" containing:
|
|
107
|
-
| id |
|
|
108
|
-
| (.*)| (.*)
|
|
107
|
+
| id | body | created_at | foo | position | published_date | starred | title | updated_at |
|
|
108
|
+
| (.*)| (.*) | (.*) | (.*) | (.*) | (.*) | (.*) | (.*) | (.*) |
|
|
109
109
|
|
|
110
110
|
Scenario: With humanize_name option turned off globally and enabled locally
|
|
111
111
|
Given a configuration of:
|
|
@@ -250,14 +250,14 @@ Feature: Index as Table
|
|
|
250
250
|
"""
|
|
251
251
|
When I am on the index page for posts
|
|
252
252
|
Then I should see the "index_table_posts" table:
|
|
253
|
-
| [ ] | Id |
|
|
254
|
-
| [ ] | 2 |
|
|
255
|
-
| [ ] | 1 |
|
|
253
|
+
| [ ] | Id | Author | Body | Created At | Category | Foo | Position | Published Date | Starred | Title | Updated At | |
|
|
254
|
+
| [ ] | 2 | | Move your... | /.*/ | | | | | No | Bye bye world | /.*/ | ViewEditDelete |
|
|
255
|
+
| [ ] | 1 | | From the body | /.*/ | | | | | No | Hello World | /.*/ | ViewEditDelete |
|
|
256
256
|
When I follow "Id"
|
|
257
257
|
Then I should see the "index_table_posts" table:
|
|
258
|
-
| [ ] | Id |
|
|
259
|
-
| [ ] | 1 |
|
|
260
|
-
| [ ] | 2 |
|
|
258
|
+
| [ ] | Id | Author | Body | Created At | Category | Foo | Position | Published Date | Starred | Title | Updated At | |
|
|
259
|
+
| [ ] | 1 | | From the body | /.*/ | | | | | No | Hello World | /.*/ | ViewEditDelete |
|
|
260
|
+
| [ ] | 2 | | Move your... | /.*/ | | | | | No | Bye bye world | /.*/ | ViewEditDelete |
|
|
261
261
|
|
|
262
262
|
Scenario: Sorting by a virtual column
|
|
263
263
|
Given a post with the title "Hello World" exists
|
data/gemfiles/rails_71.gemfile
CHANGED
|
@@ -7,10 +7,11 @@ gem 'rails-i18n'
|
|
|
7
7
|
gem 'inherited_resources', '>= 1.14.0'
|
|
8
8
|
gem 'formtastic', '>= 5.0.0'
|
|
9
9
|
gem 'ransack', '>= 4.1.0'
|
|
10
|
-
gem 'devise', '
|
|
10
|
+
gem 'devise', '~> 4.9'
|
|
11
11
|
gem 'rack', '~> 2.2'
|
|
12
12
|
gem 'bootsnap'
|
|
13
13
|
gem 'draper'
|
|
14
|
+
gem 'dartsass-sprockets'
|
|
14
15
|
gem 'sqlite3', '~> 1.4'
|
|
15
16
|
gem 'activerecord-jdbcsqlite3-adapter', '>= 60.0.x', platform: :jruby
|
|
16
17
|
|
data/gemfiles/rails_72.gemfile
CHANGED
|
@@ -7,10 +7,11 @@ gem 'rails-i18n'
|
|
|
7
7
|
gem 'inherited_resources', '>= 1.14.0'
|
|
8
8
|
gem 'formtastic', '>= 5.0.0'
|
|
9
9
|
gem 'ransack', '>= 4.1.0'
|
|
10
|
-
gem 'devise', '
|
|
10
|
+
gem 'devise', '~> 4.9'
|
|
11
11
|
gem 'rack', '>= 2.2'
|
|
12
12
|
gem 'bootsnap'
|
|
13
13
|
gem 'draper'
|
|
14
|
+
gem 'dartsass-sprockets'
|
|
14
15
|
gem 'sqlite3', '>= 2.x'
|
|
15
16
|
gem 'activerecord-jdbcsqlite3-adapter', '>= 70.0.x', platform: :jruby
|
|
16
17
|
|
data/gemfiles/rails_80.gemfile
CHANGED
|
@@ -7,10 +7,11 @@ gem 'rails-i18n'
|
|
|
7
7
|
gem 'inherited_resources', '>= 1.14.0'
|
|
8
8
|
gem 'formtastic', '>= 5.0.0'
|
|
9
9
|
gem 'ransack', '>= 4.1.0'
|
|
10
|
-
gem 'devise', '
|
|
10
|
+
gem 'devise', '~> 4.9'
|
|
11
11
|
gem 'rack', '>= 2.2'
|
|
12
12
|
gem 'bootsnap'
|
|
13
13
|
gem 'draper'
|
|
14
|
+
gem 'propshaft'
|
|
14
15
|
gem 'sqlite3', '>= 2.x'
|
|
15
16
|
gem 'activerecord-jdbcsqlite3-adapter', '>= 70.0.x', platform: :jruby
|
|
16
17
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
eval_gemfile(File.expand_path(File.join('..', 'Gemfile'), __dir__))
|
|
4
|
+
|
|
5
|
+
gem 'rails', '~> 8.1.0'
|
|
6
|
+
gem 'rails-i18n'
|
|
7
|
+
gem 'inherited_resources', '>= 1.14.0'
|
|
8
|
+
gem 'formtastic', '>= 5.0.0'
|
|
9
|
+
gem 'ransack', '>= 4.1.0'
|
|
10
|
+
gem 'devise', '~> 4.9'
|
|
11
|
+
gem 'rack', '>= 2.2'
|
|
12
|
+
gem 'bootsnap'
|
|
13
|
+
gem 'draper'
|
|
14
|
+
gem 'propshaft'
|
|
15
|
+
gem 'sqlite3', '>= 2.x'
|
|
16
|
+
gem 'activerecord-jdbcsqlite3-adapter', '>= 70.0.x', platform: :jruby
|
|
17
|
+
|
|
18
|
+
gemspec path: '../'
|
|
@@ -187,7 +187,15 @@ module ActiveAdmin
|
|
|
187
187
|
register_stylesheet 'active_admin.css', media: 'screen'
|
|
188
188
|
register_stylesheet 'active_admin/print.css', media: 'print'
|
|
189
189
|
|
|
190
|
-
register_javascript '
|
|
190
|
+
register_javascript 'https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js'
|
|
191
|
+
register_javascript 'https://cdn.jsdelivr.net/npm/jquery-ui-dist@1/jquery-ui.min.js'
|
|
192
|
+
register_javascript 'https://cdn.jsdelivr.net/npm/jquery-ujs@1.2.3/src/rails.min.js'
|
|
193
|
+
|
|
194
|
+
if defined?(Sprockets)
|
|
195
|
+
register_javascript 'active_admin.js'
|
|
196
|
+
else
|
|
197
|
+
register_javascript 'active_admin/base.js'
|
|
198
|
+
end
|
|
191
199
|
end
|
|
192
200
|
|
|
193
201
|
# Since app/admin is alphabetically before app/models, we have to remove it
|
data/lib/active_admin/engine.rb
CHANGED
|
@@ -7,11 +7,14 @@ module ActiveAdmin
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
initializer "active_admin.precompile", group: :all do |app|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
# Only add to precompile list if using Sprockets (not Propshaft)
|
|
11
|
+
if app.config.respond_to?(:assets) && app.config.assets.respond_to?(:precompile)
|
|
12
|
+
ActiveAdmin.application.stylesheets.each do |path, _|
|
|
13
|
+
app.config.assets.precompile << path
|
|
14
|
+
end
|
|
15
|
+
ActiveAdmin.application.javascripts.each do |path|
|
|
16
|
+
app.config.assets.precompile << path
|
|
17
|
+
end
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
20
|
|
|
@@ -26,8 +26,7 @@ module ActiveAdmin
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def label
|
|
29
|
-
|
|
30
|
-
translated_predicate = predicate_name.mb_chars.downcase.to_s
|
|
29
|
+
translated_predicate = predicate_name.downcase
|
|
31
30
|
if filter_label
|
|
32
31
|
"#{filter_label} #{translated_predicate}"
|
|
33
32
|
elsif related_class
|
|
@@ -291,7 +291,7 @@ module ActiveAdmin
|
|
|
291
291
|
end
|
|
292
292
|
else
|
|
293
293
|
eval "class ::#{config.controller_name} < ActiveAdmin::ResourceController; end"
|
|
294
|
-
config.controller.const_set(:DISPOSABLE, true)
|
|
294
|
+
config.controller.const_set(:DISPOSABLE, true) unless config.controller.const_defined?(:DISPOSABLE)
|
|
295
295
|
end
|
|
296
296
|
config.controller.active_admin_config = config
|
|
297
297
|
end
|
|
@@ -82,7 +82,8 @@ module ActiveAdmin
|
|
|
82
82
|
register :on_unauthorized_access, :rescue_active_admin_access_denied
|
|
83
83
|
|
|
84
84
|
# A regex to detect unsupported browser, set to false to disable
|
|
85
|
-
|
|
85
|
+
# IE11 and below are no longer supported
|
|
86
|
+
register :unsupported_browser_matcher, /MSIE|Trident/
|
|
86
87
|
|
|
87
88
|
# Whether to display 'Current Filters' on search screen
|
|
88
89
|
register :current_filters, true
|
|
@@ -4,7 +4,7 @@ module ActiveAdmin
|
|
|
4
4
|
module Attributes
|
|
5
5
|
|
|
6
6
|
def default_attributes
|
|
7
|
-
resource_class.columns.each_with_object({}) do |c, attrs|
|
|
7
|
+
resource_class.columns.sort_by(&:name).each_with_object({}) do |c, attrs|
|
|
8
8
|
unless reject_col?(c)
|
|
9
9
|
name = c.name.to_sym
|
|
10
10
|
attrs[name] = (method_for_column(name) || name)
|
data/lib/active_admin/router.rb
CHANGED
|
@@ -19,7 +19,7 @@ module ActiveAdmin
|
|
|
19
19
|
if namespace.root?
|
|
20
20
|
router.root namespace.root_to_options.merge(to: namespace.root_to, as: nil)
|
|
21
21
|
else
|
|
22
|
-
router.namespace namespace.name, namespace.route_options.dup do
|
|
22
|
+
router.namespace namespace.name, **namespace.route_options.dup do
|
|
23
23
|
router.root namespace.root_to_options.merge(to: namespace.root_to, as: :root)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -89,8 +89,8 @@ module ActiveAdmin
|
|
|
89
89
|
build_route(action.http_verb, action.name)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
def build_route(verbs, *args)
|
|
93
|
-
Array.wrap(verbs).each { |verb| router.send(verb, *args) }
|
|
92
|
+
def build_route(verbs, *args, **kwargs)
|
|
93
|
+
Array.wrap(verbs).each { |verb| router.send(verb, *args, **kwargs) }
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
def define_belongs_to_routes(config)
|
|
@@ -105,7 +105,7 @@ module ActiveAdmin
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
def define_namespace(config)
|
|
108
|
-
router.namespace config.namespace.name, config.namespace.route_options.dup do
|
|
108
|
+
router.namespace config.namespace.name, **config.namespace.route_options.dup do
|
|
109
109
|
define_routes(config)
|
|
110
110
|
end
|
|
111
111
|
end
|
data/lib/active_admin/version.rb
CHANGED