administrate_ransack 0.1.4 → 0.1.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09dd7a40c1b2e9e1c28ef00e9f39706c93309c0a35bbefaa116c217cbb6d6afa'
4
- data.tar.gz: 9ff58ae2897f5ed392f25ec2ad3f8053d89057c67110ce4933e8efa28c60f73c
3
+ metadata.gz: 30740fba6ba03d609c74a19fcce57700128abb8055735eb6e341ff445881b076
4
+ data.tar.gz: 1b040d838cb34725d8a654a6cf7376132e81e34a0a48107501ad175a9da06518
5
5
  SHA512:
6
- metadata.gz: 90026589be8b7f2e7e21af4a7a77c53230b522fcaa6d7cdf9235d758eb6ebb8e67bbd0c3e74329e5698122de65183cd29c803a0fe5adeb3f93694b7817369d87
7
- data.tar.gz: '08858e62db32973552ea94bfacf73e3a315a747f3bcedae62452f8a9eae89b40a9cfc6ec960f5c04ff57b0b066db25f46a5144d321a73a7c585c989599abbc7b'
6
+ metadata.gz: 157edfd6f4bb409bdac2394f815246e6e3b940bc5709c7d2a1cea3270c5ee71f8ae50f0a6d982765a3465473af778dd4034d7bc3a9ba40580269ae821c522a9c
7
+ data.tar.gz: 8af8b11b461b4d23db7acbed9663ed21c65a3e18f300cc81ecc85269e332fe63cb7fc98a8435a4732e19fb7842d027964c537b646599830a428d765208821ce4
data/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
  A plugin for [Administrate](https://github.com/thoughtbot/administrate) to use [Ransack](https://github.com/activerecord-hackery/ransack) for filtering resources.
3
3
 
4
4
  Features:
5
- - add Ransack method via module prepend in controller;
6
- - offer a filters bar based on the resource's attributes;
5
+ - add Ransack search results using module prepend inside an Administrate controller;
6
+ - offer a filters side bar based on the resource's attributes;
7
7
  - customize searchable attributes.
8
8
 
9
9
  ## Installation
@@ -14,13 +14,17 @@ prepend AdministrateRansack::Searchable
14
14
  ```
15
15
  - Add to your resource index view:
16
16
  ```erb
17
- <%= render('administrate_ransack/filters', attribute_types: page.attribute_types) %>
17
+ <%= render('administrate_ransack/filters') %>
18
18
  ```
19
+ - See the Customizations section to change the attributes list
19
20
 
20
21
  ## Usage
21
- For associations (has many/belongs to) the label used can be customized adding an `admin_label` method to the target model which returns a string while the collection can by filtered with `admin_scope`.
22
+ - The filters partial accepts some optional parameters:
23
+ + `attribute_labels`: hash used to override the field labels, ex. `{ title: "The title" }`
24
+ + `attribute_types`: hash used to specify the filter fields, ex. `{ title: Administrate::Field::String }`
25
+ + `search_path`: the path to use for searching (form URL)
26
+ - For associations (has many/belongs to) the label used can be customized adding an `admin_label` method to the target model which returns a string while the collection can by filtered with `admin_scope`. Example:
22
27
 
23
- Example:
24
28
  ```rb
25
29
  class Post < ApplicationRecord
26
30
  scope :admin_scope, -> { where(published: true) }
@@ -32,17 +36,31 @@ end
32
36
  ```
33
37
 
34
38
  ## Notes
35
- - Administrate Search input works independently from Ransack searches, I suggest to disable it eventually
39
+ - Administrate Search logic works independently from Ransack searches, I suggest to disable it eventually (ex. overriding `show_search_bar?` in the controller)
36
40
  - Ordering by clicking on the headers of the table preserving the Ransack searches requires a change to the headers links, replacing the th links of *_collection* partial with:
37
41
  ```rb
38
42
  sort_link(@ransack_results, attr_name) do
39
- # ...
43
+ # ...
44
+ end
45
+ ```
46
+ - Date/time filters use Rails `datetime_field` method which produces a `datetime-local` input field, at the moment this type of element is not broadly supported, a workaround is to include [flatpickr](https://github.com/flatpickr/flatpickr) datetime library.
47
+ + This gem checks if `flatpickr` function is available in the global scope and applies it to the `datetime-local` filter inputs;
48
+ + you can include the library using your application assets or via CDN, ex. adding to **app/views/layouts/admin/application.html.erb**:
49
+ ```html
50
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.5.7/dist/flatpickr.min.css">
51
+ <script src="https://cdn.jsdelivr.net/npm/flatpickr@4.5.7/dist/flatpickr.min.js"></script>
52
+
53
+ <script>
54
+ // optionally change the flatpikr options:
55
+ window.flatpickr_filters_options = { dateFormat: "Y-m-d" };
56
+ </script>
40
57
  ```
41
58
 
42
59
  ## Customizations
43
- - Allow only some fields for the filters in the index view:
60
+ - Sample with different options provided:
44
61
  ```erb
45
62
  <%
63
+ # In alternative prepare an hash in the dashboard like RANSACK_TYPES = {}
46
64
  attribute_types = {
47
65
  title: Administrate::Field::String,
48
66
  author: Administrate::Field::BelongsTo,
@@ -56,9 +74,14 @@ attribute_labels = {
56
74
  <%= render(
57
75
  'administrate_ransack/filters',
58
76
  attribute_types: attribute_types,
59
- attribute_labels: attribute_labels
77
+ attribute_labels: attribute_labels,
78
+ search_path: admin_root_path
60
79
  ) %>
61
80
  ```
81
+ - An alternative is to prepare some hashes constants in the dashboard (ex. `RANSACK_TYPES`) and then:
82
+ ```erb
83
+ <%= render('administrate_ransack/filters', attribute_types: @dashboard.class::RANSACK_TYPES) %>
84
+ ```
62
85
  - Optional basic style to setup the filters as a sidebar:
63
86
  ```css
64
87
  .main-content__body {
@@ -86,9 +109,30 @@ attribute_labels = {
86
109
  Screenshot:
87
110
  ![screenshot](screenshot.png)
88
111
 
112
+ ## Extra notes
113
+ - If you need to define custom search logics you can skip prepending the module (`AdministrateRansack::Searchable`) and create your own search query in a controller, ex:
114
+ ```ruby
115
+ def scoped_resource
116
+ @ransack_results = super.ransack(params[:q])
117
+ @ransack_results.result(distinct: true)
118
+ end
119
+ ```
120
+ - Sometimes it's easier to create a new ransack field than overriding the search logic, example to search in a `jsonb` field adding to a Post model:
121
+ ```ruby
122
+ ransacker :keywords do
123
+ Arel.sql("posts.metadata ->> 'keywords'")
124
+ end
125
+ ```
126
+ - With this component you can easily link another resource applying some filters, example to add in a tag show page the link to the related posts:
127
+ ```erb
128
+ <%= link_to("Tag's posts", admin_posts_path('q[tags_id_in][]': page.resource.id), class: "button") %>
129
+ ```
130
+
89
131
  ## Do you like it? Star it!
90
132
  If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
91
133
 
134
+ Or consider offering me a coffee, it's a small thing but it is greatly appreciated: [about me](https://www.blocknot.es/about-me).
135
+
92
136
  ## Contributors
93
137
  - [Mattia Roccoberton](https://blocknot.es/): author
94
138
 
data/Rakefile CHANGED
@@ -1,7 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'bundler/gem_tasks'
4
+
3
5
  begin
4
- require 'bundler/setup'
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
5
14
  rescue LoadError
6
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
15
+ puts '! LoadError: no RSpec available'
7
16
  end
@@ -1,5 +1,29 @@
1
- <% attribute_labels ||= {} %>
2
- <%= search_form_for [:admin, @ransack_results], html: { 'data-administrate-ransack-filters': '1' } do |f| %>
1
+ <% content_for :javascript do %>
2
+ <script>
3
+ document.addEventListener('DOMContentLoaded', (_event) => {
4
+ if(typeof window.flatpickr === 'function') {
5
+ var options = window.flatpickr_filters_options;
6
+ if(typeof options !== 'object') options = { enableTime: true };
7
+ window.flatpickr('.filter [type="datetime-local"]', options);
8
+ }
9
+ });
10
+ </script>
11
+ <% end %>
12
+
13
+ <%
14
+ attribute_labels ||= {}
15
+ attribute_types ||= @dashboard.attribute_types.select { |key, _value| @dashboard.collection_attributes.include?(key) }
16
+ form_options = { html: { 'data-administrate-ransack-filters': '1' } }
17
+ if local_assigns.has_key?(:search_path)
18
+ form_path = @ransack_results
19
+ form_options[:url] = search_path
20
+ clear_filters_path = search_path
21
+ else
22
+ form_path = [:admin, @ransack_results]
23
+ clear_filters_path = url_for(url_for([:admin, @ransack_results.klass]))
24
+ end
25
+ %>
26
+ <%= search_form_for form_path, form_options do |f| %>
3
27
  <div class="filters">
4
28
  <% attribute_types.each do |field, type| %>
5
29
  <% next if field == :id %>
@@ -12,32 +36,32 @@
12
36
  <% if association %>
13
37
  <% label = association.klass.method_defined?(:admin_label) ? :admin_label : :to_s %>
14
38
  <% collection = association.klass.send(association.klass.respond_to?(:admin_scope) ? :admin_scope : :all) %>
15
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
39
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
16
40
  <%= f.collection_select "#{field}_id_eq", collection, :id, label, include_blank: true %>
17
41
  <% end %>
18
42
  <% when 'Administrate::Field::Boolean' %>
19
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
43
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
20
44
  <%= f.select "#{field}_eq", [[t('administrate_ransack.filters.no'), false], [t('administrate_ransack.filters.yes'), true]], include_blank: true %>
21
45
  <% when 'Administrate::Field::Date' %>
22
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
46
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
23
47
  <%= f.date_field "#{field}_gteq" %>
24
48
  <%= f.date_field "#{field}_lteq" %>
25
49
  <% when 'Administrate::Field::DateTime' %>
26
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
50
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
27
51
  <%= f.datetime_field "#{field}_gteq" %>
28
52
  <%= f.datetime_field "#{field}_lteq" %>
29
53
  <% when 'Administrate::Field::Email', 'Administrate::Field::String', 'Administrate::Field::Text' %>
30
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
54
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
31
55
  <%= f.search_field "#{field}_cont" %>
32
56
  <% when 'Administrate::Field::Number' %>
33
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
57
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
34
58
  <%= f.number_field "#{field}_eq" %>
35
59
  <% when 'Administrate::Field::HasMany' %>
36
60
  <% association = @ransack_results.klass.reflections[field.to_s] %>
37
61
  <% if association %>
38
62
  <% label = association.klass.method_defined?(:admin_label) ? :admin_label : :to_s %>
39
63
  <% collection = association.klass.send(association.klass.respond_to?(:admin_scope) ? :admin_scope : :all) %>
40
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
64
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
41
65
  <%= f.collection_check_boxes "#{field}_id_in", collection, :id, label do |b| %>
42
66
  <%= b.label do %>
43
67
  <%= b.check_box %>
@@ -46,18 +70,19 @@
46
70
  <% end %>
47
71
  <% end %>
48
72
  <% when 'Administrate::Field::Select' %>
49
- <%= f.label (attribute_labels.include?(field) ? attribute_labels[field] : field) %>
73
+ <%= f.label(attribute_labels.include?(field) ? attribute_labels[field] : field) %>
50
74
  <%= f.select "#{field}_eq", type.options[:collection], include_blank: true %>
75
+ <% else %>
76
+ <!-- unsupported Field::HasOne -->
77
+ <!-- unsupported Field::Polymorphic -->
78
+ <!-- unsupported Field::Password -->
51
79
  <% end %>
52
- <%# unsupported Field::HasOne %>
53
- <%# unsupported Field::Polymorphic %>
54
- <%# unsupported Field::Password %>
55
80
  </div>
56
81
  <% end %>
57
82
  </div>
58
83
 
59
84
  <div class="filters-buttons">
60
85
  <%= f.submit %>
61
- <%= link_to t('administrate_ransack.filters.clear_filters'), url_for([:admin, @ransack_results.klass]), class: 'btn-clear-filters' %>
86
+ <%= link_to t('administrate_ransack.filters.clear_filters'), clear_filters_path, class: 'btn-clear-filters' %>
62
87
  </div>
63
88
  <% end %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AdministrateRansack
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.13'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: administrate_ransack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-07 00:00:00.000000000 Z
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: administrate
@@ -16,154 +16,182 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.14.0
19
+ version: '0.14'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.14.0
26
+ version: '0.14'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ransack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.3.2
33
+ version: '2.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.3.2
40
+ version: '2.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activestorage
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.3.2
47
+ version: '6.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 6.0.3.2
54
+ version: '6.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: capybara
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 3.33.0
61
+ version: '3.33'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 3.33.0
68
+ version: '3.33'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.13.1
75
+ version: '0.13'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.13.1
82
+ version: '0.13'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: puma
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 4.3.5
89
+ version: '4.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 4.3.5
96
+ version: '4.3'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec_junit_formatter
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.4.1
103
+ version: '0.4'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.4.1
110
+ version: '0.4'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec-rails
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 4.0.1
117
+ version: '4.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 4.0.1
124
+ version: '4.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.90.0
131
+ version: '0.90'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.90.0
138
+ version: '0.90'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sassc
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '2.4'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '2.4'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: selenium-webdriver
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: 3.142.7
159
+ version: '3.142'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.142'
167
+ - !ruby/object:Gem::Dependency
168
+ name: sprockets-rails
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '3.2'
146
174
  type: :development
147
175
  prerelease: false
148
176
  version_requirements: !ruby/object:Gem::Requirement
149
177
  requirements:
150
178
  - - "~>"
151
179
  - !ruby/object:Gem::Version
152
- version: 3.142.7
180
+ version: '3.2'
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: sqlite3
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
185
  - - "~>"
158
186
  - !ruby/object:Gem::Version
159
- version: 1.4.2
187
+ version: '1.4'
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
192
  - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: 1.4.2
194
+ version: '1.4'
167
195
  description: A plugin for Administrate to use Ransack for filtering resources
168
196
  email:
169
197
  - mat@blocknot.es
@@ -199,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
227
  - !ruby/object:Gem::Version
200
228
  version: '0'
201
229
  requirements: []
202
- rubygems_version: 3.0.3
230
+ rubygems_version: 3.1.4
203
231
  signing_key:
204
232
  specification_version: 4
205
233
  summary: Administrate Ransack plugin