cm-admin 0.6.1 → 0.6.4
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/stylesheets/cm_admin/base/table.scss +7 -7
- data/app/assets/stylesheets/cm_admin/components/_status-tag.scss +3 -17
- data/app/helpers/cm_admin/application_helper.rb +6 -0
- data/app/views/cm_admin/main/_associated_table.html.slim +29 -24
- data/app/views/cm_admin/main/_table.html.slim +17 -10
- data/app/views/cm_admin/main/_tabs.html.slim +1 -1
- data/app/views/cm_admin/main/_top_navbar.html.slim +6 -12
- data/app/views/layouts/{_flash_message.html.slim → _cm_flash_message.html.slim} +1 -1
- data/app/views/layouts/cm_admin.html.slim +1 -4
- data/config/routes.rb +1 -1
- data/lib/cm_admin/model.rb +13 -24
- data/lib/cm_admin/models/action.rb +3 -4
- data/lib/cm_admin/models/column.rb +2 -1
- data/lib/cm_admin/models/controller_method.rb +4 -2
- data/lib/cm_admin/models/dsl_method.rb +11 -14
- data/lib/cm_admin/version.rb +1 -1
- data/lib/cm_admin/view_helpers/field_display_helper.rb +2 -1
- data/lib/cm_admin/view_helpers/form_field_helper.rb +8 -8
- data/lib/cm_admin/view_helpers/page_info_helper.rb +25 -0
- data/lib/generators/cm_admin/install_generator.rb +3 -2
- data/lib/generators/cm_admin/policy_generator.rb +13 -0
- data/{app/policies → lib/generators/cm_admin/templates}/application_policy.rb +2 -2
- data/lib/generators/cm_admin/templates/policy.rb +8 -0
- data/package.json +1 -1
- data/yarn.lock +7 -7
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42bd38332aef8d07ca35563f166f706ece3c2da88fa5e22278694da5377bb983
|
4
|
+
data.tar.gz: 292d897394afa6ee6be6a1a1a970e88e77b7d9762d6859c86bafc273de20f619
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29548bef18b577c1507ce3404a8055c3083d196c4ecaf03e62e1ccd1a9b9fa46ed128c411f95c3446fa8b95a50c245ad04d94c4a131a8b46d95bc41252e3953f
|
7
|
+
data.tar.gz: 4df3cd6b9d6d3a006798a58a292dfac7f77deaff586e622499d2474525c8060e10e4746993b53ed6f9d70d3a635acfab056ffa6ed418d9e5f5f1e4f4152b7c62
|
data/Gemfile.lock
CHANGED
@@ -18,7 +18,6 @@
|
|
18
18
|
|
19
19
|
&__table-container {
|
20
20
|
padding: 20px;
|
21
|
-
height: 100%;
|
22
21
|
}
|
23
22
|
|
24
23
|
.admin-table {
|
@@ -77,13 +76,14 @@
|
|
77
76
|
overflow: auto;
|
78
77
|
margin-top: 40px;
|
79
78
|
margin-bottom: 50px;
|
80
|
-
height:
|
79
|
+
height: calc(100vh - 365px);
|
81
80
|
.cm-table {
|
82
81
|
table-layout: fixed;
|
83
82
|
position: relative;
|
84
83
|
min-width: fit-content;
|
85
84
|
border-collapse: collapse;
|
86
85
|
border: 1px solid $grey-lighter-clr;
|
86
|
+
border-top-width: 0;
|
87
87
|
border-radius: $radius-8;
|
88
88
|
&__header {
|
89
89
|
.header-row {
|
@@ -91,6 +91,7 @@
|
|
91
91
|
width: 100%;
|
92
92
|
position: relative;
|
93
93
|
box-shadow: inset 0px -1px 0px rgba(148, 151, 155, 0.15);
|
94
|
+
border-top: 1px solid $grey-lighter-clr;
|
94
95
|
th {
|
95
96
|
@include font($size: $t6-text, $color: $ink-lighter-clr, $weight: bold);
|
96
97
|
text-transform: uppercase;
|
@@ -129,7 +130,7 @@
|
|
129
130
|
// height: 335px;
|
130
131
|
display: block;
|
131
132
|
position: relative;
|
132
|
-
width: 100%;
|
133
|
+
width: 100%;
|
133
134
|
.body-row {
|
134
135
|
border-bottom: 1.21px solid rgb(240, 239, 239);
|
135
136
|
td:nth-child(2){
|
@@ -138,7 +139,7 @@
|
|
138
139
|
z-index: 2;
|
139
140
|
background-color: #fff;
|
140
141
|
}
|
141
|
-
|
142
|
+
|
142
143
|
&:nth-last-child(1) {
|
143
144
|
box-shadow: none;
|
144
145
|
}
|
@@ -190,7 +191,6 @@
|
|
190
191
|
justify-content: center;
|
191
192
|
height: 100%;
|
192
193
|
.popup-card {
|
193
|
-
width:fit-content;
|
194
194
|
.popup-option {
|
195
195
|
a {
|
196
196
|
font-weight: 500;
|
@@ -210,8 +210,8 @@
|
|
210
210
|
}
|
211
211
|
}
|
212
212
|
.cm-table > thead {
|
213
|
-
position:sticky;
|
214
|
-
top:0;
|
213
|
+
position: sticky;
|
214
|
+
top: 0;
|
215
215
|
background-color: #fff;
|
216
216
|
z-index: 3;
|
217
217
|
}
|
@@ -4,26 +4,12 @@
|
|
4
4
|
font-size: $t4-text;
|
5
5
|
line-height: 22px;
|
6
6
|
padding: 4px;
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
11
|
-
&.default-1 {
|
7
|
+
color: $primary-text-clr;
|
8
|
+
background: $grey-lighter-clr;
|
9
|
+
&.success {
|
12
10
|
color: $green-regular-clr;
|
13
11
|
background: $green-lightest-clr;
|
14
12
|
}
|
15
|
-
&.default-2 {
|
16
|
-
color: $yellow-regular-clr;
|
17
|
-
background: $yellow-lightest-clr;
|
18
|
-
}
|
19
|
-
&.default-3 {
|
20
|
-
color: $red-regular-clr;
|
21
|
-
background: $red-lightest-clr;
|
22
|
-
}
|
23
|
-
&.default-4 {
|
24
|
-
color: $blue-regular-clr;
|
25
|
-
background: $blue-lightest-clr;
|
26
|
-
}
|
27
13
|
}
|
28
14
|
|
29
15
|
.filter-chip {
|
@@ -7,5 +7,11 @@ module CmAdmin
|
|
7
7
|
def current_webpacker_instance
|
8
8
|
CmAdmin.webpacker
|
9
9
|
end
|
10
|
+
|
11
|
+
# Allow if policy is not defined.
|
12
|
+
def has_valid_policy(model_name, action_name)
|
13
|
+
return true unless policy([:cm_admin, model_name.classify.constantize]).methods.include?(:"#{action_name}?")
|
14
|
+
policy([:cm_admin, model_name.classify.constantize]).send(:"#{action_name}?")
|
15
|
+
end
|
10
16
|
end
|
11
17
|
end
|
@@ -12,38 +12,43 @@
|
|
12
12
|
table.cm-table
|
13
13
|
thead.cm-table__header
|
14
14
|
tr.header-row
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
// To be added once bulk-select is finalized
|
16
|
+
/ th.check-box-space
|
17
|
+
/ span
|
18
|
+
/ input.cm-checkbox type="checkbox"
|
18
19
|
- @model.available_fields[@action.name.to_sym].each do |column|
|
19
20
|
th = column.header
|
20
21
|
tbody.cm-table__body
|
21
22
|
- @associated_ar_object.data.each do |ar_object|
|
22
23
|
tr.body-row
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
// To be added once bulk-select is finalized
|
25
|
+
/ td.check-box-space
|
26
|
+
/ span
|
27
|
+
/ input.cm-checkbox type="checkbox"
|
26
28
|
- @model.available_fields[@action.name.to_sym].each do |column|
|
27
29
|
td
|
28
30
|
span class="#{column.cm_css_class} text-ellipsis" = show_field_value(ar_object, column)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
-
|
46
|
-
|
31
|
+
- associated_model_actions = @associated_model && @associated_model.available_actions.select{|act| act if act.route_type == 'member'}
|
32
|
+
- if associated_model_actions.present?
|
33
|
+
td.row-action-cell
|
34
|
+
.row-action-tool
|
35
|
+
button.secondary-btn.tool-btn type="button"
|
36
|
+
span
|
37
|
+
i.fa.fa-bars.bolder
|
38
|
+
span
|
39
|
+
i.fa.fa-angle-down
|
40
|
+
.popup-card.table-export-popup.hidden
|
41
|
+
// To be added once the associated model has edit actions
|
42
|
+
/ .popup-option
|
43
|
+
/ a href="#{page_url('edit', ar_object)}"
|
44
|
+
/ | Edit
|
45
|
+
- associated_model_actions.each do |custom_action|
|
46
|
+
- if custom_action.display_if.call(ar_object)
|
47
|
+
.popup-option
|
48
|
+
- if custom_action.display_type == :button
|
49
|
+
= link_to custom_action.name.titleize, custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb
|
50
|
+
- elsif custom_action.display_type == :modal
|
51
|
+
= link_to custom_action.name.titleize, '', data: { bs_toggle: "modal", bs_target: "##{custom_action.name.classify}Modal-#{ar_object.id.to_s}" }
|
47
52
|
|
48
53
|
.cm-pagination
|
49
54
|
.cm-pagination__lhs Showing #{@associated_ar_object.pagy.from} to #{@associated_ar_object.pagy.to} out of #{@associated_ar_object.pagy.count}
|
@@ -11,17 +11,18 @@
|
|
11
11
|
table.cm-table
|
12
12
|
thead.cm-table__header
|
13
13
|
tr.header-row
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
// Select all checkbox feature to be added later
|
15
|
+
/ th.check-box-space
|
16
|
+
/ span
|
17
|
+
/ input.cm-checkbox type="checkbox"
|
17
18
|
- @model.available_fields[:index].each do |column|
|
18
19
|
th = column.header
|
19
20
|
tbody.cm-table__body
|
20
21
|
- @ar_object.data.each do |ar_object|
|
21
22
|
tr.body-row
|
22
|
-
td.check-box-space
|
23
|
-
|
24
|
-
|
23
|
+
/ td.check-box-space
|
24
|
+
/ span
|
25
|
+
/ input.cm-checkbox type="checkbox"
|
25
26
|
- @model.available_fields[:index].each_with_index do |column, index|
|
26
27
|
td.text-ellipsis
|
27
28
|
span class="#{column.field_type.to_s} #{column.cm_css_class} "
|
@@ -45,12 +46,18 @@
|
|
45
46
|
.popup-card.table-export-popup.hidden
|
46
47
|
- if edit_action.any? && policy([:cm_admin, @model.name.classify.constantize]).edit?
|
47
48
|
= link_to "#{page_url('edit', ar_object)}" do
|
48
|
-
.popup-option
|
49
|
+
.popup-option
|
50
|
+
span
|
51
|
+
i.fa.fa-edit
|
52
|
+
| Edit
|
49
53
|
- custom_actions.each do |custom_action|
|
50
|
-
- if custom_action.name.present? &&
|
54
|
+
- if custom_action.name.present? && has_valid_policy(@model.name, custom_action.name)
|
51
55
|
- if custom_action.display_if.call(ar_object)
|
52
|
-
= link_to custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb do
|
53
|
-
.popup-option
|
56
|
+
= link_to cm_admin.send("#{@model.name.downcase}_index_path") + '/' + custom_action.path.gsub(':id', ar_object.id.to_s), method: custom_action.verb do
|
57
|
+
.popup-option
|
58
|
+
span
|
59
|
+
i class="#{custom_action.icon_name}"
|
60
|
+
= custom_action.name.titleize
|
54
61
|
|
55
62
|
.cm-pagination
|
56
63
|
.cm-pagination__lhs Showing #{@ar_object.pagy.from} to #{@ar_object.pagy.to} out of #{@ar_object.pagy.count}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
ul.nav.nav-pills
|
2
2
|
- @model.available_tabs.each do |nav_item|
|
3
|
-
- if nav_item.custom_action.present? && policy([:cm_admin, @model.name.classify.constantize]).send(:"#{nav_item.custom_action}?")
|
3
|
+
- if nav_item.custom_action.empty? || (nav_item.custom_action.present? && policy([:cm_admin, @model.name.classify.constantize]).send(:"#{nav_item.custom_action}?"))
|
4
4
|
li.nav-item
|
5
5
|
- nav_item_action_name = nav_item.custom_action.present? ? nav_item.custom_action : 'show'
|
6
6
|
= link_to nav_item.nav_item_name.to_s.titleize, "/cm_admin/#{@model.name.underscore.pluralize}/#{@ar_object.id}/#{nav_item.custom_action}", class: "nav-link #{ nav_item_action_name == action_name ? 'active' : ''}"
|
@@ -1,7 +1,9 @@
|
|
1
1
|
.cm-navbar
|
2
2
|
.cm-navbar__lhs
|
3
|
-
.
|
4
|
-
|
3
|
+
- if cm_admin.method_defined?(:"#{@model.name.downcase}_index_path") && (@model.current_action.name == 'show' || @model.current_action.layout_type.present?)
|
4
|
+
.bread-crumb-area
|
5
|
+
.breadcrumb-text
|
6
|
+
= link_to @model.name + ' /', cm_admin.send(:"#{@model.name.downcase}_index_path")
|
5
7
|
.nav-title-area
|
6
8
|
p.title-text = action_title
|
7
9
|
p.title-sub-text = action_description
|
@@ -24,18 +26,10 @@
|
|
24
26
|
- if new_action.any? && policy([:cm_admin, @model.name.classify.constantize]).new?
|
25
27
|
= link_to 'Add', "#{page_url('new')}", class: 'primary-btn ml-2'
|
26
28
|
- @model.available_actions.select{|act| act if act.route_type == 'collection'}.each do |custom_action|
|
27
|
-
|
28
|
-
- if custom_action.display_type == :button
|
29
|
-
= link_to custom_action.name.titleize, @model.ar_model.table_name + '/' + custom_action.path, class: 'primary-btn ml-2', method: custom_action.verb
|
30
|
-
- elsif custom_action.display_type == :modal
|
31
|
-
= link_to custom_action.name.titleize, '', class: 'primary-btn ml-2', data: { bs_toggle: "modal", bs_target: "##{custom_action.name.classify}Modal" }
|
29
|
+
= custom_action_items(custom_action, 'index')
|
32
30
|
- elsif @model.current_action.name == 'show'
|
33
31
|
- @model.available_actions.select{|act| act if act.route_type == 'member'}.each do |custom_action|
|
34
|
-
|
35
|
-
- if custom_action.display_type == :button && custom_action.display_if.call(@ar_object)
|
36
|
-
= link_to custom_action.name.titleize, custom_action.path.gsub(':id', params[:id]), class: 'primary-btn ml-2', method: custom_action.verb
|
37
|
-
- elsif custom_action.display_type == :modal && custom_action.display_if.call(@ar_object)
|
38
|
-
= link_to custom_action.name.titleize, '', class: 'primary-btn ml-2', data: { bs_toggle: "modal", bs_target: "##{custom_action.name.classify}Modal" }
|
32
|
+
= custom_action_items(custom_action, 'show')
|
39
33
|
|
40
34
|
- edit_action = @model.available_actions.select{|act| act if act.action_type.eql?(:default) && act.name.eql?('edit')}
|
41
35
|
- if edit_action.any? && policy([:cm_admin, @model.name.classify.constantize]).edit?
|
@@ -15,9 +15,6 @@ html
|
|
15
15
|
script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"
|
16
16
|
script src="https://raw.githack.com/SortableJS/Sortable/master/Sortable.js"
|
17
17
|
body
|
18
|
-
- flash.each do |type, msg|
|
19
|
-
.alert class="alert-#{type}"
|
20
|
-
= msg
|
21
18
|
.cm-admin
|
22
19
|
= render 'layouts/left_sidebar_nav'
|
23
20
|
.panel-area
|
@@ -41,6 +38,6 @@ html
|
|
41
38
|
= yield
|
42
39
|
- else
|
43
40
|
= yield
|
44
|
-
= render 'layouts/
|
41
|
+
= render 'layouts/cm_flash_message'
|
45
42
|
= render 'layouts/custom_action_modals'
|
46
43
|
|
data/config/routes.rb
CHANGED
@@ -10,7 +10,7 @@ CmAdmin::Engine.routes.draw do
|
|
10
10
|
|
11
11
|
# Defining action routes for each model
|
12
12
|
CmAdmin.config.cm_admin_models.each do |model|
|
13
|
-
model.available_actions.sort_by {|act| act.
|
13
|
+
model.available_actions.sort_by {|act| act.name}.each do |act|
|
14
14
|
scope model.name.tableize do
|
15
15
|
send(act.verb, act.path.present? ? act.path : act.name, to: "#{model.name.underscore}##{act.name}", as: "#{model.name.underscore}_#{act.name}")
|
16
16
|
end
|
data/lib/cm_admin/model.rb
CHANGED
@@ -45,7 +45,6 @@ module CmAdmin
|
|
45
45
|
actions unless @actions_set
|
46
46
|
$available_actions = @available_actions.dup
|
47
47
|
self.class.all_actions.push(@available_actions)
|
48
|
-
define_policy
|
49
48
|
define_controller
|
50
49
|
end
|
51
50
|
|
@@ -101,23 +100,6 @@ module CmAdmin
|
|
101
100
|
|
102
101
|
private
|
103
102
|
|
104
|
-
def define_policy
|
105
|
-
klass = Class.new(ApplicationPolicy) do
|
106
|
-
def initialize(user, record)
|
107
|
-
@user = user
|
108
|
-
@record = record
|
109
|
-
end
|
110
|
-
|
111
|
-
$available_actions.each do |action|
|
112
|
-
define_method :"#{action.name}?" do
|
113
|
-
accessible_by = action.accessible_by.map { |role| "user.#{role}" }.join(' || ')
|
114
|
-
eval(accessible_by)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
CmAdmin.const_set "#{@name}Policy", klass
|
119
|
-
end
|
120
|
-
|
121
103
|
# Controller defined for each model
|
122
104
|
# If model is User, controller will be UsersController
|
123
105
|
def define_controller
|
@@ -135,7 +117,7 @@ module CmAdmin
|
|
135
117
|
@model.current_action = @action
|
136
118
|
@ar_object = @model.try(@action.parent || action_name, params)
|
137
119
|
@ar_object, @associated_model, @associated_ar_object = @model.custom_controller_action(action_name, params.permit!) if !@ar_object.present? && params[:id].present?
|
138
|
-
authorize controller_name.classify.constantize, policy_class: "CmAdmin::#{controller_name.classify}Policy".constantize
|
120
|
+
authorize controller_name.classify.constantize, policy_class: "CmAdmin::#{controller_name.classify}Policy".constantize if defined? "CmAdmin::#{controller_name.classify}Policy".constantize
|
139
121
|
aar_model = request.url.split('/')[-2].classify.constantize if params[:aar_id]
|
140
122
|
@associated_ar_object = aar_model.find(params[:aar_id]) if params[:aar_id]
|
141
123
|
nested_tables = @model.available_fields[:new].except(:fields).keys
|
@@ -157,10 +139,15 @@ module CmAdmin
|
|
157
139
|
format.html { render '/cm_admin/main/'+action_name }
|
158
140
|
end
|
159
141
|
elsif %w(create update destroy).include?(action_name)
|
142
|
+
if %w(create update).include?(action_name)
|
143
|
+
redirect_url = CmAdmin::Engine.mount_path + "/#{@model.name.underscore.pluralize}/#{@ar_object.id}"
|
144
|
+
else
|
145
|
+
redirect_url = CmAdmin::Engine.mount_path + "/#{@model.name.underscore.pluralize}"
|
146
|
+
end
|
160
147
|
if @ar_object.save
|
161
|
-
format.html { redirect_to
|
148
|
+
format.html { redirect_to redirect_url, notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is successful" }
|
162
149
|
else
|
163
|
-
format.html { render '/cm_admin/main/new' }
|
150
|
+
format.html { render '/cm_admin/main/new', notice: "#{action_name.titleize} #{@ar_object.class.name.downcase} is unsuccessful" }
|
164
151
|
end
|
165
152
|
elsif action.action_type == :custom
|
166
153
|
if action.child_records
|
@@ -169,11 +156,13 @@ module CmAdmin
|
|
169
156
|
data = @action.parent == "index" ? @ar_object.data : @ar_object
|
170
157
|
format.html { render action.partial }
|
171
158
|
else
|
172
|
-
|
159
|
+
ar_object = @action.code_block.call(@ar_object)
|
160
|
+
if ar_object.errors.empty?
|
173
161
|
redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@ar_object.id}"
|
174
|
-
format.html { redirect_to redirect_url }
|
162
|
+
format.html { redirect_to redirect_url, notice: "#{@action.name.titleize} is successful" }
|
175
163
|
else
|
176
|
-
|
164
|
+
error_messages = @ar_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
|
165
|
+
format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><ul>#{error_messages}</ul>" }
|
177
166
|
end
|
178
167
|
end
|
179
168
|
elsif action.layout.present?
|
@@ -6,7 +6,7 @@ module CmAdmin
|
|
6
6
|
include Actions::Blocks
|
7
7
|
attr_accessor :name, :verb, :layout_type, :layout, :partial, :path, :page_title, :page_description,
|
8
8
|
:child_records, :is_nested_field, :nested_table_name, :parent, :display_if, :route_type, :code_block,
|
9
|
-
:display_type, :action_type, :redirection_url, :sort_direction, :sort_column, :
|
9
|
+
:display_type, :action_type, :redirection_url, :sort_direction, :sort_column, :icon_name
|
10
10
|
|
11
11
|
VALID_SORT_DIRECTION = Set[:asc, :desc].freeze
|
12
12
|
|
@@ -34,14 +34,13 @@ module CmAdmin
|
|
34
34
|
self.action_type = :default
|
35
35
|
self.sort_column = :created_at
|
36
36
|
self.sort_direction = :desc
|
37
|
-
self.
|
37
|
+
self.icon_name = 'fa fa-th-large'
|
38
38
|
end
|
39
39
|
|
40
|
-
def set_values(page_title, page_description, partial
|
40
|
+
def set_values(page_title, page_description, partial)
|
41
41
|
self.page_title = page_title
|
42
42
|
self.page_description = page_description
|
43
43
|
self.partial = partial
|
44
|
-
self.accessible_by = (CmAdmin.authorized_roles.dup << accessible_by).flatten.compact.uniq if accessible_by
|
45
44
|
end
|
46
45
|
|
47
46
|
class << self
|
@@ -2,7 +2,7 @@ module CmAdmin
|
|
2
2
|
module Models
|
3
3
|
class Column
|
4
4
|
attr_accessor :field_name, :field_type, :header, :format, :prefix, :suffix, :exportable, :round,
|
5
|
-
:cm_css_class, :link, :url, :custom_method, :helper_method, :managable, :lockable, :drawer_partial
|
5
|
+
:cm_css_class, :link, :url, :custom_method, :helper_method, :managable, :lockable, :drawer_partial, :tag_class
|
6
6
|
|
7
7
|
def initialize(field_name, attributes = {})
|
8
8
|
@field_name = field_name
|
@@ -24,6 +24,7 @@ module CmAdmin
|
|
24
24
|
self.exportable = true
|
25
25
|
self.managable = true
|
26
26
|
self.lockable = false
|
27
|
+
self.tag_class = {}
|
27
28
|
end
|
28
29
|
|
29
30
|
#formatting value for different data types
|
@@ -5,7 +5,8 @@ module CmAdmin
|
|
5
5
|
|
6
6
|
def show(params)
|
7
7
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
|
8
|
-
|
8
|
+
scoped_model = "CmAdmin::#{self.name}Policy::Scope".constantize.new(Current.user, self.name.constantize).resolve
|
9
|
+
@ar_object = scoped_model.find(params[:id])
|
9
10
|
end
|
10
11
|
|
11
12
|
def index(params)
|
@@ -40,7 +41,8 @@ module CmAdmin
|
|
40
41
|
sort_column = "created_at"
|
41
42
|
sort_direction = %w[asc desc].include?(sort_params[:sort_direction]) ? sort_params[:sort_direction] : "asc"
|
42
43
|
sort_params = {sort_column: sort_column, sort_direction: sort_direction}
|
43
|
-
|
44
|
+
|
45
|
+
records = "CmAdmin::#{self.name}Policy::Scope".constantize.new(Current.user, self.name.constantize).resolve if records.nil?
|
44
46
|
records = records.order("#{current_action.sort_column} #{current_action.sort_direction}")
|
45
47
|
|
46
48
|
final_data = CmAdmin::Models::Filter.filtered_data(filter_params, records, @filters)
|
@@ -10,28 +10,28 @@ module CmAdmin
|
|
10
10
|
# @current_action = CmAdmin::Models::CustomAction.find_by(self, name: name)
|
11
11
|
end
|
12
12
|
|
13
|
-
def cm_index(page_title: nil, page_description: nil, partial: nil,
|
13
|
+
def cm_index(page_title: nil, page_description: nil, partial: nil, &block)
|
14
14
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'index')
|
15
|
-
@current_action.set_values(page_title, page_description, partial
|
15
|
+
@current_action.set_values(page_title, page_description, partial)
|
16
16
|
yield
|
17
17
|
# action.instance_eval(&block)
|
18
18
|
end
|
19
19
|
|
20
|
-
def cm_show(page_title: nil, page_description: nil, partial: nil,
|
20
|
+
def cm_show(page_title: nil, page_description: nil, partial: nil, &block)
|
21
21
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
|
22
|
-
@current_action.set_values(page_title, page_description, partial
|
22
|
+
@current_action.set_values(page_title, page_description, partial)
|
23
23
|
yield
|
24
24
|
end
|
25
25
|
|
26
|
-
def cm_edit(page_title: nil,page_description: nil, partial: nil,
|
26
|
+
def cm_edit(page_title: nil,page_description: nil, partial: nil, &block)
|
27
27
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'edit')
|
28
|
-
@current_action.set_values(page_title, page_description, partial
|
28
|
+
@current_action.set_values(page_title, page_description, partial)
|
29
29
|
yield
|
30
30
|
end
|
31
31
|
|
32
|
-
def cm_new(page_title: nil,page_description: nil, partial: nil,
|
32
|
+
def cm_new(page_title: nil,page_description: nil, partial: nil, &block)
|
33
33
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'new')
|
34
|
-
@current_action.set_values(page_title, page_description, partial
|
34
|
+
@current_action.set_values(page_title, page_description, partial)
|
35
35
|
yield
|
36
36
|
end
|
37
37
|
|
@@ -47,16 +47,14 @@ module CmAdmin
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def tab(tab_name, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil,
|
50
|
+
def tab(tab_name, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil, &block)
|
51
51
|
if custom_action.to_s == ''
|
52
52
|
@current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
|
53
|
-
@current_action.accessible_by = (CmAdmin.authorized_roles.dup << accessible_by).flatten.compact.uniq if accessible_by
|
54
53
|
@available_tabs << CmAdmin::Models::Tab.new(tab_name, '', &block)
|
55
54
|
else
|
56
55
|
action = CmAdmin::Models::Action.new(name: custom_action.to_s, verb: :get, path: ':id/'+custom_action,
|
57
56
|
layout_type: layout_type, layout: layout, partial: partial, child_records: associated_model,
|
58
57
|
action_type: :custom, display_type: :page)
|
59
|
-
action.accessible_by = (CmAdmin.authorized_roles.dup << accessible_by).flatten.compact.uniq if accessible_by
|
60
58
|
@available_actions << action
|
61
59
|
@current_action = action
|
62
60
|
@available_tabs << CmAdmin::Models::Tab.new(tab_name, custom_action, &block)
|
@@ -117,12 +115,11 @@ module CmAdmin
|
|
117
115
|
# end
|
118
116
|
# end
|
119
117
|
# end
|
120
|
-
def custom_action(name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, display_if: lambda { |arg| return true }, route_type: nil,
|
118
|
+
def custom_action(name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, display_if: lambda { |arg| return true }, route_type: nil, icon_name: 'fa fa-th-large', &block)
|
121
119
|
action = CmAdmin::Models::CustomAction.new(
|
122
120
|
name: name, verb: verb, layout: layout, layout_type: layout_type, partial: partial, path: path,
|
123
121
|
parent: self.current_action.name, display_type: display_type, display_if: display_if,
|
124
|
-
action_type: :custom, route_type: route_type, &block)
|
125
|
-
action.accessible_by = (CmAdmin.authorized_roles.dup << accessible_by).flatten.compact.uniq if accessible_by
|
122
|
+
action_type: :custom, route_type: route_type, icon_name: icon_name, &block)
|
126
123
|
@available_actions << action
|
127
124
|
# self.class.class_eval(&block)
|
128
125
|
end
|
data/lib/cm_admin/version.rb
CHANGED
@@ -51,7 +51,8 @@ module CmAdmin
|
|
51
51
|
when :enum
|
52
52
|
ar_object.send(field.field_name).to_s.titleize
|
53
53
|
when :tag
|
54
|
-
|
54
|
+
tag_class = field.tag_class.dig("#{ar_object.send(field.field_name.to_s)}".to_sym).to_s
|
55
|
+
content_tag :span, class: "status-tag #{tag_class}" do
|
55
56
|
ar_object.send(field.field_name).to_s.upcase
|
56
57
|
end
|
57
58
|
when :attachment
|
@@ -5,21 +5,21 @@ module CmAdmin
|
|
5
5
|
value = field.custom_value || f.object.send(field.field_name)
|
6
6
|
case field.input_type
|
7
7
|
when :integer
|
8
|
-
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, data: {behaviour: 'integer-only'}
|
8
|
+
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.humanize.downcase}", data: { behaviour: 'integer-only' }
|
9
9
|
when :decimal
|
10
|
-
return f.number_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, data: {behaviour: 'decimal-only'}
|
10
|
+
return f.number_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'decimal-only' }
|
11
11
|
when :string
|
12
|
-
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value
|
12
|
+
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
|
13
13
|
when :single_select
|
14
|
-
return f.select field.field_name, options_for_select(field.collection || []), {}, class: 'normal-input select-2', disabled: field.disabled
|
14
|
+
return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: 'normal-input select-2', disabled: field.disabled
|
15
15
|
when :multi_select
|
16
|
-
return f.select field.field_name, options_for_select(field.collection || []), {}, class: 'normal-input select-2', disabled: field.disabled, multiple: true
|
16
|
+
return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: 'normal-input select-2', disabled: field.disabled, multiple: true
|
17
17
|
when :date
|
18
|
-
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, data: {behaviour: 'date-only'}
|
18
|
+
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-only' }
|
19
19
|
when :date_time
|
20
|
-
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, data: {behaviour: 'date-time'}
|
20
|
+
return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-time' }
|
21
21
|
when :text
|
22
|
-
return f.text_area field.field_name, class: 'normal-input'
|
22
|
+
return f.text_area field.field_name, class: 'normal-input', placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
|
23
23
|
when :single_file_upload
|
24
24
|
return f.file_field field.field_name, class: 'normal-input'
|
25
25
|
when :multi_file_upload
|
@@ -53,6 +53,31 @@ module CmAdmin
|
|
53
53
|
base_path + "/#{ar_object.id}" + '/edit'
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
def custom_action_items(custom_action, current_action_name)
|
58
|
+
if custom_action.name.present? && policy([:cm_admin, @model.name.classify.constantize]).send(:"#{custom_action.name}?")
|
59
|
+
if custom_action.display_if.call(@ar_object)
|
60
|
+
case custom_action.display_type
|
61
|
+
when :button
|
62
|
+
custom_action_button(custom_action, current_action_name)
|
63
|
+
when :modal
|
64
|
+
custom_modal_button(custom_action)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def custom_action_button(custom_action, current_action_name)
|
71
|
+
if current_action_name == "index"
|
72
|
+
link_to custom_action.name.titleize, @model.ar_model.table_name + '/' + custom_action.path, class: 'secondary-btn ml-2', method: custom_action.verb
|
73
|
+
elsif current_action_name == "show"
|
74
|
+
link_to custom_action.name.titleize, custom_action.path.gsub(':id', params[:id]), class: 'secondary-btn ml-2', method: custom_action.verb
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def custom_modal_button(custom_action)
|
79
|
+
link_to custom_action.name.titleize, '', class: 'secondary-btn ml-2', data: { bs_toggle: "modal", bs_target: "##{custom_action.name.classify}Modal" }
|
80
|
+
end
|
56
81
|
end
|
57
82
|
end
|
58
83
|
end
|
@@ -7,8 +7,9 @@ module CmAdmin
|
|
7
7
|
|
8
8
|
def copy_initializer
|
9
9
|
copy_file 'cm_admin_initializer.rb', 'config/initializers/cm_admin.rb'
|
10
|
-
copy_file 'custom.js', 'app/assets/javascripts/custom.js'
|
11
|
-
copy_file 'custom.css', 'app/assets/stylesheets/custom.css'
|
10
|
+
copy_file 'custom.js', 'app/assets/javascripts/cm_admin/custom.js'
|
11
|
+
copy_file 'custom.css', 'app/assets/stylesheets/cm_admin/custom.css'
|
12
|
+
copy_file 'application_policy.rb', 'app/policies/application_policy.rb'
|
12
13
|
route 'mount CmAdmin::Engine => "/admin"'
|
13
14
|
end
|
14
15
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module CmAdmin
|
4
|
+
module Generators
|
5
|
+
class PolicyGenerator < Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
|
8
|
+
def copy_policy_files
|
9
|
+
template "policy.rb", "app/policies/cm_admin/#{file_name}_policy.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -17,7 +17,7 @@ class ApplicationPolicy
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def create?
|
20
|
-
|
20
|
+
true
|
21
21
|
end
|
22
22
|
|
23
23
|
def new?
|
@@ -43,7 +43,7 @@ class ApplicationPolicy
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def resolve
|
46
|
-
|
46
|
+
scope.all
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class CmAdmin::<%= class_name %>Policy < ApplicationPolicy
|
2
|
+
<%- available_action_names = (CmAdmin::Model.find_by({name: class_name}).available_actions.map{|action| action.name}.uniq - ['custom_action', 'new', 'edit']) %>
|
3
|
+
<%- available_action_names.each do |action_name| %>
|
4
|
+
def <%= action_name %>?
|
5
|
+
<%= CmAdmin.authorized_roles.map {|role| "@user.#{role}" }.join(' && ') %>
|
6
|
+
end
|
7
|
+
<% end %>
|
8
|
+
end
|
data/package.json
CHANGED
data/yarn.lock
CHANGED
@@ -4123,9 +4123,9 @@ minimatch@^3.0.4:
|
|
4123
4123
|
brace-expansion "^1.1.7"
|
4124
4124
|
|
4125
4125
|
minimist@^1.2.0, minimist@^1.2.5:
|
4126
|
-
version "1.2.
|
4127
|
-
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.
|
4128
|
-
integrity sha512-
|
4126
|
+
version "1.2.6"
|
4127
|
+
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
4128
|
+
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
4129
4129
|
|
4130
4130
|
minipass-collect@^1.0.2:
|
4131
4131
|
version "1.0.2"
|
@@ -4199,10 +4199,10 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
|
4199
4199
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
4200
4200
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
4201
4201
|
|
4202
|
-
moment@^2.29.
|
4203
|
-
version "2.29.
|
4204
|
-
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.
|
4205
|
-
integrity sha512-
|
4202
|
+
moment@^2.29.2, moment@^2.9.0:
|
4203
|
+
version "2.29.2"
|
4204
|
+
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4"
|
4205
|
+
integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==
|
4206
4206
|
|
4207
4207
|
move-concurrently@^1.0.1:
|
4208
4208
|
version "1.0.1"
|
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: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sajinmp
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-04-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: pagy
|
@@ -152,7 +152,6 @@ files:
|
|
152
152
|
- app/javascript/packs/cm_admin/quick_search.js
|
153
153
|
- app/javascript/packs/cm_admin/scaffolds.js
|
154
154
|
- app/javascript/stylesheets/cm_admin/application.scss
|
155
|
-
- app/policies/application_policy.rb
|
156
155
|
- app/views/cm_admin/main/_associated_table.html.slim
|
157
156
|
- app/views/cm_admin/main/_cm_pagy_nav.html.slim
|
158
157
|
- app/views/cm_admin/main/_drawer.html.slim
|
@@ -172,8 +171,8 @@ files:
|
|
172
171
|
- app/views/cm_admin/static/dashboard.html.slim
|
173
172
|
- app/views/cm_admin/static/error_401.html.slim
|
174
173
|
- app/views/cm_admin/static/error_403.html.slim
|
174
|
+
- app/views/layouts/_cm_flash_message.html.slim
|
175
175
|
- app/views/layouts/_custom_action_modals.html.slim
|
176
|
-
- app/views/layouts/_flash_message.html.slim
|
177
176
|
- app/views/layouts/_left_sidebar_nav.html.slim
|
178
177
|
- app/views/layouts/_quick_links.html.slim
|
179
178
|
- app/views/layouts/cm_admin.html.slim
|
@@ -222,9 +221,12 @@ files:
|
|
222
221
|
- lib/cm_admin/view_helpers/navigation_helper.rb
|
223
222
|
- lib/cm_admin/view_helpers/page_info_helper.rb
|
224
223
|
- lib/generators/cm_admin/install_generator.rb
|
224
|
+
- lib/generators/cm_admin/policy_generator.rb
|
225
|
+
- lib/generators/cm_admin/templates/application_policy.rb
|
225
226
|
- lib/generators/cm_admin/templates/cm_admin_initializer.rb
|
226
227
|
- lib/generators/cm_admin/templates/custom.css
|
227
228
|
- lib/generators/cm_admin/templates/custom.js
|
229
|
+
- lib/generators/cm_admin/templates/policy.rb
|
228
230
|
- lib/tasks/webpack_install.rake
|
229
231
|
- package.json
|
230
232
|
- postcss.config.js
|