cm-admin 0.7.4 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 810496f7dd375b4849ce820652272c6d36dec1767807beab966e4abc1a00a922
4
- data.tar.gz: 522f04bc7abeddf95dceebfe980c3b7d955b3d3907de9060af5923803622ed59
3
+ metadata.gz: fc4dad533a8a02bcc62cc27dd83d829b07794c32a2849e2eebc21de1c1f6cc84
4
+ data.tar.gz: 30b772fbd67cf68633111b3290685e8d3d9d03c269d93313ab915d490c458311
5
5
  SHA512:
6
- metadata.gz: fc0a6ebd3f81ee0c8df337d630c71cff47d49bb7e422e1d39f9f5f1663c21e7714bd740cf8b1a37d37cbbc3827d18ccc58822031794a228696043633886466ec
7
- data.tar.gz: 6a13e1994ea27658ac281f88970b1d5b471ee52982be02af9e8ce55dd1b9f6706085543a3f0cbddced246371254b8143243ed6e2756e413d6302fde891718c9d
6
+ metadata.gz: 31ec145cf1c7bb3c60a878b733fd251169d5403b6501f421180880ef56c7857f37e5d303ed4b93bd56a6ebfa4b7642f526db533864156a6e5a4e50af19b69d8a
7
+ data.tar.gz: c45f05a62af30393e5d8bb458374afc51695c311310d6b3d497d6326913cbc45de634385d57a757e91748033de2765e321619c2ed64d1807ec612b763b98a8c1
data/Gemfile.lock CHANGED
@@ -1,31 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cm-admin (0.7.3)
4
+ cm-admin (0.7.7)
5
5
  axlsx_rails (~> 0.6.1)
6
6
  cocoon (~> 1.2.15)
7
+ local_time (~> 2.1.0)
7
8
  pagy (~> 4.11.0)
8
9
  pundit (~> 2.2.0)
9
10
  slim (~> 4.1.0)
10
- webpacker (~> 5.2.1)
11
+ webpacker (~> 5.4.3)
11
12
 
12
13
  GEM
13
14
  remote: https://rubygems.org/
14
15
  specs:
15
- actionpack (7.0.2.3)
16
- actionview (= 7.0.2.3)
17
- activesupport (= 7.0.2.3)
16
+ actionpack (7.0.3.1)
17
+ actionview (= 7.0.3.1)
18
+ activesupport (= 7.0.3.1)
18
19
  rack (~> 2.0, >= 2.2.0)
19
20
  rack-test (>= 0.6.3)
20
21
  rails-dom-testing (~> 2.0)
21
22
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
22
- actionview (7.0.2.3)
23
- activesupport (= 7.0.2.3)
23
+ actionview (7.0.3.1)
24
+ activesupport (= 7.0.3.1)
24
25
  builder (~> 3.1)
25
26
  erubi (~> 1.4)
26
27
  rails-dom-testing (~> 2.0)
27
28
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
28
- activesupport (7.0.2.3)
29
+ activesupport (7.0.3.1)
29
30
  concurrent-ruby (~> 1.0, >= 1.0.2)
30
31
  i18n (>= 1.6, < 2)
31
32
  minitest (>= 5.1)
@@ -40,38 +41,39 @@ GEM
40
41
  nokogiri (~> 1.10, >= 1.10.4)
41
42
  rubyzip (>= 1.3.0, < 3)
42
43
  cocoon (1.2.15)
43
- concurrent-ruby (1.1.9)
44
+ concurrent-ruby (1.1.10)
44
45
  crass (1.0.6)
45
46
  diff-lcs (1.4.4)
46
47
  erubi (1.10.0)
47
48
  htmlentities (4.3.4)
48
- i18n (1.10.0)
49
+ i18n (1.11.0)
49
50
  concurrent-ruby (~> 1.0)
50
- loofah (2.17.0)
51
+ local_time (2.1.0)
52
+ loofah (2.18.0)
51
53
  crass (~> 1.0.2)
52
54
  nokogiri (>= 1.5.9)
53
55
  marcel (1.0.2)
54
56
  method_source (1.0.0)
55
- minitest (5.15.0)
56
- nokogiri (1.13.5-arm64-darwin)
57
+ minitest (5.16.2)
58
+ nokogiri (1.13.7-arm64-darwin)
57
59
  racc (~> 1.4)
58
60
  pagy (4.11.0)
59
61
  pundit (2.2.0)
60
62
  activesupport (>= 3.0.0)
61
63
  racc (1.6.0)
62
- rack (2.2.3.1)
64
+ rack (2.2.4)
63
65
  rack-proxy (0.7.2)
64
66
  rack
65
- rack-test (1.1.0)
66
- rack (>= 1.0, < 3)
67
+ rack-test (2.0.2)
68
+ rack (>= 1.3)
67
69
  rails-dom-testing (2.0.3)
68
70
  activesupport (>= 4.2.0)
69
71
  nokogiri (>= 1.6)
70
- rails-html-sanitizer (1.4.2)
72
+ rails-html-sanitizer (1.4.3)
71
73
  loofah (~> 2.3)
72
- railties (7.0.2.3)
73
- actionpack (= 7.0.2.3)
74
- activesupport (= 7.0.2.3)
74
+ railties (7.0.3.1)
75
+ actionpack (= 7.0.3.1)
76
+ activesupport (= 7.0.3.1)
75
77
  method_source
76
78
  rake (>= 12.2)
77
79
  thor (~> 1.0)
@@ -100,12 +102,12 @@ GEM
100
102
  tilt (2.0.10)
101
103
  tzinfo (2.0.4)
102
104
  concurrent-ruby (~> 1.0)
103
- webpacker (5.2.2)
105
+ webpacker (5.4.3)
104
106
  activesupport (>= 5.2)
105
107
  rack-proxy (>= 0.6.1)
106
108
  railties (>= 5.2)
107
109
  semantic_range (>= 2.3.0)
108
- zeitwerk (2.5.4)
110
+ zeitwerk (2.6.0)
109
111
 
110
112
  PLATFORMS
111
113
  ruby
data/README.md CHANGED
@@ -30,7 +30,7 @@ You can find more detailed documentation [here](https://github.com/commutatus/cm
30
30
 
31
31
  ## Demo
32
32
 
33
- For demo check [here](http://cm-admin.labs.commutatus.com/admin/users/)
33
+ For demo check [here](http://cm-admin.labs.commutatus.com)
34
34
  For demo repo check [here](https://github.com/commutatus/cm-admin-panel-demo)
35
35
 
36
36
  ## Development
@@ -1,9 +1,8 @@
1
1
  module CmAdmin
2
2
  class ApplicationController < ::ActionController::Base
3
- include Pundit::Authorization
3
+
4
4
  # before_action :check_cm_admin
5
5
  layout 'cm_admin'
6
- helper CmAdmin::ViewHelpers
7
6
 
8
7
 
9
8
  def check_cm_admin
@@ -0,0 +1,194 @@
1
+ module CmAdmin
2
+ class ResourceController < ApplicationController
3
+ include Pundit::Authorization
4
+ include Pagy::Backend
5
+
6
+ helper CmAdmin::ViewHelpers
7
+
8
+ def cm_index(params)
9
+ @current_action = CmAdmin::Models::Action.find_by(@model, name: 'index')
10
+ # Based on the params the filter and pagination object to be set
11
+ @ar_object = filter_by(params, nil, @model.filter_params(params))
12
+ # resource_identifier
13
+ respond_to do |format|
14
+ if request.xhr?
15
+ format.html { render partial: '/cm_admin/main/table' }
16
+ else
17
+ format.html { render '/cm_admin/main/' + action_name }
18
+ end
19
+ end
20
+ end
21
+
22
+ def cm_show(params)
23
+ @current_action = CmAdmin::Models::Action.find_by(@model, name: 'show')
24
+ scoped_model = "CmAdmin::#{@model.name}Policy::Scope".constantize.new(Current.user, @model.name.constantize).resolve
25
+ @ar_object = scoped_model.find(params[:id])
26
+ resource_identifier
27
+ respond_to do |format|
28
+ format.html { render '/cm_admin/main/' + action_name }
29
+ end
30
+ end
31
+
32
+ def cm_new(params)
33
+ @current_action = CmAdmin::Models::Action.find_by(@model, name: 'new')
34
+ @ar_object = @model.ar_model.new
35
+ resource_identifier
36
+ respond_to do |format|
37
+ format.html { render '/cm_admin/main/' + action_name }
38
+ end
39
+ end
40
+
41
+ def cm_edit(params)
42
+ @current_action = CmAdmin::Models::Action.find_by(@model, name: 'edit')
43
+ @ar_object = @model.ar_model.name.classify.constantize.find(params[:id])
44
+ resource_identifier
45
+ respond_to do |format|
46
+ format.html { render '/cm_admin/main/' + action_name }
47
+ end
48
+ end
49
+
50
+ def cm_update(params)
51
+ @ar_object = @model.ar_model.name.classify.constantize.find(params[:id])
52
+ @ar_object.assign_attributes(resource_params(params))
53
+ resource_identifier
54
+ resource_responder
55
+ end
56
+
57
+ def cm_create(params)
58
+ @ar_object = @model.ar_model.name.classify.constantize.new(resource_params(params))
59
+ resource_identifier
60
+ resource_responder
61
+ end
62
+
63
+ def cm_destroy(params)
64
+ @ar_object = @model.ar_model.name.classify.constantize.find(params[:id])
65
+ respond_to do |format|
66
+ if @ar_object.destroy
67
+ format.html { redirect_back fallback_location: cm_admin.send("#{@model.name.underscore}_index_path"), notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is successful" }
68
+ else
69
+ format.html { redirect_back fallback_location: cm_admin.send("#{@model.name.underscore}_index_path"), notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is unsuccessful" }
70
+ end
71
+ end
72
+ end
73
+
74
+ def cm_custom_method(params)
75
+ scoped_model = "CmAdmin::#{@model.name}Policy::Scope".constantize.new(Current.user, @model.name.constantize).resolve
76
+ resource_identifier
77
+ respond_to do |format|
78
+ if @action.action_type == :custom
79
+ if @action.child_records
80
+ format.html { render @action.layout }
81
+ elsif @action.display_type == :page
82
+ data = @action.parent == "index" ? @ar_object.data : @ar_object
83
+ format.html { render @action.partial }
84
+ else
85
+ ar_object = @action.code_block.call(@ar_object)
86
+ if ar_object.errors.empty?
87
+ redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@ar_object.id}"
88
+ format.html { redirect_to redirect_url, notice: "#{@action.name.titleize} is successful" }
89
+ else
90
+ error_messages = ar_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
91
+ format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><ul>#{error_messages}</ul>" }
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def resource_identifier
99
+ @ar_object, @associated_model, @associated_ar_object = custom_controller_action(action_name, params.permit!) if !@ar_object.present? && params[:id].present?
100
+ authorize controller_name.classify.constantize, policy_class: "CmAdmin::#{controller_name.classify}Policy".constantize if defined? "CmAdmin::#{controller_name.classify}Policy".constantize
101
+ aar_model = request.url.split('/')[-2].classify.constantize if params[:aar_id]
102
+ @associated_ar_object = aar_model.find(params[:aar_id]) if params[:aar_id]
103
+ nested_tables = @model.available_fields[:new].except(:fields).keys
104
+ nested_tables += @model.available_fields[:edit].except(:fields).keys
105
+ @reflections = @model.ar_model.reflect_on_all_associations
106
+ nested_tables.each do |table_name|
107
+ reflection = @reflections.select {|x| x if x.name == table_name}.first
108
+ if reflection.macro == :has_many
109
+ @ar_object.send(table_name).build if action_name == "new" || action_name == "edit"
110
+ elsif action_name == "new"
111
+ @ar_object.send(('build_' + table_name.to_s).to_sym)
112
+ end
113
+ end
114
+ end
115
+
116
+ def resource_responder
117
+ respond_to do |format|
118
+ if params["referrer"]
119
+ redirect_url = params["referrer"]
120
+ else
121
+ redirect_url = CmAdmin::Engine.mount_path + "/#{@model.name.underscore.pluralize}/#{@ar_object.id}"
122
+ end
123
+ if @ar_object.save
124
+ format.html { redirect_to redirect_url, notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is successful" }
125
+ else
126
+ format.html { render '/cm_admin/main/new', notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is unsuccessful" }
127
+ end
128
+ end
129
+ end
130
+
131
+ def custom_controller_action(action_name, params)
132
+ current_action = CmAdmin::Models::Action.find_by(@model, name: action_name.to_s)
133
+ if current_action
134
+ @current_action = current_action
135
+ @ar_object = @model.ar_model.name.classify.constantize.find(params[:id])
136
+ if @current_action.child_records
137
+ child_records = @ar_object.send(@current_action.child_records)
138
+ @associated_model = CmAdmin::Model.find_by(name: @model.ar_model.reflect_on_association(@current_action.child_records).klass.name)
139
+ if child_records.is_a? ActiveRecord::Relation
140
+ @associated_ar_object = filter_by(params, child_records)
141
+ else
142
+ @associated_ar_object = child_records
143
+ end
144
+ return @ar_object, @associated_model, @associated_ar_object
145
+ end
146
+ return @ar_object
147
+ end
148
+ end
149
+
150
+ def filter_by(params, records, filter_params={}, sort_params={})
151
+ filtered_result = OpenStruct.new
152
+ sort_column = "created_at"
153
+ sort_direction = %w[asc desc].include?(sort_params[:sort_direction]) ? sort_params[:sort_direction] : "asc"
154
+ sort_params = {sort_column: sort_column, sort_direction: sort_direction}
155
+
156
+ records = "CmAdmin::#{@model.name}Policy::Scope".constantize.new(Current.user, @model.name.constantize).resolve if records.nil?
157
+ records = records.order("#{@current_action.sort_column} #{@current_action.sort_direction}")
158
+
159
+ final_data = CmAdmin::Models::Filter.filtered_data(filter_params, records, @model.filters)
160
+ pagy, records = pagy(final_data)
161
+ filtered_result.data = records
162
+ filtered_result.pagy = pagy
163
+ # filtered_result.facets = paginate(page, raw_data.size)
164
+ # filtered_result.sort = sort_params
165
+ # filtered_result.facets.sort = sort_params
166
+ return filtered_result
167
+ end
168
+
169
+ def resource_params(params)
170
+ permittable_fields = @permitted_fields || @model.ar_model.columns.map(&:name).reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym)
171
+ permittable_fields += @model.ar_model.name.constantize.reflect_on_all_associations.map {|x|
172
+ next if x.options[:polymorphic]
173
+ if x.class.name.include?('HasOne')
174
+ x.name.to_s.gsub('_attachment', '').gsub('rich_text_', '').to_sym
175
+ elsif x.class.name.include?('HasMany')
176
+ Hash[x.name.to_s.gsub('_attachment', ''), []]
177
+ end
178
+ }.compact
179
+ nested_tables = @model.available_fields[:new].except(:fields).keys
180
+ nested_tables += @model.available_fields[:edit].except(:fields).keys
181
+ nested_fields = nested_tables.uniq.map {|table|
182
+ Hash[
183
+ table.to_s + '_attributes',
184
+ table.to_s.classify.constantize.columns.map(&:name).reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym) + [:id, :_destroy]
185
+ ]
186
+ }
187
+ permittable_fields += nested_fields
188
+ @model.ar_model.columns.map { |col| permittable_fields << col.name.split('_cents') if col.name.include?('_cents') }
189
+
190
+ params.require(@model.name.underscore.to_sym).permit(*permittable_fields)
191
+ end
192
+
193
+ end
194
+ end
@@ -15,9 +15,11 @@ require('./filters.js')
15
15
  require('./exports.js')
16
16
 
17
17
  import jQuery from 'jquery'
18
+ import LocalTime from "local-time"
18
19
  window.$ = jQuery
19
20
  window.jQuery = jQuery
20
21
 
22
+ LocalTime.start()
21
23
  require("@nathanvda/cocoon")
22
24
  import "@fortawesome/fontawesome-free/css/all"
23
25
  import "daterangepicker"
@@ -0,0 +1,52 @@
1
+ - edit_action = available_actions(cm_model, 'edit')
2
+ - destroy_action = available_actions(cm_model, 'destroy')
3
+ - custom_actions = available_actions(cm_model, 'custom_actions')
4
+ - custom_actions_modals = custom_actions.select{ |act| act if act.display_type.eql?(:modal) }
5
+
6
+ - if custom_actions.any? || edit_action.present? || destroy_action.present?
7
+ td.row-action-cell
8
+ .row-action-tool
9
+ button.secondary-btn.tool-btn
10
+ span
11
+ i.fa.fa-bars.bolder
12
+ span
13
+ i.fa.fa-angle-down
14
+ .popup-card.table-export-popup.hidden
15
+ - if edit_action.present?
16
+ = link_to "#{page_url('edit', ar_object)}" do
17
+ .popup-option
18
+ span
19
+ i.fa.fa-edit
20
+ | Edit
21
+ - if destroy_action.present?
22
+ = link_to "#{page_url('destroy', ar_object)}", method: :delete do
23
+ .popup-option
24
+ span
25
+ i.fa.fa-trash
26
+ | Destroy
27
+ - custom_actions.each do |custom_action|
28
+ - if custom_action.display_if.call(ar_object)
29
+ - case custom_action.display_type
30
+ - when :button
31
+ = link_to cm_admin.send("#{cm_model.name.underscore}_index_path") + '/' + custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb do
32
+ .popup-option
33
+ span
34
+ i class="#{custom_action.icon_name}"
35
+ = custom_action.name.humanize
36
+ - when :modal
37
+ = link_to '', data: { bs_toggle: 'modal', bs_target: "##{custom_action.name.classify}Modal-#{ar_object.id.to_s}" } do
38
+ .popup-option
39
+ span
40
+ i class="#{custom_action.icon_name}"
41
+ = custom_action.name.humanize
42
+
43
+ - if custom_actions_modals.any?
44
+ - custom_actions_modals.each do |custom_action|
45
+ .modal.fade id="#{custom_action.name.classify}Modal-#{ar_object.id.to_s}" aria-hidden='true' aria-labelledby="#{custom_action.name.classify}ModalLabel" tabindex='1'
46
+ .modal-dialog
47
+ .modal-content
48
+ .modal-header
49
+ h5.modal-title id="#{custom_action.name.classify}ModalLabel" = custom_action.name.classify
50
+ button.btn-close aria-label='Close' data-bs-dismiss='modal'
51
+ .modal-body
52
+ = render partial: custom_action.partial, locals: { ar_object: ar_object }
@@ -36,43 +36,10 @@
36
36
  a href="#{CmAdmin::Engine.mount_path}/#{@associated_model.name.tableize}/#{ar_object.id}" = show_field_value(ar_object, column)
37
37
  - else
38
38
  span class="#{column.cm_css_class}" = show_field_value(ar_object, column)
39
- - associated_model_actions = @associated_model && @associated_model.available_actions.select{|act| act if act.route_type == 'member'}
40
- - if associated_model_actions.present?
41
- td.row-action-cell
42
- .row-action-tool
43
- button.secondary-btn.tool-btn type="button"
44
- span
45
- i.fa.fa-bars.bolder
46
- span
47
- i.fa.fa-angle-down
48
- .popup-card.table-export-popup.hidden
49
- // To be added once the associated model has edit actions
50
- / .popup-option
51
- / a href="#{page_url('edit', ar_object)}"
52
- / | Edit
53
- - associated_model_actions.each do |custom_action|
54
- - if custom_action.display_if.call(ar_object)
55
- .popup-option
56
- - if custom_action.display_type == :button
57
- = link_to cm_admin.send("#{@associated_model.name.underscore}_index_path") + '/' + custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb do
58
- span
59
- i class="#{custom_action.icon_name}"
60
- = custom_action.name.humanize
61
- - elsif custom_action.display_type == :modal
62
- = link_to custom_action.name.humanize, '', data: { bs_toggle: 'modal', bs_target: "##{custom_action.name.classify}Modal-#{ar_object.id.to_s}" }
39
+ - if @associated_model
40
+ == render partial: 'cm_admin/main/actions_dropdown', locals: { cm_model: @associated_model, ar_object: ar_object }
63
41
 
64
42
  .cm-pagination
65
43
  .cm-pagination__lhs Showing #{@associated_ar_object.pagy.from} to #{@associated_ar_object.pagy.to} out of #{@associated_ar_object.pagy.count}
66
44
  .cm-pagination__rhs
67
45
  == render partial: 'cm_admin/main/cm_pagy_nav', locals: { pagy: @associated_ar_object.pagy }
68
-
69
- - @associated_ar_object.data.each do |ar_object|
70
- - @associated_model && @associated_model.available_actions.select{|act| act if (act.route_type == 'member' && act.display_type == :modal)}.each do |custom_action|
71
- .modal.fade id="#{custom_action.name.classify}Modal-#{ar_object.id.to_s}" aria-hidden='true' aria-labelledby="#{custom_action.name.classify}ModalLabel" tabindex='1'
72
- .modal-dialog
73
- .modal-content
74
- .modal-header
75
- h5.modal-title id="#{custom_action.name.classify}ModalLabel" = custom_action.name.classify
76
- button.btn-close aria-label='Close' data-bs-dismiss='modal'
77
- .modal-body
78
- = render partial: custom_action.partial, locals: { ar_object: ar_object }
@@ -31,40 +31,9 @@
31
31
  - else
32
32
  = show_field_value(ar_object, column)
33
33
  - if column.field_type == :drawer
34
- = render partial: column.drawer_partial, locals: { ar_object: ar_object}
35
-
36
- - edit_action = @model.available_actions.select{|act| act if act.action_type.eql?(:default) && act.name.eql?('edit')}
37
- - destroy_action = @model.available_actions.select{|act| act if act.action_type.eql?(:default) && act.name.eql?('destroy')}
38
- - custom_actions = @model.available_actions.select{|act| act if act.route_type == 'member' && [:button, :modal].include?(act.display_type)}
39
- - if custom_actions.any? || edit_action.any? || destroy_action.any?
40
- td.row-action-cell
41
- .row-action-tool
42
- button.secondary-btn.tool-btn type="button"
43
- span
44
- i.fa.fa-bars.bolder
45
- span
46
- i.fa.fa-angle-down
47
- .popup-card.table-export-popup.hidden
48
- - if edit_action.any? && policy([:cm_admin, @model.name.classify.constantize]).edit?
49
- = link_to "#{page_url('edit', ar_object)}" do
50
- .popup-option
51
- span
52
- i.fa.fa-edit
53
- | Edit
54
- - if destroy_action.any? && policy([:cm_admin, @model.name.classify.constantize]).destroy?
55
- = link_to "#{page_url('destroy', ar_object)}", method: :delete do
56
- .popup-option
57
- span
58
- i.fa.fa-trash
59
- | Destroy
60
- - custom_actions.each do |custom_action|
61
- - if custom_action.name.present? && has_valid_policy(@model.name, custom_action.name)
62
- - if custom_action.display_if.call(ar_object)
63
- = link_to cm_admin.send("#{@model.name.underscore}_index_path") + '/' + custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb do
64
- .popup-option
65
- span
66
- i class="#{custom_action.icon_name}"
67
- = custom_action.name.humanize
34
+ = render partial: column.drawer_partial, locals: { ar_object: ar_object }
35
+ - if @model
36
+ == render partial: 'cm_admin/main/actions_dropdown', locals: { cm_model: @model, ar_object: ar_object }
68
37
 
69
38
  .cm-pagination
70
39
  .cm-pagination__lhs Showing #{@ar_object.pagy.from} to #{@ar_object.pagy.to} out of #{@ar_object.pagy.count}
data/cm_admin.gemspec CHANGED
@@ -26,10 +26,11 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
- spec.add_runtime_dependency 'pagy', '~> 4.11.0'
30
- spec.add_runtime_dependency 'slim', '~> 4.1.0'
31
- spec.add_runtime_dependency 'webpacker', '~> 5.2.1'
32
29
  spec.add_runtime_dependency 'axlsx_rails', '~> 0.6.1'
33
30
  spec.add_runtime_dependency 'cocoon', '~> 1.2.15'
31
+ spec.add_runtime_dependency 'local_time', '~> 2.1.0'
32
+ spec.add_runtime_dependency 'pagy', '~> 4.11.0'
34
33
  spec.add_runtime_dependency 'pundit', '~> 2.2.0'
34
+ spec.add_runtime_dependency 'slim', '~> 4.1.0'
35
+ spec.add_runtime_dependency 'webpacker', '~> 5.4.3'
35
36
  end
@@ -10,18 +10,17 @@ require_relative 'models/export'
10
10
  require_relative 'models/cm_show_section'
11
11
  require_relative 'models/tab'
12
12
  require_relative 'models/dsl_method'
13
- require_relative 'models/controller_method'
14
13
  require 'pagy'
15
14
  require 'axlsx'
16
15
  require 'cocoon'
17
16
  require 'pundit'
17
+ require 'local_time'
18
18
 
19
19
  module CmAdmin
20
20
  class Model
21
21
  include Pagy::Backend
22
22
  include Models::Blocks
23
23
  include Models::DslMethod
24
- include Models::ControllerMethod
25
24
  attr_accessor :available_actions, :actions_set, :available_fields, :permitted_fields,
26
25
  :current_action, :params, :filters, :available_tabs, :icon_name
27
26
  attr_reader :name, :ar_model, :is_visible_on_sidebar
@@ -89,12 +88,13 @@ module CmAdmin
89
88
  @icon_name = name
90
89
  end
91
90
 
91
+ # Shared between export controller and resource controller
92
92
  def filter_params(params)
93
93
  # OPTIMIZE: Need to check if we can permit the filter_params in a better way
94
- date_columns = @filters.select{|x| x.filter_type.eql?(:date)}.map(&:db_column_name)
95
- range_columns = @filters.select{|x| x.filter_type.eql?(:range)}.map(&:db_column_name)
96
- single_select_columns = @filters.select{|x| x.filter_type.eql?(:single_select)}.map(&:db_column_name)
97
- multi_select_columns = @filters.select{|x| x.filter_type.eql?(:multi_select)}.map{|x| Hash["#{x.db_column_name}", []]}
94
+ date_columns = self.filters.select{|x| x.filter_type.eql?(:date)}.map(&:db_column_name)
95
+ range_columns = self.filters.select{|x| x.filter_type.eql?(:range)}.map(&:db_column_name)
96
+ single_select_columns = self.filters.select{|x| x.filter_type.eql?(:single_select)}.map(&:db_column_name)
97
+ multi_select_columns = self.filters.select{|x| x.filter_type.eql?(:multi_select)}.map{|x| Hash["#{x.db_column_name}", []]}
98
98
 
99
99
  params.require(:filters).permit(:search, date: date_columns, range: range_columns, single_select: single_select_columns, multi_select: multi_select_columns) if params[:filters]
100
100
  end
@@ -104,7 +104,7 @@ module CmAdmin
104
104
  # Controller defined for each model
105
105
  # If model is User, controller will be UsersController
106
106
  def define_controller
107
- klass = Class.new(CmAdmin::ApplicationController) do
107
+ klass = Class.new(CmAdmin::ResourceController) do
108
108
  include Pundit::Authorization
109
109
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
110
110
 
@@ -116,68 +116,14 @@ module CmAdmin
116
116
  @model.params = params
117
117
  @action = CmAdmin::Models::Action.find_by(@model, name: action_name)
118
118
  @model.current_action = @action
119
- @ar_object = @model.try(@action.parent || action_name, params)
120
- @ar_object, @associated_model, @associated_ar_object = @model.custom_controller_action(action_name, params.permit!) if !@ar_object.present? && params[:id].present?
121
- authorize controller_name.classify.constantize, policy_class: "CmAdmin::#{controller_name.classify}Policy".constantize if defined? "CmAdmin::#{controller_name.classify}Policy".constantize
122
- aar_model = request.url.split('/')[-2].classify.constantize if params[:aar_id]
123
- @associated_ar_object = aar_model.find(params[:aar_id]) if params[:aar_id]
124
- nested_tables = @model.available_fields[:new].except(:fields).keys
125
- nested_tables += @model.available_fields[:edit].except(:fields).keys
126
- @reflections = @model.ar_model.reflect_on_all_associations
127
- nested_tables.each do |table_name|
128
- reflection = @reflections.select {|x| x if x.name == table_name}.first
129
- if reflection.macro == :has_many
130
- @ar_object.send(table_name).build if action_name == "new" || action_name == "edit"
131
- else
132
- @ar_object.send(('build_' + table_name.to_s).to_sym) if action_name == "new"
133
- end
134
- end
135
- respond_to do |format|
136
- if %w(show index new edit).include?(action_name)
137
- if request.xhr? && action_name.eql?('index')
138
- format.html { render partial: '/cm_admin/main/table' }
139
- else
140
- format.html { render '/cm_admin/main/'+action_name }
141
- end
142
- elsif %w(create update destroy).include?(action_name)
143
- if params["referrer"]
144
- redirect_url = params["referrer"]
145
- elsif %w(create update).include?(action_name)
146
- redirect_url = CmAdmin::Engine.mount_path + "/#{@model.name.underscore.pluralize}/#{@ar_object.id}"
147
- else
148
- redirect_url = CmAdmin::Engine.mount_path + "/#{@model.name.underscore.pluralize}"
149
- end
150
- if action_name.eql?('destroy') || @ar_object.save
151
- format.html { redirect_to redirect_url, notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is successful" }
152
- else
153
- format.html { render '/cm_admin/main/new', notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is unsuccessful" }
154
- end
155
- elsif action.action_type == :custom
156
- if action.child_records
157
- format.html { render action.layout }
158
- elsif action.display_type == :page
159
- data = @action.parent == "index" ? @ar_object.data : @ar_object
160
- format.html { render action.partial }
161
- else
162
- ar_object = @action.code_block.call(@ar_object)
163
- if ar_object.errors.empty?
164
- redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@ar_object.id}"
165
- format.html { redirect_to redirect_url, notice: "#{@action.name.titleize} is successful" }
166
- else
167
- error_messages = ar_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
168
- format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><ul>#{error_messages}</ul>" }
169
- end
170
- end
171
- elsif action.layout.present?
172
- if request.xhr? && action.partial.present?
173
- format.html { render partial: action.partial }
174
- else
175
- format.html { render action.layout }
176
- end
177
- end
178
- end
119
+ send(@action.controller_action_name, params)
120
+ # @ar_object = @model.try(@action.parent || action_name, params)
179
121
  end
180
122
  end
123
+
124
+ def pundit_user
125
+ Current.user
126
+ end
181
127
  private
182
128
 
183
129
  def user_not_authorized
@@ -43,6 +43,16 @@ module CmAdmin
43
43
  self.partial = partial
44
44
  end
45
45
 
46
+ def controller_action_name
47
+ if self.action_type == :custom
48
+ 'cm_custom_method'
49
+ elsif self.parent
50
+ 'cm_' + self.parent
51
+ else
52
+ 'cm_' + name
53
+ end
54
+ end
55
+
46
56
  class << self
47
57
  def find_by(model, search_hash)
48
58
  model.available_actions.find { |i| i.name == search_hash[:name] }
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = "0.7.4"
2
+ VERSION = "0.7.7"
3
3
  end