effective_resources 1.17.2 → 1.18.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88760067301847f6d36a2f8550224e019acf06cc9fcc9021a7cf22799e09d560
4
- data.tar.gz: 8a922371e95e9f9c91e1cd907b858f19316615508a05077ec5025c7c82c4e1c4
3
+ metadata.gz: '0823eab342743da2a61c1b174cad39ffc77c6602c8422488bd32c113148b066f'
4
+ data.tar.gz: 3958c07bc7d38c1c3de867e699b899fddc1833e029b7b639635a08b9a92b9bdc
5
5
  SHA512:
6
- metadata.gz: c19cbb3988ce98384ff670148617f5779337254fcaee5b4c68f354cd0d9a2bc40d15497db83c53d3f5dd9c37a9e13191f40bf3ed435a8607b05963e2678a292b
7
- data.tar.gz: 96e9c5059d55ff3ad40a10f891fd8765eb9fee9d359d19809b1566a47dca26cbccde1f18e4f182f64740c2738134d6e08d93be7170add23ef917bed1631c7a9e
6
+ metadata.gz: 180567d91706dee43b3ae5ab9e09e9f1abe0f1f352daa1bbf69ed3110564814ddacbc542d8293d5df8093dc94a36d8547a6f4814e307b6966f5ca7e49e7a34a9
7
+ data.tar.gz: 9852aac45f8341b0e27509d1b82c59f5d739eb3d1194daad74f6f1c1a4e7a29a0705a90dedd15945fa2af14c6cc546429d6f07db559d8785b182fa0a6a2d0c3b
data/README.md CHANGED
@@ -354,6 +354,31 @@ You can also call `render_wizard_sidebar(resource)` without the block syntax.
354
354
 
355
355
  If you add `f.hidden_field(:skip_to_step, value: 'stepc')` you can control the next step.
356
356
 
357
+ ## Select2 Ajax Controller
358
+
359
+ This gem provides an admin endpoint for select2 AJAX to fetch users.
360
+
361
+ To use this endpoint please add
362
+
363
+ ```
364
+ can :admin, :effective_resources
365
+ ```
366
+
367
+ And then create a select field like this:
368
+
369
+ ```
370
+ = f.select :user_id, current_user.class.all,
371
+ ajax_url: effective_resources.users_admin_select2_ajax_index_path
372
+ ```
373
+
374
+ To format the results, add a method to your User class. It can return html.
375
+
376
+ ```
377
+ def to_select2
378
+ "<span>#{user.first_name} #{user.last_name}</span> <small>#{user.email}</small>"
379
+ end
380
+ ```
381
+
357
382
  ## Testing
358
383
 
359
384
  Run tests by:
@@ -0,0 +1,24 @@
1
+ module Admin
2
+ class Select2AjaxController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_resources) }
5
+
6
+ include Effective::Select2AjaxController
7
+
8
+ def users
9
+ collection = current_user.class.all
10
+
11
+ respond_with_select2_ajax(collection) do |user|
12
+ { id: user.to_param, text: user.try(:to_select2) || to_select2(user) }
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def to_select2(user)
19
+ "<span>#{user.first_name} #{user.last_name}</span> <small>#{user.email}</small>"
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -60,7 +60,9 @@ module Effective
60
60
  when ActiveRecord::StaleObjectError
61
61
  flash.now[:danger] = "#{flash.now[:danger]} <a href='#', class='alert-link' onclick='window.location.reload(true); return false;'>reload page and try again</a>"
62
62
  raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
63
- when Effective::ActionFailed, ActiveRecord::RecordInvalid, RuntimeError
63
+ when Effective::ActionFailed
64
+ # Nothing to do
65
+ when ActiveRecord::RecordInvalid, RuntimeError
64
66
  raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
65
67
  else
66
68
  raise(e) # This is a real error that should be sent to 500. Client should not see the message.
@@ -0,0 +1,52 @@
1
+ module Effective
2
+ module Select2AjaxController
3
+ extend ActiveSupport::Concern
4
+
5
+ def respond_with_select2_ajax(collection, skip_search: false, &block)
6
+ raise('collection should be an ActiveRecord::Relation') unless collection.kind_of?(ActiveRecord::Relation)
7
+
8
+ # Authorize
9
+ EffectiveResources.authorize!(self, :index, collection.klass)
10
+
11
+ # Scope
12
+ if collection.respond_to?(:select2_ajax)
13
+ collection = collection.select2_ajax
14
+ elsif collection.respond_to?(:sorted)
15
+ collection = collection.sorted
16
+ end
17
+
18
+ # Search
19
+ if (term = params[:term]).present? && !skip_search
20
+ collection = Effective::Resource.new(collection).search_any(term)
21
+ end
22
+
23
+ # Paginate
24
+ per_page = 50
25
+ page = (params[:page] || 1).to_i
26
+ last = (collection.reselect(:id).count.to_f / per_page).ceil
27
+ more = page < last
28
+
29
+ offset = [(page - 1), 0].max * per_page
30
+ collection = collection.limit(per_page).offset(offset)
31
+
32
+ # Results
33
+ results = collection.map do |resource|
34
+ if block_given?
35
+ option = yield(resource)
36
+ raise('expected a Hash with id and text params') unless option.kind_of?(Hash) && option[:id] && option[:text]
37
+ option
38
+ else
39
+ { id: resource.to_param, text: resource.try(:to_select2) || resource.to_s }
40
+ end
41
+ end
42
+
43
+ # Respond
44
+ respond_to do |format|
45
+ format.js do
46
+ render json: { results: results, pagination: { more: more } }
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -207,6 +207,20 @@ module EffectiveResourcesHelper
207
207
  end
208
208
  alias_method :render_resource, :render_resource_partial
209
209
 
210
+ def render_if_exists(partial, atts = {})
211
+ raise('expected a path') unless partial.kind_of?(String)
212
+ raise('path should not include spaces') if partial.include?(' ')
213
+
214
+ pieces = partial.to_s.split('/') - [nil, '']
215
+
216
+ file = pieces.last
217
+ path = pieces[0..-2].join('/')
218
+
219
+ if lookup_context.exists?(file, [path], :partial)
220
+ render(partial, atts)
221
+ end
222
+ end
223
+
210
224
  # Tableize attributes
211
225
  # This is used by effective_orders, effective_logging, effective_trash and effective_mergery
212
226
  def tableize_hash(obj, table: 'table', th: true, sub_table: 'table', sub_th: true, flatten: true)
@@ -248,4 +262,32 @@ module EffectiveResourcesHelper
248
262
  controller.class.try(:effective_wizard_controller?) && defined?(resource) && resource.draft?
249
263
  end
250
264
 
265
+ def wizard_card(resource, &block)
266
+ raise('expected a block') unless block_given?
267
+ raise('expected an acts_as_wizard resource') unless resource.class.respond_to?(:acts_as_wizard?)
268
+
269
+ step = resource.render_step
270
+ raise('expected a render_step') unless step.present?
271
+
272
+ title = resource.wizard_step_title(step)
273
+ raise("expected a title for step #{step}") unless title.present?
274
+
275
+ link = if edit_effective_wizard? && resource.can_visit_step?(step)
276
+ link_to('Edit', wizard_path(step), title: "Edit #{title}")
277
+ end
278
+
279
+ content_tag(:div, class: 'card') do
280
+ content_tag(:div, class: 'card-body yo') do
281
+ content_tag(:div, class: 'row') do
282
+ content_tag(:div, class: 'col-sm') do
283
+ content_tag(:h5, title, class: 'card-title')
284
+ end +
285
+ content_tag(:div, class: 'col-sm-auto text-right') do
286
+ (link || '')
287
+ end
288
+ end + capture(&block)
289
+ end
290
+ end
291
+ end
292
+
251
293
  end
@@ -29,6 +29,9 @@ module ActsAsWizard
29
29
 
30
30
  attr_accessor :current_user
31
31
 
32
+ # Used by the view when rendering each partial. Not the current step.
33
+ attr_accessor :render_step
34
+
32
35
  if Rails.env.test? # So our tests can override the required_steps method
33
36
  cattr_accessor :test_required_steps
34
37
  end
@@ -6,6 +6,10 @@ module Effective
6
6
  TARGET_LIST_LIMIT = 1500
7
7
  TARGET_KEYS_LIMIT = 30000
8
8
 
9
+ DO_NOT_SEARCH_EQUALS = ['unconfirmed_email', 'provider', 'secret', 'crypt', 'salt', 'uid', 'certificate', 'otp', 'ssn']
10
+ DO_NOT_SEARCH_INCLUDE = ['password']
11
+ DO_NOT_SEARCH_END_WITH = ['_url', '_param', '_token', '_type', '_id', '_key', '_ip']
12
+
9
13
  # This could be active_model? in which we just return the klass itself here
10
14
  # This value ends up being crud_controller resource_scope()
11
15
  def relation
@@ -197,18 +201,31 @@ module Effective
197
201
  end
198
202
 
199
203
  # Otherwise, we fall back to a string/text search of all columns
200
- columns = Array(columns || search_columns)
204
+ columns = Array(columns || search_columns).reject do |column|
205
+ DO_NOT_SEARCH_EQUALS.any? { |value| column == value } ||
206
+ DO_NOT_SEARCH_INCLUDE.any? { |value| column.include?(value) } ||
207
+ DO_NOT_SEARCH_END_WITH.any? { |value| column.end_with?(value) }
208
+ end
209
+
201
210
  fuzzy = true unless fuzzy == false
202
211
 
203
- conditions = (
204
- if fuzzy
205
- columns.map { |name| "#{sql_column(name)} #{ilike} :fuzzy" }
206
- else
207
- columns.map { |name| "#{sql_column(name)} = :value" }
208
- end
209
- ).join(' OR ')
212
+ # Retval
213
+ searched = relation
214
+ terms = value.split(' ') - [nil, '']
215
+
216
+ terms.each do |term|
217
+ conditions = (
218
+ if fuzzy
219
+ columns.map { |name| "#{sql_column(name)} #{ilike} :fuzzy" }
220
+ else
221
+ columns.map { |name| "#{sql_column(name)} = :term" }
222
+ end
223
+ ).join(' OR ')
224
+
225
+ searched = searched.where(conditions, fuzzy: "%#{term}%", term: term)
226
+ end
210
227
 
211
- relation.where(conditions, fuzzy: "%#{value}%", value: value)
228
+ searched
212
229
  end
213
230
 
214
231
  private
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ Rails.application.routes.draw do
2
+ mount EffectiveResources::Engine => '/', as: 'effective_resources'
3
+ end
4
+
5
+ EffectiveResources::Engine.routes.draw do
6
+
7
+ namespace :admin do
8
+ resources :select2_ajax, only: [] do
9
+ get :users, on: :collection
10
+ end
11
+ end
12
+
13
+ end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.17.2'.freeze
2
+ VERSION = '1.18.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.2
4
+ version: 1.18.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-25 00:00:00.000000000 Z
11
+ date: 2022-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -133,6 +133,7 @@ files:
133
133
  - README.md
134
134
  - app/assets/javascripts/effective_resources.js
135
135
  - app/assets/javascripts/effective_resources/effective_ujs.js
136
+ - app/controllers/admin/select2_ajax_controller.rb
136
137
  - app/controllers/concerns/effective/crud_controller.rb
137
138
  - app/controllers/concerns/effective/crud_controller/actions.rb
138
139
  - app/controllers/concerns/effective/crud_controller/dsl.rb
@@ -142,6 +143,7 @@ files:
142
143
  - app/controllers/concerns/effective/crud_controller/save.rb
143
144
  - app/controllers/concerns/effective/crud_controller/submits.rb
144
145
  - app/controllers/concerns/effective/flash_messages.rb
146
+ - app/controllers/concerns/effective/select2_ajax_controller.rb
145
147
  - app/controllers/concerns/effective/wizard_controller.rb
146
148
  - app/controllers/concerns/effective/wizard_controller/actions.rb
147
149
  - app/controllers/concerns/effective/wizard_controller/before_actions.rb
@@ -206,6 +208,7 @@ files:
206
208
  - app/views/effective/resource/_actions_glyphicons.html.haml
207
209
  - app/views/layouts/effective_mailer_layout.html.haml
208
210
  - config/effective_resources.rb
211
+ - config/routes.rb
209
212
  - lib/effective_resources.rb
210
213
  - lib/effective_resources/effective_gem.rb
211
214
  - lib/effective_resources/engine.rb