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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/assets/javascripts/cm_admin/filters.js +30 -3
- data/app/assets/javascripts/cm_admin/scaffolds.js +0 -1
- data/app/assets/stylesheets/cm_admin/base/filters.scss +20 -0
- data/app/assets/stylesheets/cm_admin/cm_admin.css.scss +0 -1
- data/app/controllers/cm_admin/resource_controller.rb +58 -56
- data/app/views/cm_admin/main/_associated_table.html.slim +10 -12
- data/app/views/cm_admin/main/_nested_table_form.html.slim +1 -1
- data/app/views/cm_admin/main/_sort.html.slim +27 -0
- data/app/views/cm_admin/main/_table.html.slim +4 -5
- data/app/views/layouts/cm_admin.html.slim +1 -0
- data/config/importmap.rb +0 -1
- data/config/routes.rb +7 -1
- data/lib/cm_admin/model.rb +63 -60
- data/lib/cm_admin/models/dsl_method.rb +23 -0
- data/lib/cm_admin/version.rb +1 -1
- metadata +3 -3
- data/app/assets/stylesheets/cm_admin/dependency/fontawesome.all.css +0 -7831
data/lib/cm_admin/model.rb
CHANGED
@@ -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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
90
|
-
acts
|
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 =
|
142
|
-
range_columns =
|
143
|
-
single_select_columns =
|
144
|
-
multi_select_columns =
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
|
171
|
-
|
172
|
-
|
173
|
+
def pundit_user
|
174
|
+
Current.user
|
175
|
+
end
|
173
176
|
|
174
|
-
|
177
|
+
private
|
175
178
|
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
184
|
+
end
|
181
185
|
CmAdmin.const_set "#{@name}Controller", klass
|
182
186
|
end
|
183
187
|
|
184
188
|
def define_pundit_policy(ar_model)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
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 [
|
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
|
data/lib/cm_admin/version.rb
CHANGED
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.
|
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-
|
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
|