activeadmin_dynamic_fields 0.4.0 → 0.6.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/README.md +47 -14
- data/Rakefile +14 -1
- data/app/assets/javascripts/activeadmin/dynamic_fields.js +104 -59
- data/lib/activeadmin/dynamic_fields/version.rb +1 -1
- metadata +3 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04dad08d3de4d4cfd25de86ec9a07e3010e081afc8481b513e85103026863869
|
4
|
+
data.tar.gz: 193871cc16015051ae231a3894c6dbf3fa71f043156fcfac7162bc830380e92c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed3de892e2f3e225bfc875c37906dfca703c1769413c631f20caf8a1fcded149c9560cf523c50f3e56ff60cca02622061c5fe8185a09d8bd081963d3674ee9ed
|
7
|
+
data.tar.gz: 70e75c688f0b2c8448e23f747752202288c89abf9ab7b4c5b11a1c4de1d92c3c18ff1e029e2e7728f5333bf76c2cc4ad54c0ca5b76402b33e698a83e448b410a
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
# ActiveAdmin Dynamic Fields [](https://badge.fury.io/rb/activeadmin_dynamic_fields) [](https://badge.fury.io/rb/activeadmin_dynamic_fields) [](https://rubygems.org/gems/activeadmin_dynamic_fields) [](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/specs.yml)
|
2
2
|
|
3
3
|
An Active Admin plugin to add dynamic behaviors to some fields.
|
4
4
|
|
5
5
|
Features:
|
6
|
+
|
6
7
|
- set conditional checks on fields
|
7
8
|
- trigger actions on target elements
|
8
9
|
- inline field editing
|
@@ -10,41 +11,67 @@ Features:
|
|
10
11
|
|
11
12
|
The easiest way to show how this plugin works is looking the examples [below](#examples).
|
12
13
|
|
14
|
+
Please :star: if you like it.
|
15
|
+
|
13
16
|
## Install
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
|
18
|
+
First, add the gem to your ActiveAdmin project: `gem 'activeadmin_dynamic_fields'` (and execute `bundle`)
|
19
|
+
|
20
|
+
If you installed Active Admin **without Webpacker** support:
|
21
|
+
- add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
|
17
22
|
|
18
23
|
```js
|
19
24
|
//= require activeadmin/dynamic_fields
|
20
25
|
```
|
21
26
|
|
27
|
+
Otherwise **with Webpacker**:
|
28
|
+
|
29
|
+
- Execute in your project root:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
yarn add blocknotes/activeadmin_dynamic_fields
|
33
|
+
```
|
34
|
+
|
35
|
+
- Add to your *app/javascript/packs/active_admin.js*:
|
36
|
+
|
37
|
+
```js
|
38
|
+
require('activeadmin_dynamic_fields')
|
39
|
+
```
|
40
|
+
|
22
41
|
## Options
|
42
|
+
|
23
43
|
Options are passed to fields using *input_html* parameter as *data* attributes.
|
24
44
|
|
25
45
|
Conditions:
|
46
|
+
|
26
47
|
- **data-if**: check a condition, values:
|
27
|
-
+ **checked**: check if a checkbox is checked
|
48
|
+
+ **checked**: check if a checkbox is checked (ex. `"data-if": "checked"`)
|
28
49
|
+ **not_checked**: check if a checkbox is not checked
|
29
50
|
+ **blank**: check if a field is blank
|
30
51
|
+ **not_blank**: check if a field is not blank
|
31
52
|
+ **changed**: check if the value of an input is changed (dirty)
|
32
|
-
- **data-eq**: check if a field has a specific value
|
33
|
-
- **data-not**: check if a field
|
34
|
-
- **data-
|
53
|
+
- **data-eq**: check if a field has a specific value (ex. `"data-eq": "42"`)
|
54
|
+
- **data-not**: check if a field has not a specific value
|
55
|
+
- **data-match**: check if a field match a regexp
|
56
|
+
- **data-mismatch**: check if a field doesn't match a regexp (ex. `"data-mismatch": "^\d+$"`)
|
57
|
+
- **data-function**: check the return value of a custom function (ex. `"data-function": "my_check"`)
|
35
58
|
|
36
59
|
Actions:
|
60
|
+
|
37
61
|
- **data-then**: action to trigger (alias **data-action**), values:
|
38
|
-
+ **hide**: hides elements
|
62
|
+
+ **hide**: hides elements (ex. `"data-then": "hide", "data-target": ".errors"`)
|
39
63
|
+ **slide**: hides elements (using sliding)
|
40
64
|
+ **fade**: hides elements (using fading)
|
41
|
-
+ **addClass**: adds classes
|
42
|
-
+ **
|
43
|
-
+ **
|
65
|
+
+ **addClass**: adds classes (ex. `"data-then": "addClass red"`)
|
66
|
+
+ **addStyle**: adds some styles (ex. `"data-then": "addStyle color: #fb1; font-size: 12px"`)
|
67
|
+
+ **setText**: set the text of an element (ex. `"data-then": "setText A sample text"`)
|
68
|
+
+ **setValue**: set the value of an input element (ex. `"data-then": "setValue A sample value"`)
|
69
|
+
+ **callback**: call a function (with arguments: **data-args**) (ex. `"data-then": "callback a_fun"`)
|
44
70
|
- **data-else**: action to trigger when the condition check is not true
|
45
71
|
- **data-args**: arguments passed to the callback function
|
46
72
|
|
47
73
|
Targets:
|
74
|
+
|
48
75
|
- **data-target**: target css selector (from parent fieldset, look for the closest match)
|
49
76
|
- **data-gtarget**: target css selector globally
|
50
77
|
|
@@ -53,6 +80,7 @@ A check condition or a custom check function are required. A trigger action is r
|
|
53
80
|
## Examples
|
54
81
|
|
55
82
|
### Dynamic fields examples
|
83
|
+
|
56
84
|
- A checkbox that hides other fields if is checked (ex. model *Article*):
|
57
85
|
|
58
86
|
```rb
|
@@ -124,6 +152,7 @@ function on_change_category(el) {
|
|
124
152
|
```
|
125
153
|
|
126
154
|
### Inline editing examples
|
155
|
+
|
127
156
|
- Prepare a custom member action to save data, an *update* helper function is available (third parameter is optional, allow to filter using strong parameters):
|
128
157
|
|
129
158
|
```rb
|
@@ -161,6 +190,7 @@ end
|
|
161
190
|
```
|
162
191
|
|
163
192
|
### Dialog example
|
193
|
+
|
164
194
|
Example with 2 models: *Author* and *Article*
|
165
195
|
|
166
196
|
Prepare the content dialog - in Active Admin Author config:
|
@@ -204,13 +234,16 @@ end
|
|
204
234
|
The link url is loaded via AJAX before opening the dialog.
|
205
235
|
|
206
236
|
## Do you like it? Star it!
|
207
|
-
If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
|
208
237
|
|
209
|
-
|
238
|
+
If you use this component just star it. A developer is more motivated to improve a project when there is some interest. My other [Active Admin components](https://github.com/blocknotes?utf8=✓&tab=repositories&q=activeadmin&type=source).
|
239
|
+
|
240
|
+
Or consider offering me a coffee, it's a small thing but it is greatly appreciated: [about me](https://www.blocknot.es/about-me).
|
210
241
|
|
211
242
|
## Contributors
|
243
|
+
|
212
244
|
- [Mattia Roccoberton](http://blocknot.es): author
|
213
245
|
- The good guys that opened issues and pull requests from time to time
|
214
246
|
|
215
247
|
## License
|
248
|
+
|
216
249
|
The gem is available as open-source under the terms of the [MIT](LICENSE.txt).
|
data/Rakefile
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
9
|
+
# t.ruby_opts = %w[-w]
|
10
|
+
t.rspec_opts = ['--color', '--format documentation']
|
11
|
+
end
|
12
|
+
|
13
|
+
task default: :spec
|
14
|
+
rescue LoadError
|
15
|
+
puts '! LoadError: no RSpec available'
|
16
|
+
end
|
@@ -1,10 +1,19 @@
|
|
1
1
|
(function () {
|
2
2
|
'use strict'
|
3
3
|
|
4
|
+
// noinspection JSUnusedGlobalSymbols
|
4
5
|
const ACTIONS = {
|
5
6
|
addClass: (el, name) => el.addClass(name),
|
7
|
+
addStyle: (el, extra_style) => {
|
8
|
+
let style = (el.attr('style') || '').trim()
|
9
|
+
if (!style.includes(extra_style)) {
|
10
|
+
if (style) style = style.replace(/;$/, '') + '; ' // ensure style ends with ;
|
11
|
+
el.attr('style', `${style}${extra_style}`)
|
12
|
+
}
|
13
|
+
},
|
6
14
|
callback: (el, name) => {
|
7
|
-
|
15
|
+
const cb_function = window.hasOwnProperty(name) ? window[name] : null
|
16
|
+
if (typeof cb_function === 'function') cb_function(el.data('args'))
|
8
17
|
else {
|
9
18
|
el.attr('data-df-errors', 'callback function not found')
|
10
19
|
console.warn(`activeadmin_dynamic_fields callback function not found: ${name}`)
|
@@ -12,19 +21,23 @@
|
|
12
21
|
},
|
13
22
|
fade: el => el.fadeOut(),
|
14
23
|
hide: el => el.hide(),
|
24
|
+
setText: (el, text) => el.text(text),
|
15
25
|
setValue: (el, value) => {
|
16
|
-
if (el.attr('type')
|
26
|
+
if (el.attr('type') === 'checkbox') el.prop('checked', value === '1')
|
17
27
|
else el.val(value)
|
18
28
|
el.trigger('change')
|
19
29
|
},
|
20
30
|
slide: el => el.slideUp()
|
21
31
|
}
|
22
32
|
|
33
|
+
// noinspection EqualityComparisonWithCoercionJS, JSUnusedGlobalSymbols
|
23
34
|
const CONDITIONS = {
|
24
35
|
blank: el => el.val().length === 0 || !el.val().trim(),
|
25
36
|
changed: _el => true,
|
26
37
|
checked: el => el.is(':checked'),
|
27
38
|
eq: (el, value) => el.val() == value,
|
39
|
+
match: (el, regexp) => regexp.test(el.val()),
|
40
|
+
mismatch: (el, regexp) => !regexp.test(el.val()),
|
28
41
|
not: (el, value) => el.val() != value,
|
29
42
|
not_blank: el => el.val().trim(),
|
30
43
|
not_checked: el => !el.is(':checked')
|
@@ -32,6 +45,9 @@
|
|
32
45
|
|
33
46
|
const REVERSE_ACTIONS = {
|
34
47
|
addClass: (el, name) => el.removeClass(name),
|
48
|
+
addStyle: (el, extra_style) => {
|
49
|
+
if(el.attr('style')) el.attr('style', el.attr('style').replace(extra_style, ''))
|
50
|
+
},
|
35
51
|
fade: el => el.fadeIn(),
|
36
52
|
hide: el => el.show(),
|
37
53
|
slide: el => el.slideDown()
|
@@ -39,74 +55,98 @@
|
|
39
55
|
|
40
56
|
class Field {
|
41
57
|
constructor(el) {
|
42
|
-
|
58
|
+
this.el = el
|
59
|
+
const action_name = this.evaluateAction()
|
60
|
+
const result = this.evaluateCondition()
|
61
|
+
this.condition = result.condition
|
62
|
+
this.condition_arg = result.condition_arg
|
63
|
+
this.evaluateTarget(action_name)
|
64
|
+
}
|
65
|
+
|
66
|
+
apply() {
|
67
|
+
if (this.condition(this.el, this.condition_arg)) {
|
68
|
+
if (this.else_reverse_action) this.else_reverse_action(this.target, this.else_action_arg)
|
69
|
+
this.action(this.target, this.action_arg)
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
if (this.reverse_action) this.reverse_action(this.target, this.action_arg)
|
73
|
+
if (this.else_action) this.else_action(this.target, this.else_action_arg)
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
evaluateAction() {
|
78
|
+
const action = this.el.data('then') || this.el.data('action') || ''
|
43
79
|
const action_name = action.split(' ', 1)[0]
|
44
|
-
const else_action = el.data('else') || ''
|
80
|
+
const else_action = this.el.data('else') || ''
|
45
81
|
const else_action_name = else_action.split(' ', 1)[0]
|
46
82
|
|
47
|
-
this.el = el
|
48
83
|
this.action = ACTIONS[action_name]
|
49
84
|
this.action_arg = action.substring(action.indexOf(' ') + 1)
|
50
85
|
this.reverse_action = REVERSE_ACTIONS[action_name]
|
51
86
|
this.else_action = ACTIONS[else_action_name]
|
52
87
|
this.else_action_arg = else_action.substring(else_action.indexOf(' ') + 1)
|
53
88
|
this.else_reverse_action = REVERSE_ACTIONS[else_action_name]
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
89
|
+
|
90
|
+
return action_name
|
91
|
+
}
|
92
|
+
|
93
|
+
evaluateCondition() {
|
94
|
+
let value = CONDITIONS[this.el.data('if')?.trim()]
|
95
|
+
if (value) return { condition: value }
|
96
|
+
|
97
|
+
value = this.el.data('eq')
|
98
|
+
if (value) return { condition: CONDITIONS['eq'], condition_arg: value }
|
99
|
+
|
100
|
+
value = this.el.data('not')
|
101
|
+
if (value) return { condition: CONDITIONS['not'], condition_arg: value }
|
102
|
+
|
103
|
+
value = this.el.data('match')
|
104
|
+
if (value) return { condition: CONDITIONS['match'], condition_arg: new RegExp(value) }
|
105
|
+
|
106
|
+
value = this.el.data('mismatch')
|
107
|
+
if (value) return { condition: CONDITIONS['mismatch'], condition_arg: new RegExp(value) }
|
108
|
+
|
109
|
+
this.custom_function = this.el.data('function')
|
110
|
+
if (this.custom_function) {
|
111
|
+
value = window[this.custom_function]
|
112
|
+
if (value) return { condition: value }
|
113
|
+
else {
|
114
|
+
this.el.attr('data-df-errors', 'custom function not found')
|
66
115
|
console.warn(`activeadmin_dynamic_fields custom function not found: ${this.custom_function}`)
|
67
116
|
}
|
68
117
|
}
|
69
118
|
|
70
|
-
|
71
|
-
if (el.data('target')) this.target = el.closest('fieldset').find(el.data('target'))
|
72
|
-
else if (el.data('gtarget')) this.target = $(el.data('gtarget'))
|
73
|
-
if (action_name == 'callback') this.target = el
|
119
|
+
return {}
|
74
120
|
}
|
75
121
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
else {
|
82
|
-
if (this.reverse_action) this.reverse_action(this.target, this.action_arg)
|
83
|
-
if (this.else_action) this.else_action(this.target, this.else_action_arg)
|
84
|
-
}
|
122
|
+
evaluateTarget(action_name) {
|
123
|
+
// closest find for has many associations
|
124
|
+
if (this.el.data('target')) this.target = this.el.closest('fieldset').find(this.el.data('target'))
|
125
|
+
else if (this.el.data('gtarget')) this.target = $(this.el.data('gtarget'))
|
126
|
+
if (action_name === 'callback') this.target = this.el
|
85
127
|
}
|
86
128
|
|
87
|
-
|
129
|
+
isValid() {
|
88
130
|
if (!this.condition) return false
|
89
|
-
|
90
|
-
|
91
|
-
return true
|
131
|
+
return (this.action || this.custom_function)
|
92
132
|
}
|
93
133
|
|
94
134
|
setup() {
|
95
|
-
if (!this.
|
96
|
-
if (this.el.data('if')
|
97
|
-
this.el.on('change', () => this.apply(
|
135
|
+
if (!this.isValid()) return
|
136
|
+
if (this.el.data('if') !== 'changed') this.apply()
|
137
|
+
this.el.on('change', () => this.apply())
|
98
138
|
}
|
99
139
|
}
|
100
140
|
|
101
|
-
// Inline update - must be called
|
141
|
+
// Inline update - must be called bound on the editing element
|
102
142
|
function dfUpdateField() {
|
103
|
-
if ($(this).data('loading')
|
143
|
+
if ($(this).data('loading') !== '1') {
|
104
144
|
$(this).data('loading', '1');
|
105
145
|
let _this = $(this);
|
106
146
|
let type = $(this).data('field-type');
|
107
147
|
let new_value;
|
108
|
-
if (type
|
109
|
-
else if (type
|
148
|
+
if (type === 'boolean') new_value = !$(this).data('field-value');
|
149
|
+
else if (type === 'select') new_value = $(this).val();
|
110
150
|
else new_value = $(this).text();
|
111
151
|
let data = {};
|
112
152
|
data[$(this).data('field')] = new_value;
|
@@ -115,16 +155,16 @@
|
|
115
155
|
data: { data: data },
|
116
156
|
method: 'POST',
|
117
157
|
url: $(this).data('save-url'),
|
118
|
-
complete: function (
|
158
|
+
complete: function (_req, _status) {
|
119
159
|
$(this).data('loading', '0');
|
120
160
|
},
|
121
|
-
success: function (data,
|
122
|
-
if (data.status
|
161
|
+
success: function (data, _status, _req) {
|
162
|
+
if (data.status === 'error') {
|
123
163
|
if ($(this).data('show-errors')) {
|
124
164
|
let result = '';
|
125
165
|
let message = data.message;
|
126
166
|
for (let key in message) {
|
127
|
-
if (typeof (message[key]) === 'object') {
|
167
|
+
if (message.hasOwnProperty(key) && typeof (message[key]) === 'object') {
|
128
168
|
if (result) result += ' - ';
|
129
169
|
result += key + ': ' + message[key].join('; ');
|
130
170
|
}
|
@@ -150,10 +190,9 @@
|
|
150
190
|
}
|
151
191
|
}
|
152
192
|
|
153
|
-
|
154
|
-
$(document).ready(function () {
|
193
|
+
function dfInit() {
|
155
194
|
// Setup dynamic fields
|
156
|
-
const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-function]'
|
195
|
+
const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-match], .active_admin .input [data-mismatch], .active_admin .input [data-function]'
|
157
196
|
$(selectors).each(function () {
|
158
197
|
new Field($(this)).setup()
|
159
198
|
})
|
@@ -174,20 +213,23 @@
|
|
174
213
|
$('.active_admin [data-df-dialog]').on('click', function (event) {
|
175
214
|
event.preventDefault()
|
176
215
|
$(this).blur()
|
177
|
-
|
178
|
-
|
179
|
-
|
216
|
+
const df_dialog = $('#df-dialog')
|
217
|
+
|
218
|
+
if (df_dialog.data('loading') !== '1') {
|
219
|
+
df_dialog.data('loading', '1')
|
220
|
+
if (df_dialog.length === 0) $('body').append('<div id="df-dialog"></div>')
|
180
221
|
let title = $(this).attr('title')
|
181
222
|
$.ajax({
|
182
223
|
url: $(this).attr('href'),
|
183
|
-
complete: function (
|
224
|
+
complete: function (_req, _status) {
|
184
225
|
$('#df-dialog').data('loading', '0')
|
185
226
|
},
|
186
|
-
success: function (data,
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
227
|
+
success: function (data, _status, _req) {
|
228
|
+
const dialog = $('#df-dialog')
|
229
|
+
if (title) dialog.attr('title', title)
|
230
|
+
dialog.html(data)
|
231
|
+
dialog.dialog({ modal: true })
|
232
|
+
}
|
191
233
|
})
|
192
234
|
}
|
193
235
|
})
|
@@ -200,11 +242,14 @@
|
|
200
242
|
$(this).data('field-value', $(this).text())
|
201
243
|
let fnUpdate = $.proxy(dfUpdateField, $(this))
|
202
244
|
$(this).on('blur', function () {
|
203
|
-
if ($(this).data('field-value')
|
245
|
+
if ($(this).data('field-value') !== $(this).text()) fnUpdate()
|
204
246
|
})
|
205
247
|
})
|
206
248
|
$('[data-field][data-field-type="select"][data-save-url]').each(function () {
|
207
249
|
$(this).on('change', $.proxy(dfUpdateField, $(this)))
|
208
250
|
})
|
209
|
-
}
|
251
|
+
}
|
252
|
+
|
253
|
+
$(document).ready(dfInit)
|
254
|
+
$(document).on('turbolinks:load', dfInit)
|
210
255
|
})()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeadmin_dynamic_fields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeadmin
|
@@ -24,132 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: activestorage
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 6.0.3.2
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 6.0.3.2
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: capybara
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 3.33.0
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 3.33.0
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: pry
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.13.1
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.13.1
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: puma
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 4.3.5
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 4.3.5
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec_junit_formatter
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 0.4.1
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 0.4.1
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rspec-rails
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 4.0.1
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 4.0.1
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.90.0
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.90.0
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: selenium-webdriver
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 3.142.7
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 3.142.7
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: sqlite3
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 1.4.2
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 1.4.2
|
153
27
|
description: An Active Admin plugin to add dynamic behaviors to fields
|
154
28
|
email: mat@blocknot.es
|
155
29
|
executables: []
|
@@ -183,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
57
|
- !ruby/object:Gem::Version
|
184
58
|
version: '0'
|
185
59
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
60
|
+
rubygems_version: 3.1.4
|
187
61
|
signing_key:
|
188
62
|
specification_version: 4
|
189
63
|
summary: Dynamic fields for ActiveAdmin
|