From 7833965adb2f4d5406bc2b7c95449dbbe9aa64b3 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 15 Feb 2018 14:05:26 -0700 Subject: [PATCH 01/68] Initial Bootstrap3 branch commit --- README.md | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 19b9c708..f4cdfc7f 100644 --- a/README.md +++ b/README.md @@ -16,33 +16,19 @@ For use with any Rails 3, 4, 5 application already using Twitter Bootstrap 3. Works with postgres, mysql, sqlite3 and arrays. -## effective_datatables 3.0 +## Bootstrap3 -This is the 3.0 release of effective_datatables. It's a complete rewrite, with a similar but totally changed DSL. +This is the `bootstrap3` branch of effective_datatables which supports Twitter Bootstrap 3. -[Effective Datatables 2.0 README](https://github.com/code-and-effect/effective_datatables/tree/2.12.2) +All published effective_datatables 3.x gems will support Twitter Bootstrap 3 and SimpleForm. -Previous versions of the gem were excellent, but the 3.0 release has stepped things up. - -Internally, all columns now have separate compute and format methods, removing the need for a ton of internal parsing and type conversions. -This allows things like filters, aggregates and searching/sorting to work effectively. - -Column rendering has been improved so all datatable and view methods are callable from anywhere in the DSL. -This allows the developer to do things like: include/exclude/configure columns based on the current_user, apply logic around current filters -to change columns dynamically, to use regular ifs instead of procs in toggling visibility, and generally removes all weirdness. - -This release adds a dependency on [effective_resources](https://github.com/code-and-effect/effective_resources) for ActiveRecord resource discovery, -full sql table fuzzy searching/sorting, attribute parsing, and checking availability & authorization of edit/show actions. - -A cookie has been added to persist the user's selected filters, search, sort, length, column visibility and pagination settings. - -A lot has changed. See below for full details. +For Bootstrap 4 please see the master branch and/or effective_datatables 4.x gems. # Getting Started ```ruby gem 'haml-rails' # or try using gem 'hamlit-rails' -gem 'effective_datatables' +gem 'effective_datatables', github: 'code-and-effect/effective_datatables', branch: 'bootstrap3' ``` Run the bundle command to install it: From 782b501d4352c41c8156d37abb2bc10e308bdd2a Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Mar 2018 10:44:17 -0700 Subject: [PATCH 02/68] Remove helper method from initializer --- lib/effective_datatables/engine.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/effective_datatables/engine.rb b/lib/effective_datatables/engine.rb index bf431390..f2d87b16 100644 --- a/lib/effective_datatables/engine.rb +++ b/lib/effective_datatables/engine.rb @@ -7,9 +7,6 @@ class Engine < ::Rails::Engine # Include Helpers to base application initializer 'effective_datatables.action_controller' do |app| ActiveSupport.on_load :action_controller do - helper EffectiveDatatablesHelper - helper EffectiveDatatablesPrivateHelper - ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper end end From 31c17f7fc9b2597689d1ac8648ab6836d2a617a0 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Mar 2018 10:48:33 -0700 Subject: [PATCH 03/68] Version 3.4.1 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index d7db5eef..5dd4000a 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.0'.freeze + VERSION = '3.4.1'.freeze end From dd8ba02419057f633641830ee1dac5fdd31d1cd3 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 7 Mar 2018 16:15:32 -0700 Subject: [PATCH 04/68] update readme for 3.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4cdfc7f..409637ea 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ For Bootstrap 4 please see the master branch and/or effective_datatables 4.x gem ```ruby gem 'haml-rails' # or try using gem 'hamlit-rails' -gem 'effective_datatables', github: 'code-and-effect/effective_datatables', branch: 'bootstrap3' +gem 'effective_datatables', '~> 3.0' ``` Run the bundle command to install it: From f8182d0083133801d0095ffdda621ae7a783e46b Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 21 Mar 2018 10:12:50 -0600 Subject: [PATCH 05/68] change cookie_param --- app/controllers/effective/datatables_controller.rb | 2 +- app/models/effective/effective_datatable/cookie.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/effective/datatables_controller.rb b/app/controllers/effective/datatables_controller.rb index 95ddd5fa..2fdb1f7b 100644 --- a/app/controllers/effective/datatables_controller.rb +++ b/app/controllers/effective/datatables_controller.rb @@ -21,7 +21,7 @@ def show private def find_datatable(id) - id = id.to_s.gsub(/-\d{12}\z/, '').gsub('-', '/') + id = id.to_s.gsub(/-\d+\z/, '').gsub('-', '/') id.classify.safe_constantize || id.classify.pluralize.safe_constantize end diff --git a/app/models/effective/effective_datatable/cookie.rb b/app/models/effective/effective_datatable/cookie.rb index 88678719..3815e3c8 100644 --- a/app/models/effective/effective_datatable/cookie.rb +++ b/app/models/effective/effective_datatable/cookie.rb @@ -17,7 +17,7 @@ def cookie_keys end def cookie_param - [self.class, attributes].hash.to_s.last(12) + [self.class, attributes].hash.abs.to_s.last(12) # Not guaranteed to be 12 long end private From 1ea40e0f21249a5bf5d302b429bdf44aebd98e64 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 21 Mar 2018 10:13:09 -0600 Subject: [PATCH 06/68] Version 3.4.2 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 5dd4000a..65bee664 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.1'.freeze + VERSION = '3.4.2'.freeze end From d03f1f106e78bbb3b6f01746d1187b736fcd0b0b Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 26 Mar 2018 12:20:21 -0600 Subject: [PATCH 07/68] Add EffectiveDatatables.save_state config option --- app/models/effective/effective_datatable/state.rb | 2 +- config/effective_datatables.rb | 4 ++++ lib/effective_datatables.rb | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/effective/effective_datatable/state.rb b/app/models/effective/effective_datatable/state.rb index 6d0fb97a..11bd2140 100644 --- a/app/models/effective/effective_datatable/state.rb +++ b/app/models/effective/effective_datatable/state.rb @@ -91,7 +91,7 @@ def load_state! if datatables_ajax_request? load_filter_params! load_ajax_state! - elsif cookie.present? && cookie[:params] == params.length + elsif cookie.present? && cookie[:params] == params.length && EffectiveDatatables.save_state load_cookie_state! else # Nothing to do for default state diff --git a/config/effective_datatables.rb b/config/effective_datatables.rb index a0d80e55..1a32eb39 100644 --- a/config/effective_datatables.rb +++ b/config/effective_datatables.rb @@ -28,6 +28,10 @@ # Default class used on the tag config.html_class = 'table table-bordered table-striped' + # If a user has previously visited this page and is returning, use the cookie to restore last session + # Irregardless of this setting, effective_datatables still uses a cookie to function + config.save_state = true + # When using the actions_column DSL method, apply the following behavior # Valid values for each action are: # true - display this action if authorized?(:show, Post) diff --git a/lib/effective_datatables.rb b/lib/effective_datatables.rb index 78d5d245..5ce6a6f2 100644 --- a/lib/effective_datatables.rb +++ b/lib/effective_datatables.rb @@ -8,6 +8,7 @@ module EffectiveDatatables mattr_accessor :default_length mattr_accessor :html_class + mattr_accessor :save_state mattr_accessor :actions_column # A Hash mattr_accessor :debug From b52cba08e0a3164206828f2f063ee499a1a97c5e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 26 Mar 2018 12:20:46 -0600 Subject: [PATCH 08/68] Version 3.4.3 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 65bee664..511c231e 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.2'.freeze + VERSION = '3.4.3'.freeze end From 23150bea4e3902de111d5453ff283771d9eff636 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 23 Apr 2018 16:21:51 -0600 Subject: [PATCH 09/68] resource search dont load collection --- app/models/effective/effective_datatable/resource.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/effective/effective_datatable/resource.rb b/app/models/effective/effective_datatable/resource.rb index 2ca5ab80..e27556b2 100644 --- a/app/models/effective/effective_datatable/resource.rb +++ b/app/models/effective/effective_datatable/resource.rb @@ -148,7 +148,7 @@ def load_resource_search! if array_collection? && opts[:resource].present? search.reverse_merge!(resource.search_form_field(name, collection.first[opts[:index]])) - else + elsif search[:as] != :string search.reverse_merge!(resource.search_form_field(name, opts[:as])) end end From e5c5ce9c7318b6505e06417777c1ec03e102d3d3 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 23 Apr 2018 16:22:09 -0600 Subject: [PATCH 10/68] Version 3.4.4 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 511c231e..b3b949dd 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.3'.freeze + VERSION = '3.4.4'.freeze end From 362078b6b36970e275aa421d14bc2cfed4b72b89 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 28 May 2018 13:19:50 -0600 Subject: [PATCH 11/68] better Access Denied --- lib/effective_datatables.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/effective_datatables.rb b/lib/effective_datatables.rb index 5ce6a6f2..47fb1e64 100644 --- a/lib/effective_datatables.rb +++ b/lib/effective_datatables.rb @@ -21,7 +21,7 @@ def self.authorized?(controller, action, resource) @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact return !!authorization_method unless authorization_method.respond_to?(:call) - controller = controller.controller if controller.respond_to?(:controller) # Do the right thing with a view + controller = controller.controller if controller.respond_to?(:controller) begin !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method) @@ -31,7 +31,7 @@ def self.authorized?(controller, action, resource) end def self.authorize!(controller, action, resource) - raise Effective::AccessDenied unless authorized?(controller, action, resource) + raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource) end end From 9e31b0d0bca5f0715ccb48028eed96997e316c4b Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 28 May 2018 13:32:05 -0600 Subject: [PATCH 12/68] bootstrap3 render resource --- README.md | 12 ++++----- app/models/effective/datatable_dsl_tool.rb | 14 +++++++--- .../effective/effective_datatable/compute.rb | 2 ++ .../effective/effective_datatable/cookie.rb | 2 +- .../effective_datatable/dsl/datatable.rb | 8 +++--- .../effective/effective_datatable/format.rb | 26 ++++++------------- .../datatables/_actions_column.html.haml | 9 +------ 7 files changed, 32 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 409637ea..e236fb1a 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ We're going to display this DataTable on the posts#index action. ```ruby class PostsController < ApplicationController def index - @datatable = PostsDatatable.new(self) + @datatable = PostsDatatable.new end end ``` @@ -255,7 +255,7 @@ In the above example, when `attributes[:user_id]` is present, the table displays ```ruby class PostsController < ApplicationController def index - @datatable = PostsDatatable.new(self, user_id: current_user.id) + @datatable = PostsDatatable.new(user_id: current_user.id) end end ``` @@ -311,7 +311,7 @@ Attributes cannot be changed by search, filter, or state in any way. They're gua ```ruby class PostsController < ApplicationController def index - @datatable = PostsDatatable.new(self, user_id: current_user.id, admin: true) + @datatable = PostsDatatable.new(user_id: current_user.id, admin: true) end end ``` @@ -407,7 +407,7 @@ Sometimes it's handy to call `.reorder(nil)` on a scope. The `datatable do ... end` block configures a table of data. -Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new(self)`, and render it in your view `<%= render_datatable(@datatable) %>` +Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new`, and render it in your view `<%= render_datatable(@datatable) %>` ### col @@ -608,7 +608,7 @@ Creates a single form with fields for each `filter` and a single radio input fie The form is submitted by an AJAX POST action, or, in some advanced circumstances (see Dynamic Columns below) as a regular POST or even GET. -Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new(self)`, and render its filters anywhere with `<%= render_datatable_filters(@datatable) %>`. +Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new`, and render its filters anywhere with `<%= render_datatable_filters(@datatable) %>`. ### scope @@ -864,7 +864,7 @@ If you just want to render a datatable and nothing else, there is a quick way to ```ruby class PostsController < ApplicationController def index - render_datatable_index PostsDatatable.new(self) + render_datatable_index PostsDatatable.new end end ``` diff --git a/app/models/effective/datatable_dsl_tool.rb b/app/models/effective/datatable_dsl_tool.rb index c76a01f6..49939c89 100644 --- a/app/models/effective/datatable_dsl_tool.rb +++ b/app/models/effective/datatable_dsl_tool.rb @@ -16,16 +16,24 @@ def initialize(datatable) @view = datatable.view end - def method_missing(method, *args) + def method_missing(method, *args, &block) # Catch a common error if [:bulk_actions, :charts, :collection, :filters].include?(method) && in_datatables_do_block raise "#{method} block must be declared outside the datatable do ... end block" end if datatable.respond_to?(method) - datatable.send(method, *args) + if block_given? + datatable.send(method, *args) { yield } + else + datatable.send(method, *args) + end elsif view.respond_to?(method) - view.send(method, *args) + if block_given? + view.send(method, *args) { yield } + else + view.send(method, *args) + end else super end diff --git a/app/models/effective/effective_datatable/compute.rb b/app/models/effective/effective_datatable/compute.rb index efa1c459..822a77ef 100644 --- a/app/models/effective/effective_datatable/compute.rb +++ b/app/models/effective/effective_datatable/compute.rb @@ -75,6 +75,8 @@ def arrayize(collection) resource.send(name) end + elsif opts[:as] == :actions + obj elsif opts[:as] == :effective_obfuscation obj.to_param elsif array_collection? diff --git a/app/models/effective/effective_datatable/cookie.rb b/app/models/effective/effective_datatable/cookie.rb index 3815e3c8..f6202f44 100644 --- a/app/models/effective/effective_datatable/cookie.rb +++ b/app/models/effective/effective_datatable/cookie.rb @@ -1,7 +1,7 @@ module Effective module EffectiveDatatable module Cookie - MAX_COOKIE_SIZE = 2500 # String size. Real byte size is about 1.5 times bigger. + MAX_COOKIE_SIZE = 2000 # String size. Real byte size is about 1.5 times bigger. def cookie @cookie diff --git a/app/models/effective/effective_datatable/dsl/datatable.rb b/app/models/effective/effective_datatable/dsl/datatable.rb index 952b0526..221155b8 100644 --- a/app/models/effective/effective_datatable/dsl/datatable.rb +++ b/app/models/effective/effective_datatable/dsl/datatable.rb @@ -97,7 +97,7 @@ def bulk_actions_col(col_class: nil, partial: nil, partial_as: nil, responsive: ) end - def actions_col(show: true, edit: true, destroy: true, col_class: nil, partial: nil, partial_as: nil, responsive: 5000, visible: true, &format) + def actions_col(show: nil, edit: nil, destroy: nil, col_class: nil, partial: nil, partial_as: nil, responsive: 5000, visible: true, &format) raise 'You can only have one actions column' if datatable.columns[:_actions].present? datatable._columns[:_actions] = Effective::DatatableColumn.new( @@ -109,7 +109,7 @@ def actions_col(show: true, edit: true, destroy: true, col_class: nil, partial: index: nil, label: '', name: :actions, - partial: partial || '/effective/datatables/actions_column', + partial: partial, partial_as: partial_as, responsive: responsive, search: false, @@ -119,9 +119,7 @@ def actions_col(show: true, edit: true, destroy: true, col_class: nil, partial: th_append: nil, visible: visible, - show: show, - edit: edit, - destroy: destroy + actions: { show: show, edit: edit, destroy: destroy, partial: :glyphicons }.reject { |k, v| v.nil? } ) end diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 9c6fe917..a35ce2dc 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -15,7 +15,7 @@ def format(collection) datatable: self, column: columns[name], controller_namespace: controller_namespace - }.merge(actions_col_locals(opts)).merge(resource_col_locals(opts)) + }.merge(resource_col_locals(opts)) rendered[name] = (view.render( partial: opts[:partial], @@ -58,6 +58,8 @@ def format_column(value, column) end case column[:as] + when :actions + view.render_resource_actions(value, **column[:actions].merge(effective_resource: resource)) when :boolean case value when true ; 'Yes' @@ -101,23 +103,11 @@ def format_column(value, column) end def actions_col_locals(opts) - return {} unless opts[:as] == :actions - - locals = { - show_action: ( - active_record_collection? && opts[:show] && resource.routes[:show] && - EffectiveDatatables.authorized?(view.controller, :show, collection_class) - ), - edit_action: ( - active_record_collection? && opts[:edit] && resource.routes[:edit] && - EffectiveDatatables.authorized?(view.controller, :edit, collection_class) - ), - destroy_action: ( - active_record_collection? && opts[:destroy] && resource.routes[:destroy] && - EffectiveDatatables.authorized?(view.controller, :destroy, collection_class) - ), - effective_resource: resource - } + if opts[:as] == :actions + { actions_col_locals: opts[:actions].merge(effective_resource: resource) } + else + {} + end end def resource_col_locals(opts) diff --git a/app/views/effective/datatables/_actions_column.html.haml b/app/views/effective/datatables/_actions_column.html.haml index 3d80beef..225de783 100644 --- a/app/views/effective/datatables/_actions_column.html.haml +++ b/app/views/effective/datatables/_actions_column.html.haml @@ -1,8 +1 @@ -- if show_action && EffectiveDatatables.authorized?(self, :show, resource) - = show_icon_to effective_resource.action_path(:show, resource) - -- if edit_action && EffectiveDatatables.authorized?(self, :edit, resource) - = edit_icon_to effective_resource.action_path(:edit, resource) - -- if destroy_action && EffectiveDatatables.authorized?(self, :destroy, resource) - = destroy_icon_to effective_resource.action_path(:destroy, resource), data: { method: :delete, confirm: "Delete #{resource}?" } += render_resource_actions(resource, **actions_col_locals) From 501106e1c0241f54e01280ce5710bb6d6445b29e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 28 May 2018 13:39:17 -0600 Subject: [PATCH 13/68] Version 3.4.5 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index b3b949dd..445d2427 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.4'.freeze + VERSION = '3.4.5'.freeze end From 08e9518868182da1e5da26f24b4ab907eb280e1c Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 12 Jul 2018 11:19:07 -0600 Subject: [PATCH 14/68] work with newest effective_resources --- app/models/effective/effective_datatable/format.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index a35ce2dc..6657245f 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -59,7 +59,7 @@ def format_column(value, column) case column[:as] when :actions - view.render_resource_actions(value, **column[:actions].merge(effective_resource: resource)) + view.render_resource_actions(resource, value, **column[:actions]) when :boolean case value when true ; 'Yes' From 60d15d2ba9c524e4948b73cb5567e572f27510fd Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 12 Jul 2018 11:19:40 -0600 Subject: [PATCH 15/68] Version 3.4.6 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 445d2427..9c0fed19 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.5'.freeze + VERSION = '3.4.6'.freeze end From 6a50789a53c70009f9d913de2e83c59377e73590 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 25 Jul 2018 10:05:34 -0600 Subject: [PATCH 16/68] Use collection rendering --- .../effective/effective_datatable/format.rb | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 6657245f..b0ba7e18 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -2,6 +2,8 @@ module Effective module EffectiveDatatable module Format BLANK = ''.freeze + SPACER = 'EFFECTIVEDATATABLESSPACER'.freeze + SPACER_TEMPLATE = '/effective/datatables/spacer_template'.freeze private @@ -11,11 +13,7 @@ def format(collection) columns.each do |name, opts| if opts[:partial] && state[:visible][name] - locals = { - datatable: self, - column: columns[name], - controller_namespace: controller_namespace - }.merge(resource_col_locals(opts)) + locals = { datatable: self, column: columns[name] }.merge(resource_col_locals(opts)) rendered[name] = (view.render( partial: opts[:partial], @@ -23,9 +21,18 @@ def format(collection) collection: collection.map { |row| row[opts[:index]] }, formats: :html, locals: locals, - spacer_template: '/effective/datatables/spacer_template', - ) || '').split('EFFECTIVEDATATABLESSPACER') + spacer_template: SPACER_TEMPLATE + ) || '').split(SPACER) + elsif opts[:as] == :actions # This is default actions_col + locals = { datatable: self, column: columns[name], spacer_template: SPACER_TEMPLATE } + + rendered[name] = (view.render_resource_actions( + resource, + collection.map { |row| row[opts[:index]] }, + opts[:actions].merge(locals: locals) + ) || '').split(SPACER) end + end collection.each_with_index do |row, row_index| @@ -42,6 +49,8 @@ def format(collection) dsl_tool.instance_exec(value, row, &opts[:format]) elsif opts[:partial] rendered[name][row_index] + elsif opts[:as] == :actions + rendered[name][row_index] else format_column(value, opts) end @@ -102,14 +111,6 @@ def format_column(value, column) end end - def actions_col_locals(opts) - if opts[:as] == :actions - { actions_col_locals: opts[:actions].merge(effective_resource: resource) } - else - {} - end - end - def resource_col_locals(opts) return {} unless (resource = opts[:resource]).present? From 9c807bf7287b9a9ee7e28989c30bf29b03a47779 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 25 Jul 2018 10:05:50 -0600 Subject: [PATCH 17/68] Version 3.4.7 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 9c0fed19..ea1120a0 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.6'.freeze + VERSION = '3.4.7'.freeze end From 5acdbe4178253a920159d8acb52616b692481bc7 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 25 Jul 2018 10:08:09 -0600 Subject: [PATCH 18/68] doc the weird actions_col syntax. sigh. --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e236fb1a..6f160c59 100644 --- a/README.md +++ b/README.md @@ -234,13 +234,15 @@ class PostsDatatable < Effective::Datatable aggregate :total # Uses effective_resources gem to discover the resource path and authorization actions - # Puts in icons to show/edit/destroy actions, if authorized to those actions. + # Puts links to show/edit/destroy actions, if authorized to those actions. # Use the actions_col block to add additional actions - actions_col show: false do |post| - if !post.approved? && can?(:approve, Post) - link_to 'Approve', approve_post_path(post) data: { method: :post, confirm: 'Really approve?'} + + actions_col do |post| + render_resource_actions(resource, post, edit: false, partial: :glyphicons) do + glyphicon_to('print', print_post_path(post), title: 'Print') end end + end end @@ -541,6 +543,16 @@ actions_col show: false do |post| end ``` +or + +```ruby +actions_col do |post| + render_resource_actions(resource, post, edit: false, partial: :glyphicons) do + glyphicon_to('print', print_post_path(post), title: 'Print') + end +end +``` + The `glyphicon_to` helper is part of the [effective_resources](https://github.com/code-and-effect/effective_resources) gem, which is a dependency of this gem. ### length From dc571d101ef0c4cf13fe033513caafe9def28e10 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Fri, 3 Aug 2018 11:23:42 -0600 Subject: [PATCH 19/68] Drop sass-rails dependency, so sites can use sassc-rails or sass-rails. --- effective_datatables.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/effective_datatables.gemspec b/effective_datatables.gemspec index f0e6e95f..6912378e 100644 --- a/effective_datatables.gemspec +++ b/effective_datatables.gemspec @@ -19,6 +19,6 @@ Gem::Specification.new do |s| s.add_dependency 'rails', ['>= 3.2.0'] s.add_dependency 'coffee-rails' s.add_dependency 'effective_resources', '>= 0.7.0' - s.add_dependency 'sass-rails' + s.add_dependency 'sass' s.add_dependency 'simple_form' end From f6fda4e105df0facde5a740871bb0ebfc7f48fab Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Fri, 3 Aug 2018 11:23:51 -0600 Subject: [PATCH 20/68] Version 3.4.8 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index ea1120a0..9b8a8242 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.7'.freeze + VERSION = '3.4.8'.freeze end From 7bb2bd437c4dbbeda257248e1d6f4b4c0b94d453 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 3 Sep 2018 14:09:10 -0600 Subject: [PATCH 21/68] changes as per effective_resources >= 0.10.0 --- .../effective_datatable/dsl/datatable.rb | 14 ++++++++------ .../effective/effective_datatable/format.rb | 19 +++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/models/effective/effective_datatable/dsl/datatable.rb b/app/models/effective/effective_datatable/dsl/datatable.rb index 221155b8..c9157ca3 100644 --- a/app/models/effective/effective_datatable/dsl/datatable.rb +++ b/app/models/effective/effective_datatable/dsl/datatable.rb @@ -31,7 +31,7 @@ def col(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, pa col_class: col_class, format: (format if block_given?), index: nil, - label: label || name.to_s.split('.').last.titleize, + label: (label.nil? ? name.to_s.split('.').last.titleize : label), name: name, partial: partial, partial_as: partial_as, @@ -59,7 +59,7 @@ def val(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, pa col_class: col_class, format: nil, index: nil, - label: label || name.to_s.split('.').last.titleize, + label: (label.nil? ? name.to_s.split('.').last.titleize : label), name: name, partial: partial, partial_as: partial_as, @@ -83,7 +83,7 @@ def bulk_actions_col(col_class: nil, partial: nil, partial_as: nil, responsive: col_class: col_class, format: nil, index: nil, - label: '', + label: false, name: :bulk_actions, partial: partial || '/effective/datatables/bulk_actions_column', partial_as: partial_as, @@ -97,7 +97,7 @@ def bulk_actions_col(col_class: nil, partial: nil, partial_as: nil, responsive: ) end - def actions_col(show: nil, edit: nil, destroy: nil, col_class: nil, partial: nil, partial_as: nil, responsive: 5000, visible: true, &format) + def actions_col(col_class: nil, partial: nil, partial_as: nil, actions_partial: nil, responsive: 5000, visible: true, **actions, &format) raise 'You can only have one actions column' if datatable.columns[:_actions].present? datatable._columns[:_actions] = Effective::DatatableColumn.new( @@ -107,10 +107,11 @@ def actions_col(show: nil, edit: nil, destroy: nil, col_class: nil, partial: nil col_class: col_class, format: (format if block_given?), index: nil, - label: '', + label: false, name: :actions, partial: partial, partial_as: partial_as, + actions_partial: (actions_partial || :glyphicons), responsive: responsive, search: false, sort: false, @@ -119,7 +120,8 @@ def actions_col(show: nil, edit: nil, destroy: nil, col_class: nil, partial: nil th_append: nil, visible: visible, - actions: { show: show, edit: edit, destroy: destroy, partial: :glyphicons }.reject { |k, v| v.nil? } + # { approve: false }. These args are passed to effective_resources render_resource_actions + actions: actions ) end diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index b0ba7e18..8688156e 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -23,14 +23,13 @@ def format(collection) locals: locals, spacer_template: SPACER_TEMPLATE ) || '').split(SPACER) - elsif opts[:as] == :actions # This is default actions_col + elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something' locals = { datatable: self, column: columns[name], spacer_template: SPACER_TEMPLATE } - rendered[name] = (view.render_resource_actions( - resource, - collection.map { |row| row[opts[:index]] }, - opts[:actions].merge(locals: locals) - ) || '').split(SPACER) + resources = collection.map { |row| row[opts[:index]] } + atts = opts[:actions].merge(effective_resource: resource, locals: locals, partial: opts[:actions_partial]) + + rendered[name] = (view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER) end end @@ -43,14 +42,14 @@ def format(collection) value = row[index] row[index] = ( - if opts[:format] && rendered.key?(name) + if opts[:as] == :actions + rendered[name][row_index] + elsif opts[:format] && rendered.key?(name) dsl_tool.instance_exec(value, row, rendered[name][row_index], &opts[:format]) elsif opts[:format] dsl_tool.instance_exec(value, row, &opts[:format]) elsif opts[:partial] rendered[name][row_index] - elsif opts[:as] == :actions - rendered[name][row_index] else format_column(value, opts) end @@ -68,7 +67,7 @@ def format_column(value, column) case column[:as] when :actions - view.render_resource_actions(resource, value, **column[:actions]) + view.render_resource_actions(value, **column[:actions].merge(effective_resource: resource, partial: column[:actions_partial])) when :boolean case value when true ; 'Yes' From 9c153d25a857f1cf3537cc32012d077f4221f72e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 3 Sep 2018 14:36:03 -0600 Subject: [PATCH 22/68] label false fix --- README.md | 6 ++---- app/helpers/effective_datatables_private_helper.rb | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6f160c59..66e5f6c6 100644 --- a/README.md +++ b/README.md @@ -237,10 +237,8 @@ class PostsDatatable < Effective::Datatable # Puts links to show/edit/destroy actions, if authorized to those actions. # Use the actions_col block to add additional actions - actions_col do |post| - render_resource_actions(resource, post, edit: false, partial: :glyphicons) do - glyphicon_to('print', print_post_path(post), title: 'Print') - end + actions_col(edit: false) do |post| + glyphicon_to('print', print_post_path(post), title: 'Print') end end diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index 3d6b3a5f..ddb6d31f 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -9,7 +9,7 @@ def datatable_columns(datatable) datatable.columns.map do |name, opts| { name: name, - title: content_tag(:span, opts[:label], class: 'search-label'), + title: content_tag(:span, (opts[:label] == false ? '' : opts[:label]), class: 'search-label'), className: opts[:col_class], searchHtml: (datatable_search_html(form, name, datatable.state[:search][name], opts) unless datatable.simple?), responsivePriority: opts[:responsive], From 668c80103288f69ee01fe67bb3529a0d89013aaa Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 3 Sep 2018 14:38:24 -0600 Subject: [PATCH 23/68] updated documentation for actions_col. Sorry! --- README.md | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 66e5f6c6..ba2f1480 100644 --- a/README.md +++ b/README.md @@ -514,45 +514,36 @@ You can only have one `bulk_actions_col` per datatable. ### actions_col -When working with an ActiveRecord based collection, this column will consider the `current_user`'s authorization, and generate -glyphicon links to edit, show and destroy actions for any collection class. +When working with an ActiveRecord based collection, this column will consider the `current_user`'s authorization, and generate links to edit, show and destroy actions for any collection class. The authorization method is configured via the `config/initializers/effective_datatables.rb` initializer file. There are just a few options: ```ruby -show: true|false|:authorize -edit: true|false|:authorize -destroy: true|false|:authorize - +show: true|false +edit: true|false +destroy: true|false visible: true|false +actions_partial: :glyphicons ``` -When the show, edit and destroy actions are `true` (default), the permission check will be made just once, authorizing the class. -When set to `:authorize`, permission to each individual object will be checked. +Each object is checked individually for authorization. -Use the block syntax to add additional actions +The arguments to `actions_col` are passed through to the `effective_resource` gem's [render_resource_actions](https://github.com/code-and-effect/effective_resources/blob/master/app/helpers/effective_resources_helper.rb#L57). -```ruby -actions_col show: false do |post| - (post.approved? ? link_to('Approve', approve_post_path(post)) : '') + - glyphicon_to('print', print_ticket_path(ticket), title: 'Print') -end -``` +It's all very complicated. -or +If you just want to override this entire column with your own actions implementation, you can pass `actions_col partial: 'my_partial'` and roll your own. + +Otherwise, use the following block syntax to add additional actions. This helper comes from `effective_form_inputs` gem. ```ruby actions_col do |post| - render_resource_actions(resource, post, edit: false, partial: :glyphicons) do - glyphicon_to('print', print_post_path(post), title: 'Print') - end + glyphicon_to('print', print_post_path(post), title: 'Print') end ``` -The `glyphicon_to` helper is part of the [effective_resources](https://github.com/code-and-effect/effective_resources) gem, which is a dependency of this gem. - ### length Sets the default number of rows per page. Valid lengths are `5`, `10`, `25`, `50`, `100`, `250`, `500`, `:all` From 72320bfc5bab259b8960d48d3f17caefd942e137 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 3 Sep 2018 14:38:41 -0600 Subject: [PATCH 24/68] Version 3.5.0 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 9b8a8242..1276282b 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.4.8'.freeze + VERSION = '3.5.0'.freeze end From 5ba1d374f51bc50071a3ed3fb003eb4730fe22df Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 29 Oct 2018 08:36:58 -0600 Subject: [PATCH 25/68] effective_resources changes --- .../effective/effective_datatable/format.rb | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 8688156e..064260cb 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -2,6 +2,7 @@ module Effective module EffectiveDatatable module Format BLANK = ''.freeze + NONVISIBLE = '...'.freeze SPACER = 'EFFECTIVEDATATABLESSPACER'.freeze SPACER_TEMPLATE = '/effective/datatables/spacer_template'.freeze @@ -12,7 +13,9 @@ def format(collection) rendered = {} columns.each do |name, opts| - if opts[:partial] && state[:visible][name] + next unless state[:visible][name] + + if opts[:partial] locals = { datatable: self, column: columns[name] }.merge(resource_col_locals(opts)) rendered[name] = (view.render( @@ -24,10 +27,9 @@ def format(collection) spacer_template: SPACER_TEMPLATE ) || '').split(SPACER) elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something' - locals = { datatable: self, column: columns[name], spacer_template: SPACER_TEMPLATE } - resources = collection.map { |row| row[opts[:index]] } - atts = opts[:actions].merge(effective_resource: resource, locals: locals, partial: opts[:actions_partial]) + locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE } + atts = { actions: actions_col_actions(opts), effective_resource: resource, locals: locals, partial: opts[:actions_partial] }.merge(opts[:actions]) rendered[name] = (view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER) end @@ -36,13 +38,13 @@ def format(collection) collection.each_with_index do |row, row_index| columns.each do |name, opts| - next unless state[:visible][name] - index = opts[:index] value = row[index] row[index] = ( - if opts[:as] == :actions + if state[:visible][name] == false + NONVISIBLE + elsif opts[:as] == :actions rendered[name][row_index] elsif opts[:format] && rendered.key?(name) dsl_tool.instance_exec(value, row, rendered[name][row_index], &opts[:format]) @@ -67,7 +69,8 @@ def format_column(value, column) case column[:as] when :actions - view.render_resource_actions(value, **column[:actions].merge(effective_resource: resource, partial: column[:actions_partial])) + atts = { actions: actions_col_actions(column), effective_resource: resource, partial: column[:actions_partial] }.merge(column[:actions]) + (view.render_resource_actions(value, atts) || '') when :boolean case value when true ; 'Yes' @@ -110,6 +113,12 @@ def format_column(value, column) end end + # Takes all default resource actions + # Applies data-remote to anything that's data-method post or delete + def actions_col_actions(column) + resource.resource_actions + end + def resource_col_locals(opts) return {} unless (resource = opts[:resource]).present? From 2e84fb3e856448759972a60843c4af12cba5f506 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 29 Oct 2018 08:41:07 -0600 Subject: [PATCH 26/68] Version 3.5.2 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 1276282b..611744e3 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.5.0'.freeze + VERSION = '3.5.2'.freeze end From e6cd1ff7695b2294cbeffbbb1c60e8ca19d8f075 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 12 Dec 2018 09:33:10 -0700 Subject: [PATCH 27/68] Extract max cookie size into a config variable --- app/models/effective/effective_datatable/cookie.rb | 4 +--- config/effective_datatables.rb | 3 +++ lib/effective_datatables.rb | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/effective/effective_datatable/cookie.rb b/app/models/effective/effective_datatable/cookie.rb index f6202f44..a0567fb7 100644 --- a/app/models/effective/effective_datatable/cookie.rb +++ b/app/models/effective/effective_datatable/cookie.rb @@ -1,8 +1,6 @@ module Effective module EffectiveDatatable module Cookie - MAX_COOKIE_SIZE = 2000 # String size. Real byte size is about 1.5 times bigger. - def cookie @cookie end @@ -45,7 +43,7 @@ def save_cookie! @dt_cookie ||= [] @dt_cookie << [cookie_key, cookie_payload] - while @dt_cookie.to_s.size > MAX_COOKIE_SIZE + while @dt_cookie.to_s.size > EffectiveDatatables.max_cookie_size.to_i @dt_cookie.shift((@dt_cookie.length / 3) + 1) end diff --git a/config/effective_datatables.rb b/config/effective_datatables.rb index 1a32eb39..50011f63 100644 --- a/config/effective_datatables.rb +++ b/config/effective_datatables.rb @@ -49,4 +49,7 @@ # Log search/sort information to the console config.debug = true + # String size. Final byte size is about 1.5 times bigger, after rails signs it + config.max_cookie_size = 2000 + end diff --git a/lib/effective_datatables.rb b/lib/effective_datatables.rb index 47fb1e64..70113681 100644 --- a/lib/effective_datatables.rb +++ b/lib/effective_datatables.rb @@ -9,6 +9,7 @@ module EffectiveDatatables mattr_accessor :default_length mattr_accessor :html_class mattr_accessor :save_state + mattr_accessor :max_cookie_size mattr_accessor :actions_column # A Hash mattr_accessor :debug From b5618aec0ba60ef5cbdc753be332a5fff890df25 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 12 Dec 2018 09:33:23 -0700 Subject: [PATCH 28/68] Version 3.5.3 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 611744e3..c35362eb 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.5.2'.freeze + VERSION = '3.5.3'.freeze end From 8d33ca437f51f46bc7cb26843265792bfbe09565 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Fri, 12 Apr 2019 10:56:44 -0600 Subject: [PATCH 29/68] add form authenticity token --- app/assets/javascripts/effective_datatables/initialize.js.coffee | 1 + app/helpers/effective_datatables_helper.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/assets/javascripts/effective_datatables/initialize.js.coffee b/app/assets/javascripts/effective_datatables/initialize.js.coffee index 6e076a19..841e4c1b 100644 --- a/app/assets/javascripts/effective_datatables/initialize.js.coffee +++ b/app/assets/javascripts/effective_datatables/initialize.js.coffee @@ -64,6 +64,7 @@ initializeDataTables = -> $form = $(".effective-datatables-filters[aria-controls='#{$table.attr('id')}']").first() params['cookie'] = $table.data('cookie') + params['authenticity_token'] = $table.data('authenticity-token') if $form.length > 0 params['scope'] = $form.find("input[id^='filters_scope']:checked").val() || '' diff --git a/app/helpers/effective_datatables_helper.rb b/app/helpers/effective_datatables_helper.rb index decc6a7e..a63a74c9 100644 --- a/app/helpers/effective_datatables_helper.rb +++ b/app/helpers/effective_datatables_helper.rb @@ -20,6 +20,7 @@ def render_datatable(datatable, input_js: {}, buttons: true, charts: true, filte id: datatable.to_param, class: ('effective-datatable ' + Array(datatable.table_html_class).join(' ')), data: { + 'authenticity-token' => form_authenticity_token, 'effective-form-inputs' => defined?(EffectiveFormInputs), 'bulk-actions' => datatable_bulk_actions(datatable), 'columns' => datatable_columns(datatable), From f0593fe6d903e4c31f13ff2c8bb72be0ca023711 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Fri, 12 Apr 2019 10:56:57 -0600 Subject: [PATCH 30/68] Version 3.5.4 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index c35362eb..56d2bdea 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.5.3'.freeze + VERSION = '3.5.4'.freeze end From cf895b57cbb54043b2f5b55748f44f5b1494d4cc Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 5 Aug 2019 12:16:32 -0600 Subject: [PATCH 31/68] Fix scss include issues --- .../buttons/{buttons.bootstrap.css => buttons.bootstrap.scss} | 0 .../{dataTables.bootstrap.css => dataTables.bootstrap.scss} | 0 .../{responsive.bootstrap.css => responsive.bootstrap.scss} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename app/assets/stylesheets/dataTables/buttons/{buttons.bootstrap.css => buttons.bootstrap.scss} (100%) rename app/assets/stylesheets/dataTables/{dataTables.bootstrap.css => dataTables.bootstrap.scss} (100%) rename app/assets/stylesheets/dataTables/responsive/{responsive.bootstrap.css => responsive.bootstrap.scss} (100%) diff --git a/app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.css b/app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.scss similarity index 100% rename from app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.css rename to app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.scss diff --git a/app/assets/stylesheets/dataTables/dataTables.bootstrap.css b/app/assets/stylesheets/dataTables/dataTables.bootstrap.scss similarity index 100% rename from app/assets/stylesheets/dataTables/dataTables.bootstrap.css rename to app/assets/stylesheets/dataTables/dataTables.bootstrap.scss diff --git a/app/assets/stylesheets/dataTables/responsive/responsive.bootstrap.css b/app/assets/stylesheets/dataTables/responsive/responsive.bootstrap.scss similarity index 100% rename from app/assets/stylesheets/dataTables/responsive/responsive.bootstrap.css rename to app/assets/stylesheets/dataTables/responsive/responsive.bootstrap.scss From 3d59a625e06d6383e78c4054c27d0fa74ad1a058 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Aug 2019 14:28:53 -0600 Subject: [PATCH 32/68] better resource column --- .../datatables/_resource_column.html.haml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/app/views/effective/datatables/_resource_column.html.haml b/app/views/effective/datatables/_resource_column.html.haml index cdb1c490..1c8c5e1a 100644 --- a/app/views/effective/datatables/_resource_column.html.haml +++ b/app/views/effective/datatables/_resource_column.html.haml @@ -1,8 +1,11 @@ -- Array(datatable.array_collection? ? resource : resource.send(name)).each do |resource| - .col-resource_item - - if show_action - = link_to resource.to_s, effective_resource.action_path(:show, resource), title: resource.to_s - - elsif edit_action - = link_to resource.to_s, effective_resource.action_path(:edit, resource), title: resource.to_s - - else - = resource.to_s.html_safe +- Array(local_assigns[:resource_name] ? resource.public_send(resource_name) : resource).each do |resource| + - resource_to_s = ((local_assigns[:resource_to_s] && resource) ? resource.public_send(resource_to_s) : resource.to_s) + + - if resource_to_s.present? + .col-resource_item + - if edit_action && EffectiveDatatables.authorized?(controller, :edit, resource) && (path = effective_resource.action_path(:edit, resource)).present? + = link_to resource_to_s, path, title: resource_to_s + - elsif show_action && EffectiveDatatables.authorized?(controller, :show, resource) && (path = effective_resource.action_path(:show, resource)).present? + = link_to resource_to_s, path, title: resource_to_s + - else + = resource_to_s.to_s.html_safe From 83c2543c6b116e38ad7ca2c9861e39e8cd0961b0 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Aug 2019 14:32:42 -0600 Subject: [PATCH 33/68] better resource actions --- .../effective/effective_datatable/format.rb | 96 ++++++++++++++----- 1 file changed, 71 insertions(+), 25 deletions(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 064260cb..9c8c05d5 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -16,7 +16,7 @@ def format(collection) next unless state[:visible][name] if opts[:partial] - locals = { datatable: self, column: columns[name] }.merge(resource_col_locals(opts)) + locals = { datatable: self, column: opts }.merge(resource_col_locals(opts)) rendered[name] = (view.render( partial: opts[:partial], @@ -29,11 +29,24 @@ def format(collection) elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something' resources = collection.map { |row| row[opts[:index]] } locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE } - atts = { actions: actions_col_actions(opts), effective_resource: resource, locals: locals, partial: opts[:actions_partial] }.merge(opts[:actions]) - rendered[name] = (view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER) - end + atts = { + actions: actions_col_actions(opts), + btn_class: opts[:btn_class], + effective_resource: effective_resource, + locals: locals, + partial: opts[:actions_partial], + }.compact.merge(opts[:actions]) + rendered[name] = if effective_resource.blank? + resources.map do |resource| + polymorphic_resource = Effective::Resource.new(resource, namespace: controller_namespace) + (view.render_resource_actions(resource, atts.merge(effective_resource: polymorphic_resource), &opts[:format]) || '') + end + else + (view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER) + end + end end collection.each_with_index do |row, row_index| @@ -69,13 +82,9 @@ def format_column(value, column) case column[:as] when :actions - atts = { actions: actions_col_actions(column), effective_resource: resource, partial: column[:actions_partial] }.merge(column[:actions]) - (view.render_resource_actions(value, atts) || '') + raise("please use actions_col instead of col(#{name}, as: :actions)") when :boolean - case value - when true ; 'Yes' - when false ; 'No' - end + view.t("effective_datatables.boolean_#{value}") when :currency view.number_to_currency(value) when :date @@ -96,10 +105,10 @@ def format_column(value, column) view.mail_to(value) when :integer value - when :percentage + when :percent case value - when Integer ; "#{value}%" - when Numeric ; view.number_to_percentage(value * 100, precision: 2) + when Integer ; view.number_to_percentage(value / 1000.0, precision: 3).gsub('.000%', '%') + when Numeric ; view.number_to_percentage(value, precision: 3).gsub('.000%', '%') end when :price case value @@ -115,29 +124,66 @@ def format_column(value, column) # Takes all default resource actions # Applies data-remote to anything that's data-method post or delete + # Merges in any extra attributes when passed as a Hash def actions_col_actions(column) - resource.resource_actions + resource_actions = (effective_resource&.resource_actions || fallback_effective_resource.fallback_resource_actions) + + actions = if column[:inline] + resource_actions.transform_values { |opts| opts['data-remote'] = true; opts } + else + resource_actions.transform_values { |opts| opts['data-remote'] = true if opts['data-method']; opts } + end + + # Merge local options. Special behaviour for remote: false + if column[:actions].kind_of?(Hash) + column[:actions].each do |action, opts| + next unless opts.kind_of?(Hash) + + existing = actions.find { |_, v| v[:action] == action }&.first + next unless existing.present? + + actions[existing]['data-remote'] = opts[:remote] if opts.key?(:remote) + actions[existing]['data-remote'] = opts['remote'] if opts.key?('remote') + + actions[existing].merge!(opts.except(:remote, 'remote')) + end + + actions = actions.sort do |(_, a), (_, b)| + (column[:actions].keys.index(a[:action]) || 99) <=> (column[:actions].keys.index(b[:action]) || 99) + end.to_h + + end + + actions end def resource_col_locals(opts) - return {} unless (resource = opts[:resource]).present? + return {} unless (associated_resource = opts[:resource]).present? + + associated = associated_resource.macros.include?(opts[:as]) + polymorphic = (opts[:as] == :belongs_to_polymorphic) - locals = { name: opts[:name], effective_resource: resource, show_action: false, edit_action: false } + resource_name = opts[:name] if associated + resource_to_s = opts[:name] unless associated || array_collection? + + locals = { + resource_name: resource_name, + resource_to_s: resource_to_s, + effective_resource: associated_resource, + show_action: false, + edit_action: false + } case opts[:action] when :edit - locals[:edit_action] = (resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass)) + locals[:edit_action] = (polymorphic || associated_resource.routes[:edit].present?) when :show - locals[:show_action] = (resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass)) + locals[:show_action] = (polymorphic || associated_resource.routes[:show].present?) when false - # Nothing + # Nothing. Already false. else - # Fallback to defaults - check edit then show - if resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass) - locals[:edit_action] = true - elsif resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass) - locals[:show_action] = true - end + locals[:edit_action] = (polymorphic || associated_resource.routes[:edit].present?) + locals[:show_action] = (polymorphic || associated_resource.routes[:show].present?) end locals From 368ffe04c0ab7eef0bffbe0622294683be4ab309 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Aug 2019 17:13:42 -0600 Subject: [PATCH 34/68] restore boolean --- app/models/effective/effective_datatable/format.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 9c8c05d5..80f5d98b 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -84,7 +84,10 @@ def format_column(value, column) when :actions raise("please use actions_col instead of col(#{name}, as: :actions)") when :boolean - view.t("effective_datatables.boolean_#{value}") + case value + when true ; 'Yes' + when false ; 'No' + end when :currency view.number_to_currency(value) when :date From 905b16b7efa10f93d604fac6e5846c20f33ea22b Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 6 Aug 2019 17:13:55 -0600 Subject: [PATCH 35/68] Version 3.6.0 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 56d2bdea..50ff5902 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.5.4'.freeze + VERSION = '3.6.0'.freeze end From b6c9f06cc0f21f62dcb7c5e813b469a72e59bb60 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 7 Aug 2019 09:18:23 -0600 Subject: [PATCH 36/68] effective addresses column fix --- app/models/effective/effective_datatable/format.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 80f5d98b..e2888c63 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -99,7 +99,7 @@ def format_column(value, column) when :duration view.number_to_duration(value) when :effective_addresses - value.to_html + (value.respond_to?(:to_html) ? value.to_html : value).to_s when :effective_obfuscation value when :effective_roles From a9f7596dd9356bf26dc42ea12f79d2f51fdd8c02 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 7 Aug 2019 09:18:33 -0600 Subject: [PATCH 37/68] Version 3.6.1 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 50ff5902..b198557f 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.6.0'.freeze + VERSION = '3.6.1'.freeze end From a7d1a9552d5db5fa69d6450099f279621c55c245 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 7 Aug 2019 11:59:38 -0600 Subject: [PATCH 38/68] move towards effective_resource --- app/models/effective/datatable.rb | 10 +++++++++- app/models/effective/datatable_column_tool.rb | 2 +- app/models/effective/effective_datatable/resource.rb | 8 +++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/models/effective/datatable.rb b/app/models/effective/datatable.rb index 96a2c5fb..db89a81c 100644 --- a/app/models/effective/datatable.rb +++ b/app/models/effective/datatable.rb @@ -1,7 +1,7 @@ module Effective class Datatable attr_reader :attributes # Anything that we initialize our table with. That's it. Can't be changed by state. - attr_reader :resource + attr_reader :effective_resource attr_reader :state # Hashes of DSL options @@ -149,6 +149,14 @@ def dsl_tool @dsl_tool ||= DatatableDslTool.new(self) end + def resource + @effective_resource + end + + def fallback_effective_resource + @fallback_effective_resource ||= Effective::Resource.new('', namespace: controller_namespace) + end + private def column_tool diff --git a/app/models/effective/datatable_column_tool.rb b/app/models/effective/datatable_column_tool.rb index 0cba14c3..c8ef8525 100644 --- a/app/models/effective/datatable_column_tool.rb +++ b/app/models/effective/datatable_column_tool.rb @@ -43,7 +43,7 @@ def order_column(collection, direction, column, sql_column) Rails.logger.info "COLUMN TOOL: order_column #{column.to_s} #{direction} #{sql_column}" if EffectiveDatatables.debug if column[:sql_as_column] - collection.order("#{sql_column} #{datatable.resource.sql_direction(direction)}") + collection.order("#{sql_column} #{datatable.effective_resource.sql_direction(direction)}") else Effective::Resource.new(collection) .order(column[:name], direction, as: column[:as], sort: column[:sort], sql_column: column[:sql_column], limit: datatable.limit) diff --git a/app/models/effective/effective_datatable/resource.rb b/app/models/effective/effective_datatable/resource.rb index e27556b2..fb62c934 100644 --- a/app/models/effective/effective_datatable/resource.rb +++ b/app/models/effective/effective_datatable/resource.rb @@ -13,9 +13,15 @@ def controller_namespace private + def load_effective_resource! + @effective_resource = if active_record_collection? + Effective::Resource.new(collection_class, namespace: controller_namespace) + end + end + # This looks at all the columns and figures out the as: def load_resource! - @resource = Effective::Resource.new(collection_class, namespace: controller_namespace) + load_effective_resource! if active_record_collection? columns.each do |name, opts| From 265a73e399661ff28ea247a9877acfbb752c0c13 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 7 Aug 2019 12:57:28 -0600 Subject: [PATCH 39/68] Version 3.6.3 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index b198557f..c1a25609 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.6.1'.freeze + VERSION = '3.6.3'.freeze end From 347b5955e5cf8462b7b7208140ffaf6d0e053a38 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 10:16:58 -0600 Subject: [PATCH 40/68] working wellish --- .../effective_datatables/initialize.js.coffee | 1 - .../effective_datatables/_overrides.scss | 22 +++ app/helpers/effective_datatables_helper.rb | 2 +- .../effective_datatables_private_helper.rb | 158 ++++++++++++++++-- .../effective_datatable/dsl/datatable.rb | 2 +- .../datatables/_reorder_column.html.haml | 2 +- 6 files changed, 172 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/effective_datatables/initialize.js.coffee b/app/assets/javascripts/effective_datatables/initialize.js.coffee index dd41f9b1..06a7508c 100644 --- a/app/assets/javascripts/effective_datatables/initialize.js.coffee +++ b/app/assets/javascripts/effective_datatables/initialize.js.coffee @@ -47,7 +47,6 @@ initializeDataTables = (target) -> deferLoading: [datatable.data('display-records'), datatable.data('total-records')] deferRender: true displayStart: datatable.data('display-start') - dom: "<'row'<'col-sm-12'B>><'row'<'col-sm-12'tr>><'row'<'col-sm-6 dataTables_entries'il><'col-sm-6'p>>" iDisplayLength: datatable.data('display-length') language: datatable.data('language') lengthMenu: [[5, 10, 25, 50, 100, 250, 500, 9999999], ['5', '10', '25', '50', '100', '250', '500', 'All']] diff --git a/app/assets/stylesheets/effective_datatables/_overrides.scss b/app/assets/stylesheets/effective_datatables/_overrides.scss index 3b5707ce..432bba89 100644 --- a/app/assets/stylesheets/effective_datatables/_overrides.scss +++ b/app/assets/stylesheets/effective_datatables/_overrides.scss @@ -35,6 +35,8 @@ table.dataTable thead { border-bottom: none; white-space: nowrap; padding: 6px; + + span { display: block; } } .form-control, .form-group { @@ -194,3 +196,23 @@ table.dataTable { p { margin-bottom: 0px; } } } + +// Simple styles +table.dataTable.hide-sort > thead { + .sorting { background-image: none; cursor: default; } + .sorting_asc { background-image: none; cursor: default; } + .sorting_desc { background-image: none; cursor: default; } +} + +table.dataTable.hide-search > thead { + .form-group { display: none; } +} + +table.dataTable.hide-buttons { + .col-bulk_actions { display: none; } +} + +// Datatables entries +@media screen and (max-width: 767px) { + div.dataTables_wrapper div.dataTables_entries { text-align: center; } +} \ No newline at end of file diff --git a/app/helpers/effective_datatables_helper.rb b/app/helpers/effective_datatables_helper.rb index e654b0b6..2f80b147 100644 --- a/app/helpers/effective_datatables_helper.rb +++ b/app/helpers/effective_datatables_helper.rb @@ -55,7 +55,7 @@ def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entri 'reorder' => datatable_reorder(datatable), 'reorder-index' => (datatable.columns[:_reorder][:index] if datatable.reorder?).to_s, 'simple' => simple.to_s, - 'spinner' => icon('spinner'), # effective_bootstrap + 'spinner' => '', # effective_bootstrap 'source' => effective_datatables.datatable_path(datatable, {format: 'json'}), 'total-records' => datatable.to_json[:recordsTotal] } diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index ddb6d31f..5cdc263e 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -1,21 +1,21 @@ # These aren't expected to be called by a developer. They are internal methods. +# These aren't expected to be called by a developer. They are internal methods. module EffectiveDatatablesPrivateHelper # https://datatables.net/reference/option/columns def datatable_columns(datatable) - form = nil - simple_form_for(:datatable_search, url: '#', html: {id: "#{datatable.to_param}-form"}) { |f| form = f } + sortable = datatable.sortable? datatable.columns.map do |name, opts| { - name: name, - title: content_tag(:span, (opts[:label] == false ? '' : opts[:label]), class: 'search-label'), className: opts[:col_class], - searchHtml: (datatable_search_html(form, name, datatable.state[:search][name], opts) unless datatable.simple?), + name: name, responsivePriority: opts[:responsive], search: datatable.state[:search][name], - sortable: (opts[:sort] && !datatable.simple?), - visible: datatable.state[:visible][name], + searchHtml: datatable_search_tag(datatable, name, opts), + sortable: (opts[:sort] && sortable), + title: datatable_label_tag(datatable, name, opts), + visible: datatable.state[:visible][name] } end.to_json.html_safe end @@ -26,17 +26,71 @@ def datatable_bulk_actions(datatable) end end + def datatable_display_order(datatable) + (datatable.sortable? ? [datatable.order_index, datatable.order_direction] : false).to_json.html_safe + end + def datatable_reset(datatable) - render(partial: '/effective/datatables/reset', locals: { datatable: datatable }).gsub("'", '"').html_safe + link_to(content_tag(:span, t('effective_datatables.reset')), '#', class: 'btn btn-link btn-sm buttons-reset-search') + end + + def datatable_reorder(datatable) + return unless datatable.reorder? && EffectiveDatatables.authorized?(self, :update, datatable.collection_class) + link_to(content_tag(:span, t('effective_datatables.reorder')), '#', class: 'btn btn-link btn-sm buttons-reorder', disabled: true) end - def datatable_search_html(form, name, value, opts) + def datatable_new_resource_button(datatable, name, column) + return unless column[:inline] && (column[:actions][:new] != false) + + action = { action: :new, class: ['btn', column[:btn_class].presence].compact.join(' '), 'data-remote': true } + + if column[:actions][:new].kind_of?(Hash) # This might be active_record_array_collection? + action = action.merge(column[:actions][:new]) + + effective_resource = (datatable.effective_resource || datatable.fallback_effective_resource) + klass = (column[:actions][:new][:klass] || effective_resource&.klass || datatable.collection_class) + elsif Array(datatable.effective_resource&.actions).include?(:new) + effective_resource = datatable.effective_resource + klass = effective_resource.klass + else + return + end + + # Will only work if permitted + render_resource_actions(klass, actions: { t('effective_datatables.new') => action }, effective_resource: effective_resource) + end + + def datatable_label_tag(datatable, name, opts) + case opts[:as] + when :actions + content_tag(:span, t('effective_datatables.actions'), style: 'display: none;') + when :bulk_actions + content_tag(:span, t('effective_datatables.bulk_actions'), style: 'display: none;') + when :reorder + content_tag(:span, t('effective_datatables.reorder'), style: 'display: none;') + else + content_tag(:span, opts[:label].presence) + end + end + + def datatable_search_tag(datatable, name, opts) + return datatable_new_resource_button(datatable, name, opts) if name == :_actions + + return if opts[:search] == false + + # Build the search + @_effective_datatables_form_builder || simple_form_for(:datatable_search, url: '#', html: {id: "#{datatable.to_param}-form"}) { |f| @_effective_datatables_form_builder = f } + form = @_effective_datatables_form_builder + include_blank = opts[:search].key?(:include_blank) ? opts[:search][:include_blank] : opts[:label] pattern = opts[:search][:pattern] placeholder = opts[:search][:placeholder] || '' title = opts[:search][:title] || opts[:label] wrapper_html = { class: 'datatable_search' } + collection = opts[:search].delete(:collection) + value = datatable.state[:search][name] + input_html = { name: nil, value: value, @@ -83,7 +137,7 @@ def datatable_search_html(form, name, value, opts) when :select, :boolean form.input name, label: false, required: false, value: value, as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_select) ? :effective_select : :select), - collection: opts[:search][:collection], + collection: collection, selected: opts[:search][:value], multiple: opts[:search][:multiple], grouped: opts[:search][:grouped], @@ -102,4 +156,86 @@ def datatable_search_html(form, name, value, opts) end end -end + def render_datatable_filters(datatable) + raise 'expected datatable to be present' unless datatable + + datatable.view ||= self + return unless datatable._scopes.present? || datatable._filters.present? + + if datatable._filters_form_required? + render partial: 'effective/datatables/filters', locals: { datatable: datatable } + else + render(partial: 'effective/datatables/filters', locals: { datatable: datatable }).gsub('', '/div>').html_safe + end + + end + + def datatable_filter_tag(form, datatable, name, opts) + as = opts[:as].to_s.chomp('_field').to_sym + value = datatable.state[:filter][name] + collection = opts[:collection] + + options = { + autocomplete: 'off', + feedback: false, + label: false, + placeholder: (opts[:label] || name.to_s.titleize), + value: value, + wrapper: { class: 'form-group col-auto'} + }.merge(opts.except(:as, :collection, :parse)) + + options[:name] = '' unless datatable._filters_form_required? + + if [:select, :radios, :checks].include?(as) + options.delete(:name) unless as == :select + form.public_send(as, name, collection, options) # select, radios, checks + elsif as == :boolean + collection ||= [true, false].map { |value| [t("effective_datatables.boolean_#{value}"), value] } + form.public_send(:select, name, collection, options) # boolean + elsif form.respond_to?(as) + form.public_send(as, name, options) # check_box, text_area + else + form.public_send("#{as}_field", name, options) # text_field, number_field, all the rest. + end + + end + + def datatable_scope_tag(form, datatable, opts = {}) + collection = datatable._scopes.map { |name, opts| [opts[:label], name] } + value = datatable.state[:scope] + + options = { + autocomplete: 'off', + buttons: true, + checked: value, + feedback: false, + label: false, + required: false, + wrapper: { class: 'form-group col-auto'} + }.merge(opts) + + form.radios :scope, collection, options + end + + def render_datatable_charts(datatable) + raise 'expected datatable to be present' unless datatable + + datatable.view ||= self + return unless datatable._charts.present? + + datatable._charts.map { |name, _| render_datatable_chart(datatable, name) }.join.html_safe + end + + def render_datatable_chart(datatable, name) + raise 'expected datatable to be present' unless datatable + + datatable.view ||= self + return unless datatable._charts[name].present? + + chart = datatable._charts[name] + chart_data = datatable.to_json[:charts][name][:data] + + render partial: chart[:partial], locals: { datatable: datatable, chart: chart, chart_data: chart_data } + end + +end \ No newline at end of file diff --git a/app/models/effective/effective_datatable/dsl/datatable.rb b/app/models/effective/effective_datatable/dsl/datatable.rb index 0bd6a3e5..71c67b99 100644 --- a/app/models/effective/effective_datatable/dsl/datatable.rb +++ b/app/models/effective/effective_datatable/dsl/datatable.rb @@ -98,7 +98,7 @@ def actions_col(btn_class: nil, col_class: nil, inline: nil, partial: nil, parti name: :actions, partial: partial, partial_as: partial_as, - actions_partial: (actions_partial || :dropleft), + actions_partial: (actions_partial || :glyphicons), responsive: responsive, search: false, sort: false, diff --git a/app/views/effective/datatables/_reorder_column.html.haml b/app/views/effective/datatables/_reorder_column.html.haml index aaf2b442..ae131447 100644 --- a/app/views/effective/datatables/_reorder_column.html.haml +++ b/app/views/effective/datatables/_reorder_column.html.haml @@ -2,4 +2,4 @@ - value = resource.send(column[:reorder]) %input{type: 'hidden', value: value, 'data-reorder-resource': id} -= icon('move') += glypicon('move') From 7b3420f3ad8fd79af236cdd0290e7ca1bd647417 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 10:18:31 -0600 Subject: [PATCH 41/68] old bulk actions --- .../bulk_actions.js.coffee | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee index c7cb357f..1e6dfa89 100644 --- a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +++ b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee @@ -1,66 +1,50 @@ #### Checkbox toggling and Bulk Actions dropdown disabling -$(document).on 'change', ".dataTables_wrapper input[data-role='bulk-action']", (event) -> +$(document).on 'change', "input[data-role='bulk-actions-resource']", (event) -> $wrapper = $(event.currentTarget).closest('.dataTables_wrapper') - $wrapper.find("input[data-role='bulk-actions']").prop('checked', false) - toggleDropdown($wrapper) + $wrapper.find("input[data-role='bulk-actions-all']").prop('checked', false) + toggleClosestBulkActionsButton($wrapper) -$(document).on 'change', ".dataTables_wrapper input[data-role='bulk-actions']", (event) -> +$(document).on 'change', "input[data-role='bulk-actions-all']", (event) -> $wrapper = $(event.currentTarget).closest('.dataTables_wrapper') - $resources = $wrapper.find("input[data-role='bulk-action']") + $resources = $wrapper.find("input[data-role='bulk-actions-resource']") if $(event.currentTarget).is(':checked') $resources.prop('checked', true) else $resources.prop('checked', false) - toggleDropdown($wrapper) + toggleClosestBulkActionsButton($wrapper) -toggleDropdown = ($wrapper) -> +toggleClosestBulkActionsButton = ($wrapper) -> $bulkActions = $wrapper.children().first().find('.buttons-bulk-actions').children('button') - if $wrapper.find("input[data-role='bulk-action']:checked").length > 0 + if $wrapper.find("input[data-role='bulk-actions-resource']:checked").length > 0 $bulkActions.removeAttr('disabled') else $bulkActions.attr('disabled', 'disabled') -restoreSelected = ($table, selected) -> - $bulkActions = $table.closest('.dataTables_wrapper').children().first().find('.buttons-bulk-actions').children('button') - present = false - - if selected && selected.length > 0 - $table.find("input[data-role='bulk-action']").each (_, input) -> - $input = $(input) - - if selected.indexOf($input.val()) > -1 - $input.prop('checked', true) - present = true - else - $input.prop('checked', false) - - if present then $bulkActions.removeAttr('disabled') else $bulkActions.attr('disabled', 'disabled') #### Bulk Action link behaviour -$(document).on 'click', '.dataTables_wrapper .buttons-bulk-actions a', (event) -> +$(document).on 'click', '.buttons-bulk-actions a', (event) -> event.preventDefault() # prevent the click $bulkAction = $(event.currentTarget) # This is a regular tag $wrapper = $bulkAction.closest('.dataTables_wrapper') $table = $wrapper.find('table.dataTable').first() $processing = $table.siblings('.dataTables_processing').first() - $selected = $table.find("input[data-role='bulk-action']:checked") + $selected = $table.find("input[data-role='bulk-actions-resource']:checked") url = $bulkAction.attr('href') title = $bulkAction.text() - download = $bulkAction.data('bulk-download') - token = $table.data('authenticity-token') + token = $bulkAction.parent('li').data('authenticity-token') values = $.map($selected, (input) -> input.getAttribute('value')) - method = $bulkAction.data('ajax-method') + get_link = $bulkAction.data('bulk-actions-get') return unless url && values - if method == 'GET' + if get_link if url.includes('?') window.location.assign(url + '&' + $.param({ids: values})) else @@ -71,36 +55,52 @@ $(document).on 'click', '.dataTables_wrapper .buttons-bulk-actions a', (event) - # Disable the Bulk Actions dropdown, so only one can be run at a time $bulkAction.closest('button').attr('disabled', 'disabled') - $table.dataTable().data('bulk-actions-restore-selected-values', values) + # Show Processing... + $processing.show().data('bulk-actions-processing', true) - if download # This is a file download + if token # This is a file download $.fileDownload(url, httpMethod: 'POST', data: { ids: values, authenticity_token: token } successCallback: -> success = "Successfully completed #{title} bulk action" - $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(success, 'success') + $processing.html(success) + $table.dataTable().data('bulk-actions-restore-selected-values', values) $table.DataTable().draw() failCallback: -> error = "An error occured while attempting #{title} bulk action" - $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(error, 'danger') + $processing.html(error) + alert(error) + $table.dataTable().data('bulk-actions-restore-selected-values', values) $table.DataTable().draw() ) else # Normal AJAX post - $table.dataTable().data('bulk-actions-restore-selected-values', values) - - $.ajax( - method: method, - url: url, - data: { ids: values, authenticity_token: token } + $.post( + url, { ids: values } ).done((response) -> success = response['message'] || "Successfully completed #{title} bulk action" - $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(success, 'success') and restoreSelected($(e.target), values) - + $processing.html(success) ).fail((response) -> error = response['message'] || "An error occured while attempting #{title} bulk action: #{response.statusText}" - $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(error, 'danger') and restoreSelected($(e.target), values) - + $processing.html(error) + alert(error) ).always((response) -> + $table.dataTable().data('bulk-actions-restore-selected-values', values) $table.DataTable().draw() ) + +# We borrow the Processing div for our bulk action success/error messages +# This makes sure that the message is displayed for 1500ms +$(document).on 'processing.dt', (event, settings, visible) -> + return if settings.bDestroying + + $processing = $(event.target).siblings('.dataTables_processing').first() + return unless $processing.data('bulk-actions-processing') + + timeout = $processing.show().data('timeout') + clearTimeout(timeout) if timeout + $processing.data('timeout', setTimeout( => + $processing.html('Processing...').hide() + $processing.data('bulk-actions-processing', null) + , 1500) + ) From 3411a598119bdc83cae9c73004b1a9a19054719b Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 10:19:46 -0600 Subject: [PATCH 42/68] old dropdown --- .../effective/datatables/_bulk_actions_dropdown.html.haml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/views/effective/datatables/_bulk_actions_dropdown.html.haml b/app/views/effective/datatables/_bulk_actions_dropdown.html.haml index 78711b8f..83ba48d6 100644 --- a/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +++ b/app/views/effective/datatables/_bulk_actions_dropdown.html.haml @@ -1,10 +1,8 @@ .btn-group.buttons-bulk-actions - %button.btn.btn-default.dropdown-toggle{'type' => 'button', 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false, 'disabled' => 'disabled'} + %button.btn.btn-link.btn-sm.dropdown-toggle{'type': 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false, 'disabled': 'disabled'} Bulk Actions - %span.caret - %ul.dropdown-menu + .dropdown-menu - if datatable._bulk_actions.present? = datatable._bulk_actions.join.html_safe - else - %li - %a{href: '#'} No bulk actions + %a.dropdown-item{href: '#'} No bulk actions From 0bc2dfaa67e0c4900880600a9666ee19fb4f48b4 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 10:33:33 -0600 Subject: [PATCH 43/68] bulk actions --- app/assets/stylesheets/effective_datatables/_overrides.scss | 6 ++++++ .../effective/effective_datatable/dsl/bulk_actions.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/effective_datatables/_overrides.scss b/app/assets/stylesheets/effective_datatables/_overrides.scss index 432bba89..e7dbb0aa 100644 --- a/app/assets/stylesheets/effective_datatables/_overrides.scss +++ b/app/assets/stylesheets/effective_datatables/_overrides.scss @@ -215,4 +215,10 @@ table.dataTable.hide-buttons { // Datatables entries @media screen and (max-width: 767px) { div.dataTables_wrapper div.dataTables_entries { text-align: center; } +} + +.dataTables_buttons { + .buttons-bulk-actions { + button { font-size: inherit !important } + } } \ No newline at end of file diff --git a/app/models/effective/effective_datatable/dsl/bulk_actions.rb b/app/models/effective/effective_datatable/dsl/bulk_actions.rb index ec24b9a6..5867453b 100644 --- a/app/models/effective/effective_datatable/dsl/bulk_actions.rb +++ b/app/models/effective/effective_datatable/dsl/bulk_actions.rb @@ -34,7 +34,7 @@ def link_to_bulk_action(title, url, opts = {}) opts[:class] = [opts[:class], 'dropdown-item'].compact.join(' ') - link_to(title, url, opts) + content_tag(:li, link_to(title, url, opts)) end end From 72097da46f6ec5579bae9ab3b416320140c783d7 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 10:55:32 -0600 Subject: [PATCH 44/68] bulks --- app/assets/stylesheets/effective_datatables/_overrides.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/effective_datatables/_overrides.scss b/app/assets/stylesheets/effective_datatables/_overrides.scss index e7dbb0aa..d2b20010 100644 --- a/app/assets/stylesheets/effective_datatables/_overrides.scss +++ b/app/assets/stylesheets/effective_datatables/_overrides.scss @@ -219,6 +219,6 @@ table.dataTable.hide-buttons { .dataTables_buttons { .buttons-bulk-actions { - button { font-size: inherit !important } + button { font-size: 12px; } } } \ No newline at end of file From 749ae0640af6090afb3a568c0b5af0addf0b4b4c Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 11:12:39 -0600 Subject: [PATCH 45/68] filters --- .../effective_datatables_private_helper.rb | 54 ++++++++----------- .../effective/datatables/_filters.html.haml | 28 ++-------- 2 files changed, 26 insertions(+), 56 deletions(-) diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index 5cdc263e..59d28603 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -174,47 +174,37 @@ def datatable_filter_tag(form, datatable, name, opts) as = opts[:as].to_s.chomp('_field').to_sym value = datatable.state[:filter][name] collection = opts[:collection] + input_html = opts[:input_html] || {} - options = { - autocomplete: 'off', - feedback: false, - label: false, - placeholder: (opts[:label] || name.to_s.titleize), - value: value, - wrapper: { class: 'form-group col-auto'} - }.merge(opts.except(:as, :collection, :parse)) - - options[:name] = '' unless datatable._filters_form_required? - - if [:select, :radios, :checks].include?(as) - options.delete(:name) unless as == :select - form.public_send(as, name, collection, options) # select, radios, checks - elsif as == :boolean - collection ||= [true, false].map { |value| [t("effective_datatables.boolean_#{value}"), value] } - form.public_send(:select, name, collection, options) # boolean - elsif form.respond_to?(as) - form.public_send(as, name, options) # check_box, text_area - else - form.public_send("#{as}_field", name, options) # text_field, number_field, all the rest. - end + binding.pry + form.input name, + value: value, + selected: value, + as: as, + collection: collection, + label: opts[:label], + required: input_html.delete(:required), + multiple: input_html.delete(:multiple), + include_blank: input_html.delete(:include_blank), + group_method: input_html.delete(:group_method), + group_label_method: input_html.delete(:group_label_method), + value_method: input_html.delete(:value_method), + label_method: input_html.delete(:label_method), + input_html: (({name: ''} unless datatable._filters_form_required?) || {}).merge(input_html), + input_js: ({ placeholder: ''} if as == :effective_select), + wrapper_html: {class: 'form-group-sm'} end def datatable_scope_tag(form, datatable, opts = {}) collection = datatable._scopes.map { |name, opts| [opts[:label], name] } value = datatable.state[:scope] - options = { - autocomplete: 'off', + form.input :scope, label: false, required: false, checked: value, + as: (defined?(EffectiveFormInputs) ? :effective_radio_buttons : :radio_buttons), + collection: collection, buttons: true, - checked: value, - feedback: false, - label: false, - required: false, - wrapper: { class: 'form-group col-auto'} - }.merge(opts) - - form.radios :scope, collection, options + wrapper_html: {class: 'btn-group-sm'} end def render_datatable_charts(datatable) diff --git a/app/views/effective/datatables/_filters.html.haml b/app/views/effective/datatables/_filters.html.haml index 4cb48366..d52c24f1 100644 --- a/app/views/effective/datatables/_filters.html.haml +++ b/app/views/effective/datatables/_filters.html.haml @@ -1,37 +1,17 @@ .effective-datatables-filters{'aria-controls': datatable.to_param} = simple_form_for :filters, url: (datatable._form[:url] || '#'), method: datatable._form[:verb], html: { class: 'form-inline' } do |form| - - if datatable._scopes.present? .effective-datatables-filters-scopes - = form.input :scope, label: false, required: false, checked: datatable.state[:scope], - as: (defined?(EffectiveFormInputs) ? :effective_radio_buttons : :radio_buttons), - collection: datatable._scopes.map { |name, opts| [opts[:label], name] }, - buttons: true, - wrapper_html: {class: 'btn-group-sm'} + = datatable_scope_tag(form, datatable) - if datatable._filters.present? .effective-datatables-filters-inputs - datatable._filters.each do |name, opts| - = form.input name, - label: opts[:label], - required: opts[:input_html].delete(:required), - value: datatable.state[:filter][name], - selected: datatable.state[:filter][name], - as: opts[:as], - collection: opts[:input_html].delete(:collection), - multiple: opts[:input_html].delete(:multiple), - include_blank: opts[:input_html].delete(:include_blank), - group_method: opts[:input_html].delete(:group_method), - group_label_method: opts[:input_html].delete(:group_label_method), - value_method: opts[:input_html].delete(:value_method), - label_method: opts[:input_html].delete(:label_method), - input_html: (({name: ''} unless datatable._filters_form_required?) || {}).merge(opts[:input_html]), - input_js: ({ placeholder: ''} if opts[:as] == :effective_select), - wrapper_html: {class: 'form-group-sm'} + = datatable_filter_tag(form, datatable, name, opts) - if datatable._scopes.present? || datatable._filters.present? .effective-datatables-filters-btn - if datatable._filters_form_required? - = form.button :submit, 'Apply', 'data-disable-with': 'Applying...' + = form.button :submit, t('effective_datatables.apply'), 'data-disable-with': t('effective_datatables.applying') - else - = link_to 'Apply', '#', class: 'btn btn-primary btn-sm btn-effective-datatables-filters', 'data-apply-effective-datatables-filters': true + = link_to t('effective_datatables.apply'), '#', class: 'btn btn-primary btn-sm btn-effective-datatables-filters', 'data-apply-effective-datatables-filters': true From 54be9b0d6cb087a4474c0aca895fc406e4df134a Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 12 Aug 2019 11:14:55 -0600 Subject: [PATCH 46/68] Version 3.7.0 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index c1a25609..199d2341 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.6.3'.freeze + VERSION = '3.7.0'.freeze end From 9e1d16be8d987907a106f7cafaeb3d9be0907651 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 17 Sep 2019 10:05:55 -0600 Subject: [PATCH 47/68] remove binding.pry --- app/helpers/effective_datatables_private_helper.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index 59d28603..2f3c926a 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -176,8 +176,6 @@ def datatable_filter_tag(form, datatable, name, opts) collection = opts[:collection] input_html = opts[:input_html] || {} - binding.pry - form.input name, value: value, selected: value, @@ -228,4 +226,4 @@ def render_datatable_chart(datatable, name) render partial: chart[:partial], locals: { datatable: datatable, chart: chart, chart_data: chart_data } end -end \ No newline at end of file +end From 728db193424cf7f2bb61970a3cb642e67225ee45 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Tue, 17 Sep 2019 10:06:14 -0600 Subject: [PATCH 48/68] Version 3.7.1 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 199d2341..54edb260 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.0'.freeze + VERSION = '3.7.1'.freeze end From d096bdf55aa8eeec3a87a352ba7c435c44dc7b41 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 23 Sep 2019 07:44:28 -0600 Subject: [PATCH 49/68] searching box enter shouldn't sort column --- app/assets/javascripts/effective_datatables/initialize.js.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/effective_datatables/initialize.js.coffee b/app/assets/javascripts/effective_datatables/initialize.js.coffee index 06a7508c..9a5df1ee 100644 --- a/app/assets/javascripts/effective_datatables/initialize.js.coffee +++ b/app/assets/javascripts/effective_datatables/initialize.js.coffee @@ -145,6 +145,7 @@ initializeDataTables = (target) -> $input.parent().on 'click', (event) -> false # Dont order columns when you click inside the input $input.parent().on 'mousedown', (event) -> event.stopPropagation() # Dont order columns when you click inside the input + $input.parent().on 'keypress', (event) -> event.stopPropagation() # Don't order columns when you type inside the input if $input.is('select') $input.on 'change', (event) -> dataTableSearch($(event.currentTarget)) From 63b284580330f2b339c6e38b2f1ba1253103b3d1 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 23 Sep 2019 07:44:40 -0600 Subject: [PATCH 50/68] Version 3.7.2 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 54edb260..85216f87 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.1'.freeze + VERSION = '3.7.2'.freeze end From 1275cfe314e24a1c5749ef19066c8b9f98c216bb Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 17 Oct 2019 15:22:18 -0600 Subject: [PATCH 51/68] update initialize to match master. (csv header fix) --- .../effective_datatables/initialize.js.coffee | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/effective_datatables/initialize.js.coffee b/app/assets/javascripts/effective_datatables/initialize.js.coffee index 9a5df1ee..bd1a88eb 100644 --- a/app/assets/javascripts/effective_datatables/initialize.js.coffee +++ b/app/assets/javascripts/effective_datatables/initialize.js.coffee @@ -24,14 +24,14 @@ initializeDataTables = (target) -> extend: 'copy', exportOptions: format: - header: (str) -> $("
#{str}
").children('.search-label').first().text() + header: (str) -> $("
#{str}
").children('span').first().text() columns: buttons_export_columns }, { extend: 'csv', exportOptions: format: - header: (str) -> $("
#{str}
").children('.search-label').first().text() + header: (str) -> $("
#{str}
").children('span').first().text() columns: buttons_export_columns }, { @@ -39,7 +39,7 @@ initializeDataTables = (target) -> footer: true, exportOptions: format: - header: (str) -> $("
#{str}
").children('.search-label').first().text() + header: (str) -> $("
#{str}
").children('span').first().text() columns: ':visible:not(.col-actions)' }, ] @@ -64,12 +64,23 @@ initializeDataTables = (target) -> params['authenticity_token'] = $table.data('authenticity-token') if $form.length > 0 - params['scope'] = $form.find("input[id^='filters_scope']:checked").val() || '' + params['scope'] = $form.find("input[name='filters[scope]']:checked").val() || '' params['filter'] = {} - $form.find("[id^='filters_']:not(input[id^='filters_scope'])").each -> + $form.find("select,textarea,input:not([type=submit])").each -> $input = $(this) - params['filter'][$input.attr('id').substring(8, $input.attr('id').length)] = $input.val() + + if ['utf8', 'authenticity_token', 'filters[scope]'].includes($input.attr('name')) + # Skipped + else if $input.attr('type') == 'radio' + name = $input.attr('name') + filter_name = name.replace('filters[', '').substring(0, name.length-9) + + params['filter'][filter_name] = $form.find("input[name='#{name}']:checked").val() + + else if $input.attr('id') + filter_name = $input.attr('id').replace('filters_', '') + params['filter'][filter_name] = $input.val() serverSide: true scrollCollapse: true From 58464faf563ab70dd088e36cf2cb5405e69248b9 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 17 Oct 2019 15:34:31 -0600 Subject: [PATCH 52/68] Fix bulk actions download --- .../effective_datatables/bulk_actions.js.coffee | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee index 1e6dfa89..18313891 100644 --- a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +++ b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee @@ -38,13 +38,14 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) -> url = $bulkAction.attr('href') title = $bulkAction.text() - token = $bulkAction.parent('li').data('authenticity-token') + download = $bulkAction.data('bulk-download') + token = $table.data('authenticity-token') values = $.map($selected, (input) -> input.getAttribute('value')) - get_link = $bulkAction.data('bulk-actions-get') + method = $bulkAction.data('ajax-method') return unless url && values - if get_link + if method == 'GET' if url.includes('?') window.location.assign(url + '&' + $.param({ids: values})) else @@ -58,7 +59,7 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) -> # Show Processing... $processing.show().data('bulk-actions-processing', true) - if token # This is a file download + if download # This is a file download $.fileDownload(url, httpMethod: 'POST', data: { ids: values, authenticity_token: token } @@ -75,8 +76,10 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) -> $table.DataTable().draw() ) else # Normal AJAX post - $.post( - url, { ids: values } + $.ajax( + method: method, + url: url, + data: { ids: values, authenticity_token: token } ).done((response) -> success = response['message'] || "Successfully completed #{title} bulk action" $processing.html(success) From e0bc23b12e8809a54620053c885d5a2f290656ef Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 17 Oct 2019 15:40:20 -0600 Subject: [PATCH 53/68] Include flash --- .../javascripts/effective_datatables.js | 1 + .../bulk_actions.js.coffee | 71 +++++++++---------- .../datatables/_bulk_actions_column.html.haml | 2 +- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/app/assets/javascripts/effective_datatables.js b/app/assets/javascripts/effective_datatables.js index 199896fd..633d8474 100644 --- a/app/assets/javascripts/effective_datatables.js +++ b/app/assets/javascripts/effective_datatables.js @@ -15,6 +15,7 @@ //= require effective_datatables/bulk_actions //= require effective_datatables/events //= require effective_datatables/filters +//= require effective_datatables/flash //= require effective_datatables/reset //= require effective_datatables/responsive diff --git a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee index 18313891..2972ccd8 100644 --- a/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +++ b/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee @@ -1,40 +1,55 @@ #### Checkbox toggling and Bulk Actions dropdown disabling -$(document).on 'change', "input[data-role='bulk-actions-resource']", (event) -> +$(document).on 'change', ".dataTables_wrapper input[data-role='bulk-action']", (event) -> $wrapper = $(event.currentTarget).closest('.dataTables_wrapper') - $wrapper.find("input[data-role='bulk-actions-all']").prop('checked', false) - toggleClosestBulkActionsButton($wrapper) + $wrapper.find("input[data-role='bulk-actions']").prop('checked', false) + toggleDropdown($wrapper) -$(document).on 'change', "input[data-role='bulk-actions-all']", (event) -> +$(document).on 'change', ".dataTables_wrapper input[data-role='bulk-actions']", (event) -> $wrapper = $(event.currentTarget).closest('.dataTables_wrapper') - $resources = $wrapper.find("input[data-role='bulk-actions-resource']") + $resources = $wrapper.find("input[data-role='bulk-action']") if $(event.currentTarget).is(':checked') $resources.prop('checked', true) else $resources.prop('checked', false) - toggleClosestBulkActionsButton($wrapper) + toggleDropdown($wrapper) -toggleClosestBulkActionsButton = ($wrapper) -> +toggleDropdown = ($wrapper) -> $bulkActions = $wrapper.children().first().find('.buttons-bulk-actions').children('button') - if $wrapper.find("input[data-role='bulk-actions-resource']:checked").length > 0 + if $wrapper.find("input[data-role='bulk-action']:checked").length > 0 $bulkActions.removeAttr('disabled') else $bulkActions.attr('disabled', 'disabled') +restoreSelected = ($table, selected) -> + $bulkActions = $table.closest('.dataTables_wrapper').children().first().find('.buttons-bulk-actions').children('button') + present = false + + if selected && selected.length > 0 + $table.find("input[data-role='bulk-action']").each (_, input) -> + $input = $(input) + + if selected.indexOf($input.val()) > -1 + $input.prop('checked', true) + present = true + else + $input.prop('checked', false) + + if present then $bulkActions.removeAttr('disabled') else $bulkActions.attr('disabled', 'disabled') #### Bulk Action link behaviour -$(document).on 'click', '.buttons-bulk-actions a', (event) -> +$(document).on 'click', '.dataTables_wrapper .buttons-bulk-actions a', (event) -> event.preventDefault() # prevent the click $bulkAction = $(event.currentTarget) # This is a regular
tag $wrapper = $bulkAction.closest('.dataTables_wrapper') $table = $wrapper.find('table.dataTable').first() $processing = $table.siblings('.dataTables_processing').first() - $selected = $table.find("input[data-role='bulk-actions-resource']:checked") + $selected = $table.find("input[data-role='bulk-action']:checked") url = $bulkAction.attr('href') title = $bulkAction.text() @@ -56,8 +71,7 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) -> # Disable the Bulk Actions dropdown, so only one can be run at a time $bulkAction.closest('button').attr('disabled', 'disabled') - # Show Processing... - $processing.show().data('bulk-actions-processing', true) + $table.dataTable().data('bulk-actions-restore-selected-values', values) if download # This is a file download $.fileDownload(url, @@ -65,45 +79,28 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) -> data: { ids: values, authenticity_token: token } successCallback: -> success = "Successfully completed #{title} bulk action" - $processing.html(success) - $table.dataTable().data('bulk-actions-restore-selected-values', values) + $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(success, 'success') and restoreSelected($(e.target), values) $table.DataTable().draw() failCallback: -> error = "An error occured while attempting #{title} bulk action" - $processing.html(error) - alert(error) - $table.dataTable().data('bulk-actions-restore-selected-values', values) + $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(error, 'danger') and restoreSelected($(e.target), values) $table.DataTable().draw() ) else # Normal AJAX post + $table.dataTable().data('bulk-actions-restore-selected-values', values) + $.ajax( method: method, url: url, data: { ids: values, authenticity_token: token } ).done((response) -> success = response['message'] || "Successfully completed #{title} bulk action" - $processing.html(success) + $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(success, 'success') and restoreSelected($(e.target), values) + ).fail((response) -> error = response['message'] || "An error occured while attempting #{title} bulk action: #{response.statusText}" - $processing.html(error) - alert(error) + $table.one 'draw.dt', (e) -> $(e.target).DataTable().flash(error, 'danger') and restoreSelected($(e.target), values) + ).always((response) -> - $table.dataTable().data('bulk-actions-restore-selected-values', values) $table.DataTable().draw() ) - -# We borrow the Processing div for our bulk action success/error messages -# This makes sure that the message is displayed for 1500ms -$(document).on 'processing.dt', (event, settings, visible) -> - return if settings.bDestroying - - $processing = $(event.target).siblings('.dataTables_processing').first() - return unless $processing.data('bulk-actions-processing') - - timeout = $processing.show().data('timeout') - clearTimeout(timeout) if timeout - $processing.data('timeout', setTimeout( => - $processing.html('Processing...').hide() - $processing.data('bulk-actions-processing', null) - , 1500) - ) diff --git a/app/views/effective/datatables/_bulk_actions_column.html.haml b/app/views/effective/datatables/_bulk_actions_column.html.haml index a58a668f..04d1cb1b 100644 --- a/app/views/effective/datatables/_bulk_actions_column.html.haml +++ b/app/views/effective/datatables/_bulk_actions_column.html.haml @@ -1,2 +1,2 @@ - id = (resource.try(:to_param) || resource.try(:id) || resource.object_id) -= check_box_tag 'bulk_actions_resources[]', id, false, autocomplete: 'off', id: "datatable_bulk_actions_resource_#{id}", data: { role: 'bulk-actions-resource' }, onClick: 'event.stopPropagation();' += check_box_tag 'bulk_actions_resources[]', id, false, autocomplete: 'off', id: "datatable_bulk_actions_resource_#{id}", data: { role: 'bulk-action' }, onClick: 'event.stopPropagation();' From 1eb4a557e2b57515473c191d371a2dcc71423daa Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 17 Oct 2019 15:42:39 -0600 Subject: [PATCH 54/68] rename data-role --- app/helpers/effective_datatables_private_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index 2f3c926a..4b80cc41 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -148,7 +148,7 @@ def datatable_search_tag(datatable, name, opts) input_html: input_html, input_js: { placeholder: placeholder } when :bulk_actions - input_html[:data]['role'] = 'bulk-actions-all' + input_html[:data]['role'] = 'bulk-actions' form.input name, label: false, required: false, value: nil, as: :boolean, From 96b8cdb8b0ee7234f82d2d3c994de6f43214ad9e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 17 Oct 2019 15:43:45 -0600 Subject: [PATCH 55/68] Version 3.7.3 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 85216f87..e6bc074b 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.2'.freeze + VERSION = '3.7.3'.freeze end From 29c9987923f26304b1f912b0fd3ec29dcafcb667 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 4 Dec 2019 11:05:37 -0700 Subject: [PATCH 56/68] Use .try instead of &. for oldschool ruby compatibility --- app/helpers/effective_datatables_private_helper.rb | 4 ++-- app/models/effective/effective_datatable/format.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index 4b80cc41..f0443fdf 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -48,8 +48,8 @@ def datatable_new_resource_button(datatable, name, column) action = action.merge(column[:actions][:new]) effective_resource = (datatable.effective_resource || datatable.fallback_effective_resource) - klass = (column[:actions][:new][:klass] || effective_resource&.klass || datatable.collection_class) - elsif Array(datatable.effective_resource&.actions).include?(:new) + klass = (column[:actions][:new][:klass] || effective_resource.try(:klass) || datatable.collection_class) + elsif Array(datatable.effective_resource.try(:actions)).include?(:new) effective_resource = datatable.effective_resource klass = effective_resource.klass else diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index 34d62ddd..fb58f278 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -126,7 +126,7 @@ def format_column(value, column) # Applies data-remote to anything that's data-method post or delete # Merges in any extra attributes when passed as a Hash def actions_col_actions(column) - resource_actions = (effective_resource&.resource_actions || fallback_effective_resource.fallback_resource_actions) + resource_actions = (effective_resource.try(:resource_actions) || fallback_effective_resource.fallback_resource_actions) actions = if column[:inline] resource_actions.transform_values { |opts| opts['data-remote'] = true; opts } @@ -139,7 +139,7 @@ def actions_col_actions(column) column[:actions].each do |action, opts| next unless opts.kind_of?(Hash) - existing = actions.find { |_, v| v[:action] == action }&.first + existing = actions.find { |_, v| v[:action] == action }.try(:first) next unless existing.present? actions[existing]['data-remote'] = opts[:remote] if opts.key?(:remote) From b70ae2891e50c8f010c9d7471549e2a31334194a Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 4 Dec 2019 11:07:38 -0700 Subject: [PATCH 57/68] Version 3.7.5 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index e6bc074b..cd3072af 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.3'.freeze + VERSION = '3.7.5'.freeze end From 2a049a506a51f9a5f4352643d5be0cded3cb978f Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 2 Jan 2020 16:10:43 -0700 Subject: [PATCH 58/68] boolean search fix --- app/models/effective/datatable_value_tool.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/effective/datatable_value_tool.rb b/app/models/effective/datatable_value_tool.rb index 5f9d1310..81fb2b3a 100644 --- a/app/models/effective/datatable_value_tool.rb +++ b/app/models/effective/datatable_value_tool.rb @@ -94,10 +94,10 @@ def search_column(collection, original, column, index) case column[:as] when :boolean - if fuzzy - term ? (obj == true) : (obj != true) + if term + ['Yes', 'yes', true, 'true', '1'].include?(value) else - obj == term + ['No', 'no', false, 'false', '0'].include?(value) end when :datetime, :date end_at = ( From d3b55d068f339cbec201367e17268e3172e31527 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 2 Jan 2020 16:27:18 -0700 Subject: [PATCH 59/68] filter fields should be required false by default --- app/helpers/effective_datatables_private_helper.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/helpers/effective_datatables_private_helper.rb b/app/helpers/effective_datatables_private_helper.rb index f0443fdf..ce9bd1e1 100644 --- a/app/helpers/effective_datatables_private_helper.rb +++ b/app/helpers/effective_datatables_private_helper.rb @@ -176,15 +176,15 @@ def datatable_filter_tag(form, datatable, name, opts) collection = opts[:collection] input_html = opts[:input_html] || {} - form.input name, + attributes = { value: value, selected: value, as: as, collection: collection, label: opts[:label], - required: input_html.delete(:required), - multiple: input_html.delete(:multiple), - include_blank: input_html.delete(:include_blank), + required: input_html.delete(:required) || opts[:required], + multiple: input_html.delete(:multiple) || opts[:multiple], + include_blank: input_html.delete(:include_blank) || opts[:include_blank], group_method: input_html.delete(:group_method), group_label_method: input_html.delete(:group_label_method), value_method: input_html.delete(:value_method), @@ -192,6 +192,9 @@ def datatable_filter_tag(form, datatable, name, opts) input_html: (({name: ''} unless datatable._filters_form_required?) || {}).merge(input_html), input_js: ({ placeholder: ''} if as == :effective_select), wrapper_html: {class: 'form-group-sm'} + }.compact + + form.input name, **attributes end def datatable_scope_tag(form, datatable, opts = {}) From 411ef732ee6eff7c4d471cc122b168072468e7e9 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 2 Jan 2020 16:28:59 -0700 Subject: [PATCH 60/68] Version 3.7.6 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index cd3072af..fa3203bd 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.5'.freeze + VERSION = '3.7.6'.freeze end From 89766f8250ff39fb37fd7b8994142b85b217fd29 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 8 Oct 2020 10:52:05 -0600 Subject: [PATCH 61/68] Add config variables for datetime formats --- app/models/effective/effective_datatable/format.rb | 6 +++--- config/effective_datatables.rb | 4 ++++ lib/effective_datatables.rb | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/models/effective/effective_datatable/format.rb b/app/models/effective/effective_datatable/format.rb index fb58f278..9b6e9b6f 100644 --- a/app/models/effective/effective_datatable/format.rb +++ b/app/models/effective/effective_datatable/format.rb @@ -88,9 +88,9 @@ def format_column(value, column) when :currency view.number_to_currency(value) when :date - (value.strftime('%F') rescue BLANK) + value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_date) : BLANK when :datetime - (value.strftime('%F %H:%M') rescue BLANK) + value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_datetime) : BLANK when :decimal value when :duration @@ -116,7 +116,7 @@ def format_column(value, column) when Numeric ; view.number_to_currency(value) end when :time - (value.strftime('%H:%M') rescue BLANK) + value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_time) : BLANK else value.to_s end diff --git a/config/effective_datatables.rb b/config/effective_datatables.rb index 32edaa04..b1f11650 100644 --- a/config/effective_datatables.rb +++ b/config/effective_datatables.rb @@ -39,4 +39,8 @@ config.cookie_domain = :all # Should usually be :all config.cookie_tld_length = nil # Leave nil to autodetect, or set to probably 2 + # Date formatting + config.format_datetime = '%F %H:%M' + config.format_date = '%F' + config.format_time = '%H:%M' end diff --git a/lib/effective_datatables.rb b/lib/effective_datatables.rb index 7a156e57..8d542030 100644 --- a/lib/effective_datatables.rb +++ b/lib/effective_datatables.rb @@ -16,6 +16,10 @@ module EffectiveDatatables mattr_accessor :cookie_domain mattr_accessor :cookie_tld_length + mattr_accessor :format_datetime + mattr_accessor :format_date + mattr_accessor :format_time + mattr_accessor :debug alias_method :max_cookie_size, :cookie_max_size From 30de4f2e70963cc3cc51263192865f8db0dc537e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Thu, 8 Oct 2020 10:52:17 -0600 Subject: [PATCH 62/68] Version 3.7.7 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index fa3203bd..554fc4bd 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.6'.freeze + VERSION = '3.7.7'.freeze end From 45fe9ddb74b1fd82b414e7bb8972891b02362fcf Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 8 May 2023 10:26:40 -0600 Subject: [PATCH 63/68] updates for rails 7+ --- .../config/effective_datatables_manifest.js | 3 +++ lib/effective_datatables/engine.rb | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 app/assets/config/effective_datatables_manifest.js diff --git a/app/assets/config/effective_datatables_manifest.js b/app/assets/config/effective_datatables_manifest.js new file mode 100644 index 00000000..8a42cf13 --- /dev/null +++ b/app/assets/config/effective_datatables_manifest.js @@ -0,0 +1,3 @@ +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css +//= link_tree ../images diff --git a/lib/effective_datatables/engine.rb b/lib/effective_datatables/engine.rb index 8d7ca558..eb6eb508 100644 --- a/lib/effective_datatables/engine.rb +++ b/lib/effective_datatables/engine.rb @@ -1,16 +1,26 @@ +require_relative '../../app/helpers/effective_datatables_controller_helper' +require_relative '../../app/helpers/effective_datatables_helper' +require_relative '../../app/helpers/effective_datatables_private_helper' + module EffectiveDatatables class Engine < ::Rails::Engine engine_name 'effective_datatables' config.autoload_paths += Dir["#{config.root}/app/models/concerns", '/app/datatables/**/'] + initializer 'effective_datatables.assets' do |app| + app.config.assets.precompile += ['effective_datatables_manifest.js', 'images/*'] + end + # Include Helpers to base application initializer 'effective_datatables.action_controller' do |app| - ActiveSupport.on_load :action_controller_base do - helper EffectiveDatatablesHelper - helper EffectiveDatatablesPrivateHelper + app.config.to_prepare do + ActiveSupport.on_load :action_controller_base do + helper EffectiveDatatablesHelper + helper EffectiveDatatablesPrivateHelper - ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper + ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper + end end end From da37ad1b97286c78ff3a0227f9177e63016b10d2 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 8 May 2023 10:29:22 -0600 Subject: [PATCH 64/68] Version 3.7.8 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 554fc4bd..4568fe03 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.7'.freeze + VERSION = '3.7.8'.freeze end From ad2b419b6426f41051e304f95fff0aaf8e4aa48e Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 8 May 2023 12:09:03 -0600 Subject: [PATCH 65/68] fix for newer resources --- app/models/effective/datatable_column_tool.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/effective/datatable_column_tool.rb b/app/models/effective/datatable_column_tool.rb index c8ef8525..a93ad893 100644 --- a/app/models/effective/datatable_column_tool.rb +++ b/app/models/effective/datatable_column_tool.rb @@ -76,7 +76,7 @@ def search_column(collection, value, column, sql_column) Rails.logger.info "COLUMN TOOL: search_column #{column.to_s} #{value} #{sql_column}" if EffectiveDatatables.debug Effective::Resource.new(collection) - .search(column[:name], value, as: column[:as], fuzzy: column[:search][:fuzzy], sql_column: sql_column) + .search(column[:name], value, as: column[:as], operation: (column[:search][:fuzzy] ? :matches : :eq), column: sql_column) end def paginate(collection) From ce941231416ebccaba1501016c4e857945c800c5 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Mon, 8 May 2023 12:09:22 -0600 Subject: [PATCH 66/68] Version 3.7.9 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 4568fe03..27ede47f 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.8'.freeze + VERSION = '3.7.9'.freeze end From e8aea602daea025cc4d3b9ab3ee42340de8ae0a7 Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 31 May 2023 09:16:14 -0600 Subject: [PATCH 67/68] Only fuzzy search string columns --- app/models/effective/datatable_column_tool.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/effective/datatable_column_tool.rb b/app/models/effective/datatable_column_tool.rb index a93ad893..de4f721e 100644 --- a/app/models/effective/datatable_column_tool.rb +++ b/app/models/effective/datatable_column_tool.rb @@ -75,8 +75,10 @@ def search(collection) def search_column(collection, value, column, sql_column) Rails.logger.info "COLUMN TOOL: search_column #{column.to_s} #{value} #{sql_column}" if EffectiveDatatables.debug + operation = (column[:search][:fuzzy] && column[:as] == :string) ? :matches : :eq + Effective::Resource.new(collection) - .search(column[:name], value, as: column[:as], operation: (column[:search][:fuzzy] ? :matches : :eq), column: sql_column) + .search(column[:name], value, as: column[:as], operation: operation, column: sql_column) end def paginate(collection) From 1c9db33b5a12b146d440a914e04d3eb0e6d3598d Mon Sep 17 00:00:00 2001 From: Matt Riemer Date: Wed, 31 May 2023 09:16:30 -0600 Subject: [PATCH 68/68] Version 3.7.10 --- lib/effective_datatables/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/effective_datatables/version.rb b/lib/effective_datatables/version.rb index 27ede47f..83cda898 100644 --- a/lib/effective_datatables/version.rb +++ b/lib/effective_datatables/version.rb @@ -1,3 +1,3 @@ module EffectiveDatatables - VERSION = '3.7.9'.freeze + VERSION = '3.7.10'.freeze end