cm-admin 2.1.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,12 +117,12 @@ 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
 
122
- def table_name
123
- @display_name.present? ? @display_name : @ar_model.table_name
124
+ def formatted_name
125
+ @display_name != @name ? @display_name : @ar_model.table_name
124
126
  end
125
127
 
126
128
  def alert_box(options = {})
@@ -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,30 @@ 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
+ # @note default sort direction will be ascending
382
+ # @param columns [Array] the array of hash for column and display name
383
+ # @example Sortable Columns
384
+ # sortable_columns([{column: 'id', display_name: 'ID'},
385
+ # {column: 'updated_at', display_name: 'Last Updated At'}])
386
+ #
387
+ # @example Sortable Columns with default column and direction
388
+ # sortable_columns([{column: 'id', display_name: 'ID', default: true, default_direction: 'desc'},
389
+ # {column: 'updated_at', display_name: 'Last Updated At'}])
390
+ def sortable_columns(columns)
391
+ @sort_columns = columns
392
+ default_column = columns.filter do |column|
393
+ column.key?(:default) || column.key?(:default_direction)
394
+ end
395
+ raise ArgumentError, 'only one column can be default' if default_column.size > 1
396
+ return if default_column.blank?
397
+
398
+ default_column = default_column.first
399
+
400
+ @default_sort_column = default_column[:column]
401
+ @default_sort_direction = default_column[:default_direction] if default_column[:default_direction].present?
402
+ end
377
403
  end
378
404
  end
379
405
  end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = '2.1.5'
2
+ VERSION = '2.2.1'
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.1
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-03 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