cm-admin 2.1.5 → 2.2.0
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.
- 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
|