active_admin_date_range_preset 0.3.1 → 0.4.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 +5 -5
- data/README.md +80 -10
- data/lib/active_admin_date_range_preset/version.rb +1 -1
- data/vendor/assets/javascripts/active_admin_date_range_preset.js +245 -0
- data/vendor/assets/stylesheets/active_admin_date_range_preset.scss +14 -0
- metadata +27 -25
- data/.idea/vcs.xml +0 -6
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/active_admin_date_range_preset.gemspec +0 -24
- data/screen/step_1.jpg +0 -0
- data/screen/step_2.jpg +0 -0
- data/screen/step_2_1.png +0 -0
- data/screen/step_2_2.png +0 -0
- data/vendor/assets/javascripts/active_admin_date_range_preset.coffee +0 -191
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9017cfc30106119dd13d0064a6fd63d8d6eacb3bf6e526a97eb26793f8d47c21
|
|
4
|
+
data.tar.gz: eb4e677c8381eff213f9ab5efd4c924e7a38f0543b2e6b159e650a86c1deb85b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5ed90bdb897e4463d9979b6bf70edd059b4ff3f3b2454ad6b989b31257e3fa1eb5e9109810c5ec73f5fdcbc032b0190b7bde3c0731c89e43ef14a52e3713e46
|
|
7
|
+
data.tar.gz: d1e948d843d9aa35bcc40592fcbce5fcdc5d4044bd70747c4c872cf27c9606723240ea046500df9010825e8bc3a67191a839eb9f8f6ad747018c223bef9bf416
|
data/README.md
CHANGED
|
@@ -1,16 +1,35 @@
|
|
|
1
|
+
[](https://badge.fury.io/rb/active_admin_date_range_preset)
|
|
2
|
+
[](https://badge.fury.io/js/@activeadmin-plugins%2Factive_admin_date_range_preset)
|
|
3
|
+

|
|
4
|
+
[](https://github.com/activeadmin-plugins/active_admin_date_range_preset/actions/workflows/ci.yml)
|
|
5
|
+
|
|
1
6
|
# active_admin_date_range_preset
|
|
2
7
|
|
|
3
8
|
Preset links for ActiveAdmin date_range inputs in sidebar filters in forms
|
|
4
9
|
|
|
5
10
|
This is how it looks like
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
<img width="1008" height="942" alt="combined" src="https://github.com/user-attachments/assets/cbe22410-078e-4f2b-894b-4457c13e3e22" />
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Compatibility
|
|
16
|
+
|
|
17
|
+
Active Admin 3.2 or newer, in the 3.x series. Rails 8.0 or newer, Ruby 3.3 or
|
|
18
|
+
newer. CI covers Active Admin 3.2 and 3.5 on Ruby 3.3, 3.4 and 4.0 against
|
|
19
|
+
Rails 8.0 and 8.1 — every Rails series still supported upstream.
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
Version 0.4.0 raised the Rails floor from 7.1 to 8.0. Every 7.x series is out
|
|
22
|
+
of support — 7.1 since October 2025, 7.2 since August 2026 — and none of them
|
|
23
|
+
is tested. Stay on 0.3.x if you are still on Rails 7.
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
The Rails and Ruby floors are declared explicitly because Active Admin 3.2
|
|
26
|
+
still allows `railties >= 6.1` and Ruby `>= 2.6`, both long past end of life
|
|
27
|
+
and neither tested here.
|
|
12
28
|
|
|
13
|
-
|
|
29
|
+
Active Admin 4 is not supported. It drops `jquery-rails` and the
|
|
30
|
+
`app/assets/javascripts` tree, and this gem is a jQuery plugin shipped through
|
|
31
|
+
Sprockets, so nothing here loads there. Supporting it means a rewrite rather
|
|
32
|
+
than a port, and that is tracked separately.
|
|
14
33
|
|
|
15
34
|
## Installation
|
|
16
35
|
|
|
@@ -28,7 +47,7 @@ Or install it yourself as:
|
|
|
28
47
|
|
|
29
48
|
$ gem install active_admin_date_range_preset
|
|
30
49
|
|
|
31
|
-
|
|
50
|
+
##### Using assets via Sprockets
|
|
32
51
|
|
|
33
52
|
JS asset
|
|
34
53
|
```//= require active_admin_date_range_preset```
|
|
@@ -36,8 +55,59 @@ Include assests:
|
|
|
36
55
|
CSS
|
|
37
56
|
```@import "active_admin_date_range_preset";```
|
|
38
57
|
|
|
58
|
+
##### Using assets via Webpacker (or any other assets bundler) as a NPM module (Yarn package)
|
|
59
|
+
|
|
60
|
+
Execute:
|
|
61
|
+
|
|
62
|
+
$ npm i @activeadmin-plugins/active_admin_date_range_preset
|
|
63
|
+
|
|
64
|
+
Or
|
|
65
|
+
|
|
66
|
+
$ yarn add @activeadmin-plugins/active_admin_date_range_preset
|
|
67
|
+
|
|
68
|
+
Or add manually to `package.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@activeadmin-plugins/active_admin_date_range_preset": "0.3.1"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
and execute:
|
|
76
|
+
|
|
77
|
+
$ yarn
|
|
78
|
+
|
|
79
|
+
Add the following line into `app/assets/javascripts/active_admin.js`:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
import '@activeadmin-plugins/active_admin_date_range_preset';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Add the following line into `app/assets/stylesheets/active_admin.scss`:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
@import '@activeadmin-plugins/active_admin_date_range_preset';
|
|
89
|
+
```
|
|
90
|
+
|
|
39
91
|
Your sidebar filters should now have link "Set Range"
|
|
40
92
|
|
|
93
|
+
## Development
|
|
94
|
+
|
|
95
|
+
The specs run against a throwaway Rails app built by `spec/support/rails_template.rb`.
|
|
96
|
+
It is generated automatically on the first run (or via `bundle exec rake setup`) into
|
|
97
|
+
`spec/rails/rails-<version>/`, which is gitignored.
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
bundle install
|
|
101
|
+
bundle exec rspec spec
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Pick the versions under test with env vars:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
RAILS=8.0.0 AA=3.5.0 bundle install
|
|
108
|
+
RAILS=8.0.0 AA=3.5.0 bundle exec rspec spec
|
|
109
|
+
```
|
|
110
|
+
|
|
41
111
|
## Usage
|
|
42
112
|
|
|
43
113
|
in New/Edit formtastic forms:
|
|
@@ -75,7 +145,7 @@ In active_admin.js
|
|
|
75
145
|
Add following lines to JavaScript
|
|
76
146
|
|
|
77
147
|
```javascript
|
|
78
|
-
$(
|
|
148
|
+
$(function () {
|
|
79
149
|
$('form.filter_form div.filter_date_time_range').date_range_ext_preset();
|
|
80
150
|
});
|
|
81
151
|
```
|
|
@@ -89,7 +159,7 @@ You can assign "Set range" almost to any input-text-pair filters/forms.
|
|
|
89
159
|
For example, you have complex form where input-pairs are not close to each other and not standard.
|
|
90
160
|
|
|
91
161
|
```javascript
|
|
92
|
-
$(
|
|
162
|
+
$(function () {
|
|
93
163
|
$('.any_jquery_selector').date_range_ext_preset({
|
|
94
164
|
lteq_input: '.jquery_selector_to_first_input',
|
|
95
165
|
gteq_input: '.jquery_selector_to_second_input'
|
|
@@ -111,7 +181,7 @@ $('.any_jquery_selector').date_range_ext_preset({
|
|
|
111
181
|
setting_name: "setting_value"
|
|
112
182
|
});
|
|
113
183
|
```
|
|
114
|
-
Example how to set global settings. Write it before
|
|
184
|
+
Example how to set global settings. Write it before the `$(function () { ... })` block
|
|
115
185
|
|
|
116
186
|
```javascript
|
|
117
187
|
$.fn.date_range_ext_preset.defaults.setting_name = "setting_value"
|
|
@@ -166,12 +236,12 @@ Example:
|
|
|
166
236
|
$.fn.date_range_ext_preset.defaults.hours_offset = +3
|
|
167
237
|
// or
|
|
168
238
|
$.fn.date_range_ext_preset.defaults.hours_offset = -3
|
|
169
|
-
```
|
|
239
|
+
```
|
|
170
240
|
|
|
171
241
|
### Addition ranges
|
|
172
242
|
|
|
173
243
|
```javascript
|
|
174
|
-
$(
|
|
244
|
+
$(function () {
|
|
175
245
|
|
|
176
246
|
$('.filter_form .filter_date_range').date_range_ext_preset({
|
|
177
247
|
date_to_human_readable: true, # affects last day
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
$(function () {
|
|
2
|
+
// options:
|
|
3
|
+
// gteq_input: jQuery-selecotr for input date_from
|
|
4
|
+
// lteq_input: jQuery-selecotr for input date_to
|
|
5
|
+
// hours_offset: Int number - hours +/- to correct time
|
|
6
|
+
$.fn.date_range_ext_preset = function(options) {
|
|
7
|
+
// settings
|
|
8
|
+
options = options || {};
|
|
9
|
+
let opts = $.extend({}, $.fn.date_range_ext_preset.defaults, options);
|
|
10
|
+
|
|
11
|
+
// aditional functions
|
|
12
|
+
function num_with_leading_zero(num, digitsCount = 2) {
|
|
13
|
+
let s = num + '';
|
|
14
|
+
while (s.length < digitsCount) {
|
|
15
|
+
s = '0' + s;
|
|
16
|
+
}
|
|
17
|
+
return s;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// formated date YYYY-MM-DD, with converting to UTC
|
|
21
|
+
// note: getMonth Returns the month (from 0-11), so we do +1
|
|
22
|
+
function formatDate(date, el_opts) {
|
|
23
|
+
let str = date.getFullYear() + '-' + num_with_leading_zero(date.getMonth()+1) + '-' + num_with_leading_zero(date.getDate());
|
|
24
|
+
if (el_opts.show_time) {
|
|
25
|
+
str += (' ' + num_with_leading_zero(date.getHours()) + ':' + num_with_leading_zero(date.getMinutes()) + ':' + num_with_leading_zero(date.getSeconds()));
|
|
26
|
+
}
|
|
27
|
+
return str;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Days from the Monday that opens this date's week. getDay() counts from
|
|
31
|
+
// Sunday, so a plain `- getDay() + 1` lands on tomorrow for Sundays and
|
|
32
|
+
// hands back the week that has not started yet.
|
|
33
|
+
function days_since_monday(date) {
|
|
34
|
+
return (date.getDay() + 6) % 7;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function unbindClickEventBlockTimerange() {
|
|
38
|
+
$('.block_timerange').remove();
|
|
39
|
+
$('body').off('click.CalendarRangeSet');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// local datetime now
|
|
43
|
+
let now = new Date();
|
|
44
|
+
// UTC datetime now
|
|
45
|
+
let now_utc = new Date(
|
|
46
|
+
now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),
|
|
47
|
+
now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(),
|
|
48
|
+
now.getUTCMilliseconds()
|
|
49
|
+
);
|
|
50
|
+
// datetime object, UTC with hours offset
|
|
51
|
+
let datetime = new Date(now_utc.getTime() + opts.hours_offset * 60 * 60 * 1000);
|
|
52
|
+
|
|
53
|
+
// PLUGIN BEGIN
|
|
54
|
+
return this.each(function(i, el) {
|
|
55
|
+
let $this = $(el);
|
|
56
|
+
|
|
57
|
+
// Re-initialising an element replaces its wiring instead of adding to
|
|
58
|
+
// it. The auto-init below was dead from jQuery 3 onwards, so hosts
|
|
59
|
+
// worked around it by calling the plugin themselves; now that it works
|
|
60
|
+
// again both run, and without this the label grows a second "Set range"
|
|
61
|
+
// whose handler tears down the first one's popup.
|
|
62
|
+
//
|
|
63
|
+
// Replacing rather than skipping matters: the auto-init registers its
|
|
64
|
+
// ready callback before anything a host adds to active_admin.js, so
|
|
65
|
+
// bailing out on the second call would silently drop the host's
|
|
66
|
+
// options. Reading the link itself rather than a data flag keeps the
|
|
67
|
+
// guard and the thing it guards from drifting apart across clone() and
|
|
68
|
+
// Turbo cache restores, which copy the node but not jQuery's data.
|
|
69
|
+
$this.find('a.btn_timerange').remove();
|
|
70
|
+
$this.off('click.dateRangeExtPreset');
|
|
71
|
+
|
|
72
|
+
// Per element, because data-show-time is read off the element itself.
|
|
73
|
+
// Writing it back into the shared opts let one pair's setting reach
|
|
74
|
+
// every other pair in the same call, and formatDate reads the flag at
|
|
75
|
+
// click time rather than here, so the leak was not even order-dependent.
|
|
76
|
+
let el_opts = $.extend({}, opts);
|
|
77
|
+
|
|
78
|
+
// The attribute is authoritative in both directions when present. Only
|
|
79
|
+
// ever assigning true made it impossible for one element to opt out of
|
|
80
|
+
// a show_time the call or the defaults had turned on.
|
|
81
|
+
if (typeof $this.data('show-time') != 'undefined') {
|
|
82
|
+
el_opts.show_time = $this.data('show-time').toString() == 'true';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// detect inputs
|
|
86
|
+
let lteq_input = $this.find('input:last');
|
|
87
|
+
if (options.lteq_input) {
|
|
88
|
+
lteq_input = $(options.lteq_input);
|
|
89
|
+
} else if ($this.hasClass('datetime_preset_pair')) {
|
|
90
|
+
lteq_input = $this.next().find('input');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let gteq_input = $this.find('input:first');
|
|
94
|
+
if (options.gteq_input) {
|
|
95
|
+
gteq_input = $(options.gteq_input);
|
|
96
|
+
} else if ($this.hasClass('datetime_preset_pair')) {
|
|
97
|
+
gteq_input = $this.find('input');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// filter modifying
|
|
101
|
+
let main_btn_html = '<a href="#" class="btn_timerange">Set range</a>';
|
|
102
|
+
$this.find('label').addClass('datetime_preset_filter_label').append(main_btn_html);
|
|
103
|
+
|
|
104
|
+
// helper
|
|
105
|
+
function fillInputs(start, end) {
|
|
106
|
+
gteq_input.val(formatDate(start, el_opts));
|
|
107
|
+
if (el_opts.date_to_human_readable) {
|
|
108
|
+
end.setTime(end.getTime() - 1000);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
lteq_input.val(formatDate(end, el_opts));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
$this.on('click.dateRangeExtPreset', '.btn_timerange', function(e) {
|
|
115
|
+
unbindClickEventBlockTimerange();
|
|
116
|
+
e.stopPropagation();
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
|
|
119
|
+
let additional_items_html = '';
|
|
120
|
+
opts.add_range.forEach(function(el, i) {
|
|
121
|
+
return additional_items_html += '<div><span class="btn_date_range_' + i + '">' + el['title'] + '</span></div>';
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Bind in the same tick the popup is appended. Active Admin 3 ships
|
|
125
|
+
// jQuery 3, which rebuilt .ready() on top of a Deferred whose .then
|
|
126
|
+
// schedules through setTimeout, so handlers attached inside it landed
|
|
127
|
+
// a macrotask late and the popup was on screen but inert until then.
|
|
128
|
+
// On a non-document collection the method is deprecated anyway.
|
|
129
|
+
let container = $('<div style="min-width: '+e.target.offsetWidth+'px; top: '+(e.target.offsetTop)+'px; left: '+(e.target.offsetLeft)+'px" class="block_timerange">' +
|
|
130
|
+
'<div><span class="btn_today">Today</span></div>' +
|
|
131
|
+
'<div><span class="btn_yesterday">Yesterday</span></div>' +
|
|
132
|
+
'<div><span class="btn_week">This Week</span></div>' +
|
|
133
|
+
'<div><span class="btn_month">This Month</span></div>' +
|
|
134
|
+
'<div><span class="btn_last_week">Last Week</span></div>' +
|
|
135
|
+
'<div><span class="btn_last_month">Last Month</span></div>' +
|
|
136
|
+
additional_items_html +
|
|
137
|
+
'</div>'
|
|
138
|
+
).appendTo('body');
|
|
139
|
+
|
|
140
|
+
// additional ranges
|
|
141
|
+
opts.add_range.forEach(function(el, i) {
|
|
142
|
+
container.on('click.CalendarRangeSet', '.btn_date_range_' + i, function(e) {
|
|
143
|
+
unbindClickEventBlockTimerange();
|
|
144
|
+
let start = new Date(el['start'].getFullYear(), el['start'].getMonth(), el['start'].getDate());
|
|
145
|
+
let end = new Date(el['end'].getFullYear(), el['end'].getMonth(), el['end'].getDate());
|
|
146
|
+
fillInputs(start, end)
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Today
|
|
151
|
+
container.on('click.CalendarRangeSet', '.btn_today', function(e) {
|
|
152
|
+
unbindClickEventBlockTimerange();
|
|
153
|
+
let start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate());
|
|
154
|
+
let end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + 1);
|
|
155
|
+
fillInputs(start, end);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Yesterday
|
|
159
|
+
container.on('click.CalendarRangeSet', '.btn_yesterday', function(e) {
|
|
160
|
+
unbindClickEventBlockTimerange();
|
|
161
|
+
let start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - 1);
|
|
162
|
+
let end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate());
|
|
163
|
+
fillInputs(start, end);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Week
|
|
167
|
+
container.on('click.CalendarRangeSet', '.btn_week', function(e) {
|
|
168
|
+
unbindClickEventBlockTimerange();
|
|
169
|
+
let start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - days_since_monday(datetime));
|
|
170
|
+
let end = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 7);
|
|
171
|
+
fillInputs(start, end);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Month
|
|
175
|
+
container.on('click.CalendarRangeSet', '.btn_month', function(e) {
|
|
176
|
+
unbindClickEventBlockTimerange();
|
|
177
|
+
let start = new Date(datetime.getFullYear(), datetime.getMonth(), 1);
|
|
178
|
+
let end = new Date(datetime.getFullYear(), datetime.getMonth() + 1, 1);
|
|
179
|
+
fillInputs(start, end);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Last Week
|
|
183
|
+
container.on('click.CalendarRangeSet', '.btn_last_week', function(e) {
|
|
184
|
+
unbindClickEventBlockTimerange();
|
|
185
|
+
let end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - days_since_monday(datetime));
|
|
186
|
+
let start = new Date(end.getFullYear(), end.getMonth(), end.getDate() - 7);
|
|
187
|
+
fillInputs(start, end);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Last Month
|
|
191
|
+
container.on('click.CalendarRangeSet', '.btn_last_month', function(e) {
|
|
192
|
+
unbindClickEventBlockTimerange();
|
|
193
|
+
let end = new Date(datetime.getFullYear(), datetime.getMonth(), 1);
|
|
194
|
+
let start = new Date(end.getFullYear(), end.getMonth() - 1, 1);
|
|
195
|
+
fillInputs(start, end);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Outer
|
|
199
|
+
// No stopPropagation here: this listener only watches for a click
|
|
200
|
+
// that should close the popup. Active Admin delegates Clear Filters
|
|
201
|
+
// and the has_many buttons from <document>, which is upstream of
|
|
202
|
+
// <body>, so swallowing the event would break them for as long as
|
|
203
|
+
// the popup is open.
|
|
204
|
+
$('body').on('click.CalendarRangeSet', function(e) {
|
|
205
|
+
if ($(e.target).closest('.block_timerange').length == 0) {
|
|
206
|
+
unbindClickEventBlockTimerange();
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
$.fn.date_range_ext_preset.defaults = {
|
|
214
|
+
// Manual global time shift, from UTC can be +/- number
|
|
215
|
+
hours_offset: 0,
|
|
216
|
+
|
|
217
|
+
// date_to_human_readable = true, then "date_to" consider as including full day without last second
|
|
218
|
+
// For example Today will be:
|
|
219
|
+
// true
|
|
220
|
+
// 2015-06-10 - 2015-06-10
|
|
221
|
+
// 2015-06-10 00:00:00 - 2015-06-10 23:59:59
|
|
222
|
+
// false
|
|
223
|
+
// 2015-06-10 - 2015-06-11
|
|
224
|
+
// 2015-06-10 00:00:00 - 2015-06-11 00:00:00
|
|
225
|
+
date_to_human_readable: false,
|
|
226
|
+
|
|
227
|
+
// Display time or not: 2015-06-10 vs 2015-06-10 00:00:00
|
|
228
|
+
show_time: false,
|
|
229
|
+
|
|
230
|
+
// Array of addition ranges
|
|
231
|
+
// example:
|
|
232
|
+
// {
|
|
233
|
+
// title: 'Last 30 days',
|
|
234
|
+
// start: new Date().setDate((new Date()).getDate() - 30)
|
|
235
|
+
// end: new Date()
|
|
236
|
+
// }
|
|
237
|
+
add_range: []
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// jQuery 3 removed $(document).on('ready'), so this must stay $(fn).
|
|
242
|
+
$(function() {
|
|
243
|
+
// Init in forms
|
|
244
|
+
$('.datetime_preset_pair').date_range_ext_preset();
|
|
245
|
+
});
|
|
@@ -9,6 +9,20 @@ form label.datetime_preset_filter_label .btn_timerange {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
// A form pair gets Active Admin's full label column, which is wide enough
|
|
13
|
+
// that the float above parks the link at the far right of it, away from the
|
|
14
|
+
// inputs it drives. Put it on its own line under the label text instead.
|
|
15
|
+
// `display: table` keeps it shrink-to-fit, so the dashed underline stays
|
|
16
|
+
// under the words rather than stretching the whole column.
|
|
17
|
+
//
|
|
18
|
+
// The sidebar filter keeps the float: there the label and the link share a
|
|
19
|
+
// narrow panel and right alignment is what the plugin has always shown.
|
|
20
|
+
.datetime_preset_pair > label.datetime_preset_filter_label .btn_timerange {
|
|
21
|
+
float: none;
|
|
22
|
+
display: table;
|
|
23
|
+
margin: 2px 0 0 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
.block_timerange {
|
|
13
27
|
position: absolute;
|
|
14
28
|
display: block;
|
metadata
CHANGED
|
@@ -1,43 +1,56 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_admin_date_range_preset
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gena M.
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: activeadmin
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
type: :
|
|
18
|
+
version: '3.2'
|
|
19
|
+
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '3.2'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: railties
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '8.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '8.0'
|
|
27
40
|
- !ruby/object:Gem::Dependency
|
|
28
41
|
name: rake
|
|
29
42
|
requirement: !ruby/object:Gem::Requirement
|
|
30
43
|
requirements:
|
|
31
|
-
- - "
|
|
44
|
+
- - ">="
|
|
32
45
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
46
|
+
version: '0'
|
|
34
47
|
type: :development
|
|
35
48
|
prerelease: false
|
|
36
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
50
|
requirements:
|
|
38
|
-
- - "
|
|
51
|
+
- - ">="
|
|
39
52
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
53
|
+
version: '0'
|
|
41
54
|
description: Integrate useful fast links to set date ranges in to ActiveAdmin, for
|
|
42
55
|
example today range, week range, month range
|
|
43
56
|
email:
|
|
@@ -46,25 +59,16 @@ executables: []
|
|
|
46
59
|
extensions: []
|
|
47
60
|
extra_rdoc_files: []
|
|
48
61
|
files:
|
|
49
|
-
- ".idea/vcs.xml"
|
|
50
|
-
- Gemfile
|
|
51
62
|
- LICENSE.txt
|
|
52
63
|
- README.md
|
|
53
|
-
- Rakefile
|
|
54
|
-
- active_admin_date_range_preset.gemspec
|
|
55
64
|
- lib/active_admin_date_range_preset.rb
|
|
56
65
|
- lib/active_admin_date_range_preset/version.rb
|
|
57
|
-
-
|
|
58
|
-
- screen/step_2.jpg
|
|
59
|
-
- screen/step_2_1.png
|
|
60
|
-
- screen/step_2_2.png
|
|
61
|
-
- vendor/assets/javascripts/active_admin_date_range_preset.coffee
|
|
66
|
+
- vendor/assets/javascripts/active_admin_date_range_preset.js
|
|
62
67
|
- vendor/assets/stylesheets/active_admin_date_range_preset.scss
|
|
63
68
|
homepage: https://github.com/workgena/active_admin_date_range_preset
|
|
64
69
|
licenses:
|
|
65
70
|
- MIT
|
|
66
71
|
metadata: {}
|
|
67
|
-
post_install_message:
|
|
68
72
|
rdoc_options: []
|
|
69
73
|
require_paths:
|
|
70
74
|
- lib
|
|
@@ -72,16 +76,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
72
76
|
requirements:
|
|
73
77
|
- - ">="
|
|
74
78
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
79
|
+
version: '3.3'
|
|
76
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
81
|
requirements:
|
|
78
82
|
- - ">="
|
|
79
83
|
- !ruby/object:Gem::Version
|
|
80
84
|
version: '0'
|
|
81
85
|
requirements: []
|
|
82
|
-
|
|
83
|
-
rubygems_version: 2.6.12
|
|
84
|
-
signing_key:
|
|
86
|
+
rubygems_version: 3.6.9
|
|
85
87
|
specification_version: 4
|
|
86
88
|
summary: date_range_preset extension for ActiveAdmin
|
|
87
89
|
test_files: []
|
data/.idea/vcs.xml
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require "bundler/gem_tasks"
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'active_admin_date_range_preset/version'
|
|
5
|
-
|
|
6
|
-
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name = "active_admin_date_range_preset"
|
|
8
|
-
spec.version = ActiveAdminDateRangePreset::VERSION
|
|
9
|
-
spec.authors = ["Gena M."]
|
|
10
|
-
spec.email = ["workgena@gmail.com"]
|
|
11
|
-
|
|
12
|
-
spec.summary = %q{date_range_preset extension for ActiveAdmin}
|
|
13
|
-
spec.description = %q{Integrate useful fast links to set date ranges in to ActiveAdmin, for example today range, week range, month range}
|
|
14
|
-
spec.homepage = "https://github.com/workgena/active_admin_date_range_preset"
|
|
15
|
-
spec.license = "MIT"
|
|
16
|
-
|
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
-
spec.bindir = "bin"
|
|
19
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
20
|
-
spec.require_paths = ["lib"]
|
|
21
|
-
|
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.8"
|
|
23
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
|
24
|
-
end
|
data/screen/step_1.jpg
DELETED
|
Binary file
|
data/screen/step_2.jpg
DELETED
|
Binary file
|
data/screen/step_2_1.png
DELETED
|
Binary file
|
data/screen/step_2_2.png
DELETED
|
Binary file
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
(($) ->
|
|
2
|
-
# options:
|
|
3
|
-
# gteq_input: jQuery-selecotr for input date_from
|
|
4
|
-
# lteq_input: jQuery-selecotr for input date_to
|
|
5
|
-
# hours_offset: Int number - hours +/- to correct time
|
|
6
|
-
$.fn.date_range_ext_preset = (options)->
|
|
7
|
-
|
|
8
|
-
# settings
|
|
9
|
-
options = options || {}
|
|
10
|
-
opts = $.extend( {}, $.fn.date_range_ext_preset.defaults, options );
|
|
11
|
-
|
|
12
|
-
# aditional functions
|
|
13
|
-
num_with_leading_zero = (num, digits_count = 2)->
|
|
14
|
-
s = num + ''
|
|
15
|
-
s = '0' + s while (s.length < digits_count)
|
|
16
|
-
return s
|
|
17
|
-
|
|
18
|
-
# formated date YYYY-MM-DD, with converting to UTC
|
|
19
|
-
# note: getMonth Returns the month (from 0-11), so we do +1
|
|
20
|
-
formatDate = (date)->
|
|
21
|
-
str = date.getFullYear() + '-' + num_with_leading_zero(date.getMonth()+1) + '-' + num_with_leading_zero(date.getDate())
|
|
22
|
-
if opts.show_time
|
|
23
|
-
str += ( ' ' + num_with_leading_zero(date.getHours()) + ':' + num_with_leading_zero(date.getMinutes()) + ':' + num_with_leading_zero(date.getSeconds()) )
|
|
24
|
-
return str
|
|
25
|
-
|
|
26
|
-
unbindClickEventBlockTimerange = ->
|
|
27
|
-
$('.block_timerange').remove()
|
|
28
|
-
$('body').off('click.CalendarRangeSet')
|
|
29
|
-
|
|
30
|
-
# local datetime now
|
|
31
|
-
now = new Date()
|
|
32
|
-
# UTC datetime now
|
|
33
|
-
now_utc = new Date(
|
|
34
|
-
now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),
|
|
35
|
-
now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(),
|
|
36
|
-
now.getUTCMilliseconds()
|
|
37
|
-
)
|
|
38
|
-
# datetime object, UTC with hours offset
|
|
39
|
-
datetime = new Date(now_utc.getTime() + opts.hours_offset * 60 * 60 * 1000)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# PLUGIN BEGIN
|
|
43
|
-
return this.each (i, el) ->
|
|
44
|
-
$this = $(el)
|
|
45
|
-
|
|
46
|
-
if typeof $this.data('show-time') != 'undefined' && $this.data('show-time').toString() == 'true'
|
|
47
|
-
console.log $this.data('show-time')
|
|
48
|
-
opts.show_time = true
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
# detect inputs
|
|
52
|
-
if options.lteq_input
|
|
53
|
-
lteq_input = $(options.lteq_input)
|
|
54
|
-
else
|
|
55
|
-
lteq_input = if $this.hasClass('datetime_preset_pair') then $this.next().find('input') else $this.find('input:last')
|
|
56
|
-
if options.gteq_input
|
|
57
|
-
gteq_input = $(options.gteq_input)
|
|
58
|
-
else
|
|
59
|
-
gteq_input = if $this.hasClass('datetime_preset_pair') then $this.find('input') else $this.find('input:first')
|
|
60
|
-
|
|
61
|
-
# filter modifying
|
|
62
|
-
main_btn_html = '<a href="#" class="btn_timerange">Set range</a>'
|
|
63
|
-
$this.find('label').addClass('datetime_preset_filter_label').append(main_btn_html)
|
|
64
|
-
|
|
65
|
-
# helper
|
|
66
|
-
fillInputs = (start, end)->
|
|
67
|
-
gteq_input.val(formatDate(start) )
|
|
68
|
-
if opts.date_to_human_readable
|
|
69
|
-
end.setTime( end.getTime() - 1000 )
|
|
70
|
-
lteq_input.val( formatDate(end) )
|
|
71
|
-
|
|
72
|
-
$this.on('click', '.btn_timerange', (e)->
|
|
73
|
-
unbindClickEventBlockTimerange()
|
|
74
|
-
e.stopPropagation()
|
|
75
|
-
e.preventDefault()
|
|
76
|
-
|
|
77
|
-
additional_items_html = ''
|
|
78
|
-
opts.add_range.forEach (el, i)->
|
|
79
|
-
additional_items_html += '<div><span class="btn_date_range_' + i + '">' + el['title'] + '</span></div>'
|
|
80
|
-
|
|
81
|
-
$('body').append('<div style="min-width: '+e.target.offsetWidth+'px; top: '+(e.target.offsetTop)+'px; left: '+(e.target.offsetLeft)+'px" class="block_timerange">' +
|
|
82
|
-
'<div><span class="btn_today">Today</span></div>' +
|
|
83
|
-
'<div><span class="btn_yesterday">Yesterday</span></div>' +
|
|
84
|
-
'<div><span class="btn_week">This Week</span></div>' +
|
|
85
|
-
'<div><span class="btn_month">This Month</span></div>' +
|
|
86
|
-
'<div><span class="btn_last_week">Last Week</span></div>' +
|
|
87
|
-
'<div><span class="btn_last_month">Last Month</span></div>' +
|
|
88
|
-
additional_items_html +
|
|
89
|
-
'</div>'
|
|
90
|
-
).ready(->
|
|
91
|
-
container = $(this).find('.block_timerange')
|
|
92
|
-
|
|
93
|
-
# additional ranges
|
|
94
|
-
opts.add_range.forEach (el, i)->
|
|
95
|
-
$(container).on('click.CalendarRangeSet', '.btn_date_range_' + i, (e)->
|
|
96
|
-
unbindClickEventBlockTimerange()
|
|
97
|
-
start = new Date(el['start'].getFullYear(), el['start'].getMonth(), el['start'].getDate())
|
|
98
|
-
end = new Date(el['end'].getFullYear(), el['end'].getMonth(), el['end'].getDate())
|
|
99
|
-
fillInputs(start, end)
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
# Today
|
|
103
|
-
$(container).on('click.CalendarRangeSet', '.btn_today', (e)->
|
|
104
|
-
unbindClickEventBlockTimerange()
|
|
105
|
-
start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate())
|
|
106
|
-
end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + 1)
|
|
107
|
-
fillInputs(start, end)
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
# Yesterday
|
|
111
|
-
$(container).on('click.CalendarRangeSet', '.btn_yesterday', (e)->
|
|
112
|
-
unbindClickEventBlockTimerange()
|
|
113
|
-
start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - 1)
|
|
114
|
-
end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate())
|
|
115
|
-
fillInputs(start, end)
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
# Week
|
|
119
|
-
$(container).on('click.CalendarRangeSet', '.btn_week', (e)->
|
|
120
|
-
unbindClickEventBlockTimerange()
|
|
121
|
-
start = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - datetime.getDay() + 1)
|
|
122
|
-
end = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 7)
|
|
123
|
-
fillInputs(start, end)
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
# Month
|
|
127
|
-
$(container).on('click.CalendarRangeSet', '.btn_month', (e)->
|
|
128
|
-
unbindClickEventBlockTimerange()
|
|
129
|
-
start = new Date(datetime.getFullYear(), datetime.getMonth(), 1)
|
|
130
|
-
end = new Date(datetime.getFullYear(), datetime.getMonth()+1, 1)
|
|
131
|
-
fillInputs(start, end)
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
# Last Week
|
|
135
|
-
$(container).on('click.CalendarRangeSet', '.btn_last_week', (e)->
|
|
136
|
-
unbindClickEventBlockTimerange()
|
|
137
|
-
end = new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() - datetime.getDay() + 1)
|
|
138
|
-
start = new Date(end.getFullYear(), end.getMonth(), end.getDate() - 7)
|
|
139
|
-
fillInputs(start, end)
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
# Last Month
|
|
143
|
-
$(container).on('click.CalendarRangeSet', '.btn_last_month', (e)->
|
|
144
|
-
unbindClickEventBlockTimerange()
|
|
145
|
-
end = new Date(datetime.getFullYear(), datetime.getMonth(), 1)
|
|
146
|
-
start = new Date(end.getFullYear(), end.getMonth() - 1, 1)
|
|
147
|
-
fillInputs(start, end)
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
# Outer
|
|
151
|
-
$('body').on('click.CalendarRangeSet', (e)->
|
|
152
|
-
e.stopPropagation()
|
|
153
|
-
if $(e.target).closest('.block_timerange').length == 0
|
|
154
|
-
unbindClickEventBlockTimerange()
|
|
155
|
-
)
|
|
156
|
-
)
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
$.fn.date_range_ext_preset.defaults = {
|
|
160
|
-
# Manual global time shift, from UTC can be +/- number
|
|
161
|
-
hours_offset: 0,
|
|
162
|
-
|
|
163
|
-
# date_to_human_readable = true, then "date_to" consider as including full day without last second
|
|
164
|
-
# For example Today will be:
|
|
165
|
-
# true
|
|
166
|
-
# 2015-06-10 - 2015-06-10
|
|
167
|
-
# 2015-06-10 00:00:00 - 2015-06-10 23:59:59
|
|
168
|
-
# false
|
|
169
|
-
# 2015-06-10 - 2015-06-11
|
|
170
|
-
# 2015-06-10 00:00:00 - 2015-06-11 00:00:00
|
|
171
|
-
date_to_human_readable: false,
|
|
172
|
-
|
|
173
|
-
# Display time or not: 2015-06-10 vs 2015-06-10 00:00:00
|
|
174
|
-
show_time: false,
|
|
175
|
-
|
|
176
|
-
# Array of addition ranges
|
|
177
|
-
# example:
|
|
178
|
-
# {
|
|
179
|
-
# title: 'Last 30 days',
|
|
180
|
-
# start: new Date().setDate((new Date()).getDate() - 30)
|
|
181
|
-
# end: new Date()
|
|
182
|
-
# }
|
|
183
|
-
add_range: []
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
) jQuery
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
$(document).on 'ready', ->
|
|
190
|
-
# Init in forms
|
|
191
|
-
$('.datetime_preset_pair').date_range_ext_preset()
|