cm-admin 2.1.5 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,7 @@ module CmAdmin
31
31
 
32
32
  attr_accessor :available_actions, :actions_set, :available_fields, :additional_permitted_fields,
33
33
  :current_action, :params, :filters, :available_tabs, :icon_name, :bulk_actions, :display_name,
34
- :policy_scopes, :override_policy, :alerts
34
+ :policy_scopes, :override_policy, :alerts, :sort_columns, :default_sort_column, :default_sort_direction
35
35
  attr_reader :name, :ar_model, :is_visible_on_sidebar, :importer
36
36
 
37
37
  def initialize(entity, &block)
@@ -49,7 +49,9 @@ module CmAdmin
49
49
  @params = nil
50
50
  @override_policy = false
51
51
  @filters ||= []
52
- @policy_scopes ||= [{display_name: 'Full Access', scope_name: 'all'}]
52
+ @policy_scopes ||= [{ display_name: 'Full Access', scope_name: 'all' }]
53
+ @sort_columns ||= []
54
+ @default_sort_direction ||= 'asc'
53
55
  @alerts = []
54
56
  instance_eval(&block) if block_given?
55
57
  actions unless @actions_set
@@ -66,28 +68,28 @@ module CmAdmin
66
68
 
67
69
  def custom_controller_action(action_name, params)
68
70
  current_action = CmAdmin::Models::Action.find_by(self, name: action_name.to_s)
69
- if current_action
70
- @current_action = current_action
71
- @ar_object = @ar_model.name.classify.constantize.find(params[:id])
72
- if @current_action.child_records
73
- child_records = @ar_object.send(@current_action.child_records)
74
- @associated_model = CmAdmin::Model.find_by(name: @ar_model.reflect_on_association(@current_action.child_records).klass.name)
75
- if child_records.is_a? ActiveRecord::Relation
76
- @associated_ar_object = filter_by(params, child_records)
77
- else
78
- @associated_ar_object = child_records
79
- end
80
- return @ar_object, @associated_model, @associated_ar_object
81
- end
82
- return @ar_object
71
+ return unless current_action
72
+
73
+ @current_action = current_action
74
+ @ar_object = @ar_model.name.classify.constantize.find(params[:id])
75
+ if @current_action.child_records
76
+ child_records = @ar_object.send(@current_action.child_records)
77
+ @associated_model = CmAdmin::Model.find_by(name: @ar_model.reflect_on_association(@current_action.child_records).klass.name)
78
+ @associated_ar_object = if child_records.is_a? ActiveRecord::Relation
79
+ filter_by(params, child_records)
80
+ else
81
+ child_records
82
+ end
83
+ return @ar_object, @associated_model, @associated_ar_object
83
84
  end
85
+ @ar_object
84
86
  end
85
87
 
86
88
  # Insert into actions according to config block
87
89
  def actions(only: [], except: [])
88
90
  acts = CmAdmin::DEFAULT_ACTIONS.keys
89
- acts = acts & (Array.new << only).flatten if only.present?
90
- acts = acts - (Array.new << except).flatten if except.present?
91
+ acts &= ([] << only).flatten if only.present?
92
+ acts -= ([] << except).flatten if except.present?
91
93
  acts.each do |act|
92
94
  action_defaults = CmAdmin::DEFAULT_ACTIONS[act]
93
95
  @available_actions << CmAdmin::Models::Action.new(name: act.to_s, verb: action_defaults[:verb], path: action_defaults[:path])
@@ -107,7 +109,7 @@ module CmAdmin
107
109
  @icon_name = name
108
110
  end
109
111
 
110
- def override_pundit_policy(override_status=false)
112
+ def override_pundit_policy(override_status = false)
111
113
  @override_policy = override_status
112
114
  end
113
115
 
@@ -115,7 +117,7 @@ module CmAdmin
115
117
  @display_name = name
116
118
  end
117
119
 
118
- def permit_additional_fields(fields=[])
120
+ def permit_additional_fields(fields = [])
119
121
  @additional_permitted_fields = fields
120
122
  end
121
123
 
@@ -131,17 +133,17 @@ module CmAdmin
131
133
  @display_name.present? ? @display_name : @name
132
134
  end
133
135
 
134
- def set_policy_scopes(scopes=[])
135
- @policy_scopes = ([{display_name: 'Full Access', scope_name: 'all'}] + scopes).uniq
136
+ def set_policy_scopes(scopes = [])
137
+ @policy_scopes = ([{ display_name: 'Full Access', scope_name: 'all' }] + scopes).uniq
136
138
  end
137
139
 
138
140
  # Shared between export controller and resource controller
139
141
  def filter_params(params)
140
142
  # OPTIMIZE: Need to check if we can permit the filter_params in a better way
141
- date_columns = self.filters.select{|x| x.filter_type.eql?(:date)}.map(&:db_column_name)
142
- range_columns = self.filters.select{|x| x.filter_type.eql?(:range)}.map(&:db_column_name)
143
- single_select_columns = self.filters.select{|x| x.filter_type.eql?(:single_select)}.map(&:db_column_name)
144
- multi_select_columns = self.filters.select{|x| x.filter_type.eql?(:multi_select)}.map{|x| Hash["#{x.db_column_name}", []]}
143
+ date_columns = filters.select { |x| x.filter_type.eql?(:date) }.map(&:db_column_name)
144
+ range_columns = filters.select { |x| x.filter_type.eql?(:range) }.map(&:db_column_name)
145
+ single_select_columns = filters.select { |x| x.filter_type.eql?(:single_select) }.map(&:db_column_name)
146
+ multi_select_columns = filters.select { |x| x.filter_type.eql?(:multi_select) }.map { |x| Hash["#{x.db_column_name}", []] }
145
147
 
146
148
  params.require(:filters).permit(:search, date: date_columns, range: range_columns, single_select: single_select_columns, multi_select: multi_select_columns) if params[:filters]
147
149
  end
@@ -151,54 +153,55 @@ module CmAdmin
151
153
  # Controller defined for each model
152
154
  # If model is User, controller will be UsersController
153
155
  def define_controller
154
- klass = Class.new(CmAdmin::ResourceController) do
155
- include Pundit::Authorization
156
- rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
157
-
158
- $available_actions.each do |action|
159
- define_method action.name.to_sym do
160
- # controller_name & action_name from ActionController
161
- @model = CmAdmin::Model.find_by(name: controller_name.classify)
162
- @model.params = params
163
- @action = CmAdmin::Models::Action.find_by(@model, name: action_name)
164
- @model.current_action = @action
165
- send(@action.controller_action_name, params)
166
- # @ar_object = @model.try(@action.parent || action_name, params)
156
+ if $available_actions.present?
157
+ klass = Class.new(CmAdmin::ResourceController) do
158
+ include Pundit::Authorization
159
+ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
160
+
161
+ $available_actions.each do |action|
162
+ define_method action.name.to_sym do
163
+ # controller_name & action_name from ActionController
164
+ @model = CmAdmin::Model.find_by(name: controller_name.classify)
165
+ @model.params = params
166
+ @action = CmAdmin::Models::Action.find_by(@model, name: action_name)
167
+ @model.current_action = @action
168
+ send(@action.controller_action_name, params)
169
+ # @ar_object = @model.try(@action.parent || action_name, params)
170
+ end
167
171
  end
168
- end
169
172
 
170
- def pundit_user
171
- Current.user
172
- end
173
+ def pundit_user
174
+ Current.user
175
+ end
173
176
 
174
- private
177
+ private
175
178
 
176
- def user_not_authorized
177
- flash[:alert] = 'You are not authorized to perform this action.'
178
- redirect_to CmAdmin::Engine.mount_path + '/access-denied'
179
+ def user_not_authorized
180
+ flash[:alert] = 'You are not authorized to perform this action.'
181
+ redirect_to CmAdmin::Engine.mount_path + '/access-denied'
182
+ end
179
183
  end
180
- end if $available_actions.present?
184
+ end
181
185
  CmAdmin.const_set "#{@name}Controller", klass
182
186
  end
183
187
 
184
188
  def define_pundit_policy(ar_model)
185
- klass = Class.new(ApplicationPolicy) do
186
-
187
- $available_actions.each do |action|
188
- define_method "#{action.name}?".to_sym do
189
-
190
- return false unless Current.user.respond_to?(:cm_role_id)
191
- return false if Current.user.cm_role.nil?
192
-
193
- Current.user.cm_role.cm_permissions.where(action_name: action.name, ar_model_name: ar_model.name).present?
189
+ if $available_actions.present?
190
+ klass = Class.new(ApplicationPolicy) do
191
+ $available_actions.each do |action|
192
+ define_method "#{action.name}?".to_sym do
193
+ return false unless Current.user.respond_to?(:cm_role_id)
194
+ return false if Current.user.cm_role.nil?
195
+
196
+ Current.user.cm_role.cm_permissions.where(action_name: action.name, ar_model_name: ar_model.name).present?
197
+ end
194
198
  end
195
199
  end
196
-
197
- end if $available_actions.present?
200
+ end
198
201
  policy = CmAdmin.const_set "#{ar_model.name}Policy", klass
199
202
 
200
203
  $available_actions.each do |action|
201
- next if ['custom_action_modal', 'custom_action', 'create', 'update'].include?(action.name)
204
+ next if %w[custom_action_modal custom_action create update].include?(action.name)
202
205
 
203
206
  klass = Class.new(policy) do
204
207
  def initialize(user, scope)
@@ -319,6 +319,7 @@ module CmAdmin
319
319
  @filters << CmAdmin::Models::Filter.new(db_column_name:, filter_type:, options:)
320
320
  end
321
321
 
322
+ # @deprecated: use {#sortable_columns} instead of this method
322
323
  # Set sort direction for filters
323
324
  # @param direction [Symbol] the direction of sort, +:asc+, +:desc+
324
325
  # @example Setting sort direction
@@ -329,6 +330,7 @@ module CmAdmin
329
330
  @current_action.sort_direction = direction.to_sym if @current_action
330
331
  end
331
332
 
333
+ # @deprecated: use {#sortable_columns} instead of this method
332
334
  # Set sort column for filters
333
335
  # @param column [Symbol] the column name
334
336
  # @example Setting sort column
@@ -374,6 +376,27 @@ module CmAdmin
374
376
  def alert_box(header: nil, body: nil, type: nil, partial: nil, display_if: nil, html_attrs: {})
375
377
  @section_fields << CmAdmin::Models::Alert.new(header, body, type, partial:, display_if:, html_attrs:)
376
378
  end
379
+
380
+ # Configure sortable columns for model
381
+ # @param columns [Array] the array of hash for column and display name
382
+ # @example Sortable Columns
383
+ # sortable_columns([{column: 'id', display_name: 'ID'}, {column: 'updated_at', display_name: 'Last Updated At'}])
384
+ #
385
+ # @example Sortable Columns with default column and direction
386
+ # sortable_columns([{column: 'id', display_name: 'ID', default: true, default_direction: 'desc'}, {column: 'updated_at', display_name: 'Last Updated At'}])
387
+ def sortable_columns(columns)
388
+ @sort_columns = columns
389
+ default_column = columns.filter do |column|
390
+ column.key?(:default) || column.key?(:default_direction)
391
+ end
392
+ raise ArgumentError, 'only one column can be default' if default_column.size > 1
393
+ return if default_column.blank?
394
+
395
+ default_column = default_column.first
396
+
397
+ @default_sort_column = default_column[:column]
398
+ @default_sort_direction = default_column[:default_direction] if default_column[:default_direction].present?
399
+ end
377
400
  end
378
401
  end
379
402
  end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = '2.1.5'
2
+ VERSION = '2.2.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cm-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.5
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: exe
16
16
  cert_chain: []
17
- date: 2024-09-24 00:00:00.000000000 Z
17
+ date: 2024-10-01 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: caxlsx_rails
@@ -345,7 +345,6 @@ files:
345
345
  - app/assets/stylesheets/cm_admin/dependency/bootstrap/scss/utilities/_api.scss
346
346
  - app/assets/stylesheets/cm_admin/dependency/bootstrap/scss/vendor/_rfs.scss
347
347
  - app/assets/stylesheets/cm_admin/dependency/flatpickr.min.css
348
- - app/assets/stylesheets/cm_admin/dependency/fontawesome.all.css
349
348
  - app/assets/stylesheets/cm_admin/dependency/jquery-jgrowl.min.css
350
349
  - app/assets/stylesheets/cm_admin/helpers/_mixins.scss
351
350
  - app/assets/stylesheets/cm_admin/helpers/_variable.scss
@@ -387,6 +386,7 @@ files:
387
386
  - app/views/cm_admin/main/_show_as_drawer.html.slim
388
387
  - app/views/cm_admin/main/_show_content.html.slim
389
388
  - app/views/cm_admin/main/_show_section.html.slim
389
+ - app/views/cm_admin/main/_sort.html.slim
390
390
  - app/views/cm_admin/main/_table.html.slim
391
391
  - app/views/cm_admin/main/_tabs.html.slim
392
392
  - app/views/cm_admin/main/_top_navbar.html.slim